am e3a60386: (-s ours) Reconcile with jb-mr0-release - do not merge
* commit 'e3a6038600ca1447d2920cc9351a1f70fe17e9b2':
diff --git a/res/drawable/contacts_widget_preview.png b/res/drawable-nodpi/contacts_widget_preview.png
similarity index 100%
rename from res/drawable/contacts_widget_preview.png
rename to res/drawable-nodpi/contacts_widget_preview.png
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/divider_vertical_dark.9.png b/res/drawable-xlarge-nodpi/divider_vertical_dark.9.png
deleted file mode 100644
index 38b794b..0000000
--- a/res/drawable-xlarge-nodpi/divider_vertical_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/res/layout-w470dp/contact_detail_container.xml b/res/layout-land/contact_detail_container.xml
similarity index 100%
rename from res/layout-w470dp/contact_detail_container.xml
rename to res/layout-land/contact_detail_container.xml
diff --git a/res/layout-w470dp/contact_detail_fragment.xml b/res/layout-land/contact_detail_fragment.xml
similarity index 100%
rename from res/layout-w470dp/contact_detail_fragment.xml
rename to res/layout-land/contact_detail_fragment.xml
diff --git a/res/layout-w470dp/contact_detail_updates_fragment.xml b/res/layout-land/contact_detail_updates_fragment.xml
similarity index 100%
rename from res/layout-w470dp/contact_detail_updates_fragment.xml
rename to res/layout-land/contact_detail_updates_fragment.xml
diff --git a/res/layout-w470dp/detail_header_contact_with_updates.xml b/res/layout-land/detail_header_contact_with_updates.xml
similarity index 100%
rename from res/layout-w470dp/detail_header_contact_with_updates.xml
rename to res/layout-land/detail_header_contact_with_updates.xml
diff --git a/res/layout-w470dp/detail_header_contact_without_updates.xml b/res/layout-land/detail_header_contact_without_updates.xml
similarity index 100%
rename from res/layout-w470dp/detail_header_contact_without_updates.xml
rename to res/layout-land/detail_header_contact_without_updates.xml
diff --git a/res/layout-w470dp/group_source_button.xml b/res/layout-land/group_source_button.xml
similarity index 100%
rename from res/layout-w470dp/group_source_button.xml
rename to res/layout-land/group_source_button.xml
diff --git a/res/layout-w470dp/quickcontact_activity.xml b/res/layout-land/quickcontact_activity.xml
similarity index 100%
rename from res/layout-w470dp/quickcontact_activity.xml
rename to res/layout-land/quickcontact_activity.xml
diff --git a/res/layout-land/quickcontact_list_fragment_bottom.xml b/res/layout-land/quickcontact_list_fragment_bottom.xml
deleted file mode 100755
index 957ec53..0000000
--- a/res/layout-land/quickcontact_list_fragment_bottom.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<View xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_alignParentBottom="true"
- style="@style/QuickContactListBottomStyle"/>
diff --git a/res/layout-w470dp/updates_header_contact.xml b/res/layout-land/updates_header_contact.xml
similarity index 100%
rename from res/layout-w470dp/updates_header_contact.xml
rename to res/layout-land/updates_header_contact.xml
diff --git a/res/layout-sw580dp-w940dp/contact_detail_container.xml b/res/layout-sw580dp-land/contact_detail_container.xml
similarity index 100%
rename from res/layout-sw580dp-w940dp/contact_detail_container.xml
rename to res/layout-sw580dp-land/contact_detail_container.xml
diff --git a/res/layout-sw580dp-w940dp/contact_detail_fragment.xml b/res/layout-sw580dp-land/contact_detail_fragment.xml
similarity index 100%
rename from res/layout-sw580dp-w940dp/contact_detail_fragment.xml
rename to res/layout-sw580dp-land/contact_detail_fragment.xml
diff --git a/res/layout-sw580dp-w940dp/contact_detail_updates_fragment.xml b/res/layout-sw580dp-land/contact_detail_updates_fragment.xml
similarity index 100%
rename from res/layout-sw580dp-w940dp/contact_detail_updates_fragment.xml
rename to res/layout-sw580dp-land/contact_detail_updates_fragment.xml
diff --git a/res/layout-sw580dp-w940dp/contact_editor_activity.xml b/res/layout-sw580dp-land/contact_editor_activity.xml
similarity index 100%
rename from res/layout-sw580dp-w940dp/contact_editor_activity.xml
rename to res/layout-sw580dp-land/contact_editor_activity.xml
diff --git a/res/layout-sw580dp-w940dp/detail_header_contact_with_updates.xml b/res/layout-sw580dp-land/detail_header_contact_with_updates.xml
similarity index 100%
rename from res/layout-sw580dp-w940dp/detail_header_contact_with_updates.xml
rename to res/layout-sw580dp-land/detail_header_contact_with_updates.xml
diff --git a/res/layout-sw580dp-w940dp/detail_header_contact_without_updates.xml b/res/layout-sw580dp-land/detail_header_contact_without_updates.xml
similarity index 100%
rename from res/layout-sw580dp-w940dp/detail_header_contact_without_updates.xml
rename to res/layout-sw580dp-land/detail_header_contact_without_updates.xml
diff --git a/res/layout-sw580dp-w940dp/group_browse_list_account_header.xml b/res/layout-sw580dp-land/group_browse_list_account_header.xml
similarity index 100%
rename from res/layout-sw580dp-w940dp/group_browse_list_account_header.xml
rename to res/layout-sw580dp-land/group_browse_list_account_header.xml
diff --git a/res/layout-sw580dp-w940dp/people_activity.xml b/res/layout-sw580dp-land/people_activity.xml
similarity index 100%
rename from res/layout-sw580dp-w940dp/people_activity.xml
rename to res/layout-sw580dp-land/people_activity.xml
diff --git a/res/layout-sw580dp-w940dp/quickcontact_activity.xml b/res/layout-sw580dp-land/quickcontact_activity.xml
similarity index 100%
rename from res/layout-sw580dp-w940dp/quickcontact_activity.xml
rename to res/layout-sw580dp-land/quickcontact_activity.xml
diff --git a/res/layout-sw580dp-w940dp/updates_header_contact.xml b/res/layout-sw580dp-land/updates_header_contact.xml
similarity index 100%
rename from res/layout-sw580dp-w940dp/updates_header_contact.xml
rename to res/layout-sw580dp-land/updates_header_contact.xml
diff --git a/res/layout-sw580dp-w940dp/quickcontact_list_fragment_bottom.xml b/res/layout-sw580dp-w940dp/quickcontact_list_fragment_bottom.xml
deleted file mode 100755
index e08b3aa..0000000
--- a/res/layout-sw580dp-w940dp/quickcontact_list_fragment_bottom.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<View xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_alignBottom="@+id/list"
- style="@style/QuickContactListBottomStyle"/>
diff --git a/res/layout-sw580dp/favorites_star.xml b/res/layout-sw580dp/favorites_star.xml
index 22b9339..6c83866 100644
--- a/res/layout-sw580dp/favorites_star.xml
+++ b/res/layout-sw580dp/favorites_star.xml
@@ -15,11 +15,14 @@
-->
<!-- The favorite star, shown outside of the ActionBar -->
-<ImageView
+<!-- The content description is set in code -->
+<ImageButton
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/star"
android:layout_width="48dip"
android:layout_height="48dip"
android:scaleType="center"
android:background="?android:attr/selectableItemBackground"
- android:src="@drawable/btn_star_off_normal_holo_light" />
+ android:src="@drawable/btn_star_off_normal_holo_light"
+ tools:ignore="ContentDescription" />
diff --git a/res/layout-sw680dp-w1000dp/contact_detail_container.xml b/res/layout-sw680dp-land/contact_detail_container.xml
similarity index 100%
rename from res/layout-sw680dp-w1000dp/contact_detail_container.xml
rename to res/layout-sw680dp-land/contact_detail_container.xml
diff --git a/res/layout-sw680dp-w1000dp/contact_detail_empty.xml b/res/layout-sw680dp-land/contact_detail_empty.xml
similarity index 100%
rename from res/layout-sw680dp-w1000dp/contact_detail_empty.xml
rename to res/layout-sw680dp-land/contact_detail_empty.xml
diff --git a/res/layout-sw680dp-w1000dp/contact_detail_fragment.xml b/res/layout-sw680dp-land/contact_detail_fragment.xml
similarity index 100%
rename from res/layout-sw680dp-w1000dp/contact_detail_fragment.xml
rename to res/layout-sw680dp-land/contact_detail_fragment.xml
diff --git a/res/layout-sw680dp-w1000dp/contact_detail_list_item.xml b/res/layout-sw680dp-land/contact_detail_list_item.xml
similarity index 100%
rename from res/layout-sw680dp-w1000dp/contact_detail_list_item.xml
rename to res/layout-sw680dp-land/contact_detail_list_item.xml
diff --git a/res/layout-sw680dp-w1000dp/contact_detail_updates_fragment.xml b/res/layout-sw680dp-land/contact_detail_updates_fragment.xml
similarity index 100%
rename from res/layout-sw680dp-w1000dp/contact_detail_updates_fragment.xml
rename to res/layout-sw680dp-land/contact_detail_updates_fragment.xml
diff --git a/res/layout-sw680dp-w1000dp/detail_header_contact_with_updates.xml b/res/layout-sw680dp-land/detail_header_contact_with_updates.xml
similarity index 100%
rename from res/layout-sw680dp-w1000dp/detail_header_contact_with_updates.xml
rename to res/layout-sw680dp-land/detail_header_contact_with_updates.xml
diff --git a/res/layout-sw680dp-w1000dp/detail_header_contact_without_updates.xml b/res/layout-sw680dp-land/detail_header_contact_without_updates.xml
similarity index 100%
rename from res/layout-sw680dp-w1000dp/detail_header_contact_without_updates.xml
rename to res/layout-sw680dp-land/detail_header_contact_without_updates.xml
diff --git a/res/layout-sw680dp-w1000dp/people_activity.xml b/res/layout-sw680dp-land/people_activity.xml
similarity index 100%
rename from res/layout-sw680dp-w1000dp/people_activity.xml
rename to res/layout-sw680dp-land/people_activity.xml
diff --git a/res/layout-sw680dp-w1000dp/quickcontact_activity.xml b/res/layout-sw680dp-land/quickcontact_activity.xml
similarity index 100%
rename from res/layout-sw680dp-w1000dp/quickcontact_activity.xml
rename to res/layout-sw680dp-land/quickcontact_activity.xml
diff --git a/res/layout-sw680dp-w1000dp/updates_header_contact.xml b/res/layout-sw680dp-land/updates_header_contact.xml
similarity index 100%
rename from res/layout-sw680dp-w1000dp/updates_header_contact.xml
rename to res/layout-sw680dp-land/updates_header_contact.xml
diff --git a/res/layout-sw680dp/contact_detail_container.xml b/res/layout-sw680dp/contact_detail_container.xml
deleted file mode 100644
index dfbd0d0..0000000
--- a/res/layout-sw680dp/contact_detail_container.xml
+++ /dev/null
@@ -1,37 +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.
--->
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <android.support.v4.view.ViewPager
- android:id="@+id/pager"
- android:layout_alignParentTop="true"
- android:layout_alignParentLeft="true"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
-
- <include
- android:id="@+id/tab_carousel"
- layout="@layout/contact_detail_tab_carousel"
- android:layout_alignParentTop="true"
- android:layout_alignParentLeft="true"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:visibility="gone"/>
-
-</RelativeLayout>
diff --git a/res/layout-sw680dp/contact_detail_fragment.xml b/res/layout-sw680dp/contact_detail_fragment.xml
deleted file mode 100644
index 4c6315e..0000000
--- a/res/layout-sw680dp/contact_detail_fragment.xml
+++ /dev/null
@@ -1,50 +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.
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/contact_detail"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <!-- Placeholder for empty list -->
- <include
- android:id="@android:id/empty"
- layout="@layout/contact_detail_empty"
- android:visibility="gone" />
-
- <!-- Real list -->
- <ListView android:id="@android:id/list"
- android:layout_weight="1"
- android:layout_width="match_parent"
- android:layout_height="0dip"
- android:fadingEdge="none"
- android:cacheColorHint="#00000000"
- android:divider="@null"
- android:scrollbarStyle="outsideOverlay"
- android:paddingRight="12dip" />
-
- <!-- "QuickFix"- button (Copy to local contact, add to group) -->
- <Button
- android:id="@+id/contact_quick_fix"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:visibility="gone"
- android:layout_gravity="center"
- android:layout_marginTop="10dip"
- android:layout_marginBottom="10dip" />
-</LinearLayout>
diff --git a/res/layout-sw680dp/contact_detail_updates_fragment.xml b/res/layout-sw680dp/contact_detail_updates_fragment.xml
deleted file mode 100644
index a2d1abb..0000000
--- a/res/layout-sw680dp/contact_detail_updates_fragment.xml
+++ /dev/null
@@ -1,31 +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.
--->
-
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/contact_detail_updates_fragment"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <ListView android:id="@android:id/list"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:fadingEdge="none"
- android:divider="@null"
- android:scrollbarStyle="outsideOverlay"
- android:paddingRight="12dip" />
-
-</FrameLayout>
diff --git a/res/layout-sw680dp/quickcontact_activity.xml b/res/layout-sw680dp/quickcontact_activity.xml
deleted file mode 100644
index 8843fc9..0000000
--- a/res/layout-sw680dp/quickcontact_activity.xml
+++ /dev/null
@@ -1,48 +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.
--->
-<view
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
- class="com.android.contacts.quickcontact.FloatingChildLayout"
- android:id="@+id/floating_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:focusable="true"
- android:focusableInTouchMode="true"
- android:descendantFocusability="afterDescendants">
- <LinearLayout
- android:id="@android:id/content"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:padding="32dip"
- android:orientation="vertical" >
- <FrameLayout
- android:layout_width="360dip"
- android:layout_height="@dimen/quick_contact_photo_container_height">
- <include layout="@layout/quickcontact_photo_container" />
- </FrameLayout>
- <include layout="@layout/quickcontact_track" />
- <View
- android:id="@+id/line_after_track"
- android:layout_width="match_parent"
- android:layout_height="2dip"
- android:background="@color/quickcontact_tab_indicator" />
- <android.support.v4.view.ViewPager
- android:id="@+id/item_list_pager"
- android:layout_width="match_parent"
- android:layout_height="160dip" />
- </LinearLayout>
-</view>
diff --git a/res/layout/call_log_fragment.xml b/res/layout/call_log_fragment.xml
index 9e88c49..5e7061c 100644
--- a/res/layout/call_log_fragment.xml
+++ b/res/layout/call_log_fragment.xml
@@ -33,6 +33,30 @@
<include layout="@layout/call_log_voicemail_status"
/>
</FrameLayout>
+
+ <FrameLayout>
+ <TextView
+ android:id="@+id/filter_status"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="@dimen/call_log_outer_margin"
+ android:paddingRight="@dimen/call_log_outer_margin"
+ android:paddingTop="@dimen/call_log_inner_margin"
+ android:paddingBottom="@dimen/call_log_inner_margin"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentBottom="true"
+ android:visibility="gone"
+ />
+ <View
+ android:id="@+id/call_log_divider"
+ android:layout_width="match_parent"
+ android:layout_height="1px"
+ android:layout_marginLeft="@dimen/call_log_outer_margin"
+ android:layout_marginRight="@dimen/call_log_outer_margin"
+ android:layout_gravity="bottom"
+ android:background="#55ffffff"
+ />
+ </FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
diff --git a/res/layout/quickcontact_list_fragment.xml b/res/layout/quickcontact_list_fragment.xml
index e542f7a..712f116 100755
--- a/res/layout/quickcontact_list_fragment.xml
+++ b/res/layout/quickcontact_list_fragment.xml
@@ -28,5 +28,7 @@
android:cacheColorHint="@null"
android:layout_alignParentTop="true"
/>
- <include layout="@layout/quickcontact_list_fragment_bottom"/>
+ <View
+ android:layout_alignBottom="@+id/list"
+ style="@style/QuickContactListBottomStyle"/>
</RelativeLayout>
diff --git a/res/layout/quickcontact_list_fragment_bottom.xml b/res/layout/quickcontact_list_fragment_bottom.xml
deleted file mode 100755
index e08b3aa..0000000
--- a/res/layout/quickcontact_list_fragment_bottom.xml
+++ /dev/null
@@ -1,18 +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.
--->
-<View xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_alignBottom="@+id/list"
- style="@style/QuickContactListBottomStyle"/>
diff --git a/res/menu/call_log_options.xml b/res/menu/call_log_options.xml
index c41f9da..bf2973f 100644
--- a/res/menu/call_log_options.xml
+++ b/res/menu/call_log_options.xml
@@ -16,20 +16,39 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
- android:id="@+id/show_voicemails_only"
- android:title="@string/menu_show_voicemails_only"
- android:showAsAction="withText"
- android:orderInCategory="1" />
-
- <item
android:id="@+id/show_all_calls"
android:title="@string/menu_show_all_calls"
- android:showAsAction="withText"
- android:orderInCategory="1" />
+ android:showAsAction="never"
+ android:orderInCategory="1"/>
+
+ <item
+ android:id="@+id/show_voicemails_only"
+ android:title="@string/menu_show_voicemails_only"
+ android:showAsAction="never"
+ android:orderInCategory="1"/>
+
+ <item
+ android:id="@+id/show_missed_only"
+ android:title="@string/menu_show_missed_only"
+ android:showAsAction="never"
+ android:orderInCategory="1"/>
+
+ <item
+ android:id="@+id/show_outgoing_only"
+ android:title="@string/menu_show_outgoing_only"
+ android:showAsAction="never"
+ android:orderInCategory="1"/>
+
+ <item
+ android:id="@+id/show_incoming_only"
+ android:title="@string/menu_show_incoming_only"
+ android:showAsAction="never"
+ android:orderInCategory="1"/>
+
<item
android:id="@+id/delete_all"
android:title="@string/recentCalls_deleteAll"
- android:showAsAction="withText"
- android:orderInCategory="1" />
+ android:showAsAction="never"
+ android:orderInCategory="1"/>
</menu>
diff --git a/res/menu/people_options.xml b/res/menu/people_options.xml
index 8c91e88..2b3c918 100644
--- a/res/menu/people_options.xml
+++ b/res/menu/people_options.xml
@@ -55,4 +55,10 @@
<item
android:id="@+id/menu_help"
android:title="@string/menu_help" />
+
+ <item
+ android:id="@+id/export_database"
+ android:title="@string/menu_export_database"
+ android:visible="false"
+ android:showAsAction="never" />
</menu>
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 2c5135a..36b3cad 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"terugvee"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"nommer om te skakel"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"kontakfoto"</string>
- <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"vee uit"</string>
<string name="description_plus_button" msgid="515164827856229880">"plus"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Bekyk kontak"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Geen berging gevind nie."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>)<xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Groep se naam"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Kontak ontvang via NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Wys slegs uitgaande"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Wys slegs inkomend"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Wys slegs misgeloop"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Wys net stemboodskappe"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Wys alle oproepe"</string>
<string name="status_available" msgid="5586870015822828392">"Beskikbaar"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Oproep nie gestuur nie"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Om stemboodskapdiens op te stel, gaan na Kieslys > Instellings."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Om stemboodskapdiens te bel, skakel eers vliegtuigmodus af."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Voer databasislêers uit"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Meer opsies"</string>
</resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 7bc0b56..544fed1 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"የኋሊት ደምሳሽ"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"ቁጥር ለመደወል"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"የዕውቂያ ፎቶ"</string>
- <string name="description_minus_button" msgid="387136707700230172">"ሲቀነስ"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"ሰርዝ"</string>
<string name="description_plus_button" msgid="515164827856229880">"ተጨማሪ"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"ዕውቂያ ዕይ"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"ምንም ማከማቻ አልተገኘም፡፡"</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"የቡድኑ ስም"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"በ NFC የደረሱ ዕውቂያዎች"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"ወጪዎቹን ብቻ አሳይ"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"ገቢዎቹን ብቻ አሳይ"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"ያመለጡትን ብቻ አሳይ"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"የድምፅ መልዕክቶች ብቻ አሳይ"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"ሁሉንም ጥሪዎች አሳይ"</string>
<string name="status_available" msgid="5586870015822828392">"የሚገኝ"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"ጥሪ አልተላከም"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"ድምጽ መልዕክትን ለማደራጀት ወደ ምናሌ > ቅንብሮች ሂድ::"</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"የድምጽ መልዕክት ጥሪ ለማድረግ፣ በመጀመሪያ የአውሮፕላን ሁነታን አጥፋ።"</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"የውሂብ ጎታ ፋይሎችን ወደ ውጭ ላክ"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"ተጨማሪ አማራጮች"</string>
</resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index a43fda8..1b28a37 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"الرقم الذي سيتم طلبه"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"صورة جهة الاتصال"</string>
- <string name="description_minus_button" msgid="387136707700230172">"علامة الطرح"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"حذف"</string>
<string name="description_plus_button" msgid="515164827856229880">"علامة زائد"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"عرض جهة الاتصال"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"لم يتم العثور على وحدة تخزين."</string>
@@ -286,7 +286,7 @@
<string name="missing_name" msgid="8745511583852904385">"(بلا اسم)"</string>
<string name="menu_accounts" msgid="8499114602017077970">"الحسابات"</string>
<string name="menu_clear_frequents" msgid="7688250191932838833">"محو قائمة من يتصل بهم كثيرًا"</string>
- <string name="menu_contacts_filter" msgid="2165153460860262501">"جهات الاتصال التي يتم عرضها"</string>
+ <string name="menu_contacts_filter" msgid="2165153460860262501">"جهات الاتصال المعروضة"</string>
<string name="menu_import_export" msgid="26217871113229507">"استيراد/تصدير"</string>
<string name="dialog_import_export" msgid="4360648034889921624">"استيراد/تصدير جهات اتصال"</string>
<string name="dialog_import" msgid="2431698729761448759">"استيراد جهات الاتصال"</string>
@@ -455,7 +455,7 @@
<string name="custom_list_filter" msgid="7836035257402013957">"تحديد عرض مخصص"</string>
<string name="contact_list_loading" msgid="5488620820563977329">"جارٍ التحميل..."</string>
<string name="activity_title_settings" msgid="5464130076132770781">"الإعدادات"</string>
- <string name="activity_title_contacts_filter" msgid="8275542497615516969">"جهات الاتصال التي يتم عرضها"</string>
+ <string name="activity_title_contacts_filter" msgid="8275542497615516969">"جهات الاتصال المعروضة"</string>
<string name="menu_settings" msgid="377929915873428211">"الإعدادات"</string>
<string name="menu_help" msgid="5123887102216637725">"مساعدة"</string>
<string name="preference_displayOptions" msgid="1341720270148252393">"خيارات العرض"</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"اسم المجموعة"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"استلام ج اتص.NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"عرض الصادر فقط"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"عرض الوارد فقط"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"عرض الفائت فقط"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"إظهار رسائل البريد الصوتي فقط"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"عرض جميع المكالمات"</string>
<string name="status_available" msgid="5586870015822828392">"متوفر"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"لم يتم إرسال المكالمة"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"لإعداد البريد الصوتي، انتقل إلى القائمة > الإعدادات."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"للاتصال بالبريد الصوتي، يجب أولاً إيقاف وضع الطائرة."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"تصدير ملفات قاعدة البيانات"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"مزيد من الخيارات"</string>
</resources>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index d52e6ae..1804f3a 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"нумар для набору"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"фатаграфія кантакта"</string>
- <string name="description_minus_button" msgid="387136707700230172">"мінус"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"выдаліць"</string>
<string name="description_plus_button" msgid="515164827856229880">"плюс"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Прагледзець кантакт"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Назапашвальнiк не знойдзены."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"( <xliff:g id="COUNT">%1$d</xliff:g> ) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Назва групы"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Кант. атр. праз NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Паказаць толькі выходныя"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Паказаць толькі ўваходныя"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Паказаць толькі прапушчаныя"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Паказаць толькі галас. пошту"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Паказаць усе выклікі"</string>
<string name="status_available" msgid="5586870015822828392">"Даступны"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Выклік не зроблены"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Каб наладзіць галасавую пошту, націсніце \"Меню\" i перайдзiце ў налады."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Каб зрабiць выклік галасавой пошты, спачатку адключыце рэжым палёту."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Экспарт базы дадзеных файлаў"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Дадатковыя параметры"</string>
</resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index f34fdc1..5882952 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"назад"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"номер за набиране"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"снимка на контакта"</string>
- <string name="description_minus_button" msgid="387136707700230172">"минус"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"изтриване"</string>
<string name="description_plus_button" msgid="515164827856229880">"плюс"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Преглед на контакта"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Не бе намерено хранилище."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Име на групата"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Контакт: Получ. чрез NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Показване само на изходящите"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Показване само на входящите"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Показване само на пропуснатите"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Показване само на гл. поща"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Показване на всички обаждания"</string>
<string name="status_available" msgid="5586870015822828392">"Налице"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Обаждането не е извършено"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"За да настроите гласовата поща, отворете „Меню“ > „Настройки“."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"За да чуете гласовата си поща, първо изключете самолетния режим."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Експортиране на файловете на базата от данни"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Още опции"</string>
</resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index de92f5f..53b6f74 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"retrocés"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"número que es marcarà"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"foto del contacte"</string>
- <string name="description_minus_button" msgid="387136707700230172">"menys"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"suprimeix"</string>
<string name="description_plus_button" msgid="515164827856229880">"més"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Mostra el contacte"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"No s\'ha trobat emmagatzematge."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Nom del grup"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Contac. reb. NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Mostra només les sortints"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Mostra només les entrants"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Mostra només les perdudes"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Mostra només missatges de veu"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Mostra totes les trucades"</string>
<string name="status_available" msgid="5586870015822828392">"Disponible"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"No s\'ha enviat la trucada"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Per configurar la bústia de veu, vés a Menú > Configuració."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Per trucar al correu de veu, primer has de desactivar el mode d\'avió."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Exporta els fitxers de la base de dades"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Més opcions"</string>
</resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 609604f..5c3c6cb 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"číslo, které chcete vytočit"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"fotografie kontaktu"</string>
- <string name="description_minus_button" msgid="387136707700230172">"mínus"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"smazat"</string>
<string name="description_plus_button" msgid="515164827856229880">"plus"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Zobrazit kontakt"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Nebylo nalezeno žádné úložiště."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Název skupiny"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Kontakt přijatý přes NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Zobrazit pouze odchozí"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Zobrazit pouze příchozí"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Zobrazit pouze zmeškané"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Zobrazit pouze hlas. schránku"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Zobrazit všechny hovory"</string>
<string name="status_available" msgid="5586870015822828392">"K dispozici"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Hovor nebyl odeslán"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Chcete-li nastavit hlasovou schránku, přejděte do části Menu > Nastavení."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Chcete-li volat hlasovou schránku, nejdříve vypněte režim V letadle."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Exportovat soubory databáze"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Více možností"</string>
</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 73c2c84..acc9790 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"nummer at ringe op"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"kontaktpersonfoto"</string>
- <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"slet"</string>
<string name="description_plus_button" msgid="515164827856229880">"plus"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Vis kontaktperson"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Intet lager blev fundet."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Gruppens navn"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Kontakt via NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Vis kun udgående"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Vis kun indgående"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Vis kun ubesvarede"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Vis kun telefonsvarerbeskeder"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Vis alle opkald"</string>
<string name="status_available" msgid="5586870015822828392">"Tilgængelig"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Opkaldet blev ikke sendt"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Hvis du vil konfigurere telefonsvareren, skal du gå til Menu > Indstillinger."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Hvis du vil ringe til telefonsvareren, skal du først slå Flytilstand fra."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Eksportér databasefiler"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Flere valgmuligheder"</string>
</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 41431bd..15e97a8 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"Rücktaste"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"Zu wählende Nummer"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"Kontaktbild"</string>
- <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"Löschen"</string>
<string name="description_plus_button" msgid="515164827856229880">"plus"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Kontakt anzeigen"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Kein Speicher gefunden"</string>
@@ -281,7 +281,7 @@
<string name="call_disambig_title" msgid="4392886850104795739">"Nummer auswählen"</string>
<string name="call_settings" msgid="7666474782093693667">"Einstellungen"</string>
<string name="sms_disambig_title" msgid="5846266399240630846">"Nummer auswählen"</string>
- <string name="make_primary" msgid="5829291915305113983">"Diese Auswahl speichern"</string>
+ <string name="make_primary" msgid="5829291915305113983">"Auswahl speichern"</string>
<string name="quickcontact_missing_app" msgid="358168575340921552">"Für diese Aktion wurde keine App gefunden."</string>
<string name="missing_name" msgid="8745511583852904385">"(Kein Name)"</string>
<string name="menu_accounts" msgid="8499114602017077970">"Konten"</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Gruppenname"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Kontakt erhalten per NCF"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Nur ausgehende Anrufe anzeigen"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Nur eingehende Anrufe anzeigen"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Nur entgangene Anrufe anzeigen"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Nur Mailbox-Nachr. anzeigen"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Alle Anrufe anzeigen"</string>
<string name="status_available" msgid="5586870015822828392">"Verfügbar"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Anruf nicht verbunden"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Konfigurieren Sie Ihre Mailbox unter \"Menü\" > \"Einstellungen\"."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Deaktivieren Sie zunächst den Flugmodus, um die Mailbox anzurufen."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Datenbankdateien exportieren"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Mehr Optionen"</string>
</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 9010745..cad7c2d 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"αριθμός για κλήση"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"φωτογραφία επαφής"</string>
- <string name="description_minus_button" msgid="387136707700230172">"μείον"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"διαγραφή"</string>
<string name="description_plus_button" msgid="515164827856229880">"συν"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Προβολή επαφής"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Δεν βρέθηκε χώρος αποθήκευσης."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Όνομα ομάδας"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Λήψ.επ.μέσω ΕΚΠ"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Εμφάνιση μόνο εξερχόμενων"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Εμφάνιση μόνο εισερχόμενων"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Εμφάνιση μόνο αναπάντητων"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Εμφ. μόνο μην. αυτόμ. τηλεφων."</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Εμφάνιση όλων"</string>
<string name="status_available" msgid="5586870015822828392">"Διαθέσιμος"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Η κλήση δεν πραγματοποιήθηκε"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Για τη r;yumish του αυτόματου τηλεφωνητή, μεταβείτε στο στοιχείο Μενού > Ρυθμίσεις."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Για κλήση αυτόματου τηλεφωνητή, πρώτα απενεργοποιήστε τη λειτουργία πτήσης."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Εξαγωγή αρχείων βάσης δεδομένων"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Περισσότερες επιλογές"</string>
</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index a601cda..de7ff0f 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"number to dial"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"contact photo"</string>
- <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"delete"</string>
<string name="description_plus_button" msgid="515164827856229880">"plus"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"View contact"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"No storage was found."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Group\'s name"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Contact received over NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Show outgoing only"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Show incoming only"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Show missed only"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Show voicemails only"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Show all calls"</string>
<string name="status_available" msgid="5586870015822828392">"Available"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Call not sent"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"To set up voicemail, go to Menu > Settings."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"To call voicemail, first turn off Aeroplane mode."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Export database files"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"More options"</string>
</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 738822c..af34cac 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"retroceso"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"número para marcar"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"foto de contacto"</string>
- <string name="description_minus_button" msgid="387136707700230172">"menos"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"Eliminar"</string>
<string name="description_plus_button" msgid="515164827856229880">"más"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Ver contacto"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"No se encontró almacenamiento."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Nombre del grupo"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Contac recib NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Mostrar solo salientes"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Mostrar solo entrantes"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Mostrar solo perdidas"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Mostrar solo mensajes de voz"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Mostrar todas las llamadas"</string>
<string name="status_available" msgid="5586870015822828392">"Disponible"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"No se realizó la llamada."</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Para configurar el buzón de voz, ve a a Menú > Configuración."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Para escuchar los mensajes de tu buzón de voz, desactiva primero el modo de avión."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Exportar archivos de base de datos"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Más opciones"</string>
</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 33a3b36..0856bac 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -185,7 +185,7 @@
<string name="type_missed" msgid="2720502601640509542">"Llamada perdida"</string>
<string name="type_voicemail" msgid="5153139450668549908">"Buzón de voz"</string>
<string name="actionIncomingCall" msgid="6028930669817038600">"Llamadas entrantes"</string>
- <string name="callBack" msgid="5498224409038809224">"Volver a llamar"</string>
+ <string name="callBack" msgid="5498224409038809224">"Llamar"</string>
<string name="callAgain" msgid="3197312117049874778">"Volver a llamar"</string>
<string name="returnCall" msgid="8171961914203617813">"Devolver llamada"</string>
<string name="callDetailsDurationFormat" msgid="8157706382818184268">"<xliff:g id="MINUTES">%s</xliff:g> min. y <xliff:g id="SECONDS">%s</xliff:g> seg."</string>
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"retroceder un espacio"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"número que se va a marcar"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"foto de contacto"</string>
- <string name="description_minus_button" msgid="387136707700230172">"menos"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"eliminar"</string>
<string name="description_plus_button" msgid="515164827856229880">"más"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Ver contacto"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"No hay ningún almacenamiento."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Nombre del grupo"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Contacto recibido por NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Mostrar solo llamadas salientes"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Mostrar solo llamadas entrantes"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Mostrar solo llamadas perdidas"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Solo mensajes de voz"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Mostrar todas las llamadas"</string>
<string name="status_available" msgid="5586870015822828392">"Disponible"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Llamada no enviada"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Para configurar el buzón de voz, toca la tecla de menú y, a continuación, toca Ajustes."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Para llamar al buzón de voz, debes desactivar el modo avión."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Exportar archivos de base de datos"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Más opciones"</string>
</resources>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 013febb..c47bbde 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"tagasilüke"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"number valimiseks"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"kontakti foto"</string>
- <string name="description_minus_button" msgid="387136707700230172">"miinus"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"kustutamine"</string>
<string name="description_plus_button" msgid="515164827856229880">"pluss"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Vaadake kontakti"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Mäluruumi ei leitud."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Rühma nimi"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Kontakt võeti vastu NFC kaudu"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Kuva ainult väljuvad"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Kuva ainult sissetulevad"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Kuva ainult vastamata"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Kuva ainult kõnepostisõnumeid"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Kuva kõik kõned"</string>
<string name="status_available" msgid="5586870015822828392">"Saadaval"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Kõnet ei tehtud"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Kõneposti seadistamiseks minge valikusse Menüü > Seaded."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Kõneposti kuulamiseks lülitage lennurežiim välja."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Andmebaasi failide eksportimine"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Rohkem valikuid"</string>
</resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 3967d87..e9951fc 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -26,7 +26,7 @@
<string name="callShortcutActivityTitle" msgid="6065749861423648991">"انتخاب یک شماره برای تماس"</string>
<string name="messageShortcutActivityTitle" msgid="3084542316620335911">"انتخاب یک شماره برای پیام"</string>
<string name="contactPickerActivityTitle" msgid="4301062192337417640">"انتخاب یک مخاطب"</string>
- <string name="starredList" msgid="4817256136413959463">"ستاره دار"</string>
+ <string name="starredList" msgid="4817256136413959463">"ستارهدار"</string>
<string name="frequentList" msgid="7154768136473953056">"مکرر"</string>
<string name="strequentList" msgid="5640192862059373511">"موارد دلخواه"</string>
<string name="viewContactTitle" msgid="7989394521836644384">"اطلاعات تماس"</string>
@@ -36,7 +36,7 @@
<string name="editGroupDescription" msgid="6321161304201540561">"ویرایش گروه"</string>
<string name="insertGroupDescription" msgid="5658512271662210139">"ایجاد گروه"</string>
<string name="contactDetailAbout" msgid="5430408883907061400">"درباره"</string>
- <string name="contactDetailUpdates" msgid="3780588624763446941">"نسخه های به روز"</string>
+ <string name="contactDetailUpdates" msgid="3780588624763446941">"نسخههای به روز"</string>
<string name="searchHint" msgid="8482945356247760701">"جستجوی مخاطبین"</string>
<string name="menu_search" msgid="9147752853603483719">"جستجو"</string>
<string name="menu_newContact" msgid="1209922412763274638">"مخاطب جدید"</string>
@@ -47,7 +47,7 @@
<string name="menu_editContact" msgid="9042415603857662633">"ویرایش"</string>
<string name="menu_deleteContact" msgid="6788644058868189393">"حذف"</string>
<string name="menu_copy" msgid="6108677035381940698">"کپی"</string>
- <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"محل بر روی صفحه اصلی"</string>
+ <string name="menu_create_contact_shortcut" msgid="1217971915748509640">"محل بر روی صفحهٔ اصلی"</string>
<string name="menu_call" msgid="3992595586042260618">"تماس با مخاطب"</string>
<string name="menu_sendSMS" msgid="5535886767547006515">"ارسال متن به مخاطب"</string>
<string name="menu_splitAggregate" msgid="8368636463748691868">"تفکیک"</string>
@@ -67,18 +67,18 @@
<string name="menu_set_ring_tone" msgid="8728345772068064946">"تنظیم آهنگ زنگ"</string>
<string name="menu_redirect_calls_to_vm" msgid="4181789196416396656">"همه تماسها به پست صوتی"</string>
<string name="readOnlyContactWarning" msgid="7808825687289848259">"شما نمیتوانید مخاطبین را از حسابهای فقط خواندنی حذف کنید اما میتوانید آنها را در لیستهای مخاطبین خود پنهان کنید."</string>
- <string name="readOnlyContactDeleteConfirmation" msgid="2137170726670196909">"این مخاطب دارای اطلاعاتی از چند حساب است. اطلاعات حساب های فقط خواندنی در لیست های مخاطبین پنهان می شوند اما حذف نمی شوند."</string>
- <string name="multipleContactDeleteConfirmation" msgid="938900978442960800">"حذف این مخاطب اطلاعات را از حساب های متعدد حذف می کند."</string>
- <string name="deleteConfirmation" msgid="811706994761610640">"این مخاطب حذف می شود."</string>
+ <string name="readOnlyContactDeleteConfirmation" msgid="2137170726670196909">"این مخاطب دارای اطلاعاتی از چند حساب است. اطلاعات حسابهای فقط خواندنی در لیستهای مخاطبین پنهان میشوند اما حذف نمیشوند."</string>
+ <string name="multipleContactDeleteConfirmation" msgid="938900978442960800">"حذف این مخاطب اطلاعات را از حسابهای متعدد حذف میکند."</string>
+ <string name="deleteConfirmation" msgid="811706994761610640">"این مخاطب حذف میشود."</string>
<string name="menu_done" msgid="796017761764190697">"انجام شد"</string>
<string name="menu_doNotSave" msgid="58593876893538465">"لغو"</string>
<string name="menu_discard" msgid="6456087569315685632">"صرفنظر"</string>
- <string name="label_notes" msgid="8337354953278341042">"یادداشت ها"</string>
+ <string name="label_notes" msgid="8337354953278341042">"یادداشتها"</string>
<string name="label_sip_address" msgid="124073911714324974">"تماس اینترنتی"</string>
<string name="ghostData_company" msgid="5414421120553765775">"شرکت"</string>
<string name="ghostData_title" msgid="7496735200318496110">"عنوان"</string>
<string name="invalidContactMessage" msgid="8215051456181842274">"مخاطبی موجود نیست."</string>
- <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"ابزارک مخاطب به صفحه اصلی شما اضافه شد."</string>
+ <string name="createContactShortcutSuccessful" msgid="7874133287558150877">"ابزارک مخاطب به صفحهٔ اصلی شما اضافه شد."</string>
<string name="pickerNewContactHeader" msgid="7750705279843568147">"ایجاد مخاطب جدید"</string>
<string name="pickerNewContactText" msgid="6166997164401048211">"ایجاد مخاطب جدید"</string>
<string name="phoneLabelsGroup" msgid="6468091477851199285">"تلفن"</string>
@@ -89,7 +89,7 @@
<item msgid="8287841928119937597">"سازمان"</item>
<item msgid="7196592230748086755">"توجه"</item>
</string-array>
- <string name="photoPickerNotFoundText" product="tablet" msgid="6247290728908599701">"عکسی در رایانه لوحی موجود نیست."</string>
+ <string name="photoPickerNotFoundText" product="tablet" msgid="6247290728908599701">"عکسی در رایانهٔ لوحی موجود نیست."</string>
<string name="photoPickerNotFoundText" product="default" msgid="431331662154342581">"عکسی در گوشی موجود نیست."</string>
<string name="attach_photo_dialog_title" msgid="5599827035558557169">"عکس مخاطب"</string>
<string name="customLabelPickerTitle" msgid="1081475101983255212">"نام برچسب سفارشی"</string>
@@ -103,18 +103,18 @@
<string name="emptyGroup" msgid="7502116218697177370">"هیچ فردی در این گروه نیست."</string>
<string name="addPeopleToGroup" msgid="7879585947222263516">"برای افزودن چند عضو، گروه را ویرایش کنید."</string>
<string name="savingContact" msgid="4075751076741924939">"در حال ذخیره مخاطب..."</string>
- <string name="savingDisplayGroups" msgid="2133152192716475939">"در حال ذخیره گزینه های نمایش..."</string>
+ <string name="savingDisplayGroups" msgid="2133152192716475939">"در حال ذخیره گزینههای نمایش..."</string>
<string name="contactSavedToast" msgid="7152589189385441091">"مخاطب ذخیره شد."</string>
<string name="contactSavedErrorToast" msgid="3207250533172944892">"تغییرات مخاطب ذخیره نمیشود."</string>
<string name="groupSavedToast" msgid="1168756874239833756">"گروه ذخیره شد."</string>
- <string name="groupSavedErrorToast" msgid="7984466936615304740">"ذخیره تغییرات گروه انجام نشد."</string>
+ <string name="groupSavedErrorToast" msgid="7984466936615304740">"ذخیرهٔ تغییرات گروه انجام نشد."</string>
<plurals name="listTotalPhoneContacts">
- <item quantity="one" msgid="3015357862286673986">"1 مخاطب با شماره تلفن"</item>
+ <item quantity="one" msgid="3015357862286673986">"۱ مخاطب با شماره تلفن"</item>
<item quantity="other" msgid="3299954047880968205">"<xliff:g id="COUNT">%d</xliff:g> مخاطب دارای شماره تلفن"</item>
</plurals>
<string name="listTotalPhoneContactsZero" msgid="6968813857632984319">"مخاطبی با شماره تلفن موجود نیست"</string>
<plurals name="listTotalAllContacts">
- <item quantity="one" msgid="3405747744700823280">"1 مخاطب"</item>
+ <item quantity="one" msgid="3405747744700823280">"۱ مخاطب"</item>
<item quantity="other" msgid="3578469907265375314">"<xliff:g id="COUNT">%d</xliff:g> مخاطب"</item>
</plurals>
<string name="listTotalAllContactsZero" msgid="5513001821794568211">"مخاطبی موجود نیست."</string>
@@ -135,7 +135,7 @@
<item quantity="other" msgid="7988132539476575389">"<xliff:g id="COUNT">%d</xliff:g> یافت شد"</item>
</plurals>
<string name="contactsAllLabel" msgid="6479708629170672169">"همه مخاطبین"</string>
- <string name="contactsGroupsLabel" msgid="2841971472518003524">"گروه ها"</string>
+ <string name="contactsGroupsLabel" msgid="2841971472518003524">"گروهها"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"موارد دلخواه"</string>
<string name="dialerIconLabel" msgid="6500826552823403796">"تلفن"</string>
<string name="recentCallsIconLabel" msgid="1419116422359067949">"گزارش تماس"</string>
@@ -160,22 +160,22 @@
<string name="unknown" msgid="740067747858270469">"ناشناس"</string>
<string name="private_num" msgid="6374339738119166953">"شماره خصوصی"</string>
<string name="payphone" msgid="4864313342828942922">"تلفن عمومی"</string>
- <string name="dialerKeyboardHintText" msgid="5401660096579787344">"استفاده از صفحه کلید برای شماره گیری"</string>
+ <string name="dialerKeyboardHintText" msgid="5401660096579787344">"استفاده از صفحهکلید برای شماره گیری"</string>
<string name="dialerDialpadHintText" msgid="5824490365898349041">"شماره گیری برای افزودن یک تماس"</string>
<string name="simContacts_emptyLoading" msgid="6700035985448642408">"در حال بارگیری سیم کارت..."</string>
<string name="simContacts_title" msgid="27341688347689769">"مخاطبین سیم کارت"</string>
- <string name="noContactsHelpTextWithSyncForCreateShortcut" msgid="801504710275614594">"شما مخاطبی برای نمایش ندارید. (در صورتی که اکنون یک حساب را اضافه کردید، همگام سازی مخاطبین چند دقیقه طول می کشد.)"</string>
+ <string name="noContactsHelpTextWithSyncForCreateShortcut" msgid="801504710275614594">"شما مخاطبی برای نمایش ندارید. (در صورتی که اکنون یک حساب را اضافه کردید، همگام سازی مخاطبین چند دقیقه طول میکشد.)"</string>
<string name="noContactsHelpTextForCreateShortcut" msgid="3081286388667108335">"شما مخاطبی برای نمایش ندارید."</string>
- <string name="noContactsHelpText" product="tablet" msgid="6226271923423236696">"شما مخاطبی برای نمایش ندارید."\n\n"برای افزودن مخاطبین، "<font fgcolor="#ffffffff"><b>"منو"</b></font>" را لمس کرده و سپس این موارد را لمس کنید:"\n" "\n<li><font fgcolor="#ffffffff"><b>"حسابها"</b></font>" برای افزودن یا تنظیم یک حساب با مخاطبینی که میتوانید با رایانه لوحی همگامسازی کنید"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"مخاطب جدید"</b></font>" برای ایجاد یک مخاطب جدید از ابتدا"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"وارد کردن/صادر کردن"</b></font>" برای وارد کردن مخاطبین از سیم کارت یا کارت SD شما"\n</li></string>
+ <string name="noContactsHelpText" product="tablet" msgid="6226271923423236696">"شما مخاطبی برای نمایش ندارید."\n\n"برای افزودن مخاطبین، "<font fgcolor="#ffffffff"><b>"منو"</b></font>" را لمس کرده و سپس این موارد را لمس کنید:"\n" "\n<li><font fgcolor="#ffffffff"><b>"حسابها"</b></font>" برای افزودن یا تنظیم یک حساب با مخاطبینی که میتوانید با رایانهٔ لوحی همگامسازی کنید"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"مخاطب جدید"</b></font>" برای ایجاد یک مخاطب جدید از ابتدا"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"وارد کردن/صادر کردن"</b></font>" برای وارد کردن مخاطبین از سیم کارت یا کارت SD شما"\n</li></string>
<string name="noContactsHelpText" product="default" msgid="4405064135698982080">"شما مخاطبی برای نمایش ندارید."\n\n"برای افزودن مخاطب، "<font fgcolor="#ffffffff"><b>"منو"</b></font>" را لمس کرده و سپس این موارد را لمس کنید:"\n" "\n<li><font fgcolor="#ffffffff"><b>"حسابها"</b></font>" برای افزودن یا تنظیم یک حساب با مخاطبینی که میتوانید با گوشی همگامسازی کنید"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"مخاطب جدید"</b></font>" برای ایجاد یک مخاطب جدید از ابتدا"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"وارد کردن/صادر کردن"</b></font>" برای وارد کردن مخاطبین از سیم کارت یا کارت SD شما"\n</li></string>
- <string name="noContactsHelpTextWithSync" product="tablet" msgid="6773195806404659174">"شما مخاطبی برای نمایش ندارید. (در صورتی که اکنون یک حساب اضافه کردهاید، همگامسازی مخاطبین چند دقیقه طول میکشد.)"\n\n"برای افزودن مخاطبین، "<font fgcolor="#ffffffff"><b>"منو"</b></font>" را لمی کرده و سپس این موارد را لمس کنید:"\n" "\n<li><font fgcolor="#ffffffff"><b>"حسابها"</b></font>" برای افزودن یا پیکربندی یک حساب با مخاطبینی که میتوانید در رایانه لوحی همگامسازی کنید"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"گزینههای نمایش"</b></font>" برای تغییر مخاطبینی که قابل مشاهده هستند"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"مخاطب جدید"</b></font>" برای ایجاد یک مخاطب جدید از ابتدا"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"وارد کردن/صادر کردن"</b></font>" برای وارد کردن مخاطبین از سیم کارت یا کارت SD شما"\n</li></string>
+ <string name="noContactsHelpTextWithSync" product="tablet" msgid="6773195806404659174">"شما مخاطبی برای نمایش ندارید. (در صورتی که اکنون یک حساب اضافه کردهاید، همگامسازی مخاطبین چند دقیقه طول میکشد.)"\n\n"برای افزودن مخاطبین، "<font fgcolor="#ffffffff"><b>"منو"</b></font>" را لمی کرده و سپس این موارد را لمس کنید:"\n" "\n<li><font fgcolor="#ffffffff"><b>"حسابها"</b></font>" برای افزودن یا پیکربندی یک حساب با مخاطبینی که میتوانید در رایانهٔ لوحی همگامسازی کنید"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"گزینههای نمایش"</b></font>" برای تغییر مخاطبینی که قابل مشاهده هستند"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"مخاطب جدید"</b></font>" برای ایجاد یک مخاطب جدید از ابتدا"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"وارد کردن/صادر کردن"</b></font>" برای وارد کردن مخاطبین از سیم کارت یا کارت SD شما"\n</li></string>
<string name="noContactsHelpTextWithSync" product="default" msgid="7016825676090327312">"شما مخاطبی برای نمایش ندارید. (در صورتی که اکنون یک حساب اضافه کردهاید، همگامسازی مخاطبین چند دقیقه طول میکشد.)"\n\n"برای افزودن مخاطبین، "<font fgcolor="#ffffffff"><b>"منو"</b></font>" را لمس کرده و سپس این موارد را لمس کنید:"\n" "\n<li><font fgcolor="#ffffffff"><b>"حسابها"</b></font>" برای افزودن یا تنظیم یک حساب با مخاطبینی که میتوانید با گوشی همگامسازی کنید"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"گزینههای نمایش"</b></font>" برای تغییر مخاطبینی که قابل مشاهده هستند"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"مخاطب جدید"</b></font>" برای ایجاد یک مخاطب جدید از ابتدا"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"وارد کردن/صادر کردن"</b></font>" برای وارد کردن مخاطبین از سیم کارت یا کارت SD شما"\n</li></string>
- <string name="noContactsNoSimHelpText" product="tablet" msgid="7823757505923033456">"شما مخاطبی برای نمایش ندارید."\n\n"برای افزودن مخاطب، "<font fgcolor="#ffffffff"><b>"منو"</b></font>" را لمس کرده و سپس این موارد را لمس کنید:"\n" "\n<li><font fgcolor="#ffffffff"><b>"حسابها"</b></font>" برای افزودن یا تنظیم یک حساب با مخاطبینی که میتوانید با رایانه لوحی همگامسازی کنید"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"مخاطب جدید"</b></font>" برای ایجاد یک مخاطب جدید از ابتدا"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"وارد کردن/صادر کردن"</b></font>" برای وارد کردن مخاطبین از سیم کارت یا کارت SD شما"\n</li></string>
+ <string name="noContactsNoSimHelpText" product="tablet" msgid="7823757505923033456">"شما مخاطبی برای نمایش ندارید."\n\n"برای افزودن مخاطب، "<font fgcolor="#ffffffff"><b>"منو"</b></font>" را لمس کرده و سپس این موارد را لمس کنید:"\n" "\n<li><font fgcolor="#ffffffff"><b>"حسابها"</b></font>" برای افزودن یا تنظیم یک حساب با مخاطبینی که میتوانید با رایانهٔ لوحی همگامسازی کنید"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"مخاطب جدید"</b></font>" برای ایجاد یک مخاطب جدید از ابتدا"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"وارد کردن/صادر کردن"</b></font>" برای وارد کردن مخاطبین از سیم کارت یا کارت SD شما"\n</li></string>
<string name="noContactsNoSimHelpText" product="default" msgid="6224952277619986841">"شما مخاطبی برای نمایش ندارید."\n\n"برای افزودن مخاطبین، "<font fgcolor="#ffffffff"><b>"منو"</b></font>" را لمس کرده و سپس این موارد را لمس کنید:"\n" "\n<li><font fgcolor="#ffffffff"><b>"حسابها"</b></font>" برای افزودن یا تنظیم یک حساب با مخاطبینی که میتوانید با گوشی همگامسازی کنید"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"مخاطب جدید"</b></font>" برای ایجاد یک مخاطب جدید از ابتدا"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"وارد کردن/صادر کردن"</b></font>" برای وارد کردن مخاطبین از کارت SD شما"\n</li></string>
- <string name="noContactsNoSimHelpTextWithSync" product="tablet" msgid="5415762667445638265">"شما مخاطبی برای نمایش ندارید. (در صورتی که اکنون یک حساب اضافه کردهاید، همگامسازی مخاطبین چند دقیقه طول میکشد.)"\n\n"برای افزودن مخاطبین، "<font fgcolor="#ffffffff"><b>"منو"</b></font>" را لمس کرده و سپس این موارد را لمس کنید:"\n" "\n<li><font fgcolor="#ffffffff"><b>"حسابها"</b></font>" برای افزودن یا پیکربندی یک حساب با مخاطبینی که میتوانید در رایانه لوحی همگامسازی کنید"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"گزینههای نمایش"</b></font>" برای تغییر مخاطبینی که قابل مشاهده هستند"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"مخاطب جدید"</b></font>" برای ایجاد یک مخاطب جدید از ابتدا"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"وارد کردن/صادر کردن"</b></font>" برای وارد کردن مخاطبین از کارت SD شما"\n</li></string>
+ <string name="noContactsNoSimHelpTextWithSync" product="tablet" msgid="5415762667445638265">"شما مخاطبی برای نمایش ندارید. (در صورتی که اکنون یک حساب اضافه کردهاید، همگامسازی مخاطبین چند دقیقه طول میکشد.)"\n\n"برای افزودن مخاطبین، "<font fgcolor="#ffffffff"><b>"منو"</b></font>" را لمس کرده و سپس این موارد را لمس کنید:"\n" "\n<li><font fgcolor="#ffffffff"><b>"حسابها"</b></font>" برای افزودن یا پیکربندی یک حساب با مخاطبینی که میتوانید در رایانهٔ لوحی همگامسازی کنید"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"گزینههای نمایش"</b></font>" برای تغییر مخاطبینی که قابل مشاهده هستند"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"مخاطب جدید"</b></font>" برای ایجاد یک مخاطب جدید از ابتدا"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"وارد کردن/صادر کردن"</b></font>" برای وارد کردن مخاطبین از کارت SD شما"\n</li></string>
<string name="noContactsNoSimHelpTextWithSync" product="default" msgid="7443705129830284440">"شما مخاطبی برای نمایش ندارید. (در صورتی که اکنون یک حساب اضافه کردهاید، همگامسازی مخاطبین چند دقیقه طول میکشد.)"\n\n"برای افزودن مخاطبین، "<font fgcolor="#ffffffff"><b>"منو"</b></font>" را لمس کرده و سپس این موارد را لمس کنید:"\n" "\n<li><font fgcolor="#ffffffff"><b>"حسابها"</b></font>" برای افزودن یا تنظیم یک حساب با مخاطبینی که میتوانید با گوشی همگامسازی کنید"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"گزینههای نمایش"</b></font>" برای تغییر مخاطبینی که قابل مشاهده هستند"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"مخاطب جدید"</b></font>" برای ایجاد یک مخاطب جدید از ابتدا"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"وارد کردن/صادر کردن"</b></font>" برای وارد کردن مخاطبین از کارت SD شما"\n</li></string>
- <string name="noFavoritesHelpText" msgid="3744655776704833277">"شما هیچ مورد دلخواهی ندارید."\n\n"برای افزودن یک مخاطب به لیست موارد دلخواه خود: "\n\n" "<li>"برگه "<b>"مخاطبین"</b>\n</li>" را لمس کنید"\n<li>"مخاطبی را که می خواهید به لیست موارد دلخواه خود اضافه کنید لمس کنید"\n</li>" "\n<li>"ستاره واقع در کنار نام مخاطب را لمس کنید"\n</li></string>
- <string name="dialer_useDtmfDialpad" msgid="1707548397435075040">"استفاده از صفحه کلید لمسی"</string>
+ <string name="noFavoritesHelpText" msgid="3744655776704833277">"شما هیچ مورد دلخواهی ندارید."\n\n"برای افزودن یک مخاطب به لیست موارد دلخواه خود: "\n\n" "<li>"برگه "<b>"مخاطبین"</b>\n</li>" را لمس کنید"\n<li>"مخاطبی را که میخواهید به لیست موارد دلخواه خود اضافه کنید لمس کنید"\n</li>" "\n<li>"ستاره واقع در کنار نام مخاطب را لمس کنید"\n</li></string>
+ <string name="dialer_useDtmfDialpad" msgid="1707548397435075040">"استفاده از صفحهکلید لمسی"</string>
<string name="dialer_returnToInCallScreen" msgid="3719386377550913067">"برگشت به تماس در حال انجام"</string>
<string name="dialer_addAnotherCall" msgid="4205688819890074468">"افزودن تماس"</string>
<string name="callDetailTitle" msgid="5340227785196217938">"جزئیات تماس"</string>
@@ -184,7 +184,7 @@
<string name="type_outgoing" msgid="343108709599392641">"تماس خروجی"</string>
<string name="type_missed" msgid="2720502601640509542">"تماس بی پاسخ"</string>
<string name="type_voicemail" msgid="5153139450668549908">"پست صوتی"</string>
- <string name="actionIncomingCall" msgid="6028930669817038600">"تماس های ورودی"</string>
+ <string name="actionIncomingCall" msgid="6028930669817038600">"تماسهای ورودی"</string>
<string name="callBack" msgid="5498224409038809224">"بازگرداندن تماس"</string>
<string name="callAgain" msgid="3197312117049874778">"تماس مجدد"</string>
<string name="returnCall" msgid="8171961914203617813">"برگشت تماس"</string>
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"Backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"شماره برای شماره گیری"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"عکس مخاطب"</string>
- <string name="description_minus_button" msgid="387136707700230172">"منها"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"حذف"</string>
<string name="description_plus_button" msgid="515164827856229880">"به اضافه"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"مشاهده مخاطب"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"هیچ دستگاه ذخیرهای یافت نشد."</string>
@@ -218,12 +218,12 @@
<string name="import_from_sim" msgid="3859272228033941659">"وارد کردن از سیم کارت"</string>
<string name="import_from_sdcard" product="default" msgid="8668347930577565175">"وارد کردن از حافظه"</string>
<string name="export_to_sdcard" product="default" msgid="6092815580965201089">"صادر کردن به حافظه"</string>
- <string name="share_visible_contacts" msgid="890150378880783797">"اشتراک گذاری مخاطبین قابل مشاهده"</string>
+ <string name="share_visible_contacts" msgid="890150378880783797">"اشتراکگذاری مخاطبین قابل مشاهده"</string>
<string name="import_one_vcard_string" msgid="9059163467020328433">"وارد کردن یک فایل کارت ویزیت"</string>
<string name="import_multiple_vcard_string" msgid="3810226492811062392">"وارد کردن چند فایل کارت ویزیت"</string>
- <string name="import_all_vcard_string" msgid="5518136113853448474">"وارد کردن همه فایل های کارت ویزیت"</string>
+ <string name="import_all_vcard_string" msgid="5518136113853448474">"وارد کردن همه فایلهای کارت ویزیت"</string>
<string name="searching_vcard_message" product="nosdcard" msgid="557077639409584945">"جستجوی داده کارت ویزیت در دستگاه ذخیره..."</string>
- <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"درحال جستجوی دادههای کارت ویزیت در کارت SD..."</string>
+ <string name="searching_vcard_message" product="default" msgid="3962269894118092049">"در حال جستجوی دادههای کارت ویزیت در کارت SD..."</string>
<string name="scanning_sdcard_failed_message" product="nosdcard" msgid="7221682312959229201">"دستگاه ذخیره نمیتواند بررسی شود. (علت: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
<string name="scanning_sdcard_failed_message" product="default" msgid="189023067829510792">"کارت SD نمیتواند بررسی شود. (علت: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\")"</string>
<string name="fail_reason_io_error" msgid="6748358842976073255">"خطای ورودی/خروجی"</string>
@@ -237,7 +237,7 @@
<string name="fail_reason_failed_to_read_files" msgid="5823434810622484922">"نمیتوان یک یا چند فایل را وارد کرد (%s)."</string>
<string name="fail_reason_unknown" msgid="1714092345030570863">"خطای ناشناخته."</string>
<string name="select_vcard_title" msgid="7791371083694672861">"فایل کارت ویزیت را انتخاب کنید"</string>
- <string name="caching_vcard_title" msgid="1226272312940516605">"در حال ذخیره در حافظه پنهان"</string>
+ <string name="caching_vcard_title" msgid="1226272312940516605">"در حال ذخیره در حافظهٔ پنهان"</string>
<string name="caching_vcard_message" msgid="4926308675041506756">"در حال ذخیره کارتهای ویزیت در حافظه موقت محلی است. وارد کردن واقعی به زودی آغاز خواهد شد."</string>
<string name="progress_notifier_message" msgid="2311011466908220528">"وارد کردن <xliff:g id="CURRENT_NUMBER">%s</xliff:g>/<xliff:g id="TOTAL_NUMBER">%s</xliff:g>: <xliff:g id="NAME">%s</xliff:g>"</string>
<string name="importing_vcard_description" msgid="4245275224298571351">"وارد کردن <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -245,10 +245,10 @@
<string name="reading_vcard_canceled_title" msgid="1925216585981542019">"خواندن داده کارت ویزیت لغو شد"</string>
<string name="importing_vcard_finished_title" msgid="3341541727268747967">"وارد کردن کارت ویزیت <xliff:g id="FILENAME">%s</xliff:g> پایان یافت"</string>
<string name="importing_vcard_canceled_title" msgid="2147475978165599336">"واردکردن <xliff:g id="FILENAME">%s</xliff:g> لغو شد"</string>
- <string name="vcard_import_will_start_message" msgid="2804911199145873396">"<xliff:g id="FILENAME">%s</xliff:g> به زودی وارد می شود."</string>
- <string name="vcard_import_will_start_message_with_default_name" msgid="1022969530654129470">"فایل پس از مدت کوتاهی وارد می شود."</string>
+ <string name="vcard_import_will_start_message" msgid="2804911199145873396">"<xliff:g id="FILENAME">%s</xliff:g> به زودی وارد میشود."</string>
+ <string name="vcard_import_will_start_message_with_default_name" msgid="1022969530654129470">"فایل پس از مدت کوتاهی وارد میشود."</string>
<string name="vcard_import_request_rejected_message" msgid="2890471184508516011">"درخواست وارد کردن کارت ویزیت رد شد. لطفاً بعداً امتحان کنید."</string>
- <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> به زودی صادر می شود."</string>
+ <string name="vcard_export_will_start_message" msgid="2210241345252081463">"<xliff:g id="FILENAME">%s</xliff:g> به زودی صادر میشود."</string>
<string name="vcard_export_request_rejected_message" msgid="2844874826431327531">"درخواست صدور کارت ویزیت رد شد. لطفاً بعداً امتحان کنید."</string>
<string name="vcard_unknown_filename" msgid="7171709890959915954">"مخاطب"</string>
<string name="percentage" msgid="1044592438199055502">"<xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g>"</string>
@@ -267,7 +267,7 @@
<string name="fail_reason_could_not_initialize_exporter" msgid="707260459259688510">"صادر کننده راهاندازی نشد: \"<xliff:g id="EXACT_REASON">%s</xliff:g>\"."</string>
<string name="fail_reason_error_occurred_during_export" msgid="3018855323913649063">"خطایی در هنگام صادر کردن روی داد: \"<xliff:g id="EXACT_REASON">%s</xliff:g>\""</string>
<string name="composer_failed_to_get_database_infomation" msgid="1765944280846236723">"نمیتوان اطلاعات پایگاه داده را دریافت کرد."</string>
- <string name="composer_has_no_exportable_contact" product="tablet" msgid="6991449891825077743">"مخاطب قابل صدوری وجود ندارد. اگر بر روی رایانه لوحی خود مخاطبینی دارید، بعضی از ارائهدهندگان داده ممکن است اجازه ندهند مخاطبین از رایانه لوحی صادر شوند."</string>
+ <string name="composer_has_no_exportable_contact" product="tablet" msgid="6991449891825077743">"مخاطب قابل صدوری وجود ندارد. اگر بر روی رایانهٔ لوحی خود مخاطبینی دارید، بعضی از ارائهدهندگان داده ممکن است اجازه ندهند مخاطبین از رایانهٔ لوحی صادر شوند."</string>
<string name="composer_has_no_exportable_contact" product="default" msgid="3296493229040294335">"هیچ مخاطب قابل صدوری وجود ندارد. اگر در گوشی خود مخاطبینی دارید، بعضی از ارائهدهندگان داده ممکن است اجازه ندهند تا مخاطبین از گوشی صادر شوند."</string>
<string name="composer_not_initialized" msgid="2321648986367005254">"سازنده فایل کارت ویزیت به درستی اجرا نشد."</string>
<string name="fail_reason_could_not_open_file" msgid="2067725459821997463">"\"<xliff:g id="FILE_NAME">%s</xliff:g>\" باز نشد: <xliff:g id="EXACT_REASON">%s</xliff:g>."</string>
@@ -275,8 +275,8 @@
<string name="cancel_import_confirmation_message" msgid="3929951040347726757">"وارد کردن <xliff:g id="FILENAME">%s</xliff:g> لغو شود؟"</string>
<string name="cancel_export_confirmation_message" msgid="1995462401949262638">"صادر کردن <xliff:g id="FILENAME">%s</xliff:g> لغو شود؟"</string>
<string name="cancel_vcard_import_or_export_failed" msgid="6139900383366166706">"نمیتوان وارد کردن/ صادر کردن کارت ویزیت را لغو کرد"</string>
- <string name="search_settings_description" msgid="2675223022992445813">"نام های مخاطبین شما"</string>
- <string name="add_2sec_pause" msgid="9214012315201040129">"افزودن یک مکث 2 ثانیه ای"</string>
+ <string name="search_settings_description" msgid="2675223022992445813">"نامهای مخاطبین شما"</string>
+ <string name="add_2sec_pause" msgid="9214012315201040129">"افزودن یک مکث ۲ ثانیهای"</string>
<string name="add_wait" msgid="3360818652790319634">"افزودن انتظار"</string>
<string name="call_disambig_title" msgid="4392886850104795739">"انتخاب شماره"</string>
<string name="call_settings" msgid="7666474782093693667">"تنظیمات"</string>
@@ -290,8 +290,8 @@
<string name="menu_import_export" msgid="26217871113229507">"وارد کردن/صادر کردن"</string>
<string name="dialog_import_export" msgid="4360648034889921624">"وارد کردن/صادر کردن مخاطبین"</string>
<string name="dialog_import" msgid="2431698729761448759">"وارد کردن مخاطبین"</string>
- <string name="menu_share" msgid="943789700636542260">"اشتراک گذاری"</string>
- <string name="share_via" msgid="563121028023030093">"اشتراک گذاری مخاطب از طریق"</string>
+ <string name="menu_share" msgid="943789700636542260">"اشتراکگذاری"</string>
+ <string name="share_via" msgid="563121028023030093">"اشتراکگذاری مخاطب از طریق"</string>
<string name="share_error" msgid="948429331673358107">"این مخاطب قابل اشتراکگذاری نیست."</string>
<string name="nameLabelsGroup" msgid="2034640839640477827">"نام"</string>
<string name="nicknameLabelsGroup" msgid="2891682101053358010">"نام مستعار"</string>
@@ -299,16 +299,16 @@
<string name="websiteLabelsGroup" msgid="4202998982804009261">"وب سایت"</string>
<string name="eventLabelsGroup" msgid="3695433812142818803">"رویدادها"</string>
<string name="relationLabelsGroup" msgid="1854373894284572781">"رابطه"</string>
- <string name="groupsLabel" msgid="8573535366319059326">"گروه ها"</string>
+ <string name="groupsLabel" msgid="8573535366319059326">"گروهها"</string>
<string name="dialog_new_contact_account" msgid="9044704073286262197">"ایجاد مخاطبین تحت حساب"</string>
<string name="dialog_new_group_account" msgid="2318032089273496830">"ایجاد گروه تحت حساب کاربری"</string>
<string name="menu_sync_remove" msgid="3266725887008450161">"حذف گروه همگام سازی"</string>
<string name="dialog_sync_add" msgid="8267045393119375803">"افزودن گروه همگام سازی"</string>
- <string name="display_more_groups" msgid="2682547080423434170">"گروه های بیشتر..."</string>
- <string name="display_ungrouped" msgid="6885954210243119591">"کلیه مخاطبین دیگر"</string>
+ <string name="display_more_groups" msgid="2682547080423434170">"گروههای بیشتر..."</string>
+ <string name="display_ungrouped" msgid="6885954210243119591">"همهٔ مخاطبین دیگر"</string>
<string name="display_all_contacts" msgid="2031647544742889505">"همه مخاطبین"</string>
<string name="display_warn_remove_ungrouped" msgid="8872290721676651414">"حذف \"<xliff:g id="GROUP">%s</xliff:g>\" از همگامسازی نیز هر گونه مخاطب گروهبندی نشدهای را از همگامسازی حذف میکند."</string>
- <string name="account_phone" product="tablet" msgid="7946049152658522054">"فقط رایانه لوحی، همگام سازی نشده"</string>
+ <string name="account_phone" product="tablet" msgid="7946049152658522054">"فقط رایانهٔ لوحی، همگام سازی نشده"</string>
<string name="account_phone" product="default" msgid="3682950835276226870">"فقط تلفن، همگام سازی نشده"</string>
<string name="call_custom" msgid="7756571794763171802">"تماس با <xliff:g id="CUSTOM">%s</xliff:g>"</string>
<string name="call_home" msgid="1990519474420545392">"تماس با خانه"</string>
@@ -373,7 +373,7 @@
<string name="chat_jabber" msgid="7561444230307829609">"گپ با استفاده از Jabber"</string>
<string name="chat" msgid="9025361898797412245">"گپ"</string>
<string name="audio_chat" msgid="2535716629358298691">"گپ صوتی"</string>
- <string name="video_chat" msgid="1872255818640336072">"گپ ویدیویی"</string>
+ <string name="video_chat" msgid="1872255818640336072">"گپ ویدئویی"</string>
<string name="postal_address" msgid="8765560217149624536">"آدرس"</string>
<string name="postal_street" msgid="8133143961580058972">"خیابان"</string>
<string name="postal_pobox" msgid="4431938829180269821">"صندوق پستی"</string>
@@ -406,23 +406,23 @@
<string name="display_options_sort_list_by" msgid="6080091755852211076">"مرتب سازی لیست بر اساس"</string>
<string name="display_options_sort_by_given_name" msgid="184916793466387067">"نام"</string>
<string name="display_options_sort_by_family_name" msgid="7857986975275712622">"نام خانوادگی"</string>
- <string name="display_options_view_names_as" msgid="18022868169627979">"مشاهده نام های مخاطب بعنوان"</string>
+ <string name="display_options_view_names_as" msgid="18022868169627979">"مشاهده نامهای مخاطب بهعنوان"</string>
<string name="display_options_view_given_name_first" msgid="6968288511197363292">"ابتدا نام"</string>
<string name="display_options_view_family_name_first" msgid="1447288164951453714">"ابتدا نام خانوادگی"</string>
<string name="take_photo" msgid="7496128293167402354">"عکسبرداری"</string>
<string name="take_new_photo" msgid="7341354729436576304">"گرفتن عکس جدید"</string>
<string name="pick_photo" msgid="3746334626214970837">"انتخاب عکس از گالری"</string>
<string name="pick_new_photo" msgid="7962368009197147617">"انتخاب عکس جدید از گالری"</string>
- <string name="locale_change_in_progress" msgid="7583992153091537467">"لیست مخاطبین در حال به روزرسانی برای منعکس کردن تغییرات زبان است."</string>
- <string name="upgrade_in_progress" msgid="474511436863451061">"لیست مخاطبین در حال به روزرسانی است."</string>
- <string name="upgrade_out_of_memory" msgid="1209994418877625940">"مخاطبین در حال ارتقا هستند. "\n\n"فرآیند ارتقا به تقریباً <xliff:g id="SIZE_IN_MEGABYTES">%s</xliff:g> مگابایت از حافظه داخلی نیاز دارد. "\n\n"یکی از گزینههای زیر را انتخاب کنید:"</string>
- <string name="upgrade_out_of_memory_uninstall" msgid="1721798828992091432">"حذف نصب برخی از برنامه های کاربردی"</string>
+ <string name="locale_change_in_progress" msgid="7583992153091537467">"لیست مخاطبین در حال بهروزرسانی برای منعکس کردن تغییرات زبان است."</string>
+ <string name="upgrade_in_progress" msgid="474511436863451061">"لیست مخاطبین در حال بهروزرسانی است."</string>
+ <string name="upgrade_out_of_memory" msgid="1209994418877625940">"مخاطبین در حال ارتقا هستند. "\n\n"فرآیند ارتقا به تقریباً <xliff:g id="SIZE_IN_MEGABYTES">%s</xliff:g> مگابایت از حافظهٔ داخلی نیاز دارد. "\n\n"یکی از گزینههای زیر را انتخاب کنید:"</string>
+ <string name="upgrade_out_of_memory_uninstall" msgid="1721798828992091432">"حذف نصب برخی از برنامههای کاربردی"</string>
<string name="upgrade_out_of_memory_retry" msgid="8431289830472724609">"امتحان مجدد برای ارتقا"</string>
<string name="search_results_searching" msgid="3984833028938569930">"در حال جستجو..."</string>
<string name="menu_display_selected" msgid="6470001164297969034">"نمایش موارد انتخاب شده"</string>
<string name="menu_display_all" msgid="8887488642609786198">"نمایش همه"</string>
<string name="menu_select_all" msgid="621719255150713545">"انتخاب همه"</string>
- <string name="menu_select_none" msgid="7093222469852132345">"لغو انتخاب همه موارد"</string>
+ <string name="menu_select_none" msgid="7093222469852132345">"لغو انتخاب همهٔ موارد"</string>
<string name="no_contacts_selected" msgid="5877803471037324613">"مخاطبی انتخاب نشده است."</string>
<string name="add_field" msgid="2384260056674995230">"افزودن یک قسمت دیگر"</string>
<string name="add_new_entry_for_section" msgid="5223080690667565044">"افزودن مورد جدید"</string>
@@ -439,7 +439,7 @@
</plurals>
<string name="local_invisible_directory" msgid="6046691709127661065">"سایر موارد"</string>
<string name="aggregation_suggestion_join_dialog_message" msgid="3842757977671434836">"پیوستن به مخاطب فعلی با مخاطب انتخابی؟"</string>
- <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"به ویرایش مخاطب انتخابی می روید؟ اطلاعاتی که تا حال وارد کرده اید کپی خواهد شد."</string>
+ <string name="aggregation_suggestion_edit_dialog_message" msgid="6549585283910518095">"به ویرایش مخاطب انتخابی میروید؟ اطلاعاتی که تا حال وارد کردهاید کپی خواهد شد."</string>
<string name="menu_copyContact" msgid="1573960845106822639">"کپی در مخاطبین من"</string>
<string name="add_to_my_contacts" msgid="1068274916793627723">"افزودن به مخاطبین من"</string>
<string name="contact_directory_description" msgid="683398073603909119">"دایرکتوری <xliff:g id="TYPE">%1$s</xliff:g>"</string>
@@ -447,18 +447,18 @@
<string name="local_search_label" msgid="2551177578246113614">"همه مخاطبین"</string>
<string name="toast_making_personal_copy" msgid="288549957278065542">"ایجاد یک کپی شخصی..."</string>
<string name="list_filter_all_accounts" msgid="8908683398914322369">"همه مخاطبین"</string>
- <string name="list_filter_all_starred" msgid="5031734941601931356">"ستاره دار"</string>
+ <string name="list_filter_all_starred" msgid="5031734941601931356">"ستارهدار"</string>
<string name="list_filter_custom" msgid="8910173055702057002">"سفارشی"</string>
<string name="list_filter_customize" msgid="4789963356004169321">"سفارشی کردن"</string>
<string name="list_filter_phones" msgid="735313795643493365">"همه مخاطبین دارای شماره تلفن"</string>
<string name="list_filter_single" msgid="5871400283515893087">"مخاطب"</string>
<string name="custom_list_filter" msgid="7836035257402013957">"تعیین نمای سفارشی"</string>
- <string name="contact_list_loading" msgid="5488620820563977329">"درحال بارگیری..."</string>
+ <string name="contact_list_loading" msgid="5488620820563977329">"در حال بارگیری..."</string>
<string name="activity_title_settings" msgid="5464130076132770781">"تنظیمات"</string>
<string name="activity_title_contacts_filter" msgid="8275542497615516969">"مخاطبین جهت نمایش"</string>
<string name="menu_settings" msgid="377929915873428211">"تنظیمات"</string>
<string name="menu_help" msgid="5123887102216637725">"راهنمایی"</string>
- <string name="preference_displayOptions" msgid="1341720270148252393">"گزینه های نمایش"</string>
+ <string name="preference_displayOptions" msgid="1341720270148252393">"گزینههای نمایش"</string>
<string name="organization_company_and_title" msgid="6718207751363732025">"<xliff:g id="COMPANY_0">%2$s</xliff:g>، <xliff:g id="COMPANY_1">%1$s</xliff:g>"</string>
<string name="hint_findContacts" msgid="1808681193458772072">"پیدا کردن مخاطبین"</string>
<string name="non_phone_caption" msgid="1541655052330027380">"شماره تلفن"</string>
@@ -468,7 +468,7 @@
<string name="widget_name_and_phonetic" msgid="8739586586600099979">"<xliff:g id="DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="PHONETIC_NAME">%2$s</xliff:g>)"</string>
<string name="date_year_toggle" msgid="7356532842767854606">"یک سال وارد کنید"</string>
<string name="social_widget_label" msgid="6378905543028924592">"مخاطب"</string>
- <string name="social_widget_loading" msgid="5327336597364074608">"درحال بارگیری..."</string>
+ <string name="social_widget_loading" msgid="5327336597364074608">"در حال بارگیری..."</string>
<string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"ایجاد مخاطب جدید"</string>
<string name="contacts_unavailable_add_account" msgid="7911101713860139754">"وارد شدن به یک حساب"</string>
<string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"وارد کردن مخاطبین"</string>
@@ -489,7 +489,7 @@
</plurals>
<string name="toast_join_with_empty_contact" msgid="2238581529864542985">"لطفاً قبل از ادغام با مخاطب دیگر، نام مخاطب را وارد کنید."</string>
<string name="copy_text" msgid="3257145021583508761">"کپی به کلیپ بورد"</string>
- <string name="set_default" msgid="4417505153468300351">"تنظیم پیش فرض"</string>
+ <string name="set_default" msgid="4417505153468300351">"تنظیم پیشفرض"</string>
<string name="clear_default" msgid="7193185801596678067">"پاک کردن پیش فرضها"</string>
<string name="toast_text_copied" msgid="5143776250008541719">"متن کپی شده"</string>
<string name="cancel_confirmation_dialog_message" msgid="5885724679874403115">"از تغییرات شما صرفنظر شود؟"</string>
@@ -505,13 +505,13 @@
<string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>، <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
<string name="notification_new_voicemail_ticker" msgid="895342132049452081">"پست صوتی جدید از <xliff:g id="CALLER">%1$s</xliff:g>"</string>
<string name="voicemail_playback_error" msgid="1811242131549854624">"پخش پست صوتی ممکن نیست."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"درحال بافر کردن؟؟؟"</string>
+ <string name="voicemail_buffering" msgid="738287747618697097">"در حال بافر کردن؟؟؟"</string>
<string name="voicemail_fetching_content" msgid="877911315738258780">"در حال واکشی پست صوتی؟؟؟"</string>
<string name="voicemail_fetching_timout" msgid="6691792377574905201">"واکشی پست صوتی ممکن نیست."</string>
<string name="call_log_new_header" msgid="846546437517724715">"جدید"</string>
<string name="call_log_old_header" msgid="6262205894314263629">"قدیمیتر"</string>
<string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"اتصال به سرور پست صوتی امکانپذیر نیست."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"اتصال به سرور پست صوتی امکان پذیر نیست. پستهای صوتی جدید در انتظارند."</string>
+ <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"اتصال به سرور پست صوتی امکانپذیر نیست. پستهای صوتی جدید در انتظارند."</string>
<string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"پست صوتی خود را تنظیم کنید."</string>
<string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"صدا موجود نیست."</string>
<string name="voicemail_status_action_configure" msgid="8671796489912239589">"راهاندازی"</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"نام گروه"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"مخاطب از طریق NFC رسید"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"فقط نمایش خروجی"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"فقط نمایش ورودی"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"فقط نمایش بیپاسخ"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"فقط نمایش پستهای صوتی"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"نمایش همه مکالمات"</string>
<string name="status_available" msgid="5586870015822828392">"در دسترس"</string>
@@ -550,14 +553,15 @@
<string name="no_account_prompt" msgid="7061052512446855192">"People با یک حساب Google بهتر کار میکند."\n\n"• از هر مرورگر وب به آن دسترسی دارید"\n"• از رویدادهای خود به طور امن پشتیبان تهیه کنید"</string>
<string name="generic_no_account_prompt" msgid="7218827704367325460">"مخاطبین خود را ایمن نگهدارید حتی اگر گوشی شما گم شود: با یک سرویس آنلاین همگامسازی کنید."</string>
<string name="generic_no_account_prompt_title" msgid="753783911899054860">"افزودن یک حساب"</string>
- <string name="contact_editor_prompt_zero_accounts" msgid="1785345895691886499">"از مخاطب جدید شما نسخه پشتبان تهیه نمیشود. حسابی را اضافه میکنید که از مخاطبین بصورت آنلاین نسخه پشتبان تهیه کند؟"</string>
+ <string name="contact_editor_prompt_zero_accounts" msgid="1785345895691886499">"از مخاطب جدید شما نسخه پشتبان تهیه نمیشود. حسابی را اضافه میکنید که از مخاطبین بهصورت آنلاین نسخه پشتبان تهیه کند؟"</string>
<string name="contact_editor_prompt_one_account" msgid="8669032699767375976">"مخاطب جدید شما با <xliff:g id="ACCOUNT_NAME">%1$s</xliff:g> همگامسازی خواهد شد."</string>
<string name="contact_editor_prompt_multiple_accounts" msgid="611828200100438242">"شما میتوانید مخاطب جدید خود را با یکی از حسابهای زیر همگامسازی کنید. از کدامیک میخواهید استفاده کنید؟"</string>
- <string name="keep_local" msgid="1258761699192993322">"ذخیره بصورت محلی"</string>
+ <string name="keep_local" msgid="1258761699192993322">"ذخیره بهصورت محلی"</string>
<string name="add_account" msgid="8201790677994503186">"افزودن حساب"</string>
<string name="add_new_account" msgid="5748627740680940264">"اافزودن حساب جدید"</string>
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"تماس ارسال نشد"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"برای راهاندازی پست صوتی به منو > تنظیمات بروید."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"برای تماس با پست صوتی، ابتدا حالت هواپیما را غیرفعال کنید."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"صدور فایلهای پایگاه داده"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"گزینههای بیشتر"</string>
</resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 623de8f..2450f14 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"askelpalautin"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"numero johon soitetaan"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"yhteystiedon valokuva"</string>
- <string name="description_minus_button" msgid="387136707700230172">"miinus"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"poista"</string>
<string name="description_plus_button" msgid="515164827856229880">"plus"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Näytä yhteystieto"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Tallennustilaa ei löydy."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Ryhmän nimi"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Kontakti saatu (NFC)"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Näytä vain soitetut"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Näytä vain saapuneet"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Näytä vain vastaamattomat"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Näytä vain vastaajaviestit"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Näytä kaikki puhelut"</string>
<string name="status_available" msgid="5586870015822828392">"Tavoitettavissa"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Puhelua ei soitettu"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Määritä puhelinvastaajan asetukset kohdassa Valikko > Asetukset."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Poista lentokonetila käytöstä ennen vastaajaan soittamista."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Vie tietokantatiedostot"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Lisää vaihtoehtoja"</string>
</resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index c6191bd..9a8ac18 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"retour arrière"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"numéro à composer"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"photo du contact"</string>
- <string name="description_minus_button" msgid="387136707700230172">"moins"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"supprimer"</string>
<string name="description_plus_button" msgid="515164827856229880">"plus"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Afficher le contact"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Aucune mémoire stock. trouvée."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Nom du groupe"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Contact reçu via NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Afficher appels sortants uniq."</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Afficher appels entrants uniq."</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Afficher appels manqués uniq."</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Messages vocaux uniquement"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Afficher tous les appels"</string>
<string name="status_available" msgid="5586870015822828392">"Disponible"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Appel non effectué."</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Pour configurer la messagerie vocale, accédez à Menu > Paramètres."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Veuillez désactiver le mode Avion avant d\'appeler la messagerie vocale."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Exporter les fichiers de la base de données"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Plus d\'options"</string>
</resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 50dc01f..10862ad 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"हटाएं"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"डायल करने के लिए नंबर"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"संपर्क का फ़ोटो"</string>
- <string name="description_minus_button" msgid="387136707700230172">"निकालें"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"हटाएं"</string>
<string name="description_plus_button" msgid="515164827856229880">"जोड़ें"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"संपर्क देखें"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"कोई संग्रहण नहीं मिला."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"समूह का नाम"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"NFC पर प्राप्त संपर्क"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"केवल आउटगोइंग ही दिखाएं"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"केवल इनकमिंग ही दिखाएं"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"केवल छूटे हुए ही दिखाएं"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"केवल ध्वनिमेल दिखाएं"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"सभी कॉल दिखाएं"</string>
<string name="status_available" msgid="5586870015822828392">"उपलब्ध"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"कॉल नहीं भेजा गया"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"ध्वनिमेल सेट करने के लिए, मेनू > सेटिंग पर जाएं."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"ध्वनिमेल कॉल करने के लिए, पहले हवाई जहाज़ मोड बंद करें."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"डेटाबेस फ़ाइलें निर्यात करें"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"अधिक विकल्प"</string>
</resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index c8b2785..faf71c5 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"broj za pozivanje"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"fotografija kontakta"</string>
- <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"izbriši"</string>
<string name="description_plus_button" msgid="515164827856229880">"plus"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Prikaži kontakt"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Nije pronađena nijedna pohrana."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Naziv grupe"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Kontakt NFC-om"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Prikaži samo odlazne"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Prikaži samo dolazne"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Prikaži samo propuštene"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Prikaži samo govorne pošte"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Prikaz svih poziva"</string>
<string name="status_available" msgid="5586870015822828392">"Dostupan"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Poziv nije poslan"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Da biste postavili govornu poštu, idite na Izbornik > Postavke."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Da biste nazvali govornu poštu, najprije isključite način rada u zrakoplovu."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Izvezi datoteke podatkovne baze"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Više opcija"</string>
</resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 11126b9..f1a9e25 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"Backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"a tárcsázandó szám"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"fotó a névjegyhez"</string>
- <string name="description_minus_button" msgid="387136707700230172">"mínusz"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"törlés"</string>
<string name="description_plus_button" msgid="515164827856229880">"plusz"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Névjegy megtekintése"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Nem található tárhely."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Csoport neve"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"NFC-n kapott névjegy"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Csak a kimenők megjelenítése"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Csak a bejövők megjelenítése"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Nem fogadottak megjelenítése"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Csak a hangüzenetek"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Összes hívás megjelenítése"</string>
<string name="status_available" msgid="5586870015822828392">"Elérhető"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"A hívás nem indítható."</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"A hangposta beállításához válassza a Menü > Beállítások pontot."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Hangposta hívásához kapcsolja ki a Repülőgép üzemmódot."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Adatbázisfájlok exportálása"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"További beállítások"</string>
</resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 1d51c8e..5659e42 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"nomor untuk dipanggil"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"foto kontak"</string>
- <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"hapus"</string>
<string name="description_plus_button" msgid="515164827856229880">"plus"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Lihat kontak"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Tidak ditemukan penyimpanan."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Nama grup"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Kontak yang diterima lewat NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Tampilkan panggilan keluar"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Tampilkan panggilan masuk saja"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Tampilkan panggilan terlewat"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Tampilkan pesan suara saja"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Tampilkan semua panggilan"</string>
<string name="status_available" msgid="5586870015822828392">"Tersedia"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Panggilan tidak terkirim"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Untuk menyiapkan kotak pesan, buka Menu > Setelan."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Untuk memanggil pesan suara, pertama-tama matikan mode Pesawat."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Ekspor file basis data"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Opsi lainnya"</string>
</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index cd73640..45ab9e5 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"numero da comporre"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"foto contatto"</string>
- <string name="description_minus_button" msgid="387136707700230172">"meno"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"elimina"</string>
<string name="description_plus_button" msgid="515164827856229880">"più"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Visualizza contatto"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Nessun archivio trovato."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Nome del gruppo"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Contatto ricevuto via NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Mostra solo in uscita"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Mostra solo in arrivo"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Mostra solo senza risposta"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Mostra solo messaggi vocali"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Mostra tutte le chiamate"</string>
<string name="status_available" msgid="5586870015822828392">"Disponibile"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Chiamata non inviata"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Per configurare la segreteria, seleziona Menu > Impostazioni."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Per chiamare la segreteria, disattiva la modalità aereo."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Esporta file database"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Altre opzioni"</string>
</resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 1340f07..32c1833 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"Backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"מספר לחיוג"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"תמונה של איש קשר"</string>
- <string name="description_minus_button" msgid="387136707700230172">"חיסור"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"מחק"</string>
<string name="description_plus_button" msgid="515164827856229880">"חיבור"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"הצג איש קשר"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"לא נמצאו התקני אחסון."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"שם הקבוצה"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"איש הקשר התקבל באמצעות NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"הצג רק שיחות יוצאות"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"הצג רק שיחות נכנסות"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"הצג רק שיחות שלא נענו"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"הצג הודעות דואר קולי בלבד"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"הצג את כל השיחות"</string>
<string name="status_available" msgid="5586870015822828392">"זמין"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"השיחה לא נשלחה."</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"כדי להגדיר את הדואר הקולי, עבור אל \'תפריט\' > \'הגדרות\'."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"כדי להתקשר לדואר קולי, ראשית כבה את מצב הטיסה."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"ייצוא קובצי מסד נתונים"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"אפשרויות נוספות"</string>
</resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 1d9514f..1cfe336 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -72,7 +72,7 @@
<string name="deleteConfirmation" msgid="811706994761610640">"この連絡先を削除します。"</string>
<string name="menu_done" msgid="796017761764190697">"完了"</string>
<string name="menu_doNotSave" msgid="58593876893538465">"キャンセル"</string>
- <string name="menu_discard" msgid="6456087569315685632">"破棄"</string>
+ <string name="menu_discard" msgid="6456087569315685632">"キャンセル"</string>
<string name="label_notes" msgid="8337354953278341042">"メモ"</string>
<string name="label_sip_address" msgid="124073911714324974">"インターネット通話"</string>
<string name="ghostData_company" msgid="5414421120553765775">"会社"</string>
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"Backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"発信番号"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"連絡先の写真"</string>
- <string name="description_minus_button" msgid="387136707700230172">"マイナス"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"削除"</string>
<string name="description_plus_button" msgid="515164827856229880">"プラス"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"連絡先を表示"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"ストレージはありませんでした。"</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>)<xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"グループの名前"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"NFC受信の連絡先"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"発信のみを表示"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"着信のみを表示"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"不在着信のみを表示"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"ボイスメールのみ表示"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"すべての通話を表示"</string>
<string name="status_available" msgid="5586870015822828392">"オンライン"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"発信できません"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"ボイスメールをセットアップするには、MENUキー>[設定]をタップします。"</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"機内モードをOFFにしてからボイスメールを呼び出してください。"</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"データベースファイルをエクスポート"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"その他のオプション"</string>
</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 9c1f197..54f77d3 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"백스페이스"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"전화를 걸 번호"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"주소록 사진"</string>
- <string name="description_minus_button" msgid="387136707700230172">"빼기"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"삭제"</string>
<string name="description_plus_button" msgid="515164827856229880">"더하기"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"연락처 보기"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"저장공간을 찾을 수 없습니다."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"<xliff:g id="DATE">%2$s</xliff:g>에 통화 <xliff:g id="COUNT">%1$d</xliff:g>통"</string>
<string name="group_name_hint" msgid="238359485263401293">"그룹 이름"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"NFC를 통해 받은 연락처"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"발신 전화만 표시"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"수신 전화만 표시"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"부재중 전화만 표시"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"음성사서함만 표시"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"모든 통화 표시"</string>
<string name="status_available" msgid="5586870015822828392">"대화 가능"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"전화를 걸 수 없음"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"음성사서함을 설정하려면 메뉴 > 설정으로 이동하세요."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"음성사서함에 메시지를 남기려면 먼저 비행기 모드를 해제하세요."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"데이터베이스 파일 내보내기"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"옵션 더보기"</string>
</resources>
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
index 350693a..e72a0ee 100644
--- a/res/values-land/dimens.xml
+++ b/res/values-land/dimens.xml
@@ -17,4 +17,7 @@
<dimen name="dialpad_digits_height">66dip</dimen>
<dimen name="dialpad_digits_text_size">28sp</dimen>
<dimen name="dialpad_digits_margin_bottom">50dip</dimen>
+ <!-- Center vertically -->
+ <dimen name="quick_contact_top_position">-1px</dimen>
+ <dimen name="editor_type_label_width">120dip</dimen>
</resources>
diff --git a/res/values-w470dp/donottranslate_config.xml b/res/values-land/donottranslate_config.xml
similarity index 100%
rename from res/values-w470dp/donottranslate_config.xml
rename to res/values-land/donottranslate_config.xml
diff --git a/res/values-w470dp/integers.xml b/res/values-land/integers.xml
similarity index 100%
rename from res/values-w470dp/integers.xml
rename to res/values-land/integers.xml
diff --git a/res/values-w470dp/styles.xml b/res/values-land/styles.xml
similarity index 100%
rename from res/values-w470dp/styles.xml
rename to res/values-land/styles.xml
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 4b83caa..19b74be 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"naikinimo klavišas"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"renkamas numeris"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"adresato nuotrauka"</string>
- <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"ištrinti"</string>
<string name="description_plus_button" msgid="515164827856229880">"plius"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Peržiūrėti kontaktą"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Nerasta jokių atmintinių."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Grupės pavadinimas"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Gauta per ALR"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Rodyti tik išsiunčiamus"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Rodyti tik gaunamus"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Rodyti tik praleistus"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Rodyti tik balso pšt. praneš."</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Rodyti visus skambučius"</string>
<string name="status_available" msgid="5586870015822828392">"Pasiekiamas"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Skambutis neišsiųstas"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Jei norite nustatyti balso paštą, eikite į „Meniu“ > „Nustatymai“."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Jei norite skambinti į balso paštą, išjunkite lėktuvo režimą."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Eksportuoti duomenų failus"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Daugiau parinkčių"</string>
</resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index fa38a53..50b5e27 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"atpakaļatkāpe"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"sastādītais numurs"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"kontaktpersonas fotoattēls"</string>
- <string name="description_minus_button" msgid="387136707700230172">"mīnuss"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"dzēst"</string>
<string name="description_plus_button" msgid="515164827856229880">"pluss"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Skatīt kontaktpersonu"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Netika atrasta atmiņa."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Grupas nosaukums"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"No NFC saņ. kontaktinf."</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Rādīt tikai izejošos zvanus"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Rādīt tikai ienākošos zvanus"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Rādīt tikai neatbildētos zvanus"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Rādīt tikai balss pasta ziņ."</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Rādīt visus zvanus"</string>
<string name="status_available" msgid="5586870015822828392">"Pieejama"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Nenosūtīts zvans"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Lai iestatītu balss pastu, atveriet sadaļu Izvēlne > Iestatījumi."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Lai piezvanītu balss pastam, vispirms izslēdziet lidojuma režīmu."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Eksportēt datu bāzes failus"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Vairāk opciju"</string>
</resources>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 384d3f0..ca2b8dc 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"undur ruang"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"nombor untuk didail"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"foto kenalan"</string>
- <string name="description_minus_button" msgid="387136707700230172">"tolak"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"padam"</string>
<string name="description_plus_button" msgid="515164827856229880">"tambah"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Lihat kenalan"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Tiada storan ditemui."</string>
@@ -526,6 +526,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Nama kumpulan"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Knln melalui NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Tunjukkan panggilan keluar shj"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Tunjukkan panggilan masuk shj"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Tujukkan pgln terlepas shj"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Tunjukkan mel suara sahaja"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Tunjukkan semua panggilan"</string>
<string name="status_available" msgid="5586870015822828392">"Ada"</string>
@@ -561,5 +564,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Panggilan tidak dihantar"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Untuuk menyediakan mel suara, pergi ke Menu > Tetapan."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Untuk membuat panggilan ke mel suara, mula-mula matikan mod Pesawat."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Eksport fail pangkalan data"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Lagi pilihan"</string>
</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index b435f1f..bf75dc0 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"tilbaketast"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"ring til"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"kontaktbilde"</string>
- <string name="description_minus_button" msgid="387136707700230172">"minusknapp"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"slett"</string>
<string name="description_plus_button" msgid="515164827856229880">"plussknapp"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Se kontakt"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Finner ikke lagringsplass."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Gruppens navn"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Kontakt mottatt per NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Vis bare utgående"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Vis bare innkommende"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Vis bare tapte"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Vis bare talemeldinger"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Vis alle samtaler"</string>
<string name="status_available" msgid="5586870015822828392">"Tilgjengelig"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Anrop ikke utført"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Du konfigurerer talepost ved å gå til Meny &gt Innstillinger"</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Du må slå av flymodus før du kan sjekke talepostkassen."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Eksporter databasefilene"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Flere alternativer"</string>
</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 8827837..e728d99 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"nummer om te bellen"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"contactfoto"</string>
- <string name="description_minus_button" msgid="387136707700230172">"min"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"verwijderen"</string>
<string name="description_plus_button" msgid="515164827856229880">"plus"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Contact weergeven"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Er is geen opslag gevonden."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Naam van de groep"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Contact via NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Alleen uitgaand weergeven"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Alleen inkomend weergeven"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Alleen gemist weergeven"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Alleen voicemails weergeven"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Alle oproepen weergeven"</string>
<string name="status_available" msgid="5586870015822828392">"Beschikbaar"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Oproep niet uitgevoerd"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Voor het instellen van voicemail, gaat u naar \'Menu\' > \'Instellingen\'."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Als u uw voicemail wilt bellen, moet u eerst de Vliegmodus uitschakelen."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Databasebestanden exporteren"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Meer opties"</string>
</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 699a908..81eaa2d 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"numer do wybrania"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"zdjęcie kontaktu"</string>
- <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"usuń"</string>
<string name="description_plus_button" msgid="515164827856229880">"plus"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Wyświetl kontakt"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Nie znaleziono nośnika."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Nazwa grupy"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Odebrane przez NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Pokaż tylko wychodzące"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Pokaż tylko przychodzące"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Pokaż tylko nieodebrane"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Pokaż tylko pocztę głosową"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Pokaż wszystkie połączenia"</string>
<string name="status_available" msgid="5586870015822828392">"Dostępny"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Połączenie nie zostało zrealizowane"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Aby skonfigurować pocztę głosową, przejdź do Menu > Ustawienia."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Aby połączyć się z pocztą głosową, najpierw wyłącz tryb samolotowy."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Eksportuj pliki bazy danych"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Więcej opcji"</string>
</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 98f6a06..7a2bd87 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"retrocesso"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"número a marcar"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"fotografia do contacto"</string>
- <string name="description_minus_button" msgid="387136707700230172">"menos"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"eliminar"</string>
<string name="description_plus_button" msgid="515164827856229880">"mais"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Ver contacto"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Nenhum armazen. encontrado."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Nome do Grupo"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Contacto recebido através de NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Mostrar apenas cham. efetuadas"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Mostrar apenas cham. recebidas"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Mostrar apenas cham. n. atend."</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Mostrar apenas msgs corr. voz"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Mostrar todas as chamadas"</string>
<string name="status_available" msgid="5586870015822828392">"Available"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Chamada não efetuada"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Para configurar o correio de voz, aceda a Menu > Definições."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Para efetuar uma chamada para o correio de voz, desative primeiro o Modo de avião."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Exportar ficheiros da base de dados"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Mais opções"</string>
</resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index a5acbbc..c1055a1 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"número para discagem"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"foto do contato"</string>
- <string name="description_minus_button" msgid="387136707700230172">"menos"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"excluir"</string>
<string name="description_plus_button" msgid="515164827856229880">"mais"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Visualizar contato"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Nenhum armazenamento foi encontrado."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Nome do grupo"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Contato via NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Mostrar apenas enviadas"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Mostrar apenas recebidas"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Mostrar apenas perdidas"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Exibir apenas mensagens de voz"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Mostrar todas as chamadas"</string>
<string name="status_available" msgid="5586870015822828392">"Disponível"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Chamada não realizada"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Para configurar o correio de voz, vá para Menu > Configurações."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Para chamar o correio de voz, primeiro desative o modo avião."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Exportar arquivos do banco de dados"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Mais opções"</string>
</resources>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index 43386ba..7facc56 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -276,7 +276,8 @@
<string name="description_delete_button" msgid="6263102114033407382">"tasta da return"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"numer da cumponer"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"foto dal contact"</string>
- <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
+ <!-- no translation found for description_minus_button (6908099247930477551) -->
+ <skip />
<string name="description_plus_button" msgid="515164827856229880">"plus"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Mussar il contact"</string>
<!-- no translation found for no_sdcard_message (5242558018442357189) -->
@@ -751,6 +752,12 @@
<skip />
<!-- no translation found for nfc_vcard_file_name (2823095213265993609) -->
<skip />
+ <!-- no translation found for menu_show_outgoing_only (1965570298133301970) -->
+ <skip />
+ <!-- no translation found for menu_show_incoming_only (7534206815238877417) -->
+ <skip />
+ <!-- no translation found for menu_show_missed_only (154473166059743996) -->
+ <skip />
<!-- no translation found for menu_show_voicemails_only (1898421289561435703) -->
<skip />
<!-- no translation found for menu_show_all_calls (7560347482073345885) -->
@@ -821,6 +828,8 @@
<skip />
<!-- no translation found for dialog_voicemail_airplane_mode_message (530922773669546093) -->
<skip />
+ <!-- no translation found for menu_export_database (2659719297530170820) -->
+ <skip />
<!-- no translation found for action_menu_overflow_description (2303272250613084574) -->
<!-- no translation found for action_menu_overflow_description (2295659037509008453) -->
<skip />
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 4cd53dc..38236b9 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"tasta backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"numărul de apelat"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"fotografia persoanei din agendă"</string>
- <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"ştergeţi"</string>
<string name="description_plus_button" msgid="515164827856229880">"plus"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Afişaţi persoana din agendă"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Nu s-a găsit o stocare."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Numele grupului"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Cont.prim.pr.NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Numai apelurile efectuate"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Numai apelurile primite"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Numai apelurile nepreluate"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Afişaţi numai mesajele vocale"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Afişaţi toate apelurile"</string>
<string name="status_available" msgid="5586870015822828392">"Disponibil(ă)"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Apelul nu a fost trimis"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Pentru a configura mesageria vocală, accesaţi Meniu > Setări."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Pentru a apela mesageria vocală, mai întâi dezactivaţi modul Avion."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Exportaţi fişierele bazei de date"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Mai multe opţiuni"</string>
</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 6602038..a1311a8 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"удаление последнего символа"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"набираемый номер"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"фотография контакта"</string>
- <string name="description_minus_button" msgid="387136707700230172">"минус"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"удалить"</string>
<string name="description_plus_button" msgid="515164827856229880">"плюс"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Данные контакта"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Хранилище не найдено."</string>
@@ -344,7 +344,7 @@
<string name="sms_company_main" msgid="118970873419678087">"SMS: тел. офиса"</string>
<string name="sms_isdn" msgid="8153785037515047845">"SMS: номер ISDN"</string>
<string name="sms_main" msgid="8621625784504541679">"SMS:основ. тел."</string>
- <string name="sms_other_fax" msgid="3888842199855843152">"Отправить SMS·на номер факса"</string>
+ <string name="sms_other_fax" msgid="3888842199855843152">"Отправить SMS на номер факса"</string>
<string name="sms_radio" msgid="3329166673433967820">"SMS:радиотелефон"</string>
<string name="sms_telex" msgid="9034802430065267848">"SMS: телекс"</string>
<string name="sms_tty_tdd" msgid="6782284969132531532">"SMS: телетайп"</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Название группы"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Получено по NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Исходящие"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Входящие"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Пропущенные"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Показать голосовые сообщения"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Показать все вызовы"</string>
<string name="status_available" msgid="5586870015822828392">"На месте"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Вызов невозможен"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Чтобы настроить голосовую почту, выберите \"Меню > Настройки\"."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Сначала отключите режим полета."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Экспорт файлов базы данных"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Ещё"</string>
</resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 1707fb5..d785e07 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"číslo, ktoré chcete vytočiť"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"fotografia kontaktu"</string>
- <string name="description_minus_button" msgid="387136707700230172">"mínus"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"odstrániť"</string>
<string name="description_plus_button" msgid="515164827856229880">"plus"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Zobraziť kontakt"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Ukladací priestor sa nenašiel."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Názov skupiny"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Kontakt cez NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Zobraziť len odchádzajúce"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Zobraziť len prichádzajúce"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Zobraziť len zmeškané"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Zobraziť len hlasové správy"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Zobraziť všetky hovory"</string>
<string name="status_available" msgid="5586870015822828392">"K dispozícii"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Hovor nebol spojený"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Ak chcete nastaviť hlasovú schránku, prejdite na položku Menu > Nastavenia."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Ak chcete volať hlasovú schránku, najprv vypnite režim V lietadle."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Exportovať súbory databázy"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Ďalšie možnosti"</string>
</resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 6ff2ed1..c5abbda 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"vračalka"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"številka, ki bo poklicana"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"fotografija stika"</string>
- <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"brisanje"</string>
<string name="description_plus_button" msgid="515164827856229880">"plus"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Ogled stika"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Shrambe ni bilo mogoče najti."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Ime skupine"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Stik prejet prek NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Pokaži samo odhodne"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Pokaži samo dohodne"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Pokaži samo neodgovorjene"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Pokaži samo spor. glasovne pošte"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Pokaži vse klice"</string>
<string name="status_available" msgid="5586870015822828392">"Dosegljiv"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Klic ni uspel"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Če želite nastaviti odzivnik, odprite Meni > Nastavitve."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Če želite poklicati odzivnik, najprej izklopite način za letalo."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Izvoz datotek zbirke"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Več možnosti"</string>
</resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index a290f82..1667958 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"број за бирање"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"фотографија контакта"</string>
- <string name="description_minus_button" msgid="387136707700230172">"минус"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"избриши"</string>
<string name="description_plus_button" msgid="515164827856229880">"плус"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Прикажи контакт"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Није пронађена меморија."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Назив групе"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Контакт преко NFC-а"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Прикажи само одлазне"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Прикажи само долазне"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Прикажи само пропуштене"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Прикажи само говорне поруке"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Прикажи све позиве"</string>
<string name="status_available" msgid="5586870015822828392">"Доступан/на"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Позив није послат"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Да бисте подесили говорну пошту, идите у Мени > Подешавања."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Да бисте позвали говорну пошту, прво искључите режим авионa."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Извези датотеке базе података"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Још опција"</string>
</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 18344da..21bf167 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"backsteg"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"nummer att ringa"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"kontaktbild"</string>
- <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"ta bort"</string>
<string name="description_plus_button" msgid="515164827856229880">"plus"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Visa kontakt"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Ingen lagringsenhet hittades."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Gruppens namn"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Mott. v. NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Visa endast utgående samtal"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Visa endast inkommande samtal"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Visa endast missade samtal"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Visa bara röstmeddelanden"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Visa alla samtal"</string>
<string name="status_available" msgid="5586870015822828392">"Tillgänglig"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Samtalet gick inte att koppla fram"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Välj Meny > Inställningar om du vill konfigurera röstbrevlådan."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Om du vill ringa röstbrevlådan måste du först inaktivera flygplansläget."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Exportera databasfiler"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Fler alternativ"</string>
</resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 68888d2..126e8c1 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -79,7 +79,7 @@
<string name="ghostData_title" msgid="7496735200318496110">"Jina la heshima"</string>
<string name="invalidContactMessage" msgid="8215051456181842274">"Mwasiliani hayupo."</string>
<string name="createContactShortcutSuccessful" msgid="7874133287558150877">"Wijeti ya mawasiliano imeongezwa kwenye skrini ya Nyumbani."</string>
- <string name="pickerNewContactHeader" msgid="7750705279843568147">"Unda akaunti mpya"</string>
+ <string name="pickerNewContactHeader" msgid="7750705279843568147">"Weka anwani mpya"</string>
<string name="pickerNewContactText" msgid="6166997164401048211">"Anzisha mwasiliani mpya"</string>
<string name="phoneLabelsGroup" msgid="6468091477851199285">"Simu"</string>
<string name="emailLabelsGroup" msgid="8389931313045344406">"Barua pepe"</string>
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"futa"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"nambari ya kupiga"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"picha ya anwani"</string>
- <string name="description_minus_button" msgid="387136707700230172">"kutoa"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"futa"</string>
<string name="description_plus_button" msgid="515164827856229880">"jumlisha"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Angalia anwani"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Hakuna hifadhi iliyopatikana."</string>
@@ -302,7 +302,7 @@
<string name="eventLabelsGroup" msgid="3695433812142818803">"Matukio"</string>
<string name="relationLabelsGroup" msgid="1854373894284572781">"Uhusiano"</string>
<string name="groupsLabel" msgid="8573535366319059326">"Vikundi"</string>
- <string name="dialog_new_contact_account" msgid="9044704073286262197">"Unda anwani chini ya akaunti"</string>
+ <string name="dialog_new_contact_account" msgid="9044704073286262197">"Weka anwani chini ya akaunti"</string>
<string name="dialog_new_group_account" msgid="2318032089273496830">"Unda kikundi chini ya akaunti"</string>
<string name="menu_sync_remove" msgid="3266725887008450161">"Ondoa kikundi cha usawazishaji"</string>
<string name="dialog_sync_add" msgid="8267045393119375803">"Ongeza kikundi cha usawazishaji"</string>
@@ -471,7 +471,7 @@
<string name="date_year_toggle" msgid="7356532842767854606">"Bainisha mwaka"</string>
<string name="social_widget_label" msgid="6378905543028924592">"Anwani"</string>
<string name="social_widget_loading" msgid="5327336597364074608">"Inapakia…"</string>
- <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Unda akaunti mpya"</string>
+ <string name="contacts_unavailable_create_contact" msgid="7014525713871959208">"Fungua akaunti mpya"</string>
<string name="contacts_unavailable_add_account" msgid="7911101713860139754">"Ingia katika akaunti"</string>
<string name="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Ingiza wasiliani"</string>
<string name="create_group_dialog_title" msgid="6874527142828424475">"Unda kikundi kipya"</string>
@@ -526,6 +526,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"( <xliff:g id="COUNT">%1$d</xliff:g> ) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Jina la kikundi"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Anwani imepokewa kupitia NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Onyesha zinazotoka pekee"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Onyesha zinazoingia pekee"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Onyesha zilizokosa kupokewa pekee"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Onyesha barua za sauti pekee"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Onyesha simu zote"</string>
<string name="status_available" msgid="5586870015822828392">"Nipo"</string>
@@ -560,6 +563,7 @@
<string name="add_new_account" msgid="5748627740680940264">"Ongeza akaunti mpya"</string>
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Simu haijatumwa"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Ili kusanidi ujumbe wa sauti, nenda kwa Menyu > Mipangilio."</string>
- <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Kupigia simu ujumbe wa sauti, kwanza lemaza hali ya ndege."</string>
+ <string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Kupigia simu ujumbe wa sauti, kwanza zima hali ya ndege."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Hamisha faili za hifadhidata"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Chaguo zaidi"</string>
</resources>
diff --git a/res/values-sw580dp-w940dp/dimens.xml b/res/values-sw580dp-land/dimens.xml
similarity index 100%
rename from res/values-sw580dp-w940dp/dimens.xml
rename to res/values-sw580dp-land/dimens.xml
diff --git a/res/values-sw580dp-w940dp/donottranslate_config.xml b/res/values-sw580dp-land/donottranslate_config.xml
similarity index 100%
rename from res/values-sw580dp-w940dp/donottranslate_config.xml
rename to res/values-sw580dp-land/donottranslate_config.xml
diff --git a/res/values-sw580dp-w940dp/integers.xml b/res/values-sw580dp-land/integers.xml
similarity index 100%
rename from res/values-sw580dp-w940dp/integers.xml
rename to res/values-sw580dp-land/integers.xml
diff --git a/res/values-sw580dp-w940dp/styles.xml b/res/values-sw580dp-land/styles.xml
similarity index 97%
rename from res/values-sw580dp-w940dp/styles.xml
rename to res/values-sw580dp-land/styles.xml
index d035240..9efb20b 100644
--- a/res/values-sw580dp-w940dp/styles.xml
+++ b/res/values-sw580dp-land/styles.xml
@@ -33,7 +33,6 @@
<item name="list_item_padding_left">0dip</item>
<item name="list_item_gap_between_image_and_text">8dip</item>
<item name="list_item_gap_between_label_and_data">5dip</item>
- <item name="list_item_vertical_divider_margin">5dip</item>
<item name="list_item_presence_icon_margin">4dip</item>
<item name="list_item_presence_icon_size">16dip</item>
<item name="list_item_photo_size">64dip</item>
diff --git a/res/values-sw580dp/donottranslate_config.xml b/res/values-sw580dp/donottranslate_config.xml
index 3d0dea0..406863e 100644
--- a/res/values-sw580dp/donottranslate_config.xml
+++ b/res/values-sw580dp/donottranslate_config.xml
@@ -21,7 +21,6 @@
<bool name="config_use_two_panes">true</bool>
<bool name="config_use_two_panes_in_favorites">false</bool>
<bool name="show_home_icon">true</bool>
- <bool name="config_show_group_action_in_action_bar">false</bool>
<bool name="config_browse_list_show_images">false</bool>
<item name="tab_width_screen_width_percentage" type="fraction">66.67%</item>
<item name="tab_height_screen_width_percentage" type="fraction">66.67%</item>
diff --git a/res/values-sw580dp/styles.xml b/res/values-sw580dp/styles.xml
index a8d935b..1181d5d 100644
--- a/res/values-sw580dp/styles.xml
+++ b/res/values-sw580dp/styles.xml
@@ -33,7 +33,6 @@
<item name="list_item_padding_left">0dip</item>
<item name="list_item_gap_between_image_and_text">8dip</item>
<item name="list_item_gap_between_label_and_data">5dip</item>
- <item name="list_item_vertical_divider_margin">5dip</item>
<item name="list_item_presence_icon_margin">4dip</item>
<item name="list_item_presence_icon_size">16dip</item>
<item name="list_item_photo_size">64dip</item>
@@ -69,7 +68,6 @@
<item name="list_item_padding_left">0dip</item>
<item name="list_item_gap_between_image_and_text">8dip</item>
<item name="list_item_gap_between_label_and_data">5dip</item>
- <item name="list_item_vertical_divider_margin">5dip</item>
<item name="list_item_presence_icon_margin">18dip</item>
<item name="list_item_photo_size">64dip</item>
<item name="list_item_profile_photo_size">80dip</item>
diff --git a/res/values-sw680dp-w1000dp/dimens.xml b/res/values-sw680dp-land/dimens.xml
similarity index 100%
rename from res/values-sw680dp-w1000dp/dimens.xml
rename to res/values-sw680dp-land/dimens.xml
diff --git a/res/values-sw680dp-w1000dp/integers.xml b/res/values-sw680dp-land/integers.xml
similarity index 100%
rename from res/values-sw680dp-w1000dp/integers.xml
rename to res/values-sw680dp-land/integers.xml
diff --git a/res/values-sw680dp-w1000dp/styles.xml b/res/values-sw680dp-land/styles.xml
similarity index 100%
rename from res/values-sw680dp-w1000dp/styles.xml
rename to res/values-sw680dp-land/styles.xml
diff --git a/res/values-sw680dp/styles.xml b/res/values-sw680dp/styles.xml
index fb242d9..d84c76a 100644
--- a/res/values-sw680dp/styles.xml
+++ b/res/values-sw680dp/styles.xml
@@ -33,7 +33,6 @@
<item name="list_item_padding_left">0dip</item>
<item name="list_item_gap_between_image_and_text">16dip</item>
<item name="list_item_gap_between_label_and_data">5dip</item>
- <item name="list_item_vertical_divider_margin">5dip</item>
<item name="list_item_presence_icon_margin">4dip</item>
<item name="list_item_presence_icon_size">16dip</item>
<item name="list_item_photo_size">64dip</item>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 6f43ac7..b973c45 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"ย้อนกลับ"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"หมายเลขที่จะโทร"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"ภาพของรายชื่อ"</string>
- <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"ลบ"</string>
<string name="description_plus_button" msgid="515164827856229880">"plus"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"ดูรายชื่อติดต่อ"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"ไม่พบที่จัดเก็บข้อมูล"</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"ชื่อกลุ่ม"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"ผู้ติดต่อทาง NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"แสดงสายที่โทรออกเท่านั้น"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"แสดงสายโทรเข้าเท่านั้น"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"แสดงสายที่ไม่ได้รับเท่านั้น"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"แสดงเฉพาะข้อความเสียง"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"แสดงการโทรทั้งหมด"</string>
<string name="status_available" msgid="5586870015822828392">"ว่าง"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"ไม่สามารถโทรออก"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"หากต้องการตั้งค่าข้อความเสียง ให้ไปที่เมนู > การตั้งค่า"</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"หากต้องการฟังข้อความเสียง ให้ปิดโหมดใช้งานบนเครื่องบินก่อน"</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"ส่งออกไฟล์ฐานข้อมูล"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"ตัวเลือกเพิ่มเติม"</string>
</resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index b8aed4a..af9706d 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"numerong ida-dial"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"larawan ng contact"</string>
- <string name="description_minus_button" msgid="387136707700230172">"minus"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"tanggalin"</string>
<string name="description_plus_button" msgid="515164827856229880">"plus"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Tingnan ang contact"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Walang natagpuang storage."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Pangalan ng pangkat"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Natanggap ang contact sa NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Ipakita lang ang papalabas"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Ipakita lang ang paparating"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Ipakita lang ang hindi nasagot"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Ipakita lamang ang mga voicemail"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Ipakita ang lahat ng tawag"</string>
<string name="status_available" msgid="5586870015822828392">"Available"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Hindi naipadala ang tawag"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Upang mag-set up ng voicemail, pumunta sa Menu > Mga Setting."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Upang tumawag sa voicemail, i-off muna ang Airplane mode."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"I-export ang mga file ng database"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Higit pang mga pagpipilian"</string>
</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index ee4723c..68d75e4 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"geri tuşu"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"çevrilecek numara"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"kişi fotoğrafı"</string>
- <string name="description_minus_button" msgid="387136707700230172">"eksi"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"sil"</string>
<string name="description_plus_button" msgid="515164827856229880">"artı"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Kişiyi görüntüle"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Depolama birimi bulunamadı."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Grubun adı"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Kişi NFC ile alındı"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Yalnızca gidenleri göster"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Yalnızca gelenleri göster"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Yalnızca cevapsızları göster"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Yalnızca sesli msajları göster"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Tüm çağrıları göster"</string>
<string name="status_available" msgid="5586870015822828392">"Uygun"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Çağrı yapılamadı"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Sesli mesajı yapılandırmak için Menü > Ayarlar\'a gidin."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Sesli mesaja çağrı yapmak için öncelikle Uçak modunu kapatın."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Veritabanı dosyalarını dışarı aktar"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Diğer seçenekler"</string>
</resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 347f6d5..1e07787 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"видалити"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"номер для набору"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"фото контакту"</string>
- <string name="description_minus_button" msgid="387136707700230172">"мінус"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"видалити"</string>
<string name="description_plus_button" msgid="515164827856229880">"плюс"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Переглянути контакт"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Пам’ять не знайдено."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Назва групи"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Конт., отрим.через NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Показувати лише вихідні"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Показувати лише вхідні"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Показувати лише пропущені"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Показувати лише голосову пошту"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Показувати всі виклики"</string>
<string name="status_available" msgid="5586870015822828392">"Доступний"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Виклик не здійснено"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Щоб налаштувати голосову пошту, перейдіть у Меню > Налаштування."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Щоб перевірити голосову пошту, спочатку вимкніть режим польоту."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Експортувати файли бази даних"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Інші варіанти"</string>
</resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index cc509e3..849aaf6 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"số để quay"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"ảnh của liên hệ"</string>
- <string name="description_minus_button" msgid="387136707700230172">"trừ"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"xóa"</string>
<string name="description_plus_button" msgid="515164827856229880">"cộng"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Xem địa chỉ liên hệ"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Không tìm thấy bộ nhớ nào."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Tên nhóm"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"L.h nhận qua NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Chỉ hiển thị cuộc gọi đi"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Chỉ hiển thị cuộc gọi đến"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Chỉ hiển thị cuộc gọi nhỡ"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Chỉ hiển thị thư thoại"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Hiển thị tất cả cuộc gọi"</string>
<string name="status_available" msgid="5586870015822828392">"Có mặt"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"Không thể thực hiện cuộc gọi"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Để thiết lập thư thoại, đi tới Trình đơn > Cài đặt."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Để gọi thư thoại, trước tiên hãy tắt chế độ trên Máy bay."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Xuất các tệp cơ sở dữ liệu"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Tùy chọn khác"</string>
</resources>
diff --git a/res/values-w470dp/dimens.xml b/res/values-w470dp/dimens.xml
deleted file mode 100644
index c457147..0000000
--- a/res/values-w470dp/dimens.xml
+++ /dev/null
@@ -1,20 +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.
--->
-<resources>
- <!-- Center vertically -->
- <dimen name="quick_contact_top_position">-1px</dimen>
- <dimen name="editor_type_label_width">120dip</dimen>
-</resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index e8798e4..618a467 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -74,7 +74,7 @@
<string name="menu_doNotSave" msgid="58593876893538465">"取消"</string>
<string name="menu_discard" msgid="6456087569315685632">"舍弃"</string>
<string name="label_notes" msgid="8337354953278341042">"备注"</string>
- <string name="label_sip_address" msgid="124073911714324974">"互联网通话"</string>
+ <string name="label_sip_address" msgid="124073911714324974">"互联网电话"</string>
<string name="ghostData_company" msgid="5414421120553765775">"公司"</string>
<string name="ghostData_title" msgid="7496735200318496110">"职位"</string>
<string name="invalidContactMessage" msgid="8215051456181842274">"该联系人不存在。"</string>
@@ -82,8 +82,8 @@
<string name="pickerNewContactHeader" msgid="7750705279843568147">"新建联系人"</string>
<string name="pickerNewContactText" msgid="6166997164401048211">"创建新联系人"</string>
<string name="phoneLabelsGroup" msgid="6468091477851199285">"电话"</string>
- <string name="emailLabelsGroup" msgid="8389931313045344406">"发送电子邮件"</string>
- <string name="imLabelsGroup" msgid="3898238486262614027">"即时消息"</string>
+ <string name="emailLabelsGroup" msgid="8389931313045344406">"电子邮件"</string>
+ <string name="imLabelsGroup" msgid="3898238486262614027">"即时聊天工具"</string>
<string name="postalLabelsGroup" msgid="3487738141112589324">"地址"</string>
<string-array name="otherLabels">
<item msgid="8287841928119937597">"组织"</item>
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"退格"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"要拨打的号码"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"联系人照片"</string>
- <string name="description_minus_button" msgid="387136707700230172">"删除"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"删除"</string>
<string name="description_plus_button" msgid="515164827856229880">"添加"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"查看联系人"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"未找到任何存储设备。"</string>
@@ -297,7 +297,7 @@
<string name="nicknameLabelsGroup" msgid="2891682101053358010">"昵称"</string>
<string name="organizationLabelsGroup" msgid="2478611760751832035">"组织"</string>
<string name="websiteLabelsGroup" msgid="4202998982804009261">"网站"</string>
- <string name="eventLabelsGroup" msgid="3695433812142818803">"活动"</string>
+ <string name="eventLabelsGroup" msgid="3695433812142818803">"重要日子"</string>
<string name="relationLabelsGroup" msgid="1854373894284572781">"关系"</string>
<string name="groupsLabel" msgid="8573535366319059326">"群组"</string>
<string name="dialog_new_contact_account" msgid="9044704073286262197">"在帐户下创建联系人"</string>
@@ -385,15 +385,15 @@
<string name="full_name" msgid="6602579550613988977">"姓名"</string>
<string name="name_given" msgid="1687286314106019813">"名字"</string>
<string name="name_family" msgid="3416695586119999058">"姓氏"</string>
- <string name="name_prefix" msgid="59756378548779822">"名称前缀"</string>
+ <string name="name_prefix" msgid="59756378548779822">"姓名前缀"</string>
<string name="name_middle" msgid="8467433655992690326">"中间名"</string>
- <string name="name_suffix" msgid="3855278445375651441">"名称后缀"</string>
+ <string name="name_suffix" msgid="3855278445375651441">"姓名后缀"</string>
<string name="name_phonetic_given" msgid="6853570431394449191">"名字拼音"</string>
<string name="name_phonetic_middle" msgid="8643721493320405200">"中间名拼音"</string>
<string name="name_phonetic_family" msgid="462095502140180305">"姓氏拼音"</string>
<string name="name_phonetic" msgid="4259595234312430484">"姓名拼音"</string>
- <string name="connections" msgid="8098440723172028350">"联系"</string>
- <string name="add_connection_button" msgid="4861308615789601727">"加强联系"</string>
+ <string name="connections" msgid="8098440723172028350">"社交网络"</string>
+ <string name="add_connection_button" msgid="4861308615789601727">"添加社交网络"</string>
<string name="recent" msgid="2659189233141493004">"最新"</string>
<string name="recent_updates" msgid="4267258535615860710">"最新动态"</string>
<string name="account_type_format" msgid="718948015590343010">"<xliff:g id="SOURCE">%1$s</xliff:g> 联系人"</string>
@@ -524,6 +524,12 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"群组名称"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"已通过 NFC 收到联系人信息"</string>
+ <!-- no translation found for menu_show_outgoing_only (1965570298133301970) -->
+ <skip />
+ <!-- no translation found for menu_show_incoming_only (7534206815238877417) -->
+ <skip />
+ <!-- no translation found for menu_show_missed_only (154473166059743996) -->
+ <skip />
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"只显示语音邮件"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"显示所有通话"</string>
<string name="status_available" msgid="5586870015822828392">"在线"</string>
@@ -559,5 +565,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"电话未拨出"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"要设置语音信箱,请转到“菜单”>“设置”。"</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"要呼叫语音信箱,请先关闭飞行模式。"</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"导出数据库文件"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"更多选项"</string>
</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index d24a7ec..e4eddd9 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"Backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"撥號號碼"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"聯絡人相片"</string>
- <string name="description_minus_button" msgid="387136707700230172">"負號"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"刪除"</string>
<string name="description_plus_button" msgid="515164827856229880">"加號"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"查看聯絡人"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"找不到任何儲存裝置。"</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"群組名稱"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"已透過 NFC 收到聯絡人資訊"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"僅顯示撥出電話"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"僅顯示來電"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"僅顯示未接來電"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"僅顯示語音留言"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"顯示所有通話"</string>
<string name="status_available" msgid="5586870015822828392">"線上"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"無法撥號"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"如要設定語音信箱,請前往 [選單] > [設定]。"</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"如要聽語音留言,請先關閉飛行模式。"</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"匯出資料庫檔案"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"更多選項"</string>
</resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 7caab69..2b74e9d 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -210,7 +210,7 @@
<string name="description_delete_button" msgid="6263102114033407382">"i-backspace"</string>
<string name="description_digits_edittext" msgid="8760207516497016437">"inombolo okumele uyidayele"</string>
<string name="description_contact_photo" msgid="3387458082667894062">"isithombe sothintana naye"</string>
- <string name="description_minus_button" msgid="387136707700230172">"susa"</string>
+ <string name="description_minus_button" msgid="6908099247930477551">"susa"</string>
<string name="description_plus_button" msgid="515164827856229880">"kuhlanganise"</string>
<string name="description_view_contact_detail" msgid="9133251213656414807">"Buka othintana naye"</string>
<string name="no_sdcard_message" product="nosdcard" msgid="5242558018442357189">"Ayikho indawo yokulondoloza etholakele."</string>
@@ -524,6 +524,9 @@
<string name="call_log_item_count_and_date" msgid="7641933305703520787">"(<xliff:g id="COUNT">%1$d</xliff:g>) <xliff:g id="DATE">%2$s</xliff:g>"</string>
<string name="group_name_hint" msgid="238359485263401293">"Igama leqemnbu"</string>
<string name="nfc_vcard_file_name" msgid="2823095213265993609">"Othintana naye utholakale nge-NFC"</string>
+ <string name="menu_show_outgoing_only" msgid="1965570298133301970">"Bonisa eziphumayo kuphela"</string>
+ <string name="menu_show_incoming_only" msgid="7534206815238877417">"Bonisa okungenayo kuphela"</string>
+ <string name="menu_show_missed_only" msgid="154473166059743996">"Bonisa okugejiwe kuphela"</string>
<string name="menu_show_voicemails_only" msgid="1898421289561435703">"Bonisa ama-imeyli ezwi kuphela"</string>
<string name="menu_show_all_calls" msgid="7560347482073345885">"Bonisa zonke izingcingo ezenziwe"</string>
<string name="status_available" msgid="5586870015822828392">"Yatholakala"</string>
@@ -559,5 +562,6 @@
<string name="dialog_phone_call_prohibited_message" msgid="6554711866586660441">"ucingo aluthunyelwanga"</string>
<string name="dialog_voicemail_not_ready_message" msgid="4384716252789515378">"Ukuya emyalezweni wephimbo, yana ezisethweni > zemenyu."</string>
<string name="dialog_voicemail_airplane_mode_message" msgid="530922773669546093">"Ukushayela i-voicemail, vala kuqala imodi Yendiza."</string>
+ <string name="menu_export_database" msgid="2659719297530170820">"Khipha amafayela emininingo egciniwe"</string>
<string name="action_menu_overflow_description" msgid="2303272250613084574">"Izinketho eziningi"</string>
</resources>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index f49b0bf..5a5016e 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -74,7 +74,6 @@
<attr name="list_item_padding_left" format="dimension"/>
<attr name="list_item_gap_between_image_and_text" format="dimension"/>
<attr name="list_item_gap_between_label_and_data" format="dimension"/>
- <attr name="list_item_vertical_divider_margin" format="dimension"/>
<attr name="list_item_presence_icon_margin" format="dimension"/>
<attr name="list_item_presence_icon_size" format="dimension"/>
<attr name="list_item_photo_size" format="dimension"/>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 8292a56..8b843b4 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -728,8 +728,10 @@
<!-- String describing the Contact Editor Minus button
Used by AccessibilityService to announce the purpose of the button.
+
+ [CHAR LIMIT=NONE]
-->
- <string name="description_minus_button">minus</string>
+ <string name="description_minus_button">delete</string>
<!-- String describing the Contact Editor Plus button
@@ -1607,9 +1609,21 @@
<!-- The header in the call log used to identify items that have been already consumed [CHAR LIMIT=10] -->
<string name="call_log_old_header">Older</string>
+ <!-- The header to show that call log is only showing voicemail calls. [CHAR LIMIT=40] -->
+ <string name="call_log_voicemail_header">Calls with voicemail</string>
+
+ <!-- The header to show that call log is only showing incoming calls. [CHAR LIMIT=40] -->
+ <string name="call_log_incoming_header">Incoming calls</string>
+
+ <!-- The header to show that call log is only showing outgoing calls. [CHAR LIMIT=40] -->
+ <string name="call_log_outgoing_header">Outgoing calls</string>
+
+ <!-- The header to show that call log is only showing missed calls. [CHAR LIMIT=40] -->
+ <string name="call_log_missed_header">Missed calls</string>
+
<!-- Voicemail status message shown at the top of call log to notify the user that no new
- voicemails are currently available. This can happen when both notification as well as data
- connection to the voicemail server is lost. [CHAR LIMIT=64] -->
+voicemails are currently available. This can happen when both notification as well as data
+connection to the voicemail server is lost. [CHAR LIMIT=64] -->
<string name="voicemail_status_voicemail_not_available">Can\'t connect to voicemail server.</string>
<!-- Voicemail status message shown at the top of call log to notify the user that there is no
data connection to the voicemail server, but there are new voicemails waiting on the server.
@@ -1649,6 +1663,15 @@
<!-- The "file name" displayed for vCards received directly via NFC [CHAR LIMIT=16] -->
<string name="nfc_vcard_file_name">Contact received over NFC</string>
+ <!-- Menu item used to show only outgoing in the call log. [CHAR LIMIT=30] -->
+ <string name="menu_show_outgoing_only">Show outgoing only</string>
+
+ <!-- Menu item used to show only incoming in the call log. [CHAR LIMIT=30] -->
+ <string name="menu_show_incoming_only">Show incoming only</string>
+
+ <!-- Menu item used to show only missed in the call log. [CHAR LIMIT=30] -->
+ <string name="menu_show_missed_only">Show missed only</string>
+
<!-- Menu item used to show only voicemails in the call log. [CHAR LIMIT=30] -->
<string name="menu_show_voicemails_only">Show voicemails only</string>
@@ -1818,6 +1841,9 @@
voicemail service in Airplane mode. [CHAR LIMI=NONE] -->
<string name="dialog_voicemail_airplane_mode_message">To call voicemail, first turn off Airplane mode.</string>
+ <!-- Menu item shown only when the special debug mode is enabled, which is used to send all contacts database files via email. [CHAR LIMI=NONE] -->
+ <string name="menu_export_database">Export database files</string>
+
<!-- Content description for the fake action menu overflow button.
This should be same as the description for the real action menu
overflow button available in ActionBar.
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 829b207..6a7bd6f 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -32,7 +32,6 @@
<item name="list_item_padding_left">0dip</item>
<item name="list_item_gap_between_image_and_text">8dip</item>
<item name="list_item_gap_between_label_and_data">5dip</item>
- <item name="list_item_vertical_divider_margin">5dip</item>
<item name="list_item_presence_icon_margin">4dip</item>
<item name="list_item_presence_icon_size">16dip</item>
<item name="list_item_photo_size">@dimen/contact_browser_list_item_photo_size</item>
@@ -145,7 +144,6 @@
<item name="list_item_padding_left">0dip</item>
<item name="list_item_gap_between_image_and_text">8dip</item>
<item name="list_item_gap_between_label_and_data">5dip</item>
- <item name="list_item_vertical_divider_margin">5dip</item>
<item name="list_item_presence_icon_margin">4dip</item>
<item name="list_item_presence_icon_size">16dip</item>
<item name="list_item_photo_size">@dimen/contact_browser_list_item_photo_size</item>
diff --git a/res/xml/searchable.xml b/res/xml/searchable.xml
index a78d531..3d6876e 100644
--- a/res/xml/searchable.xml
+++ b/res/xml/searchable.xml
@@ -26,12 +26,4 @@
android:searchSuggestIntentData="content://com.android.contacts/contacts/lookup"
android:searchSettingsDescription="@string/search_settings_description"
>
-
- <!-- allow green action key for search-bar and per-suggestion clicks -->
- <actionkey
- android:keycode="KEYCODE_CALL"
- android:queryActionMsg="call"
- android:suggestActionMsg="call"
- />
-
</searchable>
diff --git a/src/com/android/contacts/CallContactActivity.java b/src/com/android/contacts/CallContactActivity.java
index 793770b..c4b4dc7 100644
--- a/src/com/android/contacts/CallContactActivity.java
+++ b/src/com/android/contacts/CallContactActivity.java
@@ -16,14 +16,14 @@
package com.android.contacts;
-import com.android.contacts.interactions.PhoneNumberInteraction;
-
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract.Contacts;
+import com.android.contacts.interactions.PhoneNumberInteraction;
+
/**
* An interstitial activity used when the user selects a QSB search suggestion using
* a call button.
diff --git a/src/com/android/contacts/CallDetailActivity.java b/src/com/android/contacts/CallDetailActivity.java
index 47441ce..7bb2157 100644
--- a/src/com/android/contacts/CallDetailActivity.java
+++ b/src/com/android/contacts/CallDetailActivity.java
@@ -16,22 +16,6 @@
package com.android.contacts;
-import com.android.contacts.BackScrollManager.ScrollableHeader;
-import com.android.contacts.calllog.CallDetailHistoryAdapter;
-import com.android.contacts.calllog.CallTypeHelper;
-import com.android.contacts.calllog.ContactInfo;
-import com.android.contacts.calllog.ContactInfoHelper;
-import com.android.contacts.calllog.PhoneNumberHelper;
-import com.android.contacts.format.FormatUtils;
-import com.android.contacts.util.AsyncTaskExecutor;
-import com.android.contacts.util.AsyncTaskExecutors;
-import com.android.contacts.util.ClipboardUtils;
-import com.android.contacts.util.Constants;
-import com.android.contacts.voicemail.VoicemailPlaybackFragment;
-import com.android.contacts.voicemail.VoicemailStatusHelper;
-import com.android.contacts.voicemail.VoicemailStatusHelper.StatusMessage;
-import com.android.contacts.voicemail.VoicemailStatusHelperImpl;
-
import android.app.ActionBar;
import android.app.Activity;
import android.content.ContentResolver;
@@ -67,6 +51,22 @@
import android.widget.TextView;
import android.widget.Toast;
+import com.android.contacts.BackScrollManager.ScrollableHeader;
+import com.android.contacts.calllog.CallDetailHistoryAdapter;
+import com.android.contacts.calllog.CallTypeHelper;
+import com.android.contacts.calllog.ContactInfo;
+import com.android.contacts.calllog.ContactInfoHelper;
+import com.android.contacts.calllog.PhoneNumberHelper;
+import com.android.contacts.format.FormatUtils;
+import com.android.contacts.util.AsyncTaskExecutor;
+import com.android.contacts.util.AsyncTaskExecutors;
+import com.android.contacts.util.ClipboardUtils;
+import com.android.contacts.util.Constants;
+import com.android.contacts.voicemail.VoicemailPlaybackFragment;
+import com.android.contacts.voicemail.VoicemailStatusHelper;
+import com.android.contacts.voicemail.VoicemailStatusHelper.StatusMessage;
+import com.android.contacts.voicemail.VoicemailStatusHelperImpl;
+
import java.util.List;
/**
diff --git a/src/com/android/contacts/CallDetailActivityQueryHandler.java b/src/com/android/contacts/CallDetailActivityQueryHandler.java
index df5b4f7..41cf937 100644
--- a/src/com/android/contacts/CallDetailActivityQueryHandler.java
+++ b/src/com/android/contacts/CallDetailActivityQueryHandler.java
@@ -16,9 +16,6 @@
package com.android.contacts;
-import com.android.common.io.MoreCloseables;
-import com.android.contacts.voicemail.VoicemailStatusHelperImpl;
-
import android.content.AsyncQueryHandler;
import android.database.Cursor;
import android.net.Uri;
@@ -26,6 +23,9 @@
import android.provider.VoicemailContract.Voicemails;
import android.util.Log;
+import com.android.common.io.MoreCloseables;
+import com.android.contacts.voicemail.VoicemailStatusHelperImpl;
+
/**
* Class used by {@link CallDetailActivity} to fire async content resolver queries.
*/
diff --git a/src/com/android/contacts/ContactLoader.java b/src/com/android/contacts/ContactLoader.java
deleted file mode 100644
index 10579f3..0000000
--- a/src/com/android/contacts/ContactLoader.java
+++ /dev/null
@@ -1,1368 +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.contacts;
-
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountTypeWithDataSet;
-import com.android.contacts.model.EntityDeltaList;
-import com.android.contacts.util.ContactLoaderUtils;
-import com.android.contacts.util.DataStatus;
-import com.android.contacts.util.StreamItemEntry;
-import com.android.contacts.util.StreamItemPhotoEntry;
-import com.android.contacts.util.UriUtils;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
-import android.content.AsyncTaskLoader;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Entity;
-import android.content.Entity.NamedContentValues;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.AssetFileDescriptor;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
-import android.provider.ContactsContract.CommonDataKinds.Photo;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.Directory;
-import android.provider.ContactsContract.DisplayNameSources;
-import android.provider.ContactsContract.Groups;
-import android.provider.ContactsContract.RawContacts;
-import android.provider.ContactsContract.StreamItemPhotos;
-import android.provider.ContactsContract.StreamItems;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.LongSparseArray;
-
-import java.io.ByteArrayOutputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Loads a single Contact and all it constituent RawContacts.
- */
-public class ContactLoader extends AsyncTaskLoader<ContactLoader.Result> {
- private static final String TAG = ContactLoader.class.getSimpleName();
-
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
- /** A short-lived cache that can be set by {@link #cacheResult()} */
- private static Result sCachedResult = null;
-
- private final Uri mRequestedUri;
- private Uri mLookupUri;
- private boolean mLoadGroupMetaData;
- private boolean mLoadStreamItems;
- private boolean mLoadInvitableAccountTypes;
- private boolean mPostViewNotification;
- private Result mContact;
- private ForceLoadContentObserver mObserver;
- private final Set<Long> mNotifiedRawContactIds = Sets.newHashSet();
-
- public ContactLoader(Context context, Uri lookupUri, boolean postViewNotification) {
- this(context, lookupUri, false, false, false, postViewNotification);
- }
-
- public ContactLoader(Context context, Uri lookupUri, boolean loadGroupMetaData,
- boolean loadStreamItems, boolean loadInvitableAccountTypes,
- boolean postViewNotification) {
- super(context);
- mLookupUri = lookupUri;
- mRequestedUri = lookupUri;
- mLoadGroupMetaData = loadGroupMetaData;
- mLoadStreamItems = loadStreamItems;
- mLoadInvitableAccountTypes = loadInvitableAccountTypes;
- mPostViewNotification = postViewNotification;
- }
-
- /**
- * The result of a load operation. Contains all data necessary to display the contact.
- */
- public static final class Result {
- private enum Status {
- /** Contact is successfully loaded */
- LOADED,
- /** There was an error loading the contact */
- ERROR,
- /** Contact is not found */
- NOT_FOUND,
- }
-
- private final Uri mRequestedUri;
- private final Uri mLookupUri;
- private final Uri mUri;
- private final long mDirectoryId;
- private final String mLookupKey;
- private final long mId;
- private final long mNameRawContactId;
- private final int mDisplayNameSource;
- private final long mPhotoId;
- private final String mPhotoUri;
- private final String mDisplayName;
- private final String mAltDisplayName;
- private final String mPhoneticName;
- private final boolean mStarred;
- private final Integer mPresence;
- private final ArrayList<Entity> mEntities;
- private ArrayList<StreamItemEntry> mStreamItems;
- private final LongSparseArray<DataStatus> mStatuses;
- private ArrayList<AccountType> mInvitableAccountTypes;
-
- private String mDirectoryDisplayName;
- private String mDirectoryType;
- private String mDirectoryAccountType;
- private String mDirectoryAccountName;
- private int mDirectoryExportSupport;
-
- private ArrayList<GroupMetaData> mGroups;
-
- private byte[] mPhotoBinaryData;
- private final boolean mSendToVoicemail;
- private final String mCustomRingtone;
- private final boolean mIsUserProfile;
-
- private final Status mStatus;
- private final Exception mException;
-
- /**
- * Constructor for special results, namely "no contact found" and "error".
- */
- private Result(Uri requestedUri, Status status, Exception exception) {
- if (status == Status.ERROR && exception == null) {
- throw new IllegalArgumentException("ERROR result must have exception");
- }
- mStatus = status;
- mException = exception;
- mRequestedUri = requestedUri;
- mLookupUri = null;
- mUri = null;
- mDirectoryId = -1;
- mLookupKey = null;
- mId = -1;
- mEntities = null;
- mStreamItems = null;
- mStatuses = null;
- mNameRawContactId = -1;
- mDisplayNameSource = DisplayNameSources.UNDEFINED;
- mPhotoId = -1;
- mPhotoUri = null;
- mDisplayName = null;
- mAltDisplayName = null;
- mPhoneticName = null;
- mStarred = false;
- mPresence = null;
- mInvitableAccountTypes = null;
- mSendToVoicemail = false;
- mCustomRingtone = null;
- mIsUserProfile = false;
- }
-
- private static Result forError(Uri requestedUri, Exception exception) {
- return new Result(requestedUri, Status.ERROR, exception);
- }
-
- private static Result forNotFound(Uri requestedUri) {
- return new Result(requestedUri, Status.NOT_FOUND, null);
- }
-
- /**
- * Constructor to call when contact was found
- */
- private Result(Uri requestedUri, Uri uri, Uri lookupUri, long directoryId, String lookupKey,
- long id, long nameRawContactId, int displayNameSource, long photoId,
- String photoUri, String displayName, String altDisplayName, String phoneticName,
- boolean starred, Integer presence, boolean sendToVoicemail, String customRingtone,
- boolean isUserProfile) {
- mStatus = Status.LOADED;
- mException = null;
- mRequestedUri = requestedUri;
- mLookupUri = lookupUri;
- mUri = uri;
- mDirectoryId = directoryId;
- mLookupKey = lookupKey;
- mId = id;
- mEntities = new ArrayList<Entity>();
- mStreamItems = null;
- mStatuses = new LongSparseArray<DataStatus>();
- mNameRawContactId = nameRawContactId;
- mDisplayNameSource = displayNameSource;
- mPhotoId = photoId;
- mPhotoUri = photoUri;
- mDisplayName = displayName;
- mAltDisplayName = altDisplayName;
- mPhoneticName = phoneticName;
- mStarred = starred;
- mPresence = presence;
- mInvitableAccountTypes = null;
- mSendToVoicemail = sendToVoicemail;
- mCustomRingtone = customRingtone;
- mIsUserProfile = isUserProfile;
- }
-
- private Result(Uri requestedUri, Result from) {
- mRequestedUri = requestedUri;
-
- mStatus = from.mStatus;
- mException = from.mException;
- mLookupUri = from.mLookupUri;
- mUri = from.mUri;
- mDirectoryId = from.mDirectoryId;
- mLookupKey = from.mLookupKey;
- mId = from.mId;
- mNameRawContactId = from.mNameRawContactId;
- mDisplayNameSource = from.mDisplayNameSource;
- mPhotoId = from.mPhotoId;
- mPhotoUri = from.mPhotoUri;
- mDisplayName = from.mDisplayName;
- mAltDisplayName = from.mAltDisplayName;
- mPhoneticName = from.mPhoneticName;
- mStarred = from.mStarred;
- mPresence = from.mPresence;
- mEntities = from.mEntities;
- mStreamItems = from.mStreamItems;
- mStatuses = from.mStatuses;
- mInvitableAccountTypes = from.mInvitableAccountTypes;
-
- mDirectoryDisplayName = from.mDirectoryDisplayName;
- mDirectoryType = from.mDirectoryType;
- mDirectoryAccountType = from.mDirectoryAccountType;
- mDirectoryAccountName = from.mDirectoryAccountName;
- mDirectoryExportSupport = from.mDirectoryExportSupport;
-
- mGroups = from.mGroups;
-
- mPhotoBinaryData = from.mPhotoBinaryData;
- mSendToVoicemail = from.mSendToVoicemail;
- mCustomRingtone = from.mCustomRingtone;
- mIsUserProfile = from.mIsUserProfile;
- }
-
- /**
- * @param exportSupport See {@link Directory#EXPORT_SUPPORT}.
- */
- private void setDirectoryMetaData(String displayName, String directoryType,
- String accountType, String accountName, int exportSupport) {
- mDirectoryDisplayName = displayName;
- mDirectoryType = directoryType;
- mDirectoryAccountType = accountType;
- mDirectoryAccountName = accountName;
- mDirectoryExportSupport = exportSupport;
- }
-
- private void setPhotoBinaryData(byte[] photoBinaryData) {
- mPhotoBinaryData = photoBinaryData;
- }
-
- /**
- * Returns the URI for the contact that contains both the lookup key and the ID. This is
- * the best URI to reference a contact.
- * For directory contacts, this is the same a the URI as returned by {@link #getUri()}
- */
- public Uri getLookupUri() {
- return mLookupUri;
- }
-
- public String getLookupKey() {
- return mLookupKey;
- }
-
- /**
- * Returns the contact Uri that was passed to the provider to make the query. This is
- * the same as the requested Uri, unless the requested Uri doesn't specify a Contact:
- * If it either references a Raw-Contact or a Person (a pre-Eclair style Uri), this Uri will
- * always reference the full aggregate contact.
- */
- public Uri getUri() {
- return mUri;
- }
-
- /**
- * Returns the URI for which this {@link ContactLoader) was initially requested.
- */
- public Uri getRequestedUri() {
- return mRequestedUri;
- }
-
- /**
- * Instantiate a new EntityDeltaList for this contact.
- */
- public EntityDeltaList createEntityDeltaList() {
- return EntityDeltaList.fromIterator(getEntities().iterator());
- }
-
- /**
- * Returns the contact ID.
- */
- @VisibleForTesting
- /* package */ long getId() {
- return mId;
- }
-
- /**
- * @return true when an exception happened during loading, in which case
- * {@link #getException} returns the actual exception object.
- * Note {@link #isNotFound()} and {@link #isError()} are mutually exclusive; If
- * {@link #isError()} is {@code true}, {@link #isNotFound()} is always {@code false},
- * and vice versa.
- */
- public boolean isError() {
- return mStatus == Status.ERROR;
- }
-
- public Exception getException() {
- return mException;
- }
-
- /**
- * @return true when the specified contact is not found.
- * Note {@link #isNotFound()} and {@link #isError()} are mutually exclusive; If
- * {@link #isError()} is {@code true}, {@link #isNotFound()} is always {@code false},
- * and vice versa.
- */
- public boolean isNotFound() {
- return mStatus == Status.NOT_FOUND;
- }
-
- /**
- * @return true if the specified contact is successfully loaded.
- * i.e. neither {@link #isError()} nor {@link #isNotFound()}.
- */
- public boolean isLoaded() {
- return mStatus == Status.LOADED;
- }
-
- public long getNameRawContactId() {
- return mNameRawContactId;
- }
-
- public int getDisplayNameSource() {
- return mDisplayNameSource;
- }
-
- public long getPhotoId() {
- return mPhotoId;
- }
-
- public String getPhotoUri() {
- return mPhotoUri;
- }
-
- public String getDisplayName() {
- return mDisplayName;
- }
-
- public String getAltDisplayName() {
- return mAltDisplayName;
- }
-
- public String getPhoneticName() {
- return mPhoneticName;
- }
-
- public boolean getStarred() {
- return mStarred;
- }
-
- public Integer getPresence() {
- return mPresence;
- }
-
- public ArrayList<AccountType> getInvitableAccountTypes() {
- return mInvitableAccountTypes;
- }
-
- public ArrayList<Entity> getEntities() {
- return mEntities;
- }
-
- public ArrayList<StreamItemEntry> getStreamItems() {
- return mStreamItems;
- }
-
- public LongSparseArray<DataStatus> getStatuses() {
- return mStatuses;
- }
-
- public long getDirectoryId() {
- return mDirectoryId;
- }
-
- public boolean isDirectoryEntry() {
- return mDirectoryId != -1 && mDirectoryId != Directory.DEFAULT
- && mDirectoryId != Directory.LOCAL_INVISIBLE;
- }
-
- /**
- * @return true if this is a contact (not group, etc.) with at least one
- * writable raw-contact, and false otherwise.
- */
- public boolean isWritableContact(final Context context) {
- return getFirstWritableRawContactId(context) != -1;
- }
-
- /**
- * Return the ID of the first raw-contact in the contact data that belongs to a
- * contact-writable account, or -1 if no such entity exists.
- */
- public long getFirstWritableRawContactId(final Context context) {
- // Directory entries are non-writable
- if (isDirectoryEntry()) return -1;
-
- // Iterate through raw-contacts; if we find a writable on, return its ID.
- final AccountTypeManager accountTypes = AccountTypeManager.getInstance(context);
- for (Entity entity : getEntities()) {
- ContentValues values = entity.getEntityValues();
- String type = values.getAsString(RawContacts.ACCOUNT_TYPE);
- String dataSet = values.getAsString(RawContacts.DATA_SET);
-
- AccountType accountType = accountTypes.getAccountType(type, dataSet);
- if (accountType != null && accountType.areContactsWritable()) {
- return values.getAsLong(RawContacts._ID);
- }
- }
- // No writable raw-contact was found.
- return -1;
- }
-
- public int getDirectoryExportSupport() {
- return mDirectoryExportSupport;
- }
-
- public String getDirectoryDisplayName() {
- return mDirectoryDisplayName;
- }
-
- public String getDirectoryType() {
- return mDirectoryType;
- }
-
- public String getDirectoryAccountType() {
- return mDirectoryAccountType;
- }
-
- public String getDirectoryAccountName() {
- return mDirectoryAccountName;
- }
-
- public byte[] getPhotoBinaryData() {
- return mPhotoBinaryData;
- }
-
- public ArrayList<ContentValues> getContentValues() {
- if (mEntities.size() != 1) {
- throw new IllegalStateException(
- "Cannot extract content values from an aggregated contact");
- }
-
- Entity entity = mEntities.get(0);
- ArrayList<ContentValues> result = new ArrayList<ContentValues>();
- ArrayList<NamedContentValues> subValues = entity.getSubValues();
- if (subValues != null) {
- int size = subValues.size();
- for (int i = 0; i < size; i++) {
- NamedContentValues pair = subValues.get(i);
- if (Data.CONTENT_URI.equals(pair.uri)) {
- result.add(pair.values);
- }
- }
- }
-
- // If the photo was loaded using the URI, create an entry for the photo
- // binary data.
- if (mPhotoId == 0 && mPhotoBinaryData != null) {
- ContentValues photo = new ContentValues();
- photo.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
- photo.put(Photo.PHOTO, mPhotoBinaryData);
- result.add(photo);
- }
-
- return result;
- }
-
- public List<GroupMetaData> getGroupMetaData() {
- return mGroups;
- }
-
- public boolean isSendToVoicemail() {
- return mSendToVoicemail;
- }
-
- public String getCustomRingtone() {
- return mCustomRingtone;
- }
-
- public boolean isUserProfile() {
- return mIsUserProfile;
- }
-
- @Override
- public String toString() {
- return "{requested=" + mRequestedUri + ",lookupkey=" + mLookupKey +
- ",uri=" + mUri + ",status=" + mStatus + "}";
- }
- }
-
- /**
- * Projection used for the query that loads all data for the entire contact (except for
- * social stream items).
- */
- private static class ContactQuery {
- final static String[] COLUMNS = new String[] {
- Contacts.NAME_RAW_CONTACT_ID,
- Contacts.DISPLAY_NAME_SOURCE,
- Contacts.LOOKUP_KEY,
- Contacts.DISPLAY_NAME,
- Contacts.DISPLAY_NAME_ALTERNATIVE,
- Contacts.PHONETIC_NAME,
- Contacts.PHOTO_ID,
- Contacts.STARRED,
- Contacts.CONTACT_PRESENCE,
- Contacts.CONTACT_STATUS,
- Contacts.CONTACT_STATUS_TIMESTAMP,
- Contacts.CONTACT_STATUS_RES_PACKAGE,
- Contacts.CONTACT_STATUS_LABEL,
- Contacts.Entity.CONTACT_ID,
- Contacts.Entity.RAW_CONTACT_ID,
-
- RawContacts.ACCOUNT_NAME,
- RawContacts.ACCOUNT_TYPE,
- RawContacts.DATA_SET,
- RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
- RawContacts.DIRTY,
- RawContacts.VERSION,
- RawContacts.SOURCE_ID,
- RawContacts.SYNC1,
- RawContacts.SYNC2,
- RawContacts.SYNC3,
- RawContacts.SYNC4,
- RawContacts.DELETED,
- RawContacts.NAME_VERIFIED,
-
- Contacts.Entity.DATA_ID,
- Data.DATA1,
- Data.DATA2,
- Data.DATA3,
- Data.DATA4,
- Data.DATA5,
- Data.DATA6,
- Data.DATA7,
- Data.DATA8,
- Data.DATA9,
- Data.DATA10,
- Data.DATA11,
- Data.DATA12,
- Data.DATA13,
- Data.DATA14,
- Data.DATA15,
- Data.SYNC1,
- Data.SYNC2,
- Data.SYNC3,
- Data.SYNC4,
- Data.DATA_VERSION,
- Data.IS_PRIMARY,
- Data.IS_SUPER_PRIMARY,
- Data.MIMETYPE,
- Data.RES_PACKAGE,
-
- GroupMembership.GROUP_SOURCE_ID,
-
- Data.PRESENCE,
- Data.CHAT_CAPABILITY,
- Data.STATUS,
- Data.STATUS_RES_PACKAGE,
- Data.STATUS_ICON,
- Data.STATUS_LABEL,
- Data.STATUS_TIMESTAMP,
-
- Contacts.PHOTO_URI,
- Contacts.SEND_TO_VOICEMAIL,
- Contacts.CUSTOM_RINGTONE,
- Contacts.IS_USER_PROFILE,
- };
-
- public final static int NAME_RAW_CONTACT_ID = 0;
- public final static int DISPLAY_NAME_SOURCE = 1;
- public final static int LOOKUP_KEY = 2;
- public final static int DISPLAY_NAME = 3;
- public final static int ALT_DISPLAY_NAME = 4;
- public final static int PHONETIC_NAME = 5;
- public final static int PHOTO_ID = 6;
- public final static int STARRED = 7;
- public final static int CONTACT_PRESENCE = 8;
- public final static int CONTACT_STATUS = 9;
- public final static int CONTACT_STATUS_TIMESTAMP = 10;
- public final static int CONTACT_STATUS_RES_PACKAGE = 11;
- public final static int CONTACT_STATUS_LABEL = 12;
- public final static int CONTACT_ID = 13;
- public final static int RAW_CONTACT_ID = 14;
-
- public final static int ACCOUNT_NAME = 15;
- public final static int ACCOUNT_TYPE = 16;
- public final static int DATA_SET = 17;
- public final static int ACCOUNT_TYPE_AND_DATA_SET = 18;
- public final static int DIRTY = 19;
- public final static int VERSION = 20;
- public final static int SOURCE_ID = 21;
- public final static int SYNC1 = 22;
- public final static int SYNC2 = 23;
- public final static int SYNC3 = 24;
- public final static int SYNC4 = 25;
- public final static int DELETED = 26;
- public final static int NAME_VERIFIED = 27;
-
- public final static int DATA_ID = 28;
- public final static int DATA1 = 29;
- public final static int DATA2 = 30;
- public final static int DATA3 = 31;
- public final static int DATA4 = 32;
- public final static int DATA5 = 33;
- public final static int DATA6 = 34;
- public final static int DATA7 = 35;
- public final static int DATA8 = 36;
- public final static int DATA9 = 37;
- public final static int DATA10 = 38;
- public final static int DATA11 = 39;
- public final static int DATA12 = 40;
- public final static int DATA13 = 41;
- public final static int DATA14 = 42;
- public final static int DATA15 = 43;
- public final static int DATA_SYNC1 = 44;
- public final static int DATA_SYNC2 = 45;
- public final static int DATA_SYNC3 = 46;
- public final static int DATA_SYNC4 = 47;
- public final static int DATA_VERSION = 48;
- public final static int IS_PRIMARY = 49;
- public final static int IS_SUPERPRIMARY = 50;
- public final static int MIMETYPE = 51;
- public final static int RES_PACKAGE = 52;
-
- public final static int GROUP_SOURCE_ID = 53;
-
- public final static int PRESENCE = 54;
- public final static int CHAT_CAPABILITY = 55;
- public final static int STATUS = 56;
- public final static int STATUS_RES_PACKAGE = 57;
- public final static int STATUS_ICON = 58;
- public final static int STATUS_LABEL = 59;
- public final static int STATUS_TIMESTAMP = 60;
-
- public final static int PHOTO_URI = 61;
- public final static int SEND_TO_VOICEMAIL = 62;
- public final static int CUSTOM_RINGTONE = 63;
- public final static int IS_USER_PROFILE = 64;
- }
-
- /**
- * Projection used for the query that loads all data for the entire contact.
- */
- private static class DirectoryQuery {
- final static String[] COLUMNS = new String[] {
- Directory.DISPLAY_NAME,
- Directory.PACKAGE_NAME,
- Directory.TYPE_RESOURCE_ID,
- Directory.ACCOUNT_TYPE,
- Directory.ACCOUNT_NAME,
- Directory.EXPORT_SUPPORT,
- };
-
- public final static int DISPLAY_NAME = 0;
- public final static int PACKAGE_NAME = 1;
- public final static int TYPE_RESOURCE_ID = 2;
- public final static int ACCOUNT_TYPE = 3;
- public final static int ACCOUNT_NAME = 4;
- public final static int EXPORT_SUPPORT = 5;
- }
-
- private static class GroupQuery {
- final static String[] COLUMNS = new String[] {
- Groups.ACCOUNT_NAME,
- Groups.ACCOUNT_TYPE,
- Groups.DATA_SET,
- Groups.ACCOUNT_TYPE_AND_DATA_SET,
- Groups._ID,
- Groups.TITLE,
- Groups.AUTO_ADD,
- Groups.FAVORITES,
- };
-
- public final static int ACCOUNT_NAME = 0;
- public final static int ACCOUNT_TYPE = 1;
- public final static int DATA_SET = 2;
- public final static int ACCOUNT_TYPE_AND_DATA_SET = 3;
- public final static int ID = 4;
- public final static int TITLE = 5;
- public final static int AUTO_ADD = 6;
- public final static int FAVORITES = 7;
- }
-
- @Override
- public Result loadInBackground() {
- try {
- final ContentResolver resolver = getContext().getContentResolver();
- final Uri uriCurrentFormat = ContactLoaderUtils.ensureIsContactUri(
- resolver, mLookupUri);
- final Result cachedResult = sCachedResult;
- sCachedResult = null;
- // Is this the same Uri as what we had before already? In that case, reuse that result
- final Result result;
- final boolean resultIsCached;
- if (cachedResult != null &&
- UriUtils.areEqual(cachedResult.getLookupUri(), mLookupUri)) {
- // We are using a cached result from earlier. Below, we should make sure
- // we are not doing any more network or disc accesses
- result = new Result(mRequestedUri, cachedResult);
- resultIsCached = true;
- } else {
- result = loadContactEntity(resolver, uriCurrentFormat);
- resultIsCached = false;
- }
- if (result.isLoaded()) {
- if (result.isDirectoryEntry()) {
- if (!resultIsCached) {
- loadDirectoryMetaData(result);
- }
- } else if (mLoadGroupMetaData) {
- if (result.getGroupMetaData() == null) {
- loadGroupMetaData(result);
- }
- }
- if (mLoadStreamItems && result.getStreamItems() == null) {
- loadStreamItems(result);
- }
- if (!resultIsCached) loadPhotoBinaryData(result);
-
- // Note ME profile should never have "Add connection"
- if (mLoadInvitableAccountTypes && result.getInvitableAccountTypes() == null) {
- loadInvitableAccountTypes(result);
- }
- }
- return result;
- } catch (Exception e) {
- Log.e(TAG, "Error loading the contact: " + mLookupUri, e);
- return Result.forError(mRequestedUri, e);
- }
- }
-
- private Result loadContactEntity(ContentResolver resolver, Uri contactUri) {
- Uri entityUri = Uri.withAppendedPath(contactUri, Contacts.Entity.CONTENT_DIRECTORY);
- Cursor cursor = resolver.query(entityUri, ContactQuery.COLUMNS, null, null,
- Contacts.Entity.RAW_CONTACT_ID);
- if (cursor == null) {
- Log.e(TAG, "No cursor returned in loadContactEntity");
- return Result.forNotFound(mRequestedUri);
- }
-
- try {
- if (!cursor.moveToFirst()) {
- cursor.close();
- return Result.forNotFound(mRequestedUri);
- }
-
- // Create the loaded result starting with the Contact data.
- Result result = loadContactHeaderData(cursor, contactUri);
-
- // Fill in the raw contacts, which is wrapped in an Entity and any
- // status data. Initially, result has empty entities and statuses.
- long currentRawContactId = -1;
- Entity entity = null;
- ArrayList<Entity> entities = result.getEntities();
- LongSparseArray<DataStatus> statuses = result.getStatuses();
- for (; !cursor.isAfterLast(); cursor.moveToNext()) {
- long rawContactId = cursor.getLong(ContactQuery.RAW_CONTACT_ID);
- if (rawContactId != currentRawContactId) {
- // First time to see this raw contact id, so create a new entity, and
- // add it to the result's entities.
- currentRawContactId = rawContactId;
- entity = new android.content.Entity(loadRawContact(cursor));
- entities.add(entity);
- }
- if (!cursor.isNull(ContactQuery.DATA_ID)) {
- ContentValues data = loadData(cursor);
- entity.addSubValue(ContactsContract.Data.CONTENT_URI, data);
-
- if (!cursor.isNull(ContactQuery.PRESENCE)
- || !cursor.isNull(ContactQuery.STATUS)) {
- final DataStatus status = new DataStatus(cursor);
- final long dataId = cursor.getLong(ContactQuery.DATA_ID);
- statuses.put(dataId, status);
- }
- }
- }
-
- return result;
- } finally {
- cursor.close();
- }
- }
-
- /**
- * Looks for the photo data item in entities. If found, creates a new Bitmap instance. If
- * not found, returns null
- */
- private void loadPhotoBinaryData(Result contactData) {
-
- // If we have a photo URI, try loading that first.
- String photoUri = contactData.getPhotoUri();
- if (photoUri != null) {
- try {
- AssetFileDescriptor fd = getContext().getContentResolver()
- .openAssetFileDescriptor(Uri.parse(photoUri), "r");
- byte[] buffer = new byte[16 * 1024];
- FileInputStream fis = fd.createInputStream();
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- try {
- int size;
- while ((size = fis.read(buffer)) != -1) {
- baos.write(buffer, 0, size);
- }
- contactData.setPhotoBinaryData(baos.toByteArray());
- } finally {
- fis.close();
- fd.close();
- }
- return;
- } catch (IOException ioe) {
- // Just fall back to the case below.
- }
- }
-
- // If we couldn't load from a file, fall back to the data blob.
- final long photoId = contactData.getPhotoId();
- if (photoId <= 0) {
- // No photo ID
- return;
- }
-
- for (Entity entity : contactData.getEntities()) {
- for (NamedContentValues subValue : entity.getSubValues()) {
- final ContentValues entryValues = subValue.values;
- final long dataId = entryValues.getAsLong(Data._ID);
- if (dataId == photoId) {
- final String mimeType = entryValues.getAsString(Data.MIMETYPE);
- // Correct Data Id but incorrect MimeType? Don't load
- if (!Photo.CONTENT_ITEM_TYPE.equals(mimeType)) {
- return;
- }
- contactData.setPhotoBinaryData(entryValues.getAsByteArray(Photo.PHOTO));
- break;
- }
- }
- }
- }
-
- /**
- * Sets the "invitable" account types to {@link Result#mInvitableAccountTypes}.
- */
- private void loadInvitableAccountTypes(Result contactData) {
- final ArrayList<AccountType> resultList = Lists.newArrayList();
- if (!contactData.isUserProfile()) {
- Map<AccountTypeWithDataSet, AccountType> invitables =
- AccountTypeManager.getInstance(getContext()).getUsableInvitableAccountTypes();
- if (!invitables.isEmpty()) {
- final Map<AccountTypeWithDataSet, AccountType> resultMap =
- Maps.newHashMap(invitables);
-
- // Remove the ones that already have a raw contact in the current contact
- for (Entity entity : contactData.getEntities()) {
- final ContentValues values = entity.getEntityValues();
- final AccountTypeWithDataSet type = AccountTypeWithDataSet.get(
- values.getAsString(RawContacts.ACCOUNT_TYPE),
- values.getAsString(RawContacts.DATA_SET));
- resultMap.remove(type);
- }
-
- resultList.addAll(resultMap.values());
- }
- }
-
- // Set to mInvitableAccountTypes
- contactData.mInvitableAccountTypes = resultList;
- }
-
- /**
- * Extracts Contact level columns from the cursor.
- */
- private Result loadContactHeaderData(final Cursor cursor, Uri contactUri) {
- final String directoryParameter =
- contactUri.getQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY);
- final long directoryId = directoryParameter == null
- ? Directory.DEFAULT
- : Long.parseLong(directoryParameter);
- final long contactId = cursor.getLong(ContactQuery.CONTACT_ID);
- final String lookupKey = cursor.getString(ContactQuery.LOOKUP_KEY);
- final long nameRawContactId = cursor.getLong(ContactQuery.NAME_RAW_CONTACT_ID);
- final int displayNameSource = cursor.getInt(ContactQuery.DISPLAY_NAME_SOURCE);
- final String displayName = cursor.getString(ContactQuery.DISPLAY_NAME);
- final String altDisplayName = cursor.getString(ContactQuery.ALT_DISPLAY_NAME);
- final String phoneticName = cursor.getString(ContactQuery.PHONETIC_NAME);
- final long photoId = cursor.getLong(ContactQuery.PHOTO_ID);
- final String photoUri = cursor.getString(ContactQuery.PHOTO_URI);
- final boolean starred = cursor.getInt(ContactQuery.STARRED) != 0;
- final Integer presence = cursor.isNull(ContactQuery.CONTACT_PRESENCE)
- ? null
- : cursor.getInt(ContactQuery.CONTACT_PRESENCE);
- final boolean sendToVoicemail = cursor.getInt(ContactQuery.SEND_TO_VOICEMAIL) == 1;
- final String customRingtone = cursor.getString(ContactQuery.CUSTOM_RINGTONE);
- final boolean isUserProfile = cursor.getInt(ContactQuery.IS_USER_PROFILE) == 1;
-
- Uri lookupUri;
- if (directoryId == Directory.DEFAULT || directoryId == Directory.LOCAL_INVISIBLE) {
- lookupUri = ContentUris.withAppendedId(
- Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey), contactId);
- } else {
- lookupUri = contactUri;
- }
-
- return new Result(mRequestedUri, contactUri, lookupUri, directoryId, lookupKey,
- contactId, nameRawContactId, displayNameSource, photoId, photoUri, displayName,
- altDisplayName, phoneticName, starred, presence, sendToVoicemail,
- customRingtone, isUserProfile);
- }
-
- /**
- * Extracts RawContact level columns from the cursor.
- */
- private ContentValues loadRawContact(Cursor cursor) {
- ContentValues cv = new ContentValues();
-
- cv.put(RawContacts._ID, cursor.getLong(ContactQuery.RAW_CONTACT_ID));
-
- cursorColumnToContentValues(cursor, cv, ContactQuery.ACCOUNT_NAME);
- cursorColumnToContentValues(cursor, cv, ContactQuery.ACCOUNT_TYPE);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SET);
- cursorColumnToContentValues(cursor, cv, ContactQuery.ACCOUNT_TYPE_AND_DATA_SET);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DIRTY);
- cursorColumnToContentValues(cursor, cv, ContactQuery.VERSION);
- cursorColumnToContentValues(cursor, cv, ContactQuery.SOURCE_ID);
- cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC1);
- cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC2);
- cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC3);
- cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC4);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DELETED);
- cursorColumnToContentValues(cursor, cv, ContactQuery.CONTACT_ID);
- cursorColumnToContentValues(cursor, cv, ContactQuery.STARRED);
- cursorColumnToContentValues(cursor, cv, ContactQuery.NAME_VERIFIED);
-
- return cv;
- }
-
- /**
- * Extracts Data level columns from the cursor.
- */
- private ContentValues loadData(Cursor cursor) {
- ContentValues cv = new ContentValues();
-
- cv.put(Data._ID, cursor.getLong(ContactQuery.DATA_ID));
-
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA1);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA2);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA3);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA4);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA5);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA6);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA7);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA8);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA9);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA10);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA11);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA12);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA13);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA14);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA15);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC1);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC2);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC3);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC4);
- cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_VERSION);
- cursorColumnToContentValues(cursor, cv, ContactQuery.IS_PRIMARY);
- cursorColumnToContentValues(cursor, cv, ContactQuery.IS_SUPERPRIMARY);
- cursorColumnToContentValues(cursor, cv, ContactQuery.MIMETYPE);
- cursorColumnToContentValues(cursor, cv, ContactQuery.RES_PACKAGE);
- cursorColumnToContentValues(cursor, cv, ContactQuery.GROUP_SOURCE_ID);
- cursorColumnToContentValues(cursor, cv, ContactQuery.CHAT_CAPABILITY);
-
- return cv;
- }
-
- private void cursorColumnToContentValues(
- Cursor cursor, ContentValues values, int index) {
- switch (cursor.getType(index)) {
- case Cursor.FIELD_TYPE_NULL:
- // don't put anything in the content values
- break;
- case Cursor.FIELD_TYPE_INTEGER:
- values.put(ContactQuery.COLUMNS[index], cursor.getLong(index));
- break;
- case Cursor.FIELD_TYPE_STRING:
- values.put(ContactQuery.COLUMNS[index], cursor.getString(index));
- break;
- case Cursor.FIELD_TYPE_BLOB:
- values.put(ContactQuery.COLUMNS[index], cursor.getBlob(index));
- break;
- default:
- throw new IllegalStateException("Invalid or unhandled data type");
- }
- }
-
- private void loadDirectoryMetaData(Result result) {
- long directoryId = result.getDirectoryId();
-
- Cursor cursor = getContext().getContentResolver().query(
- ContentUris.withAppendedId(Directory.CONTENT_URI, directoryId),
- DirectoryQuery.COLUMNS, null, null, null);
- if (cursor == null) {
- return;
- }
- try {
- if (cursor.moveToFirst()) {
- final String displayName = cursor.getString(DirectoryQuery.DISPLAY_NAME);
- final String packageName = cursor.getString(DirectoryQuery.PACKAGE_NAME);
- final int typeResourceId = cursor.getInt(DirectoryQuery.TYPE_RESOURCE_ID);
- final String accountType = cursor.getString(DirectoryQuery.ACCOUNT_TYPE);
- final String accountName = cursor.getString(DirectoryQuery.ACCOUNT_NAME);
- final int exportSupport = cursor.getInt(DirectoryQuery.EXPORT_SUPPORT);
- String directoryType = null;
- if (!TextUtils.isEmpty(packageName)) {
- PackageManager pm = getContext().getPackageManager();
- try {
- Resources resources = pm.getResourcesForApplication(packageName);
- directoryType = resources.getString(typeResourceId);
- } catch (NameNotFoundException e) {
- Log.w(TAG, "Contact directory resource not found: "
- + packageName + "." + typeResourceId);
- }
- }
-
- result.setDirectoryMetaData(
- displayName, directoryType, accountType, accountName, exportSupport);
- }
- } finally {
- cursor.close();
- }
- }
-
- /**
- * Loads groups meta-data for all groups associated with all constituent raw contacts'
- * accounts.
- */
- private void loadGroupMetaData(Result result) {
- StringBuilder selection = new StringBuilder();
- ArrayList<String> selectionArgs = new ArrayList<String>();
- for (Entity entity : result.mEntities) {
- ContentValues values = entity.getEntityValues();
- String accountName = values.getAsString(RawContacts.ACCOUNT_NAME);
- String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
- String dataSet = values.getAsString(RawContacts.DATA_SET);
- if (accountName != null && accountType != null) {
- if (selection.length() != 0) {
- selection.append(" OR ");
- }
- selection.append(
- "(" + Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=?");
- selectionArgs.add(accountName);
- selectionArgs.add(accountType);
-
- if (dataSet != null) {
- selection.append(" AND " + Groups.DATA_SET + "=?");
- selectionArgs.add(dataSet);
- } else {
- selection.append(" AND " + Groups.DATA_SET + " IS NULL");
- }
- selection.append(")");
- }
- }
- final ArrayList<GroupMetaData> groupList = new ArrayList<GroupMetaData>();
- final Cursor cursor = getContext().getContentResolver().query(Groups.CONTENT_URI,
- GroupQuery.COLUMNS, selection.toString(), selectionArgs.toArray(new String[0]),
- null);
- try {
- while (cursor.moveToNext()) {
- final String accountName = cursor.getString(GroupQuery.ACCOUNT_NAME);
- final String accountType = cursor.getString(GroupQuery.ACCOUNT_TYPE);
- final String dataSet = cursor.getString(GroupQuery.DATA_SET);
- final long groupId = cursor.getLong(GroupQuery.ID);
- final String title = cursor.getString(GroupQuery.TITLE);
- final boolean defaultGroup = cursor.isNull(GroupQuery.AUTO_ADD)
- ? false
- : cursor.getInt(GroupQuery.AUTO_ADD) != 0;
- final boolean favorites = cursor.isNull(GroupQuery.FAVORITES)
- ? false
- : cursor.getInt(GroupQuery.FAVORITES) != 0;
-
- groupList.add(new GroupMetaData(
- accountName, accountType, dataSet, groupId, title, defaultGroup,
- favorites));
- }
- } finally {
- cursor.close();
- }
- result.mGroups = groupList;
- }
-
- /**
- * Loads all stream items and stream item photos belonging to this contact.
- */
- private void loadStreamItems(Result result) {
- Cursor cursor = getContext().getContentResolver().query(
- Contacts.CONTENT_LOOKUP_URI.buildUpon()
- .appendPath(result.getLookupKey())
- .appendPath(Contacts.StreamItems.CONTENT_DIRECTORY).build(),
- null, null, null, null);
- LongSparseArray<StreamItemEntry> streamItemsById =
- new LongSparseArray<StreamItemEntry>();
- ArrayList<StreamItemEntry> streamItems = new ArrayList<StreamItemEntry>();
- try {
- while (cursor.moveToNext()) {
- StreamItemEntry streamItem = new StreamItemEntry(cursor);
- streamItemsById.put(streamItem.getId(), streamItem);
- streamItems.add(streamItem);
- }
- } finally {
- cursor.close();
- }
-
- // Pre-decode all HTMLs
- final long start = System.currentTimeMillis();
- for (StreamItemEntry streamItem : streamItems) {
- streamItem.decodeHtml(getContext());
- }
- final long end = System.currentTimeMillis();
- if (DEBUG) {
- Log.d(TAG, "Decoded HTML for " + streamItems.size() + " items, took "
- + (end - start) + " ms");
- }
-
- // Now retrieve any photo records associated with the stream items.
- if (!streamItems.isEmpty()) {
- if (result.isUserProfile()) {
- // If the stream items we're loading are for the profile, we can't bulk-load the
- // stream items with a custom selection.
- for (StreamItemEntry entry : streamItems) {
- Cursor siCursor = getContext().getContentResolver().query(
- Uri.withAppendedPath(
- ContentUris.withAppendedId(
- StreamItems.CONTENT_URI, entry.getId()),
- StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
- null, null, null, null);
- try {
- while (siCursor.moveToNext()) {
- entry.addPhoto(new StreamItemPhotoEntry(siCursor));
- }
- } finally {
- siCursor.close();
- }
- }
- } else {
- String[] streamItemIdArr = new String[streamItems.size()];
- StringBuilder streamItemPhotoSelection = new StringBuilder();
- streamItemPhotoSelection.append(StreamItemPhotos.STREAM_ITEM_ID + " IN (");
- for (int i = 0; i < streamItems.size(); i++) {
- if (i > 0) {
- streamItemPhotoSelection.append(",");
- }
- streamItemPhotoSelection.append("?");
- streamItemIdArr[i] = String.valueOf(streamItems.get(i).getId());
- }
- streamItemPhotoSelection.append(")");
- Cursor sipCursor = getContext().getContentResolver().query(
- StreamItems.CONTENT_PHOTO_URI,
- null, streamItemPhotoSelection.toString(), streamItemIdArr,
- StreamItemPhotos.STREAM_ITEM_ID);
- try {
- while (sipCursor.moveToNext()) {
- long streamItemId = sipCursor.getLong(
- sipCursor.getColumnIndex(StreamItemPhotos.STREAM_ITEM_ID));
- StreamItemEntry streamItem = streamItemsById.get(streamItemId);
- streamItem.addPhoto(new StreamItemPhotoEntry(sipCursor));
- }
- } finally {
- sipCursor.close();
- }
- }
- }
-
- // Set the sorted stream items on the result.
- Collections.sort(streamItems);
- result.mStreamItems = streamItems;
- }
-
- @Override
- public void deliverResult(Result result) {
- unregisterObserver();
-
- // The creator isn't interested in any further updates
- if (isReset() || result == null) {
- return;
- }
-
- mContact = result;
-
- if (result.isLoaded()) {
- mLookupUri = result.getLookupUri();
-
- if (!result.isDirectoryEntry()) {
- Log.i(TAG, "Registering content observer for " + mLookupUri);
- if (mObserver == null) {
- mObserver = new ForceLoadContentObserver();
- }
- getContext().getContentResolver().registerContentObserver(
- mLookupUri, true, mObserver);
- }
-
- if (mPostViewNotification) {
- // inform the source of the data that this contact is being looked at
- postViewNotificationToSyncAdapter();
- }
- }
-
- super.deliverResult(mContact);
- }
-
- /**
- * Posts a message to the contributing sync adapters that have opted-in, notifying them
- * that the contact has just been loaded
- */
- private void postViewNotificationToSyncAdapter() {
- Context context = getContext();
- for (Entity entity : mContact.getEntities()) {
- final ContentValues entityValues = entity.getEntityValues();
- final long rawContactId = entityValues.getAsLong(RawContacts.Entity._ID);
- if (mNotifiedRawContactIds.contains(rawContactId)) {
- continue; // Already notified for this raw contact.
- }
- mNotifiedRawContactIds.add(rawContactId);
- final String type = entityValues.getAsString(RawContacts.ACCOUNT_TYPE);
- final String dataSet = entityValues.getAsString(RawContacts.DATA_SET);
- final AccountType accountType = AccountTypeManager.getInstance(context).getAccountType(
- type, dataSet);
- final String serviceName = accountType.getViewContactNotifyServiceClassName();
- final String servicePackageName = accountType.getViewContactNotifyServicePackageName();
- if (!TextUtils.isEmpty(serviceName) && !TextUtils.isEmpty(servicePackageName)) {
- final Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
- final Intent intent = new Intent();
- intent.setClassName(servicePackageName, serviceName);
- intent.setAction(Intent.ACTION_VIEW);
- intent.setDataAndType(uri, RawContacts.CONTENT_ITEM_TYPE);
- try {
- context.startService(intent);
- } catch (Exception e) {
- Log.e(TAG, "Error sending message to source-app", e);
- }
- }
- }
- }
-
- private void unregisterObserver() {
- if (mObserver != null) {
- getContext().getContentResolver().unregisterContentObserver(mObserver);
- mObserver = null;
- }
- }
-
- /**
- * Sets whether to load stream items. Will trigger a reload if the value has changed.
- * At the moment, this is only used for debugging purposes
- */
- public void setLoadStreamItems(boolean value) {
- if (mLoadStreamItems != value) {
- mLoadStreamItems = value;
- onContentChanged();
- }
- }
-
- /**
- * Fully upgrades this ContactLoader to one with all lists fully loaded. When done, the
- * new result will be delivered
- */
- public void upgradeToFullContact() {
- // Everything requested already? Nothing to do, so let's bail out
- if (mLoadGroupMetaData && mLoadInvitableAccountTypes && mLoadStreamItems
- && mPostViewNotification) return;
-
- mLoadGroupMetaData = true;
- mLoadInvitableAccountTypes = true;
- mLoadStreamItems = true;
- mPostViewNotification = true;
-
- // Cache the current result, so that we only load the "missing" parts of the contact.
- cacheResult();
-
- // Our load parameters have changed, so let's pretend the data has changed. Its the same
- // thing, essentially.
- onContentChanged();
- }
-
- public boolean getLoadStreamItems() {
- return mLoadStreamItems;
- }
-
- public Uri getLookupUri() {
- return mLookupUri;
- }
-
- @Override
- protected void onStartLoading() {
- if (mContact != null) {
- deliverResult(mContact);
- }
-
- if (takeContentChanged() || mContact == null) {
- forceLoad();
- }
- }
-
- @Override
- protected void onStopLoading() {
- cancelLoad();
- }
-
- @Override
- protected void onReset() {
- super.onReset();
- cancelLoad();
- unregisterObserver();
- mContact = null;
- }
-
- /**
- * Caches the result, which is useful when we switch from activity to activity, using the same
- * contact. If the next load is for a different contact, the cached result will be dropped
- */
- public void cacheResult() {
- if (mContact == null || !mContact.isLoaded()) {
- sCachedResult = null;
- } else {
- sCachedResult = mContact;
- }
- }
-}
diff --git a/src/com/android/contacts/ContactPhotoManager.java b/src/com/android/contacts/ContactPhotoManager.java
index 5b6a1ca..5c866d0 100644
--- a/src/com/android/contacts/ContactPhotoManager.java
+++ b/src/com/android/contacts/ContactPhotoManager.java
@@ -16,13 +16,6 @@
package com.android.contacts;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.util.BitmapUtil;
-import com.android.contacts.util.MemoryUtils;
-import com.android.contacts.util.UriUtils;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Sets;
-
import android.content.ComponentCallbacks2;
import android.content.ContentResolver;
import android.content.ContentUris;
@@ -55,6 +48,13 @@
import android.util.TypedValue;
import android.widget.ImageView;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.util.BitmapUtil;
+import com.android.contacts.util.MemoryUtils;
+import com.android.contacts.util.UriUtils;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.lang.ref.Reference;
diff --git a/src/com/android/contacts/ContactSaveService.java b/src/com/android/contacts/ContactSaveService.java
index b8bf45f..4333aa4 100644
--- a/src/com/android/contacts/ContactSaveService.java
+++ b/src/com/android/contacts/ContactSaveService.java
@@ -16,15 +16,6 @@
package com.android.contacts;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountWithDataSet;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDeltaList;
-import com.android.contacts.model.EntityModifier;
-import com.android.contacts.util.CallerInfoCacheUtils;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Sets;
-
import android.app.Activity;
import android.app.IntentService;
import android.content.ContentProviderOperation;
@@ -55,6 +46,15 @@
import android.util.Log;
import android.widget.Toast;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDeltaList;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.util.CallerInfoCacheUtils;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -289,7 +289,7 @@
* @param rawContactId identifies a writable raw-contact whose photo is to be updated.
* @param updatedPhotoPath denotes a temporary file containing the contact's new photo.
*/
- public static Intent createSaveContactIntent(Context context, EntityDeltaList state,
+ public static Intent createSaveContactIntent(Context context, RawContactDeltaList state,
String saveModeExtraKey, int saveMode, boolean isProfile,
Class<? extends Activity> callbackActivity, String callbackAction, long rawContactId,
String updatedPhotoPath) {
@@ -306,7 +306,7 @@
* Contact Editor.
* @param updatedPhotos maps each raw-contact's ID to the file-path of the new photo.
*/
- public static Intent createSaveContactIntent(Context context, EntityDeltaList state,
+ public static Intent createSaveContactIntent(Context context, RawContactDeltaList state,
String saveModeExtraKey, int saveMode, boolean isProfile,
Class<? extends Activity> callbackActivity, String callbackAction,
Bundle updatedPhotos) {
@@ -332,13 +332,13 @@
}
private void saveContact(Intent intent) {
- EntityDeltaList state = intent.getParcelableExtra(EXTRA_CONTACT_STATE);
+ RawContactDeltaList state = intent.getParcelableExtra(EXTRA_CONTACT_STATE);
boolean isProfile = intent.getBooleanExtra(EXTRA_SAVE_IS_PROFILE, false);
Bundle updatedPhotos = intent.getParcelableExtra(EXTRA_UPDATED_PHOTOS);
// Trim any empty fields, and RawContacts, before persisting
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(this);
- EntityModifier.trimEmpty(state, accountTypes);
+ RawContactModifier.trimEmpty(state, accountTypes);
Uri lookupUri = null;
@@ -427,16 +427,16 @@
throw new IllegalStateException("Version consistency failed for a new contact");
}
- final EntityDeltaList newState = EntityDeltaList.fromQuery(
+ final RawContactDeltaList newState = RawContactDeltaList.fromQuery(
isProfile
? RawContactsEntity.PROFILE_CONTENT_URI
: RawContactsEntity.CONTENT_URI,
resolver, sb.toString(), null, null);
- state = EntityDeltaList.mergeAfter(newState, state);
+ state = RawContactDeltaList.mergeAfter(newState, state);
// Update the new state to use profile URIs if appropriate.
if (isProfile) {
- for (EntityDelta delta : state) {
+ for (RawContactDelta delta : state) {
delta.setProfileQueryUri();
}
}
@@ -518,7 +518,7 @@
/**
* Find the ID of an existing or newly-inserted raw-contact. If none exists, return -1.
*/
- private long getRawContactId(EntityDeltaList state,
+ private long getRawContactId(RawContactDeltaList state,
final ArrayList<ContentProviderOperation> diff,
final ContentProviderResult[] results) {
long existingRawContactId = state.findRawContactId();
diff --git a/src/com/android/contacts/ContactTileLoaderFactory.java b/src/com/android/contacts/ContactTileLoaderFactory.java
index 28f2164..3a23400 100644
--- a/src/com/android/contacts/ContactTileLoaderFactory.java
+++ b/src/com/android/contacts/ContactTileLoaderFactory.java
@@ -15,8 +15,6 @@
*/
package com.android.contacts;
-import com.android.contacts.list.ContactTileView;
-
import android.content.Context;
import android.content.CursorLoader;
import android.net.Uri;
@@ -24,6 +22,8 @@
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Contacts;
+import com.android.contacts.list.ContactTileView;
+
/**
* Used to create {@link CursorLoader}s to load different groups of {@link ContactTileView}s
*/
diff --git a/src/com/android/contacts/ContactsActivity.java b/src/com/android/contacts/ContactsActivity.java
index 371b0b7..90900ce 100644
--- a/src/com/android/contacts/ContactsActivity.java
+++ b/src/com/android/contacts/ContactsActivity.java
@@ -16,9 +16,6 @@
package com.android.contacts;
-import com.android.contacts.test.InjectedServices;
-import com.android.contacts.activities.TransactionSafeActivity;
-
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
@@ -28,6 +25,9 @@
import android.os.Bundle;
import android.view.View;
+import com.android.contacts.activities.TransactionSafeActivity;
+import com.android.contacts.test.InjectedServices;
+
/**
* A common superclass for Contacts activities that handles application-wide services.
*/
diff --git a/src/com/android/contacts/ContactsApplication.java b/src/com/android/contacts/ContactsApplication.java
index 956ce65..3380553 100644
--- a/src/com/android/contacts/ContactsApplication.java
+++ b/src/com/android/contacts/ContactsApplication.java
@@ -16,12 +16,6 @@
package com.android.contacts;
-import com.android.contacts.list.ContactListFilterController;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.test.InjectedServices;
-import com.android.contacts.util.Constants;
-import com.google.common.annotations.VisibleForTesting;
-
import android.app.Application;
import android.app.FragmentManager;
import android.app.LoaderManager;
@@ -35,6 +29,12 @@
import android.provider.ContactsContract.Contacts;
import android.util.Log;
+import com.android.contacts.list.ContactListFilterController;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.test.InjectedServices;
+import com.android.contacts.util.Constants;
+import com.google.common.annotations.VisibleForTesting;
+
public final class ContactsApplication extends Application {
private static final boolean ENABLE_LOADER_LOG = false; // Don't submit with true
private static final boolean ENABLE_FRAGMENT_LOG = false; // Don't submit with true
diff --git a/src/com/android/contacts/ContactsSearchManager.java b/src/com/android/contacts/ContactsSearchManager.java
index edb2016..20d7c5c 100644
--- a/src/com/android/contacts/ContactsSearchManager.java
+++ b/src/com/android/contacts/ContactsSearchManager.java
@@ -16,14 +16,14 @@
package com.android.contacts;
-import com.android.contacts.list.ContactsRequest;
-
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Intents.UI;
+import com.android.contacts.list.ContactsRequest;
+
/**
* A convenience class that helps launch contact search from within the app.
*/
diff --git a/src/com/android/contacts/ContactsUtils.java b/src/com/android/contacts/ContactsUtils.java
index ca32ff8..e8aa1ae 100644
--- a/src/com/android/contacts/ContactsUtils.java
+++ b/src/com/android/contacts/ContactsUtils.java
@@ -16,13 +16,6 @@
package com.android.contacts;
-import com.android.contacts.activities.DialtactsActivity;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountWithDataSet;
-import com.android.contacts.test.NeededForTesting;
-import com.android.contacts.util.Constants;
-
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
@@ -39,6 +32,13 @@
import android.view.View;
import android.widget.TextView;
+import com.android.contacts.activities.DialtactsActivity;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.test.NeededForTesting;
+import com.android.contacts.util.Constants;
+
import java.util.List;
public class ContactsUtils {
diff --git a/src/com/android/contacts/GroupMemberLoader.java b/src/com/android/contacts/GroupMemberLoader.java
index 1cef4d4..12e82ce 100644
--- a/src/com/android/contacts/GroupMemberLoader.java
+++ b/src/com/android/contacts/GroupMemberLoader.java
@@ -15,8 +15,6 @@
*/
package com.android.contacts;
-import com.android.contacts.preference.ContactsPreferences;
-
import android.content.Context;
import android.content.CursorLoader;
import android.net.Uri;
@@ -26,6 +24,8 @@
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Directory;
+import com.android.contacts.preference.ContactsPreferences;
+
import java.util.ArrayList;
import java.util.List;
diff --git a/src/com/android/contacts/NfcHandler.java b/src/com/android/contacts/NfcHandler.java
index 1ae72be..3cd4b08 100644
--- a/src/com/android/contacts/NfcHandler.java
+++ b/src/com/android/contacts/NfcHandler.java
@@ -16,8 +16,6 @@
package com.android.contacts;
-import com.android.contacts.detail.ContactDetailFragment;
-
import android.app.Activity;
import android.content.ContentResolver;
import android.net.Uri;
@@ -27,9 +25,10 @@
import android.nfc.NfcEvent;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Profile;
-
import android.util.Log;
+import com.android.contacts.detail.ContactDetailFragment;
+
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
diff --git a/src/com/android/contacts/PhoneCallDetailsHelper.java b/src/com/android/contacts/PhoneCallDetailsHelper.java
index fd950fe..8192975 100644
--- a/src/com/android/contacts/PhoneCallDetailsHelper.java
+++ b/src/com/android/contacts/PhoneCallDetailsHelper.java
@@ -16,10 +16,6 @@
package com.android.contacts;
-import com.android.contacts.calllog.CallTypeHelper;
-import com.android.contacts.calllog.PhoneNumberHelper;
-import com.android.contacts.test.NeededForTesting;
-
import android.content.res.Resources;
import android.graphics.Typeface;
import android.provider.ContactsContract.CommonDataKinds.Phone;
@@ -33,6 +29,10 @@
import android.view.View;
import android.widget.TextView;
+import com.android.contacts.calllog.CallTypeHelper;
+import com.android.contacts.calllog.PhoneNumberHelper;
+import com.android.contacts.test.NeededForTesting;
+
/**
* Helper class to fill in the views in {@link PhoneCallDetailsViews}.
*/
diff --git a/src/com/android/contacts/PhoneCallDetailsViews.java b/src/com/android/contacts/PhoneCallDetailsViews.java
index ea5a461..8be7f0c 100644
--- a/src/com/android/contacts/PhoneCallDetailsViews.java
+++ b/src/com/android/contacts/PhoneCallDetailsViews.java
@@ -16,12 +16,12 @@
package com.android.contacts;
-import com.android.contacts.calllog.CallTypeIconsView;
-
import android.content.Context;
import android.view.View;
import android.widget.TextView;
+import com.android.contacts.calllog.CallTypeIconsView;
+
/**
* Encapsulates the views that are used to display the details of a phone call in the call log.
*/
diff --git a/src/com/android/contacts/SplitAggregateView.java b/src/com/android/contacts/SplitAggregateView.java
index 091cd56..1b42ca3 100644
--- a/src/com/android/contacts/SplitAggregateView.java
+++ b/src/com/android/contacts/SplitAggregateView.java
@@ -16,22 +16,16 @@
package com.android.contacts;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-
import android.content.Context;
-import android.content.pm.PackageManager;
import android.database.Cursor;
-import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
-import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Nickname;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Contacts.Data;
-import android.util.Log;
+import android.provider.ContactsContract.RawContacts;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -41,6 +35,9 @@
import android.widget.ListView;
import android.widget.TextView;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountType;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
diff --git a/src/com/android/contacts/TypePrecedence.java b/src/com/android/contacts/TypePrecedence.java
index 92f3a6e..b2d8a8f 100644
--- a/src/com/android/contacts/TypePrecedence.java
+++ b/src/com/android/contacts/TypePrecedence.java
@@ -16,9 +16,6 @@
package com.android.contacts;
-import com.android.contacts.model.EntityModifier;
-import com.android.contacts.util.Constants;
-
import android.accounts.Account;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Im;
@@ -26,11 +23,14 @@
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
+import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.util.Constants;
+
/**
* This class contains utility functions for determining the precedence of
* different types associated with contact data items.
*
- * @deprecated use {@link EntityModifier#getTypePrecedence} instead, since this
+ * @deprecated use {@link RawContactModifier#getTypePrecedence} instead, since this
* list isn't {@link Account} based.
*/
@Deprecated
diff --git a/src/com/android/contacts/ViewNotificationService.java b/src/com/android/contacts/ViewNotificationService.java
index a85c780..3bc5ed2 100644
--- a/src/com/android/contacts/ViewNotificationService.java
+++ b/src/com/android/contacts/ViewNotificationService.java
@@ -16,8 +16,6 @@
package com.android.contacts;
-import com.android.contacts.ContactLoader.Result;
-
import android.app.Service;
import android.content.Intent;
import android.content.Loader;
@@ -25,6 +23,10 @@
import android.os.IBinder;
import android.util.Log;
+import com.android.contacts.model.Contact;
+import com.android.contacts.model.ContactLoader;
+
+
/**
* Service that sends out a view notification for a contact. At the moment, this is only
* supposed to be used by the Phone app
@@ -41,9 +43,9 @@
// We simply need to start a Loader here. When its done, it will send out the
// View-Notification automatically.
final ContactLoader contactLoader = new ContactLoader(this, intent.getData(), true);
- contactLoader.registerListener(0, new OnLoadCompleteListener<ContactLoader.Result>() {
+ contactLoader.registerListener(0, new OnLoadCompleteListener<Contact>() {
@Override
- public void onLoadComplete(Loader<Result> loader, Result data) {
+ public void onLoadComplete(Loader<Contact> loader, Contact data) {
try {
loader.reset();
} catch (RuntimeException e) {
diff --git a/src/com/android/contacts/activities/ActionBarAdapter.java b/src/com/android/contacts/activities/ActionBarAdapter.java
index 4fc9866..d50c240 100644
--- a/src/com/android/contacts/activities/ActionBarAdapter.java
+++ b/src/com/android/contacts/activities/ActionBarAdapter.java
@@ -16,17 +16,12 @@
package com.android.contacts.activities;
-import com.android.contacts.R;
-import com.android.contacts.activities.ActionBarAdapter.Listener.Action;
-import com.android.contacts.list.ContactsRequest;
-
import android.app.ActionBar;
import android.app.ActionBar.LayoutParams;
import android.app.ActionBar.Tab;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.SharedPreferences;
-import android.graphics.Color;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.TextUtils;
@@ -40,6 +35,10 @@
import android.widget.SearchView.OnQueryTextListener;
import android.widget.TextView;
+import com.android.contacts.R;
+import com.android.contacts.activities.ActionBarAdapter.Listener.Action;
+import com.android.contacts.list.ContactsRequest;
+
/**
* Adapter for the action bar at the top of the Contacts activity.
*/
diff --git a/src/com/android/contacts/activities/AttachPhotoActivity.java b/src/com/android/contacts/activities/AttachPhotoActivity.java
index 9ca9cfd..2f7651f 100644
--- a/src/com/android/contacts/activities/AttachPhotoActivity.java
+++ b/src/com/android/contacts/activities/AttachPhotoActivity.java
@@ -30,15 +30,15 @@
import android.provider.ContactsContract.DisplayPhoto;
import android.util.Log;
-import com.android.contacts.ContactLoader;
-import com.android.contacts.ContactLoader.Result;
import com.android.contacts.ContactSaveService;
import com.android.contacts.ContactsActivity;
import com.android.contacts.ContactsUtils;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDeltaList;
-import com.android.contacts.model.EntityModifier;
+import com.android.contacts.model.Contact;
+import com.android.contacts.model.ContactLoader;
+import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDeltaList;
+import com.android.contacts.model.account.AccountType;
import com.android.contacts.util.ContactPhotoUtils;
import java.io.File;
@@ -131,7 +131,7 @@
} else if (requestCode == REQUEST_CROP_PHOTO) {
loadContact(mContactUri, new Listener() {
@Override
- public void onContactLoaded(ContactLoader.Result contact) {
+ public void onContactLoaded(Contact contact) {
saveContact(contact);
}
});
@@ -144,10 +144,10 @@
// instance, the loader doesn't persist across Activity restarts.
private void loadContact(Uri contactUri, final Listener listener) {
final ContactLoader loader = new ContactLoader(this, contactUri, true);
- loader.registerListener(0, new OnLoadCompleteListener<ContactLoader.Result>() {
+ loader.registerListener(0, new OnLoadCompleteListener<Contact>() {
@Override
public void onLoadComplete(
- Loader<ContactLoader.Result> loader, ContactLoader.Result contact) {
+ Loader<Contact> loader, Contact contact) {
try {
loader.reset();
}
@@ -161,7 +161,7 @@
}
private interface Listener {
- public void onContactLoaded(Result contact);
+ public void onContactLoaded(Contact contact);
}
/**
@@ -170,11 +170,11 @@
* - photo has been cropped
* - contact has been loaded
*/
- private void saveContact(ContactLoader.Result contact) {
+ private void saveContact(Contact contact) {
// Obtain the raw-contact that we will save to.
- EntityDeltaList deltaList = contact.createEntityDeltaList();
- EntityDelta raw = deltaList.getFirstWritableRawContact(this);
+ RawContactDeltaList deltaList = contact.createRawContactDeltaList();
+ RawContactDelta raw = deltaList.getFirstWritableRawContact(this);
if (raw == null) {
Log.w(TAG, "no writable raw-contact found");
return;
@@ -195,13 +195,13 @@
// the ContactSaveService would not create the new contact, and the
// full-res photo would fail to be saved to the non-existent contact.
AccountType account = raw.getRawContactAccountType(this);
- EntityDelta.ValuesDelta values =
- EntityModifier.ensureKindExists(raw, account, Photo.CONTENT_ITEM_TYPE);
+ RawContactDelta.ValuesDelta values =
+ RawContactModifier.ensureKindExists(raw, account, Photo.CONTENT_ITEM_TYPE);
if (values == null) {
Log.w(TAG, "cannot attach photo to this account type");
return;
}
- values.put(Photo.PHOTO, compressed);
+ values.setPhoto(compressed);
// Finally, invoke the ContactSaveService.
Log.v(TAG, "all prerequisites met, about to save photo to contact");
diff --git a/src/com/android/contacts/activities/ConfirmAddDetailActivity.java b/src/com/android/contacts/activities/ConfirmAddDetailActivity.java
index becbf5c..c8adf95 100644
--- a/src/com/android/contacts/activities/ConfirmAddDetailActivity.java
+++ b/src/com/android/contacts/activities/ConfirmAddDetailActivity.java
@@ -16,20 +16,6 @@
package com.android.contacts.activities;
-import com.android.contacts.R;
-import com.android.contacts.editor.Editor;
-import com.android.contacts.editor.ViewIdGenerator;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountWithDataSet;
-import com.android.contacts.model.DataKind;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.model.EntityDeltaList;
-import com.android.contacts.model.EntityModifier;
-import com.android.contacts.util.DialogManager;
-import com.android.contacts.util.EmptyService;
-
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
@@ -38,7 +24,6 @@
import android.content.ContentProviderResult;
import android.content.ContentResolver;
import android.content.ContentUris;
-import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.OperationApplicationException;
@@ -73,6 +58,21 @@
import android.widget.TextView;
import android.widget.Toast;
+import com.android.contacts.R;
+import com.android.contacts.editor.Editor;
+import com.android.contacts.editor.ViewIdGenerator;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.RawContact;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.RawContactDeltaList;
+import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.contacts.util.DialogManager;
+import com.android.contacts.util.EmptyService;
+
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
@@ -124,11 +124,11 @@
private QueryHandler mQueryHandler;
- /** {@link EntityDeltaList} for the entire selected contact. */
- private EntityDeltaList mEntityDeltaList;
+ /** {@link RawContactDeltaList} for the entire selected contact. */
+ private RawContactDeltaList mEntityDeltaList;
- /** {@link EntityDeltaList} for the editable account */
- private EntityDelta mEntityDelta;
+ /** {@link RawContactDeltaList} for the editable account */
+ private RawContactDelta mRawContactDelta;
private String mMimetype = Phone.CONTENT_ITEM_TYPE;
@@ -357,7 +357,7 @@
new String[] { String.valueOf(mContactId) }, null);
}
- private static class QueryEntitiesTask extends AsyncTask<Intent, Void, EntityDeltaList> {
+ private static class QueryEntitiesTask extends AsyncTask<Intent, Void, RawContactDeltaList> {
private ConfirmAddDetailActivity activityTarget;
private String mSelection;
@@ -367,7 +367,7 @@
}
@Override
- protected EntityDeltaList doInBackground(Intent... params) {
+ protected RawContactDeltaList doInBackground(Intent... params) {
final Intent intent = params[0];
@@ -400,7 +400,7 @@
// Note that this query does not need to concern itself with whether the contact is
// the user's profile, since the profile does not show up in the picker.
- return EntityDeltaList.fromQuery(RawContactsEntity.CONTENT_URI,
+ return RawContactDeltaList.fromQuery(RawContactsEntity.CONTENT_URI,
activityTarget.getContentResolver(), mSelection,
new String[] { selectionArg }, null);
}
@@ -425,7 +425,7 @@
}
@Override
- protected void onPostExecute(EntityDeltaList entityList) {
+ protected void onPostExecute(RawContactDeltaList entityList) {
if (activityTarget.isFinishing()) {
return;
}
@@ -567,7 +567,7 @@
}
}
- private void setEntityDeltaList(EntityDeltaList entityList) {
+ private void setEntityDeltaList(RawContactDeltaList entityList) {
if (entityList == null) {
throw new IllegalStateException();
}
@@ -578,31 +578,33 @@
mEntityDeltaList = entityList;
// Find the editable raw_contact.
- mEntityDelta = mEntityDeltaList.getFirstWritableRawContact(this);
+ mRawContactDelta = mEntityDeltaList.getFirstWritableRawContact(this);
// If no editable raw_contacts are found, create one.
- if (mEntityDelta == null) {
- mEntityDelta = addEditableRawContact(this, mEntityDeltaList);
+ if (mRawContactDelta == null) {
+ mRawContactDelta = addEditableRawContact(this, mEntityDeltaList);
- if ((mEntityDelta != null) && VERBOSE_LOGGING) {
+ if ((mRawContactDelta != null) && VERBOSE_LOGGING) {
Log.v(TAG, "setEntityDeltaList: created editable raw_contact " + entityList);
}
}
- if (mEntityDelta == null) {
+ if (mRawContactDelta == null) {
// Selected contact is read-only, and there's no editable account.
mIsReadOnly = true;
mEditableAccountType = null;
} else {
mIsReadOnly = false;
- mEditableAccountType = mEntityDelta.getRawContactAccountType(this);
+ mEditableAccountType = mRawContactDelta.getRawContactAccountType(this);
// Handle any incoming values that should be inserted
final Bundle extras = getIntent().getExtras();
if (extras != null && extras.size() > 0) {
- // If there are any intent extras, add them as additional fields in the EntityDelta.
- EntityModifier.parseExtras(this, mEditableAccountType, mEntityDelta, extras);
+ // If there are any intent extras, add them as additional fields in the
+ // RawContactDelta.
+ RawContactModifier.parseExtras(this, mEditableAccountType, mRawContactDelta,
+ extras);
}
}
@@ -610,12 +612,12 @@
}
/**
- * Create an {@link EntityDelta} for a raw_contact on the first editable account found, and add
+ * Create an {@link RawContactDelta} for a raw_contact on the first editable account found, and add
* to the list. Also copy the structured name from an existing (read-only) raw_contact to the
* new one, if any of the read-only contacts has a name.
*/
- private static EntityDelta addEditableRawContact(Context context,
- EntityDeltaList entityDeltaList) {
+ private static RawContactDelta addEditableRawContact(Context context,
+ RawContactDeltaList entityDeltaList) {
// First, see if there's an editable account.
final AccountTypeManager accounts = AccountTypeManager.getInstance(context);
final List<AccountWithDataSet> editableAccounts = accounts.getAccounts(true);
@@ -627,44 +629,29 @@
final AccountType accountType = accounts.getAccountType(
editableAccount.type, editableAccount.dataSet);
- // Create a new EntityDelta for the new raw_contact.
- final ContentValues values = new ContentValues();
- values.put(RawContacts.ACCOUNT_NAME, editableAccount.name);
- values.put(RawContacts.ACCOUNT_TYPE, editableAccount.type);
- values.put(RawContacts.DATA_SET, editableAccount.dataSet);
+ // Create a new RawContactDelta for the new raw_contact.
+ final RawContact rawContact = new RawContact(context);
+ rawContact.setAccount(editableAccount);
- final EntityDelta entityDelta = new EntityDelta(ValuesDelta.fromAfter(values));
+ final RawContactDelta entityDelta = new RawContactDelta(ValuesDelta.fromAfter(
+ rawContact.getValues()));
// Then, copy the structure name from an existing (read-only) raw_contact.
- for (EntityDelta entity : entityDeltaList) {
+ for (RawContactDelta entity : entityDeltaList) {
final ArrayList<ValuesDelta> readOnlyNames =
entity.getMimeEntries(StructuredName.CONTENT_ITEM_TYPE);
if ((readOnlyNames != null) && (readOnlyNames.size() > 0)) {
final ValuesDelta readOnlyName = readOnlyNames.get(0);
-
- final ValuesDelta newName = EntityModifier.ensureKindExists(entityDelta,
+ final ValuesDelta newName = RawContactModifier.ensureKindExists(entityDelta,
accountType, StructuredName.CONTENT_ITEM_TYPE);
// Copy all the data fields.
- newName.copyStringFrom(readOnlyName, StructuredName.DISPLAY_NAME);
-
- newName.copyStringFrom(readOnlyName, StructuredName.GIVEN_NAME);
- newName.copyStringFrom(readOnlyName, StructuredName.FAMILY_NAME);
- newName.copyStringFrom(readOnlyName, StructuredName.PREFIX);
- newName.copyStringFrom(readOnlyName, StructuredName.MIDDLE_NAME);
- newName.copyStringFrom(readOnlyName, StructuredName.SUFFIX);
-
- newName.copyStringFrom(readOnlyName, StructuredName.PHONETIC_GIVEN_NAME);
- newName.copyStringFrom(readOnlyName, StructuredName.PHONETIC_MIDDLE_NAME);
- newName.copyStringFrom(readOnlyName, StructuredName.PHONETIC_FAMILY_NAME);
-
- newName.copyStringFrom(readOnlyName, StructuredName.FULL_NAME_STYLE);
- newName.copyStringFrom(readOnlyName, StructuredName.PHONETIC_NAME_STYLE);
+ newName.copyStructuredNameFieldsFrom(readOnlyName);
break;
}
}
- // Add the new EntityDelta to the list.
+ // Add the new RawContactDelta to the list.
entityDeltaList.add(entityDelta);
return entityDelta;
@@ -695,11 +682,11 @@
// Skip kind that are not editable
if (!kind.editable) continue;
if (mMimetype.equals(kind.mimeType)) {
- for (ValuesDelta valuesDelta : mEntityDelta.getMimeEntries(mMimetype)) {
+ for (ValuesDelta valuesDelta : mRawContactDelta.getMimeEntries(mMimetype)) {
// Skip entries that aren't visible
if (!valuesDelta.isVisible()) continue;
if (valuesDelta.isInsert()) {
- inflateEditorView(kind, valuesDelta, mEntityDelta);
+ inflateEditorView(kind, valuesDelta, mRawContactDelta);
return;
}
}
@@ -712,7 +699,7 @@
* the views corresponding to the the object-model. The resulting EditorView is also added
* to the end of mEditors
*/
- private void inflateEditorView(DataKind dataKind, ValuesDelta valuesDelta, EntityDelta state) {
+ private void inflateEditorView(DataKind dataKind, ValuesDelta valuesDelta, RawContactDelta state) {
final View view = mInflater.inflate(dataKind.editorLayoutResourceId, mEditorContainerView,
false);
@@ -765,11 +752,11 @@
/**
* Background task for persisting edited contact data, using the changes
- * defined by a set of {@link EntityDelta}. This task starts
+ * defined by a set of {@link RawContactDelta}. This task starts
* {@link EmptyService} to make sure the background thread can finish
* persisting in cases where the system wants to reclaim our process.
*/
- private static class PersistTask extends AsyncTask<EntityDeltaList, Void, Integer> {
+ private static class PersistTask extends AsyncTask<RawContactDeltaList, Void, Integer> {
// In the future, use ContactSaver instead of WeakAsyncTask because of
// the danger of the activity being null during a save action
private static final int PERSIST_TRIES = 3;
@@ -799,18 +786,18 @@
}
@Override
- protected Integer doInBackground(EntityDeltaList... params) {
+ protected Integer doInBackground(RawContactDeltaList... params) {
final Context context = activityTarget;
final ContentResolver resolver = context.getContentResolver();
- EntityDeltaList state = params[0];
+ RawContactDeltaList state = params[0];
if (state == null) {
return RESULT_FAILURE;
}
// Trim any empty fields, and RawContacts, before persisting
- EntityModifier.trimEmpty(state, mAccountTypeManager);
+ RawContactModifier.trimEmpty(state, mAccountTypeManager);
// Attempt to persist changes
int tries = 0;
@@ -898,4 +885,4 @@
}
finish();
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/contacts/activities/ContactDetailActivity.java b/src/com/android/contacts/activities/ContactDetailActivity.java
index d656fdb..b03a976 100644
--- a/src/com/android/contacts/activities/ContactDetailActivity.java
+++ b/src/com/android/contacts/activities/ContactDetailActivity.java
@@ -16,23 +16,11 @@
package com.android.contacts.activities;
-import com.android.contacts.ContactLoader;
-import com.android.contacts.ContactSaveService;
-import com.android.contacts.ContactsActivity;
-import com.android.contacts.R;
-import com.android.contacts.detail.ContactDetailDisplayUtils;
-import com.android.contacts.detail.ContactDetailFragment;
-import com.android.contacts.detail.ContactDetailLayoutController;
-import com.android.contacts.detail.ContactLoaderFragment;
-import com.android.contacts.detail.ContactLoaderFragment.ContactLoaderFragmentListener;
-import com.android.contacts.interactions.ContactDeletionInteraction;
-import com.android.contacts.model.AccountWithDataSet;
-import com.android.contacts.util.PhoneCapabilityTester;
-
import android.app.ActionBar;
import android.app.Fragment;
import android.content.ActivityNotFoundException;
import android.content.ContentValues;
+import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
@@ -49,6 +37,19 @@
import android.view.accessibility.AccessibilityManager;
import android.widget.Toast;
+import com.android.contacts.ContactSaveService;
+import com.android.contacts.ContactsActivity;
+import com.android.contacts.R;
+import com.android.contacts.detail.ContactDetailDisplayUtils;
+import com.android.contacts.detail.ContactDetailFragment;
+import com.android.contacts.detail.ContactDetailLayoutController;
+import com.android.contacts.detail.ContactLoaderFragment;
+import com.android.contacts.detail.ContactLoaderFragment.ContactLoaderFragmentListener;
+import com.android.contacts.interactions.ContactDeletionInteraction;
+import com.android.contacts.model.Contact;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.util.PhoneCapabilityTester;
+
import java.util.ArrayList;
public class ContactDetailActivity extends ContactsActivity {
@@ -57,7 +58,7 @@
/** Shows a toogle button for hiding/showing updates. Don't submit with true */
private static final boolean DEBUG_TRANSITIONS = false;
- private ContactLoader.Result mContactData;
+ private Contact mContactData;
private Uri mLookupUri;
private ContactDetailLayoutController mContactDetailLayoutController;
@@ -208,7 +209,7 @@
}
@Override
- public void onDetailsLoaded(final ContactLoader.Result result) {
+ public void onDetailsLoaded(final Contact result) {
if (result == null) {
return;
}
@@ -259,11 +260,14 @@
actionBar.setTitle(displayName);
actionBar.setSubtitle(company);
- if (!TextUtils.isEmpty(displayName) &&
- AccessibilityManager.getInstance(this).isEnabled()) {
- View decorView = getWindow().getDecorView();
- decorView.setContentDescription(displayName);
- decorView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+ if (!TextUtils.isEmpty(displayName)) {
+ AccessibilityManager accessibilityManager =
+ (AccessibilityManager) this.getSystemService(Context.ACCESSIBILITY_SERVICE);
+ if (accessibilityManager.isEnabled()) {
+ View decorView = getWindow().getDecorView();
+ decorView.setContentDescription(displayName);
+ decorView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+ }
}
}
diff --git a/src/com/android/contacts/activities/ContactEditorAccountsChangedActivity.java b/src/com/android/contacts/activities/ContactEditorAccountsChangedActivity.java
index 3e2a893..f5852e5 100644
--- a/src/com/android/contacts/activities/ContactEditorAccountsChangedActivity.java
+++ b/src/com/android/contacts/activities/ContactEditorAccountsChangedActivity.java
@@ -31,7 +31,7 @@
import com.android.contacts.R;
import com.android.contacts.editor.ContactEditorUtils;
import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountWithDataSet;
+import com.android.contacts.model.account.AccountWithDataSet;
import com.android.contacts.util.AccountsListAdapter;
import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
diff --git a/src/com/android/contacts/activities/ContactEditorActivity.java b/src/com/android/contacts/activities/ContactEditorActivity.java
index 9dde2dd..77ed857 100644
--- a/src/com/android/contacts/activities/ContactEditorActivity.java
+++ b/src/com/android/contacts/activities/ContactEditorActivity.java
@@ -16,16 +16,6 @@
package com.android.contacts.activities;
-import com.android.contacts.ContactSaveService;
-import com.android.contacts.ContactsActivity;
-import com.android.contacts.R;
-import com.android.contacts.editor.ContactEditorFragment;
-import com.android.contacts.editor.ContactEditorFragment.SaveMode;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountWithDataSet;
-import com.android.contacts.util.DialogManager;
-
import android.app.ActionBar;
import android.app.Dialog;
import android.content.ContentValues;
@@ -41,6 +31,16 @@
import android.view.View;
import android.view.View.OnClickListener;
+import com.android.contacts.ContactSaveService;
+import com.android.contacts.ContactsActivity;
+import com.android.contacts.R;
+import com.android.contacts.editor.ContactEditorFragment;
+import com.android.contacts.editor.ContactEditorFragment.SaveMode;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.util.DialogManager;
+
import java.util.ArrayList;
public class ContactEditorActivity extends ContactsActivity
diff --git a/src/com/android/contacts/activities/ContactSelectionActivity.java b/src/com/android/contacts/activities/ContactSelectionActivity.java
index 0db3a0c..c60a228 100644
--- a/src/com/android/contacts/activities/ContactSelectionActivity.java
+++ b/src/com/android/contacts/activities/ContactSelectionActivity.java
@@ -16,23 +16,6 @@
package com.android.contacts.activities;
-import com.android.contacts.ContactsActivity;
-import com.android.contacts.R;
-import com.android.contacts.list.ContactEntryListFragment;
-import com.android.contacts.list.ContactPickerFragment;
-import com.android.contacts.list.ContactsIntentResolver;
-import com.android.contacts.list.ContactsRequest;
-import com.android.contacts.list.DirectoryListLoader;
-import com.android.contacts.list.EmailAddressPickerFragment;
-import com.android.contacts.list.OnContactPickerActionListener;
-import com.android.contacts.list.OnEmailAddressPickerActionListener;
-import com.android.contacts.list.OnPhoneNumberPickerActionListener;
-import com.android.contacts.list.OnPostalAddressPickerActionListener;
-import com.android.contacts.list.PhoneNumberPickerFragment;
-import com.android.contacts.list.PostalAddressPickerFragment;
-import com.android.contacts.widget.ContextMenuAdapter;
-import com.google.android.collect.Sets;
-
import android.app.ActionBar;
import android.app.ActionBar.LayoutParams;
import android.app.Activity;
@@ -53,11 +36,27 @@
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.inputmethod.InputMethodManager;
-import android.widget.Button;
import android.widget.SearchView;
import android.widget.SearchView.OnCloseListener;
import android.widget.SearchView.OnQueryTextListener;
+import com.android.contacts.ContactsActivity;
+import com.android.contacts.R;
+import com.android.contacts.list.ContactEntryListFragment;
+import com.android.contacts.list.ContactPickerFragment;
+import com.android.contacts.list.ContactsIntentResolver;
+import com.android.contacts.list.ContactsRequest;
+import com.android.contacts.list.DirectoryListLoader;
+import com.android.contacts.list.EmailAddressPickerFragment;
+import com.android.contacts.list.OnContactPickerActionListener;
+import com.android.contacts.list.OnEmailAddressPickerActionListener;
+import com.android.contacts.list.OnPhoneNumberPickerActionListener;
+import com.android.contacts.list.OnPostalAddressPickerActionListener;
+import com.android.contacts.list.PhoneNumberPickerFragment;
+import com.android.contacts.list.PostalAddressPickerFragment;
+import com.android.contacts.widget.ContextMenuAdapter;
+import com.google.common.collect.Sets;
+
import java.util.Set;
/**
diff --git a/src/com/android/contacts/activities/DialtactsActivity.java b/src/com/android/contacts/activities/DialtactsActivity.java
index b5b0a63..b71f15a 100644
--- a/src/com/android/contacts/activities/DialtactsActivity.java
+++ b/src/com/android/contacts/activities/DialtactsActivity.java
@@ -16,21 +16,6 @@
package com.android.contacts.activities;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.R;
-import com.android.contacts.calllog.CallLogFragment;
-import com.android.contacts.dialpad.DialpadFragment;
-import com.android.contacts.interactions.PhoneNumberInteraction;
-import com.android.contacts.list.ContactListFilterController;
-import com.android.contacts.list.ContactListFilterController.ContactListFilterListener;
-import com.android.contacts.list.ContactListItemView;
-import com.android.contacts.list.OnPhoneNumberPickerActionListener;
-import com.android.contacts.list.PhoneFavoriteFragment;
-import com.android.contacts.list.PhoneNumberPickerFragment;
-import com.android.contacts.util.AccountFilterUtil;
-import com.android.contacts.util.Constants;
-import com.android.internal.telephony.ITelephony;
-
import android.app.ActionBar;
import android.app.ActionBar.LayoutParams;
import android.app.ActionBar.Tab;
@@ -71,6 +56,21 @@
import android.widget.SearchView.OnCloseListener;
import android.widget.SearchView.OnQueryTextListener;
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.R;
+import com.android.contacts.calllog.CallLogFragment;
+import com.android.contacts.dialpad.DialpadFragment;
+import com.android.contacts.interactions.PhoneNumberInteraction;
+import com.android.contacts.list.ContactListFilterController;
+import com.android.contacts.list.ContactListFilterController.ContactListFilterListener;
+import com.android.contacts.list.ContactListItemView;
+import com.android.contacts.list.OnPhoneNumberPickerActionListener;
+import com.android.contacts.list.PhoneFavoriteFragment;
+import com.android.contacts.list.PhoneNumberPickerFragment;
+import com.android.contacts.util.AccountFilterUtil;
+import com.android.contacts.util.Constants;
+import com.android.internal.telephony.ITelephony;
+
/**
* The dialer activity that has one tab with the virtual 12key
* dialer, a tab with recent calls in it, a tab with the contacts and
@@ -751,7 +751,8 @@
}
/**
- * Returns true if the intent is due to hitting the green send key while in a call.
+ * Returns true if the intent is due to hitting the green send key (hardware call button:
+ * KEYCODE_CALL) while in a call.
*
* @param intent the intent that launched this activity
* @param recentCallsRequest true if the intent is requesting to view recent calls
@@ -783,7 +784,8 @@
*/
private void setCurrentTab(Intent intent) {
// If we got here by hitting send and we're in call forward along to the in-call activity
- final boolean recentCallsRequest = Calls.CONTENT_TYPE.equals(intent.getType());
+ boolean recentCallsRequest = Calls.CONTENT_TYPE.equals(intent.resolveType(
+ getContentResolver()));
if (isSendKeyWhileInCall(intent, recentCallsRequest)) {
finish();
return;
diff --git a/src/com/android/contacts/activities/GroupBrowserActivity.java b/src/com/android/contacts/activities/GroupBrowserActivity.java
index e8b3ad8..3d3af3f 100644
--- a/src/com/android/contacts/activities/GroupBrowserActivity.java
+++ b/src/com/android/contacts/activities/GroupBrowserActivity.java
@@ -16,12 +16,12 @@
package com.android.contacts.activities;
-import com.android.contacts.ContactsActivity;
-import com.android.contacts.R;
-
import android.content.Intent;
import android.os.Bundle;
+import com.android.contacts.ContactsActivity;
+import com.android.contacts.R;
+
/**
* Displays a list to browse groups.
*/
diff --git a/src/com/android/contacts/activities/GroupDetailActivity.java b/src/com/android/contacts/activities/GroupDetailActivity.java
index e49789e..492a2ff 100644
--- a/src/com/android/contacts/activities/GroupDetailActivity.java
+++ b/src/com/android/contacts/activities/GroupDetailActivity.java
@@ -16,13 +16,6 @@
package com.android.contacts.activities;
-import com.android.contacts.ContactsActivity;
-import com.android.contacts.R;
-import com.android.contacts.group.GroupDetailDisplayUtils;
-import com.android.contacts.group.GroupDetailFragment;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-
import android.app.ActionBar;
import android.content.ContentUris;
import android.content.Intent;
@@ -36,6 +29,13 @@
import android.view.View;
import android.view.View.OnClickListener;
+import com.android.contacts.ContactsActivity;
+import com.android.contacts.R;
+import com.android.contacts.group.GroupDetailDisplayUtils;
+import com.android.contacts.group.GroupDetailFragment;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountType;
+
public class GroupDetailActivity extends ContactsActivity {
private static final String TAG = "GroupDetailActivity";
diff --git a/src/com/android/contacts/activities/GroupEditorActivity.java b/src/com/android/contacts/activities/GroupEditorActivity.java
index f3255bf..ff9301b 100644
--- a/src/com/android/contacts/activities/GroupEditorActivity.java
+++ b/src/com/android/contacts/activities/GroupEditorActivity.java
@@ -16,12 +16,6 @@
package com.android.contacts.activities;
-import com.android.contacts.ContactsActivity;
-import com.android.contacts.R;
-import com.android.contacts.group.GroupEditorFragment;
-import com.android.contacts.util.DialogManager;
-import com.android.contacts.util.PhoneCapabilityTester;
-
import android.app.ActionBar;
import android.app.Dialog;
import android.content.Context;
@@ -33,6 +27,12 @@
import android.view.View;
import android.view.View.OnClickListener;
+import com.android.contacts.ContactsActivity;
+import com.android.contacts.R;
+import com.android.contacts.group.GroupEditorFragment;
+import com.android.contacts.util.DialogManager;
+import com.android.contacts.util.PhoneCapabilityTester;
+
public class GroupEditorActivity extends ContactsActivity
implements DialogManager.DialogShowingViewActivity {
diff --git a/src/com/android/contacts/activities/JoinContactActivity.java b/src/com/android/contacts/activities/JoinContactActivity.java
index 4a277cb..a580165 100644
--- a/src/com/android/contacts/activities/JoinContactActivity.java
+++ b/src/com/android/contacts/activities/JoinContactActivity.java
@@ -17,12 +17,6 @@
package com.android.contacts.activities;
-import com.android.contacts.ContactsActivity;
-import com.android.contacts.R;
-import com.android.contacts.list.ContactEntryListFragment;
-import com.android.contacts.list.JoinContactListFragment;
-import com.android.contacts.list.OnContactPickerActionListener;
-
import android.app.ActionBar;
import android.app.ActionBar.LayoutParams;
import android.app.Fragment;
@@ -42,6 +36,12 @@
import android.widget.SearchView.OnCloseListener;
import android.widget.SearchView.OnQueryTextListener;
+import com.android.contacts.ContactsActivity;
+import com.android.contacts.R;
+import com.android.contacts.list.ContactEntryListFragment;
+import com.android.contacts.list.JoinContactListFragment;
+import com.android.contacts.list.OnContactPickerActionListener;
+
/**
* An activity that shows a list of contacts that can be joined with the target contact.
*/
diff --git a/src/com/android/contacts/activities/NonPhoneActivity.java b/src/com/android/contacts/activities/NonPhoneActivity.java
index 47ae020..fc22146 100644
--- a/src/com/android/contacts/activities/NonPhoneActivity.java
+++ b/src/com/android/contacts/activities/NonPhoneActivity.java
@@ -16,10 +16,6 @@
package com.android.contacts.activities;
-import com.android.contacts.ContactsActivity;
-import com.android.contacts.R;
-import com.android.contacts.util.Constants;
-
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -33,11 +29,18 @@
import android.provider.ContactsContract.Intents.Insert;
import android.text.TextUtils;
+import com.android.contacts.ContactsActivity;
+import com.android.contacts.R;
+import com.android.contacts.util.Constants;
+
/**
* Activity that intercepts DIAL and VIEW intents for phone numbers for devices that can not
* be used as a phone. This allows the user to see the phone number
*/
public class NonPhoneActivity extends ContactsActivity {
+
+ private static final String PHONE_NUMBER_KEY = "PHONE_NUMBER";
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -48,7 +51,9 @@
}
final NonPhoneDialogFragment fragment = new NonPhoneDialogFragment();
- fragment.setArguments(Bundle.forPair("PHONE_NUMBER", phoneNumber));
+ Bundle bundle = new Bundle();
+ bundle.putString(PHONE_NUMBER_KEY, phoneNumber);
+ fragment.setArguments(bundle);
getFragmentManager().beginTransaction().add(fragment, "Fragment").commitAllowingStateLoss();
}
@@ -89,7 +94,7 @@
}
private String getArgumentPhoneNumber() {
- return getArguments().getPairValue();
+ return getArguments().getString(PHONE_NUMBER_KEY);
}
@Override
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index d1b493f..b811dd9 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -16,7 +16,37 @@
package com.android.contacts.activities;
-import com.android.contacts.ContactLoader;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.content.ActivityNotFoundException;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Parcelable;
+import android.preference.PreferenceActivity;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.ProviderStatus;
+import android.provider.ContactsContract.QuickContact;
+import android.provider.Settings;
+import android.support.v13.app.FragmentPagerAdapter;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.util.Log;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.MenuItem.OnMenuItemClickListener;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Toast;
+
import com.android.contacts.ContactSaveService;
import com.android.contacts.ContactsActivity;
import com.android.contacts.ContactsUtils;
@@ -50,7 +80,8 @@
import com.android.contacts.list.OnContactsUnavailableActionListener;
import com.android.contacts.list.ProviderStatusWatcher;
import com.android.contacts.list.ProviderStatusWatcher.ProviderStatusListener;
-import com.android.contacts.model.AccountWithDataSet;
+import com.android.contacts.model.Contact;
+import com.android.contacts.model.account.AccountWithDataSet;
import com.android.contacts.preference.ContactsPreferenceActivity;
import com.android.contacts.preference.DisplayOptionsPreferenceFragment;
import com.android.contacts.util.AccountFilterUtil;
@@ -62,37 +93,6 @@
import com.android.contacts.util.UriUtils;
import com.android.contacts.widget.TransitionAnimationView;
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
-import android.content.ActivityNotFoundException;
-import android.content.ContentValues;
-import android.content.Intent;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Parcelable;
-import android.preference.PreferenceActivity;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.ProviderStatus;
-import android.provider.ContactsContract.QuickContact;
-import android.provider.Settings;
-import android.support.v13.app.FragmentPagerAdapter;
-import android.support.v4.view.PagerAdapter;
-import android.support.v4.view.ViewPager;
-import android.util.Log;
-import android.view.KeyCharacterMap;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.MenuItem.OnMenuItemClickListener;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Toast;
-
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
@@ -110,6 +110,8 @@
/** Shows a toogle button for hiding/showing updates. Don't submit with true */
private static final boolean DEBUG_TRANSITIONS = false;
+ private static final String ENABLE_DEBUG_OPTIONS_HIDDEN_CODE = "debug debug!";
+
// These values needs to start at 2. See {@link ContactEntryListFragment}.
private static final int SUBACTIVITY_NEW_CONTACT = 2;
private static final int SUBACTIVITY_EDIT_CONTACT = 3;
@@ -165,6 +167,8 @@
private ContactDetailLayoutController mContactDetailLayoutController;
+ private boolean mEnableDebugMenuOptions;
+
private final Handler mHandler = new Handler();
/**
@@ -631,7 +635,10 @@
invalidateOptionsMenu();
break;
case ActionBarAdapter.Listener.Action.CHANGE_SEARCH_QUERY:
- setQueryTextToFragment(mActionBarAdapter.getQueryString());
+ final String queryString = mActionBarAdapter.getQueryString();
+ setQueryTextToFragment(queryString);
+ updateDebugOptionsVisibility(
+ ENABLE_DEBUG_OPTIONS_HIDDEN_CODE.equals(queryString));
break;
default:
throw new IllegalStateException("Unkonwn ActionBarAdapter action: " + action);
@@ -643,6 +650,13 @@
updateFragmentsVisibility();
}
+ private void updateDebugOptionsVisibility(boolean visible) {
+ if (mEnableDebugMenuOptions != visible) {
+ mEnableDebugMenuOptions = visible;
+ invalidateOptionsMenu();
+ }
+ }
+
/**
* Updates the fragment/view visibility according to the current mode, such as
* {@link ActionBarAdapter#isSearchMode()} and {@link ActionBarAdapter#getCurrentTab()}.
@@ -1162,7 +1176,7 @@
}
@Override
- public void onDetailsLoaded(final ContactLoader.Result result) {
+ public void onDetailsLoaded(final Contact result) {
if (result == null) {
// Nothing is loaded. Show empty state.
mContactDetailLayoutController.showEmptyState();
@@ -1449,6 +1463,9 @@
makeMenuItemVisible(menu, R.id.menu_settings,
showMiscOptions && !ContactsPreferenceActivity.isEmpty(this));
+ // Debug options need to be visible even in search mode.
+ makeMenuItemVisible(menu, R.id.export_database, mEnableDebugMenuOptions);
+
return true;
}
@@ -1545,6 +1562,12 @@
startActivity(intent);
return true;
}
+ case R.id.export_database: {
+ final Intent intent = new Intent("com.android.providers.contacts.DUMP_DATABASE");
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+ startActivity(intent);
+ return true;
+ }
}
return false;
}
diff --git a/src/com/android/contacts/activities/PhotoSelectionActivity.java b/src/com/android/contacts/activities/PhotoSelectionActivity.java
index 21cf192..6f3da00 100644
--- a/src/com/android/contacts/activities/PhotoSelectionActivity.java
+++ b/src/com/android/contacts/activities/PhotoSelectionActivity.java
@@ -15,15 +15,6 @@
*/
package com.android.contacts.activities;
-import com.android.contacts.ContactPhotoManager;
-import com.android.contacts.ContactSaveService;
-import com.android.contacts.R;
-import com.android.contacts.detail.PhotoSelectionHandler;
-import com.android.contacts.editor.PhotoActionPopup;
-import com.android.contacts.model.EntityDeltaList;
-import com.android.contacts.util.ContactPhotoUtils;
-import com.android.contacts.util.SchedulingUtils;
-
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
@@ -42,6 +33,15 @@
import android.widget.FrameLayout.LayoutParams;
import android.widget.ImageView;
+import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.ContactSaveService;
+import com.android.contacts.R;
+import com.android.contacts.detail.PhotoSelectionHandler;
+import com.android.contacts.editor.PhotoActionPopup;
+import com.android.contacts.model.RawContactDeltaList;
+import com.android.contacts.util.ContactPhotoUtils;
+import com.android.contacts.util.SchedulingUtils;
+
/**
* Popup activity for choosing a contact photo within the Contacts app.
@@ -93,7 +93,7 @@
private Uri mPhotoUri;
/** Entity delta list of the contact. */
- private EntityDeltaList mState;
+ private RawContactDeltaList mState;
/** Whether the contact is the user's profile. */
private boolean mIsProfile;
@@ -167,7 +167,7 @@
// Pull data out of the intent.
final Intent intent = getIntent();
mPhotoUri = intent.getParcelableExtra(PHOTO_URI);
- mState = (EntityDeltaList) intent.getParcelableExtra(ENTITY_DELTA_LIST);
+ mState = (RawContactDeltaList) intent.getParcelableExtra(ENTITY_DELTA_LIST);
mIsProfile = intent.getBooleanExtra(IS_PROFILE, false);
mIsDirectoryContact = intent.getBooleanExtra(IS_DIRECTORY_CONTACT, false);
mExpandPhoto = intent.getBooleanExtra(EXPAND_PHOTO, false);
@@ -268,7 +268,7 @@
* @return An intent that can be used to invoke the photo selection activity.
*/
public static Intent buildIntent(Context context, Uri photoUri, Bitmap photoBitmap,
- byte[] photoBytes, Rect photoBounds, EntityDeltaList delta, boolean isProfile,
+ byte[] photoBytes, Rect photoBounds, RawContactDeltaList delta, boolean isProfile,
boolean isDirectoryContact, boolean expandPhotoOnClick) {
Intent intent = new Intent(context, PhotoSelectionActivity.class);
if (photoUri != null && photoBitmap != null && photoBytes != null) {
@@ -515,7 +515,7 @@
private final PhotoActionListener mListener;
private PhotoHandler(
- Context context, View photoView, int photoMode, EntityDeltaList state) {
+ Context context, View photoView, int photoMode, RawContactDeltaList state) {
super(context, photoView, photoMode, PhotoSelectionActivity.this.mIsDirectoryContact,
state);
mListener = new PhotoListener();
@@ -536,7 +536,7 @@
private final class PhotoListener extends PhotoActionListener {
@Override
public void onPhotoSelected(Bitmap bitmap) {
- EntityDeltaList delta = getDeltaForAttachingPhotoToContact();
+ RawContactDeltaList delta = getDeltaForAttachingPhotoToContact();
long rawContactId = getWritableEntityId();
final String croppedPath = ContactPhotoUtils.pathForCroppedPhoto(
PhotoSelectionActivity.this, mCurrentPhotoFile);
diff --git a/src/com/android/contacts/activities/ShowOrCreateActivity.java b/src/com/android/contacts/activities/ShowOrCreateActivity.java
index 2efd6ba..1dc0197 100755
--- a/src/com/android/contacts/activities/ShowOrCreateActivity.java
+++ b/src/com/android/contacts/activities/ShowOrCreateActivity.java
@@ -16,11 +16,6 @@
package com.android.contacts.activities;
-import com.android.contacts.ContactsActivity;
-import com.android.contacts.R;
-import com.android.contacts.util.Constants;
-import com.android.contacts.util.NotifyingAsyncQueryHandler;
-
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -37,6 +32,11 @@
import android.provider.ContactsContract.RawContacts;
import android.util.Log;
+import com.android.contacts.ContactsActivity;
+import com.android.contacts.R;
+import com.android.contacts.util.Constants;
+import com.android.contacts.util.NotifyingAsyncQueryHandler;
+
/**
* Handle several edge cases around showing or possibly creating contacts in
* connected with a specific E-mail address or phone number. Will search based
diff --git a/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java b/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java
index 7b6ae63..9183208 100644
--- a/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java
+++ b/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java
@@ -16,9 +16,6 @@
package com.android.contacts.calllog;
-import com.android.contacts.PhoneCallDetails;
-import com.android.contacts.R;
-
import android.content.Context;
import android.provider.CallLog.Calls;
import android.text.format.DateUtils;
@@ -28,6 +25,9 @@
import android.widget.BaseAdapter;
import android.widget.TextView;
+import com.android.contacts.PhoneCallDetails;
+import com.android.contacts.R;
+
/**
* Adapter for a ListView containing history items from the details of a call.
*/
diff --git a/src/com/android/contacts/calllog/CallLogAdapter.java b/src/com/android/contacts/calllog/CallLogAdapter.java
index 2275a3d..3688dca 100644
--- a/src/com/android/contacts/calllog/CallLogAdapter.java
+++ b/src/com/android/contacts/calllog/CallLogAdapter.java
@@ -16,15 +16,6 @@
package com.android.contacts.calllog;
-import com.android.common.widget.GroupingListAdapter;
-import com.android.contacts.ContactPhotoManager;
-import com.android.contacts.PhoneCallDetails;
-import com.android.contacts.PhoneCallDetailsHelper;
-import com.android.contacts.R;
-import com.android.contacts.util.ExpirableCache;
-import com.android.contacts.util.UriUtils;
-import com.google.common.annotations.VisibleForTesting;
-
import android.content.ContentValues;
import android.content.Context;
import android.content.res.Resources;
@@ -40,9 +31,17 @@
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
-import java.util.LinkedList;
+import com.android.common.widget.GroupingListAdapter;
+import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.PhoneCallDetails;
+import com.android.contacts.PhoneCallDetailsHelper;
+import com.android.contacts.R;
+import com.android.contacts.util.ExpirableCache;
+import com.android.contacts.util.UriUtils;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Objects;
-import libcore.util.Objects;
+import java.util.LinkedList;
/**
* Adapter class to fill in data for the Call Log.
diff --git a/src/com/android/contacts/calllog/CallLogFragment.java b/src/com/android/contacts/calllog/CallLogFragment.java
index fcd1780..f9d21c0 100644
--- a/src/com/android/contacts/calllog/CallLogFragment.java
+++ b/src/com/android/contacts/calllog/CallLogFragment.java
@@ -16,23 +16,12 @@
package com.android.contacts.calllog;
-import com.android.common.io.MoreCloseables;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.R;
-import com.android.contacts.util.Constants;
-import com.android.contacts.util.EmptyLoader;
-import com.android.contacts.voicemail.VoicemailStatusHelper;
-import com.android.contacts.voicemail.VoicemailStatusHelper.StatusMessage;
-import com.android.contacts.voicemail.VoicemailStatusHelperImpl;
-import com.android.internal.telephony.CallerInfo;
-import com.android.internal.telephony.ITelephony;
-import com.google.common.annotations.VisibleForTesting;
-
import android.app.Activity;
import android.app.KeyguardManager;
import android.app.ListFragment;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
@@ -40,9 +29,10 @@
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.preference.PreferenceManager;
import android.provider.CallLog;
-import android.provider.ContactsContract;
import android.provider.CallLog.Calls;
+import android.provider.ContactsContract;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.util.Log;
@@ -55,6 +45,18 @@
import android.widget.ListView;
import android.widget.TextView;
+import com.android.common.io.MoreCloseables;
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.R;
+import com.android.contacts.util.Constants;
+import com.android.contacts.util.EmptyLoader;
+import com.android.contacts.voicemail.VoicemailStatusHelper;
+import com.android.contacts.voicemail.VoicemailStatusHelper.StatusMessage;
+import com.android.contacts.voicemail.VoicemailStatusHelperImpl;
+import com.android.internal.telephony.CallerInfo;
+import com.android.internal.telephony.ITelephony;
+import com.google.common.annotations.VisibleForTesting;
+
import java.util.List;
/**
@@ -69,6 +71,8 @@
*/
private static final int EMPTY_LOADER_ID = 0;
+ private static final String PREF_CALL_LOG_FILTER_LAST_CALL_TYPE = "CallLogFragment_last_filter";
+
private CallLogAdapter mAdapter;
private CallLogQueryHandler mCallLogQueryHandler;
private boolean mScrollToTop;
@@ -82,6 +86,7 @@
private View mStatusMessageView;
private TextView mStatusMessageText;
private TextView mStatusMessageAction;
+ private TextView mFilterStatusView;
private KeyguardManager mKeyguardManager;
private boolean mEmptyLoaderRunning;
@@ -108,6 +113,9 @@
// Exactly same variable is in Fragment as a package private.
private boolean mMenuVisible = true;
+ // Default to all calls.
+ private int mCallTypeFilter = CallLogQueryHandler.CALL_TYPE_ALL;
+
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
@@ -120,6 +128,11 @@
getActivity().getContentResolver().registerContentObserver(
ContactsContract.Contacts.CONTENT_URI, true, mContactsObserver);
setHasOptionsMenu(true);
+
+ // Load the last filter used.
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
+ mCallTypeFilter = prefs.getInt(PREF_CALL_LOG_FILTER_LAST_CALL_TYPE,
+ CallLogQueryHandler.CALL_TYPE_ALL);
}
/** Called by the CallLogQueryHandler when the list of calls has been fetched or updated. */
@@ -148,7 +161,9 @@
mHandler.post(new Runnable() {
@Override
public void run() {
- if (getActivity() == null || getActivity().isFinishing()) return;
+ if (getActivity() == null || getActivity().isFinishing()) {
+ return;
+ }
listView.smoothScrollToPosition(0);
}
});
@@ -202,6 +217,7 @@
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);
+ mFilterStatusView = (TextView) view.findViewById(R.id.filter_status);
return view;
}
@@ -213,6 +229,8 @@
new ContactInfoHelper(getActivity(), currentCountryIso));
setListAdapter(mAdapter);
getListView().setItemsCanFocus(true);
+
+ updateFilterHeader();
}
/**
@@ -279,6 +297,11 @@
super.onPause();
// Kill the requests thread
mAdapter.stopRequestProcessing();
+
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
+ prefs.edit()
+ .putInt(PREF_CALL_LOG_FILTER_LAST_CALL_TYPE, mCallTypeFilter)
+ .apply();
}
@Override
@@ -298,16 +321,12 @@
@Override
public void fetchCalls() {
- if (mShowingVoicemailOnly) {
- mCallLogQueryHandler.fetchVoicemailOnly();
- } else {
- mCallLogQueryHandler.fetchAllCalls();
- }
+ mCallLogQueryHandler.fetchCalls(mCallTypeFilter);
}
public void startCallsQuery() {
mAdapter.setLoading(true);
- mCallLogQueryHandler.fetchAllCalls();
+ mCallLogQueryHandler.fetchCalls(mCallTypeFilter);
if (mShowingVoicemailOnly) {
mShowingVoicemailOnly = false;
getActivity().invalidateOptionsMenu();
@@ -331,10 +350,7 @@
// menu items are ready if the first item is non-null.
if (itemDeleteAll != null) {
itemDeleteAll.setEnabled(mAdapter != null && !mAdapter.isEmpty());
- menu.findItem(R.id.show_voicemails_only).setVisible(
- mVoicemailSourcesAvailable && !mShowingVoicemailOnly);
- menu.findItem(R.id.show_all_calls).setVisible(
- mVoicemailSourcesAvailable && mShowingVoicemailOnly);
+ menu.findItem(R.id.show_voicemails_only).setVisible(mVoicemailSourcesAvailable);
}
}
@@ -345,13 +361,35 @@
ClearCallLogDialog.show(getFragmentManager());
return true;
+ case R.id.show_outgoing_only:
+ mCallLogQueryHandler.fetchCalls(Calls.OUTGOING_TYPE);
+ mCallTypeFilter = Calls.OUTGOING_TYPE;
+ updateFilterHeader();
+ return true;
+
+ case R.id.show_incoming_only:
+ mCallLogQueryHandler.fetchCalls(Calls.INCOMING_TYPE);
+ mCallTypeFilter = Calls.INCOMING_TYPE;
+ updateFilterHeader();
+ return true;
+
+ case R.id.show_missed_only:
+ mCallLogQueryHandler.fetchCalls(Calls.MISSED_TYPE);
+ mCallTypeFilter = Calls.MISSED_TYPE;
+ updateFilterHeader();
+ return true;
+
case R.id.show_voicemails_only:
- mCallLogQueryHandler.fetchVoicemailOnly();
+ mCallLogQueryHandler.fetchCalls(Calls.VOICEMAIL_TYPE);
+ mCallTypeFilter = Calls.VOICEMAIL_TYPE;
+ updateFilterHeader();
mShowingVoicemailOnly = true;
return true;
case R.id.show_all_calls:
- mCallLogQueryHandler.fetchAllCalls();
+ mCallLogQueryHandler.fetchCalls(CallLogQueryHandler.CALL_TYPE_ALL);
+ mCallTypeFilter = CallLogQueryHandler.CALL_TYPE_ALL;
+ updateFilterHeader();
mShowingVoicemailOnly = false;
return true;
@@ -360,6 +398,31 @@
}
}
+ private void updateFilterHeader() {
+ switch (mCallTypeFilter) {
+ case CallLogQueryHandler.CALL_TYPE_ALL:
+ mFilterStatusView.setVisibility(View.GONE);
+ break;
+ case Calls.INCOMING_TYPE:
+ showFilterStatus(R.string.call_log_incoming_header);
+ break;
+ case Calls.OUTGOING_TYPE:
+ showFilterStatus(R.string.call_log_outgoing_header);
+ break;
+ case Calls.MISSED_TYPE:
+ showFilterStatus(R.string.call_log_missed_header);
+ break;
+ case Calls.VOICEMAIL_TYPE:
+ showFilterStatus(R.string.call_log_voicemail_header);
+ break;
+ }
+ }
+
+ private void showFilterStatus(int resId) {
+ mFilterStatusView.setText(resId);
+ mFilterStatusView.setVisibility(View.VISIBLE);
+ }
+
public void callSelectedEntry() {
int position = getListView().getSelectedItemPosition();
if (position < 0) {
diff --git a/src/com/android/contacts/calllog/CallLogGroupBuilder.java b/src/com/android/contacts/calllog/CallLogGroupBuilder.java
index 9829d4a..5c7d3ee 100644
--- a/src/com/android/contacts/calllog/CallLogGroupBuilder.java
+++ b/src/com/android/contacts/calllog/CallLogGroupBuilder.java
@@ -16,13 +16,13 @@
package com.android.contacts.calllog;
-import com.android.common.widget.GroupingListAdapter;
-import com.google.common.annotations.VisibleForTesting;
-
import android.database.Cursor;
import android.provider.CallLog.Calls;
import android.telephony.PhoneNumberUtils;
+import com.android.common.widget.GroupingListAdapter;
+import com.google.common.annotations.VisibleForTesting;
+
/**
* Groups together calls in the call log.
* <p>
@@ -76,13 +76,13 @@
} else if (!sameNumber) {
// Should only group with calls from the same number.
shouldGroup = false;
- } else if (firstCallType == Calls.VOICEMAIL_TYPE
- || firstCallType == Calls.MISSED_TYPE) {
- // Voicemail and missed calls should only be grouped with subsequent missed calls.
- shouldGroup = callType == Calls.MISSED_TYPE;
+ } else if (firstCallType == Calls.VOICEMAIL_TYPE) {
+ // never group voicemail.
+ shouldGroup = false;
} else {
- // Incoming and outgoing calls group together.
- shouldGroup = callType == Calls.INCOMING_TYPE || callType == Calls.OUTGOING_TYPE;
+ // Incoming, outgoing, and missed calls group together.
+ shouldGroup = (callType == Calls.INCOMING_TYPE || callType == Calls.OUTGOING_TYPE ||
+ callType == Calls.MISSED_TYPE);
}
if (shouldGroup) {
diff --git a/src/com/android/contacts/calllog/CallLogListItemHelper.java b/src/com/android/contacts/calllog/CallLogListItemHelper.java
index 9485b54..eb30c81 100644
--- a/src/com/android/contacts/calllog/CallLogListItemHelper.java
+++ b/src/com/android/contacts/calllog/CallLogListItemHelper.java
@@ -16,15 +16,15 @@
package com.android.contacts.calllog;
-import com.android.contacts.PhoneCallDetails;
-import com.android.contacts.PhoneCallDetailsHelper;
-import com.android.contacts.R;
-
import android.content.res.Resources;
import android.provider.CallLog.Calls;
import android.text.TextUtils;
import android.view.View;
+import com.android.contacts.PhoneCallDetails;
+import com.android.contacts.PhoneCallDetailsHelper;
+import com.android.contacts.R;
+
/**
* Helper class to fill in the views of a call log entry.
*/
diff --git a/src/com/android/contacts/calllog/CallLogListItemViews.java b/src/com/android/contacts/calllog/CallLogListItemViews.java
index 503de43..348cd2f 100644
--- a/src/com/android/contacts/calllog/CallLogListItemViews.java
+++ b/src/com/android/contacts/calllog/CallLogListItemViews.java
@@ -16,16 +16,16 @@
package com.android.contacts.calllog;
-import com.android.contacts.PhoneCallDetailsViews;
-import com.android.contacts.R;
-import com.android.contacts.test.NeededForTesting;
-
import android.content.Context;
import android.view.View;
import android.widget.ImageView;
import android.widget.QuickContactBadge;
import android.widget.TextView;
+import com.android.contacts.PhoneCallDetailsViews;
+import com.android.contacts.R;
+import com.android.contacts.test.NeededForTesting;
+
/**
* Simple value object containing the various views within a call log entry.
*/
diff --git a/src/com/android/contacts/calllog/CallLogQueryHandler.java b/src/com/android/contacts/calllog/CallLogQueryHandler.java
index edc631f..096e882 100644
--- a/src/com/android/contacts/calllog/CallLogQueryHandler.java
+++ b/src/com/android/contacts/calllog/CallLogQueryHandler.java
@@ -16,10 +16,6 @@
package com.android.contacts.calllog;
-import com.android.common.io.MoreCloseables;
-import com.android.contacts.voicemail.VoicemailStatusHelperImpl;
-import com.google.android.collect.Lists;
-
import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
import android.content.ContentValues;
@@ -33,10 +29,15 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.provider.CallLog;
import android.provider.CallLog.Calls;
import android.provider.VoicemailContract.Status;
import android.util.Log;
+import com.android.common.io.MoreCloseables;
+import com.android.contacts.voicemail.VoicemailStatusHelperImpl;
+import com.google.common.collect.Lists;
+
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -63,6 +64,12 @@
private static final int QUERY_VOICEMAIL_STATUS_TOKEN = 58;
/**
+ * Call type similar to Calls.INCOMING_TYPE used to specify all types instead of one particular
+ * type.
+ */
+ public static final int CALL_TYPE_ALL = -1;
+
+ /**
* The time window from the current time within which an unread entry will be added to the new
* section.
*/
@@ -152,37 +159,24 @@
}
/**
- * Fetches the list of calls from the call log.
+ * Fetches the list of calls from the call log for a given type.
* <p>
* It will asynchronously update the content of the list view when the fetch completes.
*/
- public void fetchAllCalls() {
+ public void fetchCalls(int callType) {
cancelFetch();
int requestId = newCallsRequest();
- fetchCalls(QUERY_NEW_CALLS_TOKEN, requestId, true /*isNew*/, false /*voicemailOnly*/);
- fetchCalls(QUERY_OLD_CALLS_TOKEN, requestId, false /*isNew*/, false /*voicemailOnly*/);
+ fetchCalls(QUERY_NEW_CALLS_TOKEN, requestId, true /*isNew*/, callType);
+ fetchCalls(QUERY_OLD_CALLS_TOKEN, requestId, false /*isNew*/, callType);
}
- /**
- * Fetches the list of calls from the call log but include only the voicemail.
- * <p>
- * It will asynchronously update the content of the list view when the fetch completes.
- */
- public void fetchVoicemailOnly() {
- cancelFetch();
- int requestId = newCallsRequest();
- fetchCalls(QUERY_NEW_CALLS_TOKEN, requestId, true /*isNew*/, true /*voicemailOnly*/);
- fetchCalls(QUERY_OLD_CALLS_TOKEN, requestId, false /*isNew*/, true /*voicemailOnly*/);
- }
-
-
public void fetchVoicemailStatus() {
startQuery(QUERY_VOICEMAIL_STATUS_TOKEN, null, Status.CONTENT_URI,
VoicemailStatusHelperImpl.PROJECTION, null, null, null);
}
/** Fetches the list of calls in the call log, either the new one or the old ones. */
- private void fetchCalls(int token, int requestId, boolean isNew, boolean voicemailOnly) {
+ private void fetchCalls(int token, int requestId, boolean isNew, int callType) {
// We need to check for NULL explicitly otherwise entries with where READ is NULL
// may not match either the query or its negation.
// We consider the calls that are not yet consumed (i.e. IS_READ = 0) as "new".
@@ -194,10 +188,10 @@
// Negate the query.
selection = String.format("NOT (%s)", selection);
}
- if (voicemailOnly) {
+ if (callType > CALL_TYPE_ALL) {
// Add a clause to fetch only items of type voicemail.
selection = String.format("(%s) AND (%s = ?)", selection, Calls.TYPE);
- selectionArgs.add(Integer.toString(Calls.VOICEMAIL_TYPE));
+ selectionArgs.add(Integer.toString(callType));
}
startQuery(token, requestId, Calls.CONTENT_URI_WITH_VOICEMAIL,
CallLogQuery._PROJECTION, selection, selectionArgs.toArray(EMPTY_STRING_ARRAY),
@@ -359,8 +353,7 @@
void onVoicemailStatusFetched(Cursor statusCursor);
/**
- * Called when {@link CallLogQueryHandler#fetchAllCalls()} or
- * {@link CallLogQueryHandler#fetchVoicemailOnly()} complete.
+ * Called when {@link CallLogQueryHandler#fetchCalls(int)}complete.
*/
void onCallsFetched(Cursor combinedCursor);
}
diff --git a/src/com/android/contacts/calllog/CallTypeHelper.java b/src/com/android/contacts/calllog/CallTypeHelper.java
index d5d1068..2ca0db0 100644
--- a/src/com/android/contacts/calllog/CallTypeHelper.java
+++ b/src/com/android/contacts/calllog/CallTypeHelper.java
@@ -16,11 +16,11 @@
package com.android.contacts.calllog;
-import com.android.contacts.R;
-
import android.content.res.Resources;
import android.provider.CallLog.Calls;
+import com.android.contacts.R;
+
/**
* Helper class to perform operations related to call types.
*/
diff --git a/src/com/android/contacts/calllog/CallTypeIconsView.java b/src/com/android/contacts/calllog/CallTypeIconsView.java
index e0242c8..384b597 100644
--- a/src/com/android/contacts/calllog/CallTypeIconsView.java
+++ b/src/com/android/contacts/calllog/CallTypeIconsView.java
@@ -16,10 +16,6 @@
package com.android.contacts.calllog;
-import com.android.contacts.R;
-import com.android.contacts.test.NeededForTesting;
-import com.google.common.collect.Lists;
-
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
@@ -27,6 +23,10 @@
import android.util.AttributeSet;
import android.view.View;
+import com.android.contacts.R;
+import com.android.contacts.test.NeededForTesting;
+import com.google.common.collect.Lists;
+
import java.util.List;
/**
diff --git a/src/com/android/contacts/calllog/ClearCallLogDialog.java b/src/com/android/contacts/calllog/ClearCallLogDialog.java
index 426732a..c4dbb7e 100644
--- a/src/com/android/contacts/calllog/ClearCallLogDialog.java
+++ b/src/com/android/contacts/calllog/ClearCallLogDialog.java
@@ -16,8 +16,6 @@
package com.android.contacts.calllog;
-import com.android.contacts.R;
-
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
@@ -30,6 +28,8 @@
import android.os.Bundle;
import android.provider.CallLog.Calls;
+import com.android.contacts.R;
+
/**
* Dialog that clears the call log after confirming with the user
*/
diff --git a/src/com/android/contacts/calllog/ContactInfo.java b/src/com/android/contacts/calllog/ContactInfo.java
index a02b457..30e7e71 100644
--- a/src/com/android/contacts/calllog/ContactInfo.java
+++ b/src/com/android/contacts/calllog/ContactInfo.java
@@ -16,11 +16,11 @@
package com.android.contacts.calllog;
-import com.android.contacts.util.UriUtils;
-
import android.net.Uri;
import android.text.TextUtils;
+import com.android.contacts.util.UriUtils;
+
/**
* Information for a contact as needed by the Call Log.
*/
diff --git a/src/com/android/contacts/calllog/ContactInfoHelper.java b/src/com/android/contacts/calllog/ContactInfoHelper.java
index 90d5e8b..edca00c 100644
--- a/src/com/android/contacts/calllog/ContactInfoHelper.java
+++ b/src/com/android/contacts/calllog/ContactInfoHelper.java
@@ -16,8 +16,6 @@
package com.android.contacts.calllog;
-import com.android.contacts.util.UriUtils;
-
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
@@ -26,6 +24,8 @@
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
+import com.android.contacts.util.UriUtils;
+
/**
* Utility class to look up the contact information for a given number.
*/
diff --git a/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java b/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
index 1c2a595..cfac1de 100644
--- a/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
+++ b/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
@@ -16,11 +16,6 @@
package com.android.contacts.calllog;
-import com.android.common.io.MoreCloseables;
-import com.android.contacts.CallDetailActivity;
-import com.android.contacts.R;
-import com.google.common.collect.Maps;
-
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -36,6 +31,11 @@
import android.text.TextUtils;
import android.util.Log;
+import com.android.common.io.MoreCloseables;
+import com.android.contacts.CallDetailActivity;
+import com.android.contacts.R;
+import com.google.common.collect.Maps;
+
import java.util.Map;
/**
diff --git a/src/com/android/contacts/calllog/ExtendedCursor.java b/src/com/android/contacts/calllog/ExtendedCursor.java
index 499a350..3894192 100644
--- a/src/com/android/contacts/calllog/ExtendedCursor.java
+++ b/src/com/android/contacts/calllog/ExtendedCursor.java
@@ -16,13 +16,13 @@
package com.android.contacts.calllog;
-import com.android.common.io.MoreCloseables;
-
import android.database.AbstractCursor;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.DataSetObserver;
+import com.android.common.io.MoreCloseables;
+
/**
* Wraps a cursor to add an additional column with the same value for all rows.
* <p>
diff --git a/src/com/android/contacts/calllog/IntentProvider.java b/src/com/android/contacts/calllog/IntentProvider.java
index 7ddfecc..487799c 100644
--- a/src/com/android/contacts/calllog/IntentProvider.java
+++ b/src/com/android/contacts/calllog/IntentProvider.java
@@ -16,16 +16,15 @@
package com.android.contacts.calllog;
-import com.android.contacts.CallDetailActivity;
-import com.android.contacts.ContactsUtils;
-
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.CallLog.Calls;
-import android.telephony.PhoneNumberUtils;
+
+import com.android.contacts.CallDetailActivity;
+import com.android.contacts.ContactsUtils;
/**
* Used to create an intent to attach to an action in the call log.
diff --git a/src/com/android/contacts/calllog/PhoneNumberHelper.java b/src/com/android/contacts/calllog/PhoneNumberHelper.java
index af7c2f6..e24d0ae 100644
--- a/src/com/android/contacts/calllog/PhoneNumberHelper.java
+++ b/src/com/android/contacts/calllog/PhoneNumberHelper.java
@@ -16,15 +16,13 @@
package com.android.contacts.calllog;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.R;
-import com.android.internal.telephony.CallerInfo;
-
import android.content.res.Resources;
-import android.net.Uri;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
+import com.android.contacts.R;
+import com.android.internal.telephony.CallerInfo;
+
/**
* Helper for formatting and managing phone numbers.
*/
diff --git a/src/com/android/contacts/datepicker/DatePicker.java b/src/com/android/contacts/datepicker/DatePicker.java
index 629fd9c..39bbd8d 100644
--- a/src/com/android/contacts/datepicker/DatePicker.java
+++ b/src/com/android/contacts/datepicker/DatePicker.java
@@ -19,8 +19,6 @@
// This is a fork of the standard Android DatePicker that additionally allows toggling the year
// on/off. It uses some private API so that not everything has to be copied.
-import com.android.contacts.R;
-
import android.animation.LayoutTransition;
import android.annotation.Widget;
import android.content.Context;
@@ -40,6 +38,8 @@
import android.widget.NumberPicker;
import android.widget.NumberPicker.OnValueChangeListener;
+import com.android.contacts.R;
+
import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.Calendar;
@@ -54,6 +54,8 @@
*/
@Widget
public class DatePicker extends FrameLayout {
+ /** Magic year that represents "no year" */
+ public static int NO_YEAR = 0;
private static final int DEFAULT_START_YEAR = 1900;
private static final int DEFAULT_END_YEAR = 2100;
@@ -83,7 +85,7 @@
/**
* @param view The view associated with this listener.
- * @param year The year that was set.
+ * @param year The year that was set or {@link DatePicker#NO_YEAR} if no year was set
* @param monthOfYear The month that was set (0-11) for compatibility
* with {@link java.util.Calendar}.
* @param dayOfMonth The day of the month that was set.
@@ -279,7 +281,7 @@
public void updateDate(int year, int monthOfYear, int dayOfMonth) {
if (mYear != year || mMonth != monthOfYear || mDay != dayOfMonth) {
- mYear = (mYearOptional && year == 0) ? getCurrentYear() : year;
+ mYear = (mYearOptional && year == NO_YEAR) ? getCurrentYear() : year;
mMonth = monthOfYear;
mDay = dayOfMonth;
updateSpinners();
@@ -413,7 +415,7 @@
/**
* Initialize the state.
- * @param year The initial year or 0 if no year has been specified
+ * @param year The initial year or {@link #NO_YEAR} if no year has been specified
* @param monthOfYear The initial month.
* @param dayOfMonth The initial day of the month.
* @param yearOptional True if the user can toggle the year
@@ -421,11 +423,11 @@
*/
public void init(int year, int monthOfYear, int dayOfMonth, boolean yearOptional,
OnDateChangedListener onDateChangedListener) {
- mYear = (yearOptional && year == 0) ? getCurrentYear() : year;
+ mYear = (yearOptional && year == NO_YEAR) ? getCurrentYear() : year;
mMonth = monthOfYear;
mDay = dayOfMonth;
mYearOptional = yearOptional;
- mHasYear = yearOptional ? (year != 0) : true;
+ mHasYear = yearOptional ? (year != NO_YEAR) : true;
mOnDateChangedListener = onDateChangedListener;
updateSpinners();
}
@@ -454,7 +456,7 @@
}
public int getYear() {
- return (mYearOptional && !mHasYear) ? 0 : mYear;
+ return (mYearOptional && !mHasYear) ? NO_YEAR : mYear;
}
public boolean isYearOptional() {
@@ -482,7 +484,7 @@
private void notifyDateChanged() {
if (mOnDateChangedListener != null) {
- int year = (mYearOptional && !mHasYear) ? 0 : mYear;
+ int year = (mYearOptional && !mHasYear) ? NO_YEAR : mYear;
mOnDateChangedListener.onDateChanged(DatePicker.this, year, mMonth, mDay);
}
}
diff --git a/src/com/android/contacts/datepicker/DatePickerDialog.java b/src/com/android/contacts/datepicker/DatePickerDialog.java
index b0c4ed6..14ebd3b 100644
--- a/src/com/android/contacts/datepicker/DatePickerDialog.java
+++ b/src/com/android/contacts/datepicker/DatePickerDialog.java
@@ -19,10 +19,6 @@
// This is a fork of the standard Android DatePicker that additionally allows toggling the year
// on/off. It uses some private API so that not everything has to be copied.
-import com.android.contacts.R;
-import com.android.contacts.datepicker.DatePicker.OnDateChangedListener;
-import com.android.contacts.util.DateUtils;
-
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
@@ -34,6 +30,10 @@
import android.view.View;
import android.widget.TextView;
+import com.android.contacts.R;
+import com.android.contacts.datepicker.DatePicker.OnDateChangedListener;
+import com.android.contacts.util.DateUtils;
+
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
@@ -47,6 +47,9 @@
public class DatePickerDialog extends AlertDialog implements OnClickListener,
OnDateChangedListener {
+ /** Magic year that represents "no year" */
+ public static int NO_YEAR = DatePicker.NO_YEAR;
+
private static final String YEAR = "year";
private static final String MONTH = "month";
private static final String DAY = "day";
@@ -54,7 +57,6 @@
private final DatePicker mDatePicker;
private final OnDateSetListener mCallBack;
- private final Calendar mCalendar;
private final DateFormat mTitleDateFormat;
private final DateFormat mTitleNoYearDateFormat;
@@ -68,7 +70,8 @@
public interface OnDateSetListener {
/**
* @param view The view associated with this listener.
- * @param year The year that was set or 0 if the user has not specified a year
+ * @param year The year that was set or {@link DatePickerDialog#NO_YEAR} if the user has
+ * not specified a year
* @param monthOfYear The month that was set (0-11) for compatibility
* with {@link java.util.Calendar}.
* @param dayOfMonth The day of the month that was set.
@@ -94,7 +97,8 @@
/**
* @param context The context the dialog is to run in.
* @param callBack How the parent is notified that the date is set.
- * @param year The initial year of the dialog or 0 if no year has been specified
+ * @param year The initial year of the dialog or {@link DatePickerDialog#NO_YEAR} if no year
+ * has been specified
* @param monthOfYear The initial month of the dialog.
* @param dayOfMonth The initial day of the dialog.
* @param yearOptional Whether the year can be toggled by the user
@@ -115,7 +119,8 @@
* @param context The context the dialog is to run in.
* @param theme the theme to apply to this dialog
* @param callBack How the parent is notified that the date is set.
- * @param year The initial year of the dialog or 0 if no year has been specified
+ * @param year The initial year of the dialog or {@link DatePickerDialog#NO_YEAR} if no year
+ * has been specified
* @param monthOfYear The initial month of the dialog.
* @param dayOfMonth The initial day of the dialog.
*/
@@ -132,7 +137,8 @@
* @param context The context the dialog is to run in.
* @param theme the theme to apply to this dialog
* @param callBack How the parent is notified that the date is set.
- * @param year The initial year of the dialog.
+ * @param year The initial year of the dialog or {@link DatePickerDialog#NO_YEAR} if no
+ * year has been specified.
* @param monthOfYear The initial month of the dialog.
* @param dayOfMonth The initial day of the dialog.
* @param yearOptional Whether the year can be toggled by the user
@@ -154,7 +160,6 @@
mTitleDateFormat = DateFormat.getDateInstance(DateFormat.FULL);
mTitleNoYearDateFormat = new SimpleDateFormat(
DateUtils.isMonthBeforeDay(getContext()) ? "MMMM dd" : "dd MMMM");
- mCalendar = Calendar.getInstance();
updateTitle(mInitialYear, mInitialMonth, mInitialDay);
setButton(BUTTON_POSITIVE, context.getText(com.android.internal.R.string.date_time_set),
@@ -205,12 +210,13 @@
}
private void updateTitle(int year, int month, int day) {
- mCalendar.set(Calendar.YEAR, year);
- mCalendar.set(Calendar.MONTH, month);
- mCalendar.set(Calendar.DAY_OF_MONTH, day);
+ final Calendar calendar = Calendar.getInstance();
+ calendar.set(Calendar.YEAR, year);
+ calendar.set(Calendar.MONTH, month);
+ calendar.set(Calendar.DAY_OF_MONTH, day);
final DateFormat dateFormat =
- year == 0 ? mTitleNoYearDateFormat : mTitleDateFormat;
- setTitle(dateFormat.format(mCalendar.getTime()));
+ year == NO_YEAR ? mTitleNoYearDateFormat : mTitleDateFormat;
+ setTitle(dateFormat.format(calendar.getTime()));
}
@Override
diff --git a/src/com/android/contacts/detail/CarouselTab.java b/src/com/android/contacts/detail/CarouselTab.java
index 0b430b6..09e097a 100644
--- a/src/com/android/contacts/detail/CarouselTab.java
+++ b/src/com/android/contacts/detail/CarouselTab.java
@@ -16,15 +16,15 @@
package com.android.contacts.detail;
-import com.android.contacts.R;
-import com.android.contacts.widget.FrameLayoutWithOverlay;
-
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.widget.TextView;
+import com.android.contacts.R;
+import com.android.contacts.widget.FrameLayoutWithOverlay;
+
/**
* This is a tab in the {@link ContactDetailTabCarousel}.
*/
diff --git a/src/com/android/contacts/detail/ContactDetailDisplayUtils.java b/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
index 404148d..1908e96 100644
--- a/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
+++ b/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
@@ -16,23 +16,8 @@
package com.android.contacts.detail;
-import com.android.contacts.ContactLoader;
-import com.android.contacts.ContactLoader.Result;
-import com.android.contacts.ContactPhotoManager;
-import com.android.contacts.R;
-import com.android.contacts.preference.ContactsPreferences;
-import com.android.contacts.util.ContactBadgeUtil;
-import com.android.contacts.util.HtmlUtils;
-import com.android.contacts.util.MoreMath;
-import com.android.contacts.util.StreamItemEntry;
-import com.android.contacts.util.StreamItemPhotoEntry;
-import com.google.common.annotations.VisibleForTesting;
-
import android.content.ContentUris;
-import android.content.ContentValues;
import android.content.Context;
-import android.content.Entity;
-import android.content.Entity.NamedContentValues;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
@@ -40,8 +25,6 @@
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Organization;
-import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.DisplayNameSources;
import android.provider.ContactsContract.StreamItems;
import android.text.Html;
@@ -56,12 +39,27 @@
import android.widget.ListView;
import android.widget.TextView;
+import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.R;
+import com.android.contacts.model.Contact;
+import com.android.contacts.model.RawContact;
+import com.android.contacts.model.dataitem.DataItem;
+import com.android.contacts.model.dataitem.OrganizationDataItem;
+import com.android.contacts.preference.ContactsPreferences;
+import com.android.contacts.util.ContactBadgeUtil;
+import com.android.contacts.util.HtmlUtils;
+import com.android.contacts.util.MoreMath;
+import com.android.contacts.util.StreamItemEntry;
+import com.android.contacts.util.StreamItemPhotoEntry;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Iterables;
+
import java.util.List;
/**
* This class contains utility methods to bind high-level contact details
* (meaning name, phonetic name, job, and attribution) from a
- * {@link ContactLoader.Result} data object to appropriate {@link View}s.
+ * {@link Contact} data object to appropriate {@link View}s.
*/
public class ContactDetailDisplayUtils {
private static final String TAG = "ContactDetailDisplayUtils";
@@ -95,7 +93,7 @@
* Returns the display name of the contact, using the current display order setting.
* Returns res/string/missing_name if there is no display name.
*/
- public static CharSequence getDisplayName(Context context, Result contactData) {
+ public static CharSequence getDisplayName(Context context, Contact contactData) {
CharSequence displayName = contactData.getDisplayName();
CharSequence altDisplayName = contactData.getAltDisplayName();
ContactsPreferences prefs = new ContactsPreferences(context);
@@ -115,7 +113,7 @@
/**
* Returns the phonetic name of the contact or null if there isn't one.
*/
- public static String getPhoneticName(Context context, Result contactData) {
+ public static String getPhoneticName(Context context, Contact contactData) {
String phoneticName = contactData.getPhoneticName();
if (!TextUtils.isEmpty(phoneticName)) {
return phoneticName;
@@ -127,7 +125,7 @@
* Returns the attribution string for the contact, which may specify the contact directory that
* the contact came from. Returns null if there is none applicable.
*/
- public static String getAttribution(Context context, Result contactData) {
+ public static String getAttribution(Context context, Contact contactData) {
if (contactData.isDirectoryEntry()) {
String directoryDisplayName = contactData.getDirectoryDisplayName();
String directoryType = contactData.getDirectoryType();
@@ -143,40 +141,37 @@
* Returns the organization of the contact. If several organizations are given,
* the first one is used. Returns null if not applicable.
*/
- public static String getCompany(Context context, Result contactData) {
+ public static String getCompany(Context context, Contact contactData) {
final boolean displayNameIsOrganization = contactData.getDisplayNameSource()
== DisplayNameSources.ORGANIZATION;
- for (Entity entity : contactData.getEntities()) {
- for (NamedContentValues subValue : entity.getSubValues()) {
- final ContentValues entryValues = subValue.values;
- final String mimeType = entryValues.getAsString(Data.MIMETYPE);
-
- if (Organization.CONTENT_ITEM_TYPE.equals(mimeType)) {
- final String company = entryValues.getAsString(Organization.COMPANY);
- final String title = entryValues.getAsString(Organization.TITLE);
- final String combined;
- // We need to show company and title in a combined string. However, if the
- // DisplayName is already the organization, it mirrors company or (if company
- // is empty title). Make sure we don't show what's already shown as DisplayName
- if (TextUtils.isEmpty(company)) {
- combined = displayNameIsOrganization ? null : title;
+ for (RawContact rawContact : contactData.getRawContacts()) {
+ for (DataItem dataItem : Iterables.filter(
+ rawContact.getDataItems(), OrganizationDataItem.class)) {
+ OrganizationDataItem organization = (OrganizationDataItem) dataItem;
+ final String company = organization.getCompany();
+ final String title = organization.getTitle();
+ final String combined;
+ // We need to show company and title in a combined string. However, if the
+ // DisplayName is already the organization, it mirrors company or (if company
+ // is empty title). Make sure we don't show what's already shown as DisplayName
+ if (TextUtils.isEmpty(company)) {
+ combined = displayNameIsOrganization ? null : title;
+ } else {
+ if (TextUtils.isEmpty(title)) {
+ combined = displayNameIsOrganization ? null : company;
} else {
- if (TextUtils.isEmpty(title)) {
- combined = displayNameIsOrganization ? null : company;
+ if (displayNameIsOrganization) {
+ combined = title;
} else {
- if (displayNameIsOrganization) {
- combined = title;
- } else {
- combined = context.getString(
- R.string.organization_company_and_title,
- company, title);
- }
+ combined = context.getString(
+ R.string.organization_company_and_title,
+ company, title);
}
}
+ }
- if (!TextUtils.isEmpty(combined)) {
- return combined;
- }
+ if (!TextUtils.isEmpty(combined)) {
+ return combined;
}
}
}
@@ -225,7 +220,7 @@
/**
* Set the social snippet text. If there isn't one, then set the view to gone.
*/
- public static void setSocialSnippet(Context context, Result contactData, TextView statusView,
+ public static void setSocialSnippet(Context context, Contact contactData, TextView statusView,
ImageView statusPhotoView) {
if (statusView == null) {
return;
@@ -378,7 +373,7 @@
* Sets the display name of this contact to the given {@link TextView}. If
* there is none, then set the view to gone.
*/
- public static void setDisplayName(Context context, Result contactData, TextView textView) {
+ public static void setDisplayName(Context context, Contact contactData, TextView textView) {
if (textView == null) {
return;
}
@@ -389,7 +384,7 @@
* Sets the company and job title of this contact to the given {@link TextView}. If
* there is none, then set the view to gone.
*/
- public static void setCompanyName(Context context, Result contactData, TextView textView) {
+ public static void setCompanyName(Context context, Contact contactData, TextView textView) {
if (textView == null) {
return;
}
@@ -400,7 +395,7 @@
* Sets the phonetic name of this contact to the given {@link TextView}. If
* there is none, then set the view to gone.
*/
- public static void setPhoneticName(Context context, Result contactData, TextView textView) {
+ public static void setPhoneticName(Context context, Contact contactData, TextView textView) {
if (textView == null) {
return;
}
@@ -411,7 +406,7 @@
* Sets the attribution contact to the given {@link TextView}. If
* there is none, then set the view to gone.
*/
- public static void setAttribution(Context context, Result contactData, TextView textView) {
+ public static void setAttribution(Context context, Contact contactData, TextView textView) {
if (textView == null) {
return;
}
diff --git a/src/com/android/contacts/detail/ContactDetailFragment.java b/src/com/android/contacts/detail/ContactDetailFragment.java
index 5c68dcb..f66466d 100644
--- a/src/com/android/contacts/detail/ContactDetailFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailFragment.java
@@ -16,45 +16,12 @@
package com.android.contacts.detail;
-import com.android.contacts.Collapser;
-import com.android.contacts.Collapser.Collapsible;
-import com.android.contacts.ContactLoader;
-import com.android.contacts.ContactPresenceIconUtil;
-import com.android.contacts.ContactSaveService;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.GroupMetaData;
-import com.android.contacts.R;
-import com.android.contacts.TypePrecedence;
-import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
-import com.android.contacts.detail.ContactDetailPhotoSetter;
-import com.android.contacts.editor.SelectAccountDialogFragment;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountType.EditType;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountWithDataSet;
-import com.android.contacts.model.DataKind;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.model.EntityDeltaList;
-import com.android.contacts.model.EntityModifier;
-import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
-import com.android.contacts.util.ClipboardUtils;
-import com.android.contacts.util.Constants;
-import com.android.contacts.util.DataStatus;
-import com.android.contacts.util.DateUtils;
-import com.android.contacts.util.PhoneCapabilityTester;
-import com.android.contacts.util.StructuredPostalUtils;
-import com.android.internal.telephony.ITelephony;
-import com.google.common.annotations.VisibleForTesting;
-
import android.app.Activity;
import android.app.Fragment;
import android.app.SearchManager;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
-import android.content.Entity;
-import android.content.Entity.NamedContentValues;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
@@ -67,23 +34,13 @@
import android.os.ServiceManager;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Email;
-import android.provider.ContactsContract.CommonDataKinds.Event;
import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
import android.provider.ContactsContract.CommonDataKinds.Im;
-import android.provider.ContactsContract.CommonDataKinds.Nickname;
-import android.provider.ContactsContract.CommonDataKinds.Note;
-import android.provider.ContactsContract.CommonDataKinds.Organization;
import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.Relation;
-import android.provider.ContactsContract.CommonDataKinds.SipAddress;
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
-import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
-import android.provider.ContactsContract.CommonDataKinds.Website;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Directory;
import android.provider.ContactsContract.DisplayNameSources;
-import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.StatusUpdates;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
@@ -112,6 +69,52 @@
import android.widget.ListView;
import android.widget.TextView;
+import com.android.contacts.Collapser;
+import com.android.contacts.Collapser.Collapsible;
+import com.android.contacts.ContactPresenceIconUtil;
+import com.android.contacts.ContactSaveService;
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.GroupMetaData;
+import com.android.contacts.R;
+import com.android.contacts.TypePrecedence;
+import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
+import com.android.contacts.editor.SelectAccountDialogFragment;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.Contact;
+import com.android.contacts.model.RawContact;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.RawContactDeltaList;
+import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountType.EditType;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.model.dataitem.DataItem;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.contacts.model.dataitem.EmailDataItem;
+import com.android.contacts.model.dataitem.EventDataItem;
+import com.android.contacts.model.dataitem.GroupMembershipDataItem;
+import com.android.contacts.model.dataitem.ImDataItem;
+import com.android.contacts.model.dataitem.NicknameDataItem;
+import com.android.contacts.model.dataitem.NoteDataItem;
+import com.android.contacts.model.dataitem.OrganizationDataItem;
+import com.android.contacts.model.dataitem.PhoneDataItem;
+import com.android.contacts.model.dataitem.RelationDataItem;
+import com.android.contacts.model.dataitem.SipAddressDataItem;
+import com.android.contacts.model.dataitem.StructuredNameDataItem;
+import com.android.contacts.model.dataitem.StructuredPostalDataItem;
+import com.android.contacts.model.dataitem.WebsiteDataItem;
+import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
+import com.android.contacts.util.ClipboardUtils;
+import com.android.contacts.util.Constants;
+import com.android.contacts.util.DataStatus;
+import com.android.contacts.util.DateUtils;
+import com.android.contacts.util.PhoneCapabilityTester;
+import com.android.contacts.util.StructuredPostalUtils;
+import com.android.internal.telephony.ITelephony;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Iterables;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -138,7 +141,7 @@
private Uri mLookupUri;
private Listener mListener;
- private ContactLoader.Result mContactData;
+ private Contact mContactData;
private ViewGroup mStaticPhotoContainer;
private View mPhotoTouchOverlay;
private ListView mListView;
@@ -188,9 +191,8 @@
private Parcelable mListState;
/**
- * A list of distinct contact IDs included in the current contact.
+ * Lists of specific types of entries to be shown in contact details.
*/
- private ArrayList<Long> mRawContactIds = new ArrayList<Long>();
private ArrayList<DetailViewEntry> mPhoneEntries = new ArrayList<DetailViewEntry>();
private ArrayList<DetailViewEntry> mSmsEntries = new ArrayList<DetailViewEntry>();
private ArrayList<DetailViewEntry> mEmailEntries = new ArrayList<DetailViewEntry>();
@@ -336,7 +338,7 @@
return mListener;
}
- protected ContactLoader.Result getContactData() {
+ protected Contact getContactData() {
return mContactData;
}
@@ -363,7 +365,7 @@
setData(null, null);
}
- public void setData(Uri lookupUri, ContactLoader.Result result) {
+ public void setData(Uri lookupUri, Contact result) {
mLookupUri = lookupUri;
mContactData = result;
bindData();
@@ -531,65 +533,47 @@
// Clear out the old entries
mAllEntries.clear();
- mRawContactIds.clear();
-
mPrimaryPhoneUri = null;
- final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
-
// Build up method entries
if (mContactData == null) {
return;
}
ArrayList<String> groups = new ArrayList<String>();
- for (Entity entity: mContactData.getEntities()) {
- final ContentValues entValues = entity.getEntityValues();
- final String accountType = entValues.getAsString(RawContacts.ACCOUNT_TYPE);
- final String dataSet = entValues.getAsString(RawContacts.DATA_SET);
- final long rawContactId = entValues.getAsLong(RawContacts._ID);
+ for (RawContact rawContact: mContactData.getRawContacts()) {
+ final long rawContactId = rawContact.getId();
+ for (DataItem dataItem : rawContact.getDataItems()) {
+ dataItem.setRawContactId(rawContactId);
- if (!mRawContactIds.contains(rawContactId)) {
- mRawContactIds.add(rawContactId);
- }
+ if (dataItem.getMimeType() == null) continue;
- AccountType type = accountTypes.getAccountType(accountType, dataSet);
-
- for (NamedContentValues subValue : entity.getSubValues()) {
- final ContentValues entryValues = subValue.values;
- entryValues.put(Data.RAW_CONTACT_ID, rawContactId);
-
- final long dataId = entryValues.getAsLong(Data._ID);
- final String mimeType = entryValues.getAsString(Data.MIMETYPE);
- if (mimeType == null) continue;
-
- if (GroupMembership.CONTENT_ITEM_TYPE.equals(mimeType)) {
- Long groupId = entryValues.getAsLong(GroupMembership.GROUP_ROW_ID);
+ if (dataItem instanceof GroupMembershipDataItem) {
+ GroupMembershipDataItem groupMembership =
+ (GroupMembershipDataItem) dataItem;
+ Long groupId = groupMembership.getGroupRowId();
if (groupId != null) {
handleGroupMembership(groups, mContactData.getGroupMetaData(), groupId);
}
continue;
}
- final DataKind kind = accountTypes.getKindOrFallback(
- accountType, dataSet, mimeType);
+ final DataKind kind = dataItem.getDataKind();
if (kind == null) continue;
- final DetailViewEntry entry = DetailViewEntry.fromValues(mContext, mimeType, kind,
- dataId, entryValues, mContactData.isDirectoryEntry(),
- mContactData.getDirectoryId());
+ final DetailViewEntry entry = DetailViewEntry.fromValues(mContext, dataItem,
+ mContactData.isDirectoryEntry(), mContactData.getDirectoryId());
entry.maxLines = kind.maxLinesForDisplay;
final boolean hasData = !TextUtils.isEmpty(entry.data);
- Integer superPrimary = entryValues.getAsInteger(Data.IS_SUPER_PRIMARY);
- final boolean isSuperPrimary = superPrimary != null && superPrimary != 0;
+ final boolean isSuperPrimary = dataItem.isSuperPrimary();
- if (StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ if (dataItem instanceof StructuredNameDataItem) {
// Always ignore the name. It is shown in the header if set
- } else if (Phone.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
+ } else if (dataItem instanceof PhoneDataItem && hasData) {
+ PhoneDataItem phone = (PhoneDataItem) dataItem;
// Build phone entries
- String phoneNumberE164 =
- entryValues.getAsString(Phone.NORMALIZED_NUMBER);
+ String phoneNumberE164 = phone.getNormalizedNumber();
entry.data = PhoneNumberUtils.formatNumber(
entry.data, phoneNumberE164, mDefaultCountryIso);
final Intent phoneIntent = mHasPhone ?
@@ -624,7 +608,7 @@
// add to end of list
mPhoneEntries.add(entry);
}
- } else if (Email.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
+ } else if (dataItem instanceof EmailDataItem && hasData) {
// Build email entries
entry.intent = new Intent(Intent.ACTION_SENDTO,
Uri.fromParts(Constants.SCHEME_MAILTO, entry.data, null));
@@ -639,24 +623,23 @@
// When Email rows have status, create additional Im row
final DataStatus status = mContactData.getStatuses().get(entry.id);
if (status != null) {
- final String imMime = Im.CONTENT_ITEM_TYPE;
- final DataKind imKind = accountTypes.getKindOrFallback(accountType, dataSet,
- imMime);
- final DetailViewEntry imEntry = DetailViewEntry.fromValues(mContext, imMime,
- imKind, dataId, entryValues, mContactData.isDirectoryEntry(),
- mContactData.getDirectoryId());
- buildImActions(mContext, imEntry, entryValues);
+ EmailDataItem email = (EmailDataItem) dataItem;
+ ImDataItem im = ImDataItem.createFromEmail(email);
+
+ final DetailViewEntry imEntry = DetailViewEntry.fromValues(mContext, im,
+ mContactData.isDirectoryEntry(), mContactData.getDirectoryId());
+ buildImActions(mContext, imEntry, im);
imEntry.setPresence(status.getPresence());
- imEntry.maxLines = imKind.maxLinesForDisplay;
+ imEntry.maxLines = kind.maxLinesForDisplay;
mImEntries.add(imEntry);
}
- } else if (StructuredPostal.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
+ } else if (dataItem instanceof StructuredPostalDataItem && hasData) {
// Build postal entries
entry.intent = StructuredPostalUtils.getViewPostalAddressIntent(entry.data);
mPostalEntries.add(entry);
- } else if (Im.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
+ } else if (dataItem instanceof ImDataItem && hasData) {
// Build IM entries
- buildImActions(mContext, entry, entryValues);
+ buildImActions(mContext, entry, (ImDataItem) dataItem);
// Apply presence when available
final DataStatus status = mContactData.getStatuses().get(entry.id);
@@ -664,10 +647,10 @@
entry.setPresence(status.getPresence());
}
mImEntries.add(entry);
- } else if (Organization.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ } else if (dataItem instanceof OrganizationDataItem) {
// Organizations are not shown. The first one is shown in the header
// and subsequent ones are not supported anymore
- } else if (Nickname.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
+ } else if (dataItem instanceof NicknameDataItem && hasData) {
// Build nickname entries
final boolean isNameRawContact =
(mContactData.getNameRawContactId() == rawContactId);
@@ -680,11 +663,11 @@
entry.uri = null;
mNicknameEntries.add(entry);
}
- } else if (Note.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
+ } else if (dataItem instanceof NoteDataItem && hasData) {
// Build note entries
entry.uri = null;
mNoteEntries.add(entry);
- } else if (Website.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
+ } else if (dataItem instanceof WebsiteDataItem && hasData) {
// Build Website entries
entry.uri = null;
try {
@@ -695,7 +678,7 @@
Log.e(TAG, "Couldn't parse website: " + entry.data);
}
mWebsiteEntries.add(entry);
- } else if (SipAddress.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
+ } else if (dataItem instanceof SipAddressDataItem && hasData) {
// Build SipAddress entries
entry.uri = null;
if (mHasSip) {
@@ -711,11 +694,11 @@
// (Then, we'd also update FallbackAccountType.java to set
// secondary=false for this field, and tweak the weight
// of its DataKind.)
- } else if (Event.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
+ } else if (dataItem instanceof EventDataItem && hasData) {
entry.data = DateUtils.formatDate(mContext, entry.data);
entry.uri = null;
mEventEntries.add(entry);
- } else if (Relation.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
+ } else if (dataItem instanceof RelationDataItem && hasData) {
entry.intent = new Intent(Intent.ACTION_SEARCH);
entry.intent.putExtra(SearchManager.QUERY, entry.data);
entry.intent.setType(Contacts.CONTENT_TYPE);
@@ -725,14 +708,12 @@
entry.intent = new Intent(Intent.ACTION_VIEW);
entry.intent.setDataAndType(entry.uri, entry.mimetype);
- if (kind.actionBody != null) {
- CharSequence body = kind.actionBody.inflateUsing(mContext, entryValues);
- entry.data = (body == null) ? null : body.toString();
- }
+ entry.data = dataItem.buildDataString();
if (!TextUtils.isEmpty(entry.data)) {
// If the account type exists in the hash map, add it as another entry for
// that account type
+ AccountType type = dataItem.getAccountType();
if (mOtherEntriesMap.containsKey(type)) {
List<DetailViewEntry> listEntries = mOtherEntriesMap.get(type);
listEntries.add(entry);
@@ -961,37 +942,27 @@
}
}
- private static String buildDataString(DataKind kind, ContentValues values,
- Context context) {
- if (kind.actionBody == null) {
- return null;
- }
- CharSequence actionBody = kind.actionBody.inflateUsing(context, values);
- return actionBody == null ? null : actionBody.toString();
- }
-
/**
* Writes the Instant Messaging action into the given entry value.
*/
@VisibleForTesting
public static void buildImActions(Context context, DetailViewEntry entry,
- ContentValues values) {
- final boolean isEmail = Email.CONTENT_ITEM_TYPE.equals(values.getAsString(Data.MIMETYPE));
+ ImDataItem im) {
+ final boolean isEmail = im.isCreatedFromEmail();
- if (!isEmail && !isProtocolValid(values)) {
+ if (!isEmail && !im.isProtocolValid()) {
return;
}
- final String data = values.getAsString(isEmail ? Email.DATA : Im.DATA);
+ final String data = im.getData();
if (TextUtils.isEmpty(data)) {
return;
}
- final int protocol = isEmail ? Im.PROTOCOL_GOOGLE_TALK : values.getAsInteger(Im.PROTOCOL);
+ final int protocol = isEmail ? Im.PROTOCOL_GOOGLE_TALK : im.getProtocol();
if (protocol == Im.PROTOCOL_GOOGLE_TALK) {
- final Integer chatCapabilityObj = values.getAsInteger(Im.CHAT_CAPABILITY);
- final int chatCapability = chatCapabilityObj == null ? 0 : chatCapabilityObj;
+ final int chatCapability = im.getChatCapability();
entry.chatCapability = chatCapability;
entry.typeString = Im.getProtocolLabel(context.getResources(), Im.PROTOCOL_GOOGLE_TALK,
null).toString();
@@ -1012,7 +983,7 @@
}
} else {
// Build an IM Intent
- String host = values.getAsString(Im.CUSTOM_PROTOCOL);
+ String host = im.getCustomProtocol();
if (protocol != Im.PROTOCOL_CUSTOM) {
// Try bringing in a well-known host for specific protocols
@@ -1028,19 +999,6 @@
}
}
- private static boolean isProtocolValid(ContentValues values) {
- String protocolString = values.getAsString(Im.PROTOCOL);
- if (protocolString == null) {
- return false;
- }
- try {
- Integer.valueOf(protocolString);
- } catch (NumberFormatException e) {
- return false;
- }
- return true;
- }
-
/**
* Show a list popup. Used for "popup-able" entry, such as "More networks".
*/
@@ -1247,6 +1205,38 @@
private boolean mIsInSubSection = false;
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("== DetailViewEntry ==\n");
+ sb.append(" type: " + type + "\n");
+ sb.append(" kind: " + kind + "\n");
+ sb.append(" typeString: " + typeString + "\n");
+ sb.append(" data: " + data + "\n");
+ sb.append(" uri: " + uri.toString() + "\n");
+ sb.append(" maxLines: " + maxLines + "\n");
+ sb.append(" mimetype: " + mimetype + "\n");
+ sb.append(" isPrimary: " + (isPrimary ? "true" : "false") + "\n");
+ sb.append(" secondaryActionIcon: " + secondaryActionIcon + "\n");
+ sb.append(" secondaryActionDescription: " + secondaryActionDescription + "\n");
+ if (intent == null) {
+ sb.append(" intent: " + intent.toString() + "\n");
+ } else {
+ sb.append(" intent: " + intent.toString() + "\n");
+ }
+ if (secondaryIntent == null) {
+ sb.append(" secondaryIntent: (null)\n");
+ } else {
+ sb.append(" secondaryIntent: " + secondaryIntent.toString() + "\n");
+ }
+ sb.append(" ids: " + Iterables.toString(ids) + "\n");
+ sb.append(" collapseCount: " + collapseCount + "\n");
+ sb.append(" presence: " + presence + "\n");
+ sb.append(" chatCapability: " + chatCapability + "\n");
+ sb.append(" mIsInSubsection: " + (mIsInSubSection ? "true" : "false") + "\n");
+ return sb.toString();
+ }
+
DetailViewEntry() {
super(ViewAdapter.VIEW_TYPE_DETAIL_ENTRY);
isEnabled = true;
@@ -1255,34 +1245,34 @@
/**
* Build new {@link DetailViewEntry} and populate from the given values.
*/
- public static DetailViewEntry fromValues(Context context, String mimeType, DataKind kind,
- long dataId, ContentValues values, boolean isDirectoryEntry, long directoryId) {
+ public static DetailViewEntry fromValues(Context context, DataItem item,
+ boolean isDirectoryEntry, long directoryId) {
final DetailViewEntry entry = new DetailViewEntry();
- entry.id = dataId;
+ entry.id = item.getId();
entry.context = context;
entry.uri = ContentUris.withAppendedId(Data.CONTENT_URI, entry.id);
if (isDirectoryEntry) {
entry.uri = entry.uri.buildUpon().appendQueryParameter(
ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId)).build();
}
- entry.mimetype = mimeType;
- entry.kind = (kind.titleRes == -1 || kind.titleRes == 0) ? ""
- : context.getString(kind.titleRes);
- entry.data = buildDataString(kind, values, context);
+ entry.mimetype = item.getMimeType();
+ entry.kind = item.getKindString();
+ entry.data = item.buildDataString();
- if (kind.typeColumn != null && values.containsKey(kind.typeColumn)) {
- entry.type = values.getAsInteger(kind.typeColumn);
+ if (item.hasKindTypeColumn()) {
+ entry.type = item.getKindTypeColumn();
// get type string
entry.typeString = "";
- for (EditType type : kind.typeList) {
+ for (EditType type : item.getDataKind().typeList) {
if (type.rawValue == entry.type) {
if (type.customColumn == null) {
// Non-custom type. Get its description from the resource
entry.typeString = context.getString(type.labelRes);
} else {
// Custom type. Read it from the database
- entry.typeString = values.getAsString(type.customColumn);
+ entry.typeString =
+ item.getContentValues().getAsString(type.customColumn);
}
break;
}
@@ -1997,7 +1987,7 @@
if (mContactData.isUserProfile()) return false;
// Only if exactly one raw contact
- if (mContactData.getEntities().size() != 1) return false;
+ if (mContactData.getRawContacts().size() != 1) return false;
// test if the default group is assigned
final List<GroupMetaData> groups = mContactData.getGroupMetaData();
@@ -2009,28 +1999,20 @@
final long defaultGroupId = getDefaultGroupId(groups);
if (defaultGroupId == -1) return false;
- final Entity rawContactEntity = mContactData.getEntities().get(0);
- ContentValues rawValues = rawContactEntity.getEntityValues();
- final String accountType = rawValues.getAsString(RawContacts.ACCOUNT_TYPE);
- final String dataSet = rawValues.getAsString(RawContacts.DATA_SET);
- final AccountTypeManager accountTypes =
- AccountTypeManager.getInstance(mContext);
- final AccountType type = accountTypes.getAccountType(accountType, dataSet);
+ final RawContact rawContact = (RawContact) mContactData.getRawContacts().get(0);
+ final AccountType type = rawContact.getAccountType();
// Offline or non-writeable account? Nothing to fix
if (type == null || !type.areContactsWritable()) return false;
// Check whether the contact is in the default group
boolean isInDefaultGroup = false;
- for (NamedContentValues subValue : rawContactEntity.getSubValues()) {
- final String mimeType = subValue.values.getAsString(Data.MIMETYPE);
-
- if (GroupMembership.CONTENT_ITEM_TYPE.equals(mimeType)) {
- final Long groupId =
- subValue.values.getAsLong(GroupMembership.GROUP_ROW_ID);
- if (groupId == defaultGroupId) {
- isInDefaultGroup = true;
- break;
- }
+ for (DataItem dataItem : Iterables.filter(
+ rawContact.getDataItems(), GroupMembershipDataItem.class)) {
+ GroupMembershipDataItem groupMembership = (GroupMembershipDataItem) dataItem;
+ final Long groupId = groupMembership.getGroupRowId();
+ if (groupId == defaultGroupId) {
+ isInDefaultGroup = true;
+ break;
}
}
@@ -2050,19 +2032,16 @@
if (defaultGroupId == -1) return;
// add the group membership to the current state
- final EntityDeltaList contactDeltaList = mContactData.createEntityDeltaList();
- final EntityDelta rawContactEntityDelta = contactDeltaList.get(0);
+ final RawContactDeltaList contactDeltaList = mContactData.createRawContactDeltaList();
+ final RawContactDelta rawContactEntityDelta = contactDeltaList.get(0);
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
- final ValuesDelta values = rawContactEntityDelta.getValues();
- final String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
- final String dataSet = values.getAsString(RawContacts.DATA_SET);
- final AccountType type = accountTypes.getAccountType(accountType, dataSet);
+ final AccountType type = rawContactEntityDelta.getAccountType(accountTypes);
final DataKind groupMembershipKind = type.getKindForMimetype(
GroupMembership.CONTENT_ITEM_TYPE);
- final ValuesDelta entry = EntityModifier.insertChild(rawContactEntityDelta,
+ final ValuesDelta entry = RawContactModifier.insertChild(rawContactEntityDelta,
groupMembershipKind);
- entry.put(GroupMembership.GROUP_ROW_ID, defaultGroupId);
+ entry.setGroupRowId(defaultGroupId);
// and fire off the intent. we don't need a callback, as the database listener
// should update the ui
@@ -2199,7 +2178,7 @@
private final LayoutInflater mInflater;
private final ArrayList<AccountType> mAccountTypes;
- public InvitableAccountTypesAdapter(Context context, ContactLoader.Result contactData) {
+ public InvitableAccountTypesAdapter(Context context, Contact contactData) {
mContext = context;
mInflater = LayoutInflater.from(context);
final List<AccountType> types = contactData.getInvitableAccountTypes();
diff --git a/src/com/android/contacts/detail/ContactDetailFragmentCarousel.java b/src/com/android/contacts/detail/ContactDetailFragmentCarousel.java
index 08ed87b..a66baa5 100644
--- a/src/com/android/contacts/detail/ContactDetailFragmentCarousel.java
+++ b/src/com/android/contacts/detail/ContactDetailFragmentCarousel.java
@@ -16,18 +16,18 @@
package com.android.contacts.detail;
-import com.android.contacts.R;
-import com.android.contacts.widget.FrameLayoutWithOverlay;
-
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
-import android.view.ViewPropertyAnimator;
import android.view.View.OnTouchListener;
+import android.view.ViewPropertyAnimator;
import android.widget.HorizontalScrollView;
+import com.android.contacts.R;
+import com.android.contacts.widget.FrameLayoutWithOverlay;
+
/**
* This is a horizontally scrolling carousel with 2 fragments: one to see info about the contact and
* one to see updates from the contact. Depending on the scroll position and user selection of which
diff --git a/src/com/android/contacts/detail/ContactDetailLayoutController.java b/src/com/android/contacts/detail/ContactDetailLayoutController.java
index 2c18d4f..fca426c 100644
--- a/src/com/android/contacts/detail/ContactDetailLayoutController.java
+++ b/src/com/android/contacts/detail/ContactDetailLayoutController.java
@@ -16,16 +16,6 @@
package com.android.contacts.detail;
-import com.android.contacts.ContactLoader;
-
-import com.android.contacts.NfcHandler;
-import com.android.contacts.R;
-import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
-import com.android.contacts.util.PhoneCapabilityTester;
-import com.android.contacts.util.UriUtils;
-import com.android.contacts.widget.FrameLayoutWithOverlay;
-import com.android.contacts.widget.TransitionAnimationView;
-
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
@@ -44,6 +34,15 @@
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
+import com.android.contacts.NfcHandler;
+import com.android.contacts.R;
+import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
+import com.android.contacts.model.Contact;
+import com.android.contacts.util.PhoneCapabilityTester;
+import com.android.contacts.util.UriUtils;
+import com.android.contacts.widget.FrameLayoutWithOverlay;
+import com.android.contacts.widget.TransitionAnimationView;
+
/**
* Determines the layout of the contact card.
*/
@@ -103,7 +102,7 @@
private final ContactDetailFragment.Listener mContactDetailFragmentListener;
- private ContactLoader.Result mContactData;
+ private Contact mContactData;
private Uri mContactUri;
private boolean mTabCarouselIsAnimating;
@@ -271,7 +270,7 @@
}
}
- public void setContactData(ContactLoader.Result data) {
+ public void setContactData(Contact data) {
final boolean contactWasLoaded;
final boolean contactHadUpdates;
final boolean isDifferentContact;
diff --git a/src/com/android/contacts/detail/ContactDetailPhotoSetter.java b/src/com/android/contacts/detail/ContactDetailPhotoSetter.java
index dffb37b..eb832e9 100644
--- a/src/com/android/contacts/detail/ContactDetailPhotoSetter.java
+++ b/src/com/android/contacts/detail/ContactDetailPhotoSetter.java
@@ -26,9 +26,9 @@
import android.widget.ImageView;
import com.android.contacts.ContactPhotoManager;
-import com.android.contacts.ContactLoader.Result;
import com.android.contacts.activities.PhotoSelectionActivity;
-import com.android.contacts.model.EntityDeltaList;
+import com.android.contacts.model.Contact;
+import com.android.contacts.model.RawContactDeltaList;
import com.android.contacts.util.ImageViewDrawableSetter;
/**
@@ -36,7 +36,7 @@
* photo.
*/
public class ContactDetailPhotoSetter extends ImageViewDrawableSetter {
- public OnClickListener setupContactPhotoForClick(Context context, Result contactData,
+ public OnClickListener setupContactPhotoForClick(Context context, Contact contactData,
ImageView photoView, boolean expandPhotoOnClick) {
setTarget(photoView);
Bitmap bitmap = setCompressedImage(contactData.getPhotoBinaryData());
@@ -46,12 +46,12 @@
private static final class PhotoClickListener implements OnClickListener {
private final Context mContext;
- private final Result mContactData;
+ private final Contact mContactData;
private final Bitmap mPhotoBitmap;
private final byte[] mPhotoBytes;
private final boolean mExpandPhotoOnClick;
- public PhotoClickListener(Context context, Result contactData, Bitmap photoBitmap,
+ public PhotoClickListener(Context context, Contact contactData, Bitmap photoBitmap,
byte[] photoBytes, boolean expandPhotoOnClick) {
mContext = context;
mContactData = contactData;
@@ -63,7 +63,7 @@
@Override
public void onClick(View v) {
// Assemble the intent.
- EntityDeltaList delta = mContactData.createEntityDeltaList();
+ RawContactDeltaList delta = mContactData.createRawContactDeltaList();
// Find location and bounds of target view, adjusting based on the
// assumed local density.
@@ -96,7 +96,7 @@
}
}
- private OnClickListener setupClickListener(Context context, Result contactData, Bitmap bitmap,
+ private OnClickListener setupClickListener(Context context, Contact contactData, Bitmap bitmap,
boolean expandPhotoOnClick) {
final ImageView target = getTarget();
if (target == null) return null;
diff --git a/src/com/android/contacts/detail/ContactDetailTabCarousel.java b/src/com/android/contacts/detail/ContactDetailTabCarousel.java
index 3929281..540f001 100644
--- a/src/com/android/contacts/detail/ContactDetailTabCarousel.java
+++ b/src/com/android/contacts/detail/ContactDetailTabCarousel.java
@@ -16,16 +16,10 @@
package com.android.contacts.detail;
-import com.android.contacts.R;
-import com.android.contacts.ContactLoader;
-import com.android.contacts.detail.ContactDetailPhotoSetter;
-import com.android.contacts.util.MoreMath;
-import com.android.contacts.util.PhoneCapabilityTester;
-import com.android.contacts.util.SchedulingUtils;
-
import android.content.Context;
import android.content.res.Resources;
import android.util.AttributeSet;
+import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
@@ -35,7 +29,10 @@
import android.widget.ImageView;
import android.widget.TextView;
-import android.util.Log;
+import com.android.contacts.R;
+import com.android.contacts.model.Contact;
+import com.android.contacts.util.MoreMath;
+import com.android.contacts.util.SchedulingUtils;
/**
* This is a horizontally scrolling carousel with 2 tabs: one to see info about the contact and
@@ -467,7 +464,7 @@
* Loads the data from the Loader-Result. This is the only function that has to be called
* from the outside to fully setup the View
*/
- public void loadData(ContactLoader.Result contactData) {
+ public void loadData(Contact contactData) {
if (contactData == null) return;
// TODO: Move this into the {@link CarouselTab} class when the updates
diff --git a/src/com/android/contacts/detail/ContactDetailUpdatesFragment.java b/src/com/android/contacts/detail/ContactDetailUpdatesFragment.java
index e8ce622..88c30c2 100644
--- a/src/com/android/contacts/detail/ContactDetailUpdatesFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailUpdatesFragment.java
@@ -16,14 +16,6 @@
package com.android.contacts.detail;
-import com.android.contacts.ContactLoader;
-import com.android.contacts.R;
-import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
-import com.android.contacts.detail.ContactDetailDisplayUtils.StreamPhotoTag;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.util.StreamItemEntry;
-
import android.app.ListFragment;
import android.content.ContentUris;
import android.content.Intent;
@@ -32,16 +24,23 @@
import android.provider.ContactsContract.StreamItems;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
+import com.android.contacts.R;
+import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
+import com.android.contacts.detail.ContactDetailDisplayUtils.StreamPhotoTag;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.Contact;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.util.StreamItemEntry;
+
public class ContactDetailUpdatesFragment extends ListFragment implements FragmentKeyListener {
private static final String TAG = "ContactDetailUpdatesFragment";
- private ContactLoader.Result mContactData;
+ private Contact mContactData;
private Uri mLookupUri;
private LayoutInflater mInflater;
@@ -122,7 +121,7 @@
}
}
- public void setData(Uri lookupUri, ContactLoader.Result result) {
+ public void setData(Uri lookupUri, Contact result) {
if (result == null) {
return;
}
diff --git a/src/com/android/contacts/detail/ContactLoaderFragment.java b/src/com/android/contacts/detail/ContactLoaderFragment.java
index c56f659..6a69744 100644
--- a/src/com/android/contacts/detail/ContactLoaderFragment.java
+++ b/src/com/android/contacts/detail/ContactLoaderFragment.java
@@ -16,15 +16,6 @@
package com.android.contacts.detail;
-import com.android.contacts.ContactLoader;
-import com.android.contacts.ContactSaveService;
-import com.android.contacts.R;
-import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
-import com.android.contacts.list.ShortcutIntentBuilder;
-import com.android.contacts.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
-import com.android.contacts.util.PhoneCapabilityTester;
-import com.android.internal.util.Objects;
-
import android.app.Activity;
import android.app.Fragment;
import android.app.LoaderManager;
@@ -48,6 +39,16 @@
import android.view.ViewGroup;
import android.widget.Toast;
+import com.android.contacts.ContactSaveService;
+import com.android.contacts.R;
+import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
+import com.android.contacts.list.ShortcutIntentBuilder;
+import com.android.contacts.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
+import com.android.contacts.model.Contact;
+import com.android.contacts.model.ContactLoader;
+import com.android.contacts.util.PhoneCapabilityTester;
+import com.android.internal.util.Objects;
+
/**
* This is an invisible worker {@link Fragment} that loads the contact details for the contact card.
* The data is then passed to the listener, who can then pass the data to other {@link View}s.
@@ -84,7 +85,7 @@
/**
* Contact details have finished loading.
*/
- public void onDetailsLoaded(ContactLoader.Result result);
+ public void onDetailsLoaded(Contact result);
/**
* User decided to go to Edit-Mode
@@ -107,7 +108,7 @@
private Uri mLookupUri;
private ContactLoaderFragmentListener mListener;
- private ContactLoader.Result mContactData;
+ private Contact mContactData;
public ContactLoaderFragment() {
}
@@ -179,10 +180,10 @@
/**
* The listener for the detail loader
*/
- private final LoaderManager.LoaderCallbacks<ContactLoader.Result> mDetailLoaderListener =
- new LoaderCallbacks<ContactLoader.Result>() {
+ private final LoaderManager.LoaderCallbacks<Contact> mDetailLoaderListener =
+ new LoaderCallbacks<Contact>() {
@Override
- public Loader<ContactLoader.Result> onCreateLoader(int id, Bundle args) {
+ public Loader<Contact> onCreateLoader(int id, Bundle args) {
Uri lookupUri = args.getParcelable(LOADER_ARG_CONTACT_URI);
return new ContactLoader(mContext, lookupUri, true /* loadGroupMetaData */,
true /* loadStreamItems */, true /* load invitable account types */,
@@ -190,7 +191,7 @@
}
@Override
- public void onLoadFinished(Loader<ContactLoader.Result> loader, ContactLoader.Result data) {
+ public void onLoadFinished(Loader<Contact> loader, Contact data) {
if (!mLookupUri.equals(data.getRequestedUri())) {
Log.e(TAG, "Different URI: requested=" + mLookupUri + " actual=" + data);
return;
@@ -219,7 +220,7 @@
}
@Override
- public void onLoaderReset(Loader<ContactLoader.Result> loader) {}
+ public void onLoaderReset(Loader<Contact> loader) {}
};
@Override
@@ -461,14 +462,14 @@
/** Toggles whether to load stream items. Just for debugging */
public void toggleLoadStreamItems() {
- Loader<ContactLoader.Result> loaderObj = getLoaderManager().getLoader(LOADER_DETAILS);
+ Loader<Contact> loaderObj = getLoaderManager().getLoader(LOADER_DETAILS);
ContactLoader loader = (ContactLoader) loaderObj;
loader.setLoadStreamItems(!loader.getLoadStreamItems());
}
/** Returns whether to load stream items. Just for debugging */
public boolean getLoadStreamItems() {
- Loader<ContactLoader.Result> loaderObj = getLoaderManager().getLoader(LOADER_DETAILS);
+ Loader<Contact> loaderObj = getLoaderManager().getLoader(LOADER_DETAILS);
ContactLoader loader = (ContactLoader) loaderObj;
return loader != null && loader.getLoadStreamItems();
}
diff --git a/src/com/android/contacts/detail/PhotoSelectionHandler.java b/src/com/android/contacts/detail/PhotoSelectionHandler.java
index 569012e..b5e406a 100644
--- a/src/com/android/contacts/detail/PhotoSelectionHandler.java
+++ b/src/com/android/contacts/detail/PhotoSelectionHandler.java
@@ -39,12 +39,12 @@
import com.android.contacts.R;
import com.android.contacts.editor.PhotoActionPopup;
-import com.android.contacts.model.AccountType;
import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.model.EntityDeltaList;
-import com.android.contacts.model.EntityModifier;
+import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.RawContactDeltaList;
import com.android.contacts.util.ContactPhotoUtils;
import java.io.File;
@@ -64,12 +64,12 @@
private final View mPhotoView;
private final int mPhotoMode;
private final int mPhotoPickSize;
- private final EntityDeltaList mState;
+ private final RawContactDeltaList mState;
private final boolean mIsDirectoryContact;
private ListPopupWindow mPopup;
public PhotoSelectionHandler(Context context, View photoView, int photoMode,
- boolean isDirectoryContact, EntityDeltaList state) {
+ boolean isDirectoryContact, RawContactDeltaList state) {
mContext = context;
mPhotoView = photoView;
mPhotoMode = photoMode;
@@ -162,12 +162,12 @@
* or null if the photo could not be parsed or none of the accounts associated with the
* contact are writable.
*/
- public EntityDeltaList getDeltaForAttachingPhotoToContact() {
+ public RawContactDeltaList getDeltaForAttachingPhotoToContact() {
// Find the first writable entity.
int writableEntityIndex = getWritableEntityIndex();
if (writableEntityIndex != -1) {
// We are guaranteed to have contact data if we have a writable entity index.
- final EntityDelta delta = mState.get(writableEntityIndex);
+ final RawContactDelta delta = mState.get(writableEntityIndex);
// Need to find the right account so that EntityModifier knows which fields to add
final ContentValues entityValues = delta.getValues().getCompleteValues();
@@ -176,10 +176,10 @@
final AccountType accountType = AccountTypeManager.getInstance(mContext).getAccountType(
type, dataSet);
- final ValuesDelta child = EntityModifier.ensureKindExists(
+ final ValuesDelta child = RawContactModifier.ensureKindExists(
delta, accountType, Photo.CONTENT_ITEM_TYPE);
child.setFromTemplate(false);
- child.put(Photo.IS_SUPER_PRIMARY, 1);
+ child.setSuperPrimary(true);
return mState;
}
diff --git a/src/com/android/contacts/detail/StreamItemAdapter.java b/src/com/android/contacts/detail/StreamItemAdapter.java
index 089cb07..15219cd 100644
--- a/src/com/android/contacts/detail/StreamItemAdapter.java
+++ b/src/com/android/contacts/detail/StreamItemAdapter.java
@@ -16,18 +16,18 @@
package com.android.contacts.detail;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.util.StreamItemEntry;
-import com.google.android.collect.Lists;
-
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
+import com.android.contacts.R;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.util.StreamItemEntry;
+import com.google.common.collect.Lists;
+
import java.util.List;
/**
diff --git a/src/com/android/contacts/dialog/ClearFrequentsDialog.java b/src/com/android/contacts/dialog/ClearFrequentsDialog.java
index 4aeaf1c..800ba9d 100644
--- a/src/com/android/contacts/dialog/ClearFrequentsDialog.java
+++ b/src/com/android/contacts/dialog/ClearFrequentsDialog.java
@@ -16,8 +16,6 @@
package com.android.contacts.dialog;
-import com.android.contacts.R;
-
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
@@ -29,6 +27,8 @@
import android.os.Bundle;
import android.provider.ContactsContract;
+import com.android.contacts.R;
+
/**
* Dialog that clears the frequently contacted list after confirming with the user.
*/
diff --git a/src/com/android/contacts/editor/AggregationSuggestionEngine.java b/src/com/android/contacts/editor/AggregationSuggestionEngine.java
index c340f96..0da05e8 100644
--- a/src/com/android/contacts/editor/AggregationSuggestionEngine.java
+++ b/src/com/android/contacts/editor/AggregationSuggestionEngine.java
@@ -16,9 +16,6 @@
package com.android.contacts.editor;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.google.android.collect.Lists;
-
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
@@ -40,6 +37,9 @@
import android.provider.ContactsContract.RawContacts;
import android.text.TextUtils;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.google.common.collect.Lists;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
diff --git a/src/com/android/contacts/editor/AggregationSuggestionView.java b/src/com/android/contacts/editor/AggregationSuggestionView.java
index 9d7e16a..7327a4c 100644
--- a/src/com/android/contacts/editor/AggregationSuggestionView.java
+++ b/src/com/android/contacts/editor/AggregationSuggestionView.java
@@ -16,13 +16,6 @@
package com.android.contacts.editor;
-import com.android.contacts.R;
-import com.android.contacts.editor.AggregationSuggestionEngine.RawContact;
-import com.android.contacts.editor.AggregationSuggestionEngine.Suggestion;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-import com.google.android.collect.Lists;
-
import android.content.Context;
import android.graphics.BitmapFactory;
import android.net.Uri;
@@ -32,6 +25,13 @@
import android.widget.LinearLayout;
import android.widget.TextView;
+import com.android.contacts.R;
+import com.android.contacts.editor.AggregationSuggestionEngine.RawContact;
+import com.android.contacts.editor.AggregationSuggestionEngine.Suggestion;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountType;
+import com.google.common.collect.Lists;
+
import java.util.ArrayList;
import java.util.List;
diff --git a/src/com/android/contacts/editor/BaseRawContactEditorView.java b/src/com/android/contacts/editor/BaseRawContactEditorView.java
index b2d7186..66fc864 100644
--- a/src/com/android/contacts/editor/BaseRawContactEditorView.java
+++ b/src/com/android/contacts/editor/BaseRawContactEditorView.java
@@ -16,15 +16,7 @@
package com.android.contacts.editor;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountType.EditType;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.model.EntityModifier;
-
import android.content.Context;
-import android.content.Entity;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.provider.ContactsContract.CommonDataKinds.Photo;
@@ -35,14 +27,21 @@
import android.view.ViewGroup;
import android.widget.LinearLayout;
+import com.android.contacts.R;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountType.EditType;
+
/**
* Base view that provides common code for the editor interaction for a specific
- * RawContact represented through an {@link EntityDelta}.
+ * RawContact represented through an {@link RawContactDelta}.
* <p>
* Internal updates are performed against {@link ValuesDelta} so that the
- * source {@link Entity} can be swapped out. Any state-based changes, such as
+ * source {@link RawContact} can be swapped out. Any state-based changes, such as
* adding {@link Data} rows or changing {@link EditType}, are performed through
- * {@link EntityModifier} to ensure that {@link AccountType} are enforced.
+ * {@link RawContactModifier} to ensure that {@link AccountType} are enforced.
*/
public abstract class BaseRawContactEditorView extends LinearLayout {
@@ -78,7 +77,7 @@
/**
* Assign the given {@link Bitmap} to the internal {@link PhotoEditorView}
- * for the {@link EntityDelta} currently being edited.
+ * for the {@link RawContactDelta} currently being edited.
*/
public void setPhotoBitmap(Bitmap bitmap) {
mPhoto.setPhotoBitmap(bitmap);
@@ -115,10 +114,10 @@
/**
* Set the internal state for this view, given a current
- * {@link EntityDelta} state and the {@link AccountType} that
+ * {@link RawContactDelta} state and the {@link AccountType} that
* apply to that state.
*/
- public abstract void setState(EntityDelta state, AccountType source, ViewIdGenerator vig,
+ public abstract void setState(RawContactDelta state, AccountType source, ViewIdGenerator vig,
boolean isProfile);
/* package */ void setExpanded(boolean value) {
diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
index a4e4db4..780279e 100644
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorFragment.java
@@ -16,29 +16,6 @@
package com.android.contacts.editor;
-import com.android.contacts.ContactLoader;
-import com.android.contacts.ContactSaveService;
-import com.android.contacts.GroupMetaDataLoader;
-import com.android.contacts.R;
-import com.android.contacts.activities.ContactEditorAccountsChangedActivity;
-import com.android.contacts.activities.ContactEditorActivity;
-import com.android.contacts.activities.JoinContactActivity;
-import com.android.contacts.detail.PhotoSelectionHandler;
-import com.android.contacts.editor.AggregationSuggestionEngine.Suggestion;
-import com.android.contacts.editor.Editor.EditorListener;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountWithDataSet;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.model.EntityDeltaList;
-import com.android.contacts.model.EntityModifier;
-import com.android.contacts.model.GoogleAccountType;
-import com.android.contacts.util.AccountsListAdapter;
-import com.android.contacts.util.ContactPhotoUtils;
-import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
-import com.android.contacts.util.HelpUtils;
-
import android.accounts.Account;
import android.app.Activity;
import android.app.AlertDialog;
@@ -52,7 +29,6 @@
import android.content.Context;
import android.content.CursorLoader;
import android.content.DialogInterface;
-import android.content.Entity;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
@@ -85,6 +61,32 @@
import android.widget.ListPopupWindow;
import android.widget.Toast;
+import com.android.contacts.ContactSaveService;
+import com.android.contacts.GroupMetaDataLoader;
+import com.android.contacts.R;
+import com.android.contacts.activities.ContactEditorAccountsChangedActivity;
+import com.android.contacts.activities.ContactEditorActivity;
+import com.android.contacts.activities.JoinContactActivity;
+import com.android.contacts.detail.PhotoSelectionHandler;
+import com.android.contacts.editor.AggregationSuggestionEngine.Suggestion;
+import com.android.contacts.editor.Editor.EditorListener;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.Contact;
+import com.android.contacts.model.ContactLoader;
+import com.android.contacts.model.RawContact;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.RawContactDeltaList;
+import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.model.account.GoogleAccountType;
+import com.android.contacts.util.AccountsListAdapter;
+import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
+import com.android.contacts.util.ContactPhotoUtils;
+import com.android.contacts.util.HelpUtils;
+import com.google.common.collect.ImmutableList;
+
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
@@ -224,7 +226,7 @@
private ContactEditorUtils mEditorUtils;
private LinearLayout mContent;
- private EntityDeltaList mState;
+ private RawContactDeltaList mState;
private ViewIdGenerator mViewIdGenerator;
@@ -420,7 +422,7 @@
mViewIdGenerator = new ViewIdGenerator();
} else {
// Read state from savedState. No loading involved here
- mState = savedState.<EntityDeltaList> getParcelable(KEY_EDIT_STATE);
+ mState = savedState.<RawContactDeltaList> getParcelable(KEY_EDIT_STATE);
mRawContactIdRequestingPhoto = savedState.getLong(
KEY_RAW_CONTACT_ID_REQUESTING_PHOTO);
mViewIdGenerator = savedState.getParcelable(KEY_VIEW_ID_GENERATOR);
@@ -436,7 +438,7 @@
}
}
- public void setData(ContactLoader.Result data) {
+ public void setData(Contact data) {
// If we have already loaded data, we do not want to change it here to not confuse the user
if (mState != null) {
Log.v(TAG, "Ignoring background change. This will have to be rebased later");
@@ -444,19 +446,17 @@
}
// See if this edit operation needs to be redirected to a custom editor
- ArrayList<Entity> entities = data.getEntities();
- if (entities.size() == 1) {
- Entity entity = entities.get(0);
- ContentValues entityValues = entity.getEntityValues();
- String type = entityValues.getAsString(RawContacts.ACCOUNT_TYPE);
- String dataSet = entityValues.getAsString(RawContacts.DATA_SET);
- AccountType accountType = AccountTypeManager.getInstance(mContext).getAccountType(
- type, dataSet);
+ ImmutableList<RawContact> rawContacts = data.getRawContacts();
+ if (rawContacts.size() == 1) {
+ RawContact rawContact = rawContacts.get(0);
+ String type = rawContact.getAccountTypeString();
+ String dataSet = rawContact.getDataSet();
+ AccountType accountType = rawContact.getAccountType();
if (accountType.getEditContactActivityClassName() != null &&
!accountType.areContactsWritable()) {
if (mListener != null) {
- String name = entityValues.getAsString(RawContacts.ACCOUNT_NAME);
- long rawContactId = entityValues.getAsLong(RawContacts.Entity._ID);
+ String name = rawContact.getAccountName();
+ long rawContactId = rawContact.getId();
mListener.onCustomEditContactActivityRequested(
new AccountWithDataSet(name, type, dataSet),
ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
@@ -474,10 +474,10 @@
mListener.onCustomEditContactActivityRequested(account, uri, null, false);
}
- private void bindEditorsForExistingContact(ContactLoader.Result contact) {
+ private void bindEditorsForExistingContact(Contact contact) {
setEnabled(true);
- mState = contact.createEntityDeltaList();
+ mState = contact.createRawContactDeltaList();
setIntentExtras(mIntentExtras);
mIntentExtras = null;
@@ -486,7 +486,7 @@
boolean localProfileExists = false;
if (mIsUserProfile) {
- for (EntityDelta state : mState) {
+ for (RawContactDelta state : mState) {
// For profile contacts, we need a different query URI
state.setProfileQueryUri();
// Try to find a local profile contact
@@ -496,11 +496,11 @@
}
// Editor should always present a local profile for editing
if (!localProfileExists) {
- final ContentValues values = new ContentValues();
- values.putNull(RawContacts.ACCOUNT_NAME);
- values.putNull(RawContacts.ACCOUNT_TYPE);
- values.putNull(RawContacts.DATA_SET);
- EntityDelta insert = new EntityDelta(ValuesDelta.fromAfter(values));
+ final RawContact rawContact = new RawContact(mContext);
+ rawContact.setAccountToLocal();
+
+ RawContactDelta insert = new RawContactDelta(ValuesDelta.fromAfter(
+ rawContact.getValues()));
insert.setProfileQueryUri();
mState.add(insert);
}
@@ -519,13 +519,11 @@
}
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
- for (EntityDelta state : mState) {
- final String accountType = state.getValues().getAsString(RawContacts.ACCOUNT_TYPE);
- final String dataSet = state.getValues().getAsString(RawContacts.DATA_SET);
- final AccountType type = accountTypes.getAccountType(accountType, dataSet);
+ for (RawContactDelta state : mState) {
+ final AccountType type = state.getAccountType(accountTypes);
if (type.areContactsWritable()) {
// Apply extras to the first writable raw contact only
- EntityModifier.parseExtras(mContext, type, state, extras);
+ RawContactModifier.parseExtras(mContext, type, state, extras);
break;
}
}
@@ -604,7 +602,8 @@
* @param newAccount New account to be used.
*/
private void rebindEditorsForNewContact(
- EntityDelta oldState, AccountWithDataSet oldAccount, AccountWithDataSet newAccount) {
+ RawContactDelta oldState, AccountWithDataSet oldAccount,
+ AccountWithDataSet newAccount) {
AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
AccountType oldAccountType = accountTypes.getAccountType(
oldAccount.type, oldAccount.dataSet);
@@ -628,36 +627,34 @@
}
private void bindEditorsForNewContact(AccountWithDataSet newAccount,
- final AccountType newAccountType, EntityDelta oldState, AccountType oldAccountType) {
+ final AccountType newAccountType, RawContactDelta oldState,
+ AccountType oldAccountType) {
mStatus = Status.EDITING;
- final ContentValues values = new ContentValues();
+ final RawContact rawContact = new RawContact(mContext);
if (newAccount != null) {
- values.put(RawContacts.ACCOUNT_NAME, newAccount.name);
- values.put(RawContacts.ACCOUNT_TYPE, newAccount.type);
- values.put(RawContacts.DATA_SET, newAccount.dataSet);
+ rawContact.setAccount(newAccount);
} else {
- values.putNull(RawContacts.ACCOUNT_NAME);
- values.putNull(RawContacts.ACCOUNT_TYPE);
- values.putNull(RawContacts.DATA_SET);
+ rawContact.setAccountToLocal();
}
- EntityDelta insert = new EntityDelta(ValuesDelta.fromAfter(values));
+ RawContactDelta insert = new RawContactDelta(ValuesDelta.fromAfter(rawContact.getValues()));
if (oldState == null) {
// Parse any values from incoming intent
- EntityModifier.parseExtras(mContext, newAccountType, insert, mIntentExtras);
+ RawContactModifier.parseExtras(mContext, newAccountType, insert, mIntentExtras);
} else {
- EntityModifier.migrateStateForNewContact(mContext, oldState, insert,
+ RawContactModifier.migrateStateForNewContact(mContext, oldState, insert,
oldAccountType, newAccountType);
}
// Ensure we have some default fields (if the account type does not support a field,
// ensureKind will not add it, so it is safe to add e.g. Event)
- EntityModifier.ensureKindExists(insert, newAccountType, Phone.CONTENT_ITEM_TYPE);
- EntityModifier.ensureKindExists(insert, newAccountType, Email.CONTENT_ITEM_TYPE);
- EntityModifier.ensureKindExists(insert, newAccountType, Organization.CONTENT_ITEM_TYPE);
- EntityModifier.ensureKindExists(insert, newAccountType, Event.CONTENT_ITEM_TYPE);
- EntityModifier.ensureKindExists(insert, newAccountType, StructuredPostal.CONTENT_ITEM_TYPE);
+ RawContactModifier.ensureKindExists(insert, newAccountType, Phone.CONTENT_ITEM_TYPE);
+ RawContactModifier.ensureKindExists(insert, newAccountType, Email.CONTENT_ITEM_TYPE);
+ RawContactModifier.ensureKindExists(insert, newAccountType, Organization.CONTENT_ITEM_TYPE);
+ RawContactModifier.ensureKindExists(insert, newAccountType, Event.CONTENT_ITEM_TYPE);
+ RawContactModifier.ensureKindExists(insert, newAccountType,
+ StructuredPostal.CONTENT_ITEM_TYPE);
// Set the correct URI for saving the contact as a profile
if (mNewLocalProfile) {
@@ -666,7 +663,7 @@
if (mState == null) {
// Create state if none exists yet
- mState = EntityDeltaList.fromSingle(insert);
+ mState = RawContactDeltaList.fromSingle(insert);
} else {
// Add contact onto end of existing state
mState.add(insert);
@@ -690,14 +687,11 @@
int numRawContacts = mState.size();
for (int i = 0; i < numRawContacts; i++) {
// TODO ensure proper ordering of entities in the list
- final EntityDelta entity = mState.get(i);
- final ValuesDelta values = entity.getValues();
- if (!values.isVisible()) continue;
+ final RawContactDelta rawContactDelta = mState.get(i);
+ if (!rawContactDelta.isVisible()) continue;
- final String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
- final String dataSet = values.getAsString(RawContacts.DATA_SET);
- final AccountType type = accountTypes.getAccountType(accountType, dataSet);
- final long rawContactId = values.getAsLong(RawContacts._ID);
+ final AccountType type = rawContactDelta.getAccountType(accountTypes);
+ final long rawContactId = rawContactDelta.getRawContactId();
final BaseRawContactEditorView editor;
if (!type.areContactsWritable()) {
@@ -724,7 +718,7 @@
mContent.addView(editor);
- editor.setState(entity, type, mViewIdGenerator, isEditingUserProfile());
+ editor.setState(rawContactDelta, type, mViewIdGenerator, isEditingUserProfile());
// Set up the photo handler.
bindPhotoHandler(editor, type, mState);
@@ -797,7 +791,7 @@
}
private void bindPhotoHandler(BaseRawContactEditorView editor, AccountType type,
- EntityDeltaList state) {
+ RawContactDeltaList state) {
final int mode;
if (type.areContactsWritable()) {
if (editor.hasSetPhoto()) {
@@ -852,11 +846,10 @@
// Find the associated account for this contact (retrieve it here because there are
// multiple paths to creating a contact and this ensures we always have the correct
// account).
- final EntityDelta entity = mState.get(0);
- final ValuesDelta values = entity.getValues();
- String name = values.getAsString(RawContacts.ACCOUNT_NAME);
- String type = values.getAsString(RawContacts.ACCOUNT_TYPE);
- String dataSet = values.getAsString(RawContacts.DATA_SET);
+ final RawContactDelta rawContactDelta = mState.get(0);
+ String name = rawContactDelta.getAccountName();
+ String type = rawContactDelta.getAccountType();
+ String dataSet = rawContactDelta.getDataSet();
AccountWithDataSet account = (name == null || type == null) ? null :
new AccountWithDataSet(name, type, dataSet);
@@ -864,12 +857,11 @@
}
private void addAccountSwitcher(
- final EntityDelta currentState, BaseRawContactEditorView editor) {
- ValuesDelta values = currentState.getValues();
+ final RawContactDelta currentState, BaseRawContactEditorView editor) {
final AccountWithDataSet currentAccount = new AccountWithDataSet(
- values.getAsString(RawContacts.ACCOUNT_NAME),
- values.getAsString(RawContacts.ACCOUNT_TYPE),
- values.getAsString(RawContacts.DATA_SET));
+ currentState.getAccountName(),
+ currentState.getAccountType(),
+ currentState.getDataSet());
final View accountView = editor.findViewById(R.id.account);
final View anchorView = editor.findViewById(R.id.account_container);
accountView.setOnClickListener(new View.OnClickListener() {
@@ -1005,7 +997,7 @@
*/
private boolean hasPendingChanges() {
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
- return EntityModifier.hasChanges(mState, accountTypes);
+ return RawContactModifier.hasChanges(mState, accountTypes);
}
/**
@@ -1209,10 +1201,8 @@
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
int size = mState.size();
for (int i = 0; i < size; i++) {
- ValuesDelta values = mState.get(i).getValues();
- final String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
- final String dataSet = values.getAsString(RawContacts.DATA_SET);
- final AccountType type = accountTypes.getAccountType(accountType, dataSet);
+ RawContactDelta entity = mState.get(i);
+ final AccountType type = entity.getAccountType(accountTypes);
if (type.areContactsWritable()) {
return true;
}
@@ -1273,12 +1263,12 @@
Bundle intentExtras, boolean redirect);
}
- private class EntityDeltaComparator implements Comparator<EntityDelta> {
+ private class EntityDeltaComparator implements Comparator<RawContactDelta> {
/**
* Compare EntityDeltas for sorting the stack of editors.
*/
@Override
- public int compare(EntityDelta one, EntityDelta two) {
+ public int compare(RawContactDelta one, RawContactDelta two) {
// Check direct equality
if (one.equals(two)) {
return 0;
@@ -1333,11 +1323,9 @@
}
// Check account name
- ValuesDelta oneValues = one.getValues();
- String oneAccount = oneValues.getAsString(RawContacts.ACCOUNT_NAME);
+ String oneAccount = one.getAccountName();
if (oneAccount == null) oneAccount = "";
- ValuesDelta twoValues = two.getValues();
- String twoAccount = twoValues.getAsString(RawContacts.ACCOUNT_NAME);
+ String twoAccount = two.getAccountName();
if (twoAccount == null) twoAccount = "";
value = oneAccount.compareTo(twoAccount);
if (value != 0) {
@@ -1345,8 +1333,8 @@
}
// Both are in the same account, fall back to contact ID
- Long oneId = oneValues.getAsLong(RawContacts._ID);
- Long twoId = twoValues.getAsLong(RawContacts._ID);
+ Long oneId = one.getRawContactId();
+ Long twoId = two.getRawContactId();
if (oneId == null) {
return -1;
} else if (twoId == null) {
@@ -1362,7 +1350,7 @@
*/
protected long getContactId() {
if (mState != null) {
- for (EntityDelta rawContact : mState) {
+ for (RawContactDelta rawContact : mState) {
Long contactId = rawContact.getValues().getAsLong(RawContacts.CONTACT_ID);
if (contactId != null) {
return contactId;
@@ -1662,14 +1650,13 @@
int countWithPicture = 0;
final int numEntities = mState.size();
for (int i = 0; i < numEntities; i++) {
- final EntityDelta entity = mState.get(i);
- final ValuesDelta values = entity.getValues();
- if (values.isVisible()) {
+ final RawContactDelta entity = mState.get(i);
+ if (entity.isVisible()) {
final ValuesDelta primary = entity.getPrimaryEntry(Photo.CONTENT_ITEM_TYPE);
- if (primary != null && primary.getAsByteArray(Photo.PHOTO) != null) {
+ if (primary != null && primary.getPhoto() != null) {
countWithPicture++;
} else {
- final long rawContactId = values.getAsLong(RawContacts._ID);
+ final long rawContactId = entity.getRawContactId();
final String path = mUpdatedPhotos.getString(String.valueOf(rawContactId));
if (path != null) {
final File file = new File(path);
@@ -1690,16 +1677,16 @@
/**
* The listener for the data loader
*/
- private final LoaderManager.LoaderCallbacks<ContactLoader.Result> mDataLoaderListener =
- new LoaderCallbacks<ContactLoader.Result>() {
+ private final LoaderManager.LoaderCallbacks<Contact> mDataLoaderListener =
+ new LoaderCallbacks<Contact>() {
@Override
- public Loader<ContactLoader.Result> onCreateLoader(int id, Bundle args) {
+ public Loader<Contact> onCreateLoader(int id, Bundle args) {
mLoaderStartTime = SystemClock.elapsedRealtime();
return new ContactLoader(mContext, mLookupUri, true);
}
@Override
- public void onLoadFinished(Loader<ContactLoader.Result> loader, ContactLoader.Result data) {
+ public void onLoadFinished(Loader<Contact> loader, Contact data) {
final long loaderCurrentTime = SystemClock.elapsedRealtime();
Log.v(TAG, "Time needed for loading: " + (loaderCurrentTime-mLoaderStartTime));
if (!data.isLoaded()) {
@@ -1719,7 +1706,7 @@
}
@Override
- public void onLoaderReset(Loader<ContactLoader.Result> loader) {
+ public void onLoaderReset(Loader<Contact> loader) {
}
};
@@ -1772,7 +1759,7 @@
private final PhotoActionListener mPhotoEditorListener;
public PhotoHandler(Context context, BaseRawContactEditorView editor, int photoMode,
- EntityDeltaList state) {
+ RawContactDeltaList state) {
super(context, editor.getPhotoEditor(), photoMode, false, state);
mEditor = editor;
mRawContactId = editor.getRawContactId();
diff --git a/src/com/android/contacts/editor/ContactEditorUtils.java b/src/com/android/contacts/editor/ContactEditorUtils.java
index 46006a0..2791c2d 100644
--- a/src/com/android/contacts/editor/ContactEditorUtils.java
+++ b/src/com/android/contacts/editor/ContactEditorUtils.java
@@ -16,14 +16,6 @@
package com.android.contacts.editor;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountWithDataSet;
-import com.android.contacts.test.NeededForTesting;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Sets;
-
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
@@ -34,6 +26,14 @@
import android.text.TextUtils;
import android.util.Log;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.test.NeededForTesting;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Sets;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
diff --git a/src/com/android/contacts/editor/Editor.java b/src/com/android/contacts/editor/Editor.java
index 1151afd..05336f2 100644
--- a/src/com/android/contacts/editor/Editor.java
+++ b/src/com/android/contacts/editor/Editor.java
@@ -16,12 +16,12 @@
package com.android.contacts.editor;
-import com.android.contacts.model.DataKind;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-
import android.provider.ContactsContract.Data;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.dataitem.DataKind;
+
/**
* Generic definition of something that edits a {@link Data} row through an
* {@link ValuesDelta} object.
@@ -60,7 +60,7 @@
* builds any needed views. Any changes performed by the user will be
* written back to that same object.
*/
- public void setValues(DataKind kind, ValuesDelta values, EntityDelta state, boolean readOnly,
+ public void setValues(DataKind kind, ValuesDelta values, RawContactDelta state, boolean readOnly,
ViewIdGenerator vig);
public void setDeletable(boolean deletable);
diff --git a/src/com/android/contacts/editor/EditorAnimator.java b/src/com/android/contacts/editor/EditorAnimator.java
index a16b425..5196f3f 100644
--- a/src/com/android/contacts/editor/EditorAnimator.java
+++ b/src/com/android/contacts/editor/EditorAnimator.java
@@ -16,10 +16,6 @@
package com.android.contacts.editor;
-import com.android.contacts.util.SchedulingUtils;
-
-import com.google.common.collect.Lists;
-
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorListenerAdapter;
@@ -30,6 +26,9 @@
import android.view.ViewParent;
import android.widget.LinearLayout;
+import com.android.contacts.util.SchedulingUtils;
+import com.google.common.collect.Lists;
+
import java.util.List;
/**
diff --git a/src/com/android/contacts/editor/EventFieldEditorView.java b/src/com/android/contacts/editor/EventFieldEditorView.java
index 538d4dc..77f2010 100644
--- a/src/com/android/contacts/editor/EventFieldEditorView.java
+++ b/src/com/android/contacts/editor/EventFieldEditorView.java
@@ -16,17 +16,6 @@
package com.android.contacts.editor;
-import com.android.contacts.R;
-import com.android.contacts.datepicker.DatePicker;
-import com.android.contacts.datepicker.DatePickerDialog;
-import com.android.contacts.datepicker.DatePickerDialog.OnDateSetListener;
-import com.android.contacts.model.AccountType.EditField;
-import com.android.contacts.model.AccountType.EventEditType;
-import com.android.contacts.model.DataKind;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.util.DateUtils;
-
import android.app.Dialog;
import android.content.Context;
import android.content.res.Resources;
@@ -36,6 +25,17 @@
import android.view.View;
import android.widget.Button;
+import com.android.contacts.R;
+import com.android.contacts.datepicker.DatePicker;
+import com.android.contacts.datepicker.DatePickerDialog;
+import com.android.contacts.datepicker.DatePickerDialog.OnDateSetListener;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.account.AccountType.EditField;
+import com.android.contacts.model.account.AccountType.EventEditType;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.contacts.util.DateUtils;
+
import java.text.ParsePosition;
import java.util.Calendar;
import java.util.Date;
@@ -108,7 +108,7 @@
}
@Override
- public void setValues(DataKind kind, ValuesDelta entry, EntityDelta state, boolean readOnly,
+ public void setValues(DataKind kind, ValuesDelta entry, RawContactDelta state, boolean readOnly,
ViewIdGenerator vig) {
if (kind.fieldList.size() != 1) throw new IllegalStateException("kind must have 1 field");
super.setValues(kind, entry, state, readOnly, vig);
@@ -203,7 +203,7 @@
final int oldYear, oldMonth, oldDay;
if (TextUtils.isEmpty(oldValue)) {
- // Default to January first, 30 years ago
+ // Default to January first of this year
oldYear = defaultYear;
oldMonth = 0;
oldDay = 1;
@@ -221,13 +221,25 @@
oldMonth = calendar.get(Calendar.MONTH);
oldDay = calendar.get(Calendar.DAY_OF_MONTH);
} else {
- final Date date2 = kind.dateFormatWithoutYear.parse(oldValue, position);
- // Don't understand the date, lets not change it
- if (date2 == null) return null;
- calendar.setTime(date2);
- oldYear = isYearOptional ? 0 : defaultYear;
- oldMonth = calendar.get(Calendar.MONTH);
- oldDay = calendar.get(Calendar.DAY_OF_MONTH);
+ // Unfortunately, we need a one-off hack for February 29th, because
+ // the parse functions assume 1970, which wasn't a leap year
+ // Caveat here: This won't catch AccountTypes that allow omitting the year but
+ // require a time of the day. But as we don't have any of those at the moment,
+ // this shouldn't be an issue
+ if (DateUtils.NO_YEAR_DATE_FEB29TH.equals(oldValue)) {
+ oldYear = isYearOptional ? DatePickerDialog.NO_YEAR : defaultYear;
+ oldMonth = Calendar.FEBRUARY;
+ oldDay = 29;
+ } else {
+ final Date date2 = kind.dateFormatWithoutYear.parse(oldValue, position);
+ // Don't understand the date? Let's not show any dialog
+ if (date2 == null) return null;
+
+ calendar.setTime(date2);
+ oldYear = isYearOptional ? DatePickerDialog.NO_YEAR : defaultYear;
+ oldMonth = calendar.get(Calendar.MONTH);
+ oldDay = calendar.get(Calendar.DAY_OF_MONTH);
+ }
}
}
final OnDateSetListener callBack = new OnDateSetListener() {
@@ -241,8 +253,8 @@
// The format string will ignore that year.
// For formats other than Exchange, the time of the day is ignored
outCalendar.clear();
- outCalendar.set(year == 0 ? 2000 : year, monthOfYear, dayOfMonth,
- DEFAULT_HOUR, 0, 0);
+ outCalendar.set(year == DatePickerDialog.NO_YEAR ? 2000 : year, monthOfYear,
+ dayOfMonth, DEFAULT_HOUR, 0, 0);
final String resultString;
if (year == 0) {
diff --git a/src/com/android/contacts/editor/GroupMembershipView.java b/src/com/android/contacts/editor/GroupMembershipView.java
index a8e8d03..b84e22b 100644
--- a/src/com/android/contacts/editor/GroupMembershipView.java
+++ b/src/com/android/contacts/editor/GroupMembershipView.java
@@ -16,22 +16,11 @@
package com.android.contacts.editor;
-import com.android.contacts.GroupMetaDataLoader;
-import com.android.contacts.R;
-import com.android.contacts.interactions.GroupCreationDialogFragment;
-import com.android.contacts.interactions.GroupCreationDialogFragment.OnGroupCreatedListener;
-import com.android.contacts.model.DataKind;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.model.EntityModifier;
-import com.android.internal.util.Objects;
-
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
-import android.provider.ContactsContract.RawContacts;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
@@ -46,6 +35,16 @@
import android.widget.ListView;
import android.widget.TextView;
+import com.android.contacts.GroupMetaDataLoader;
+import com.android.contacts.R;
+import com.android.contacts.interactions.GroupCreationDialogFragment;
+import com.android.contacts.interactions.GroupCreationDialogFragment.OnGroupCreatedListener;
+import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.internal.util.Objects;
+
import java.util.ArrayList;
/**
@@ -127,7 +126,7 @@
}
}
- private EntityDelta mState;
+ private RawContactDelta mState;
private Cursor mGroupMetaData;
private String mAccountName;
private String mAccountType;
@@ -197,12 +196,11 @@
}
}
- public void setState(EntityDelta state) {
+ public void setState(RawContactDelta state) {
mState = state;
- ValuesDelta values = state.getValues();
- mAccountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
- mAccountName = values.getAsString(RawContacts.ACCOUNT_NAME);
- mDataSet = values.getAsString(RawContacts.DATA_SET);
+ mAccountType = mState.getAccountType();
+ mAccountName = mState.getAccountName();
+ mDataSet = mState.getDataSet();
mDefaultGroupVisibilityKnown = false;
mCreatedNewGroup = false;
updateView();
@@ -357,7 +355,7 @@
if (entries != null) {
for (ValuesDelta entry : entries) {
if (!entry.isDelete()) {
- Long groupId = entry.getAsLong(GroupMembership.GROUP_ROW_ID);
+ Long groupId = entry.getGroupRowId();
if (groupId != null && groupId != mFavoritesGroupId
&& (groupId != mDefaultGroupId || mDefaultGroupVisible)
&& !isGroupChecked(groupId)) {
@@ -372,8 +370,8 @@
GroupSelectionItem item = mAdapter.getItem(i);
long groupId = item.getGroupId();
if (item.isChecked() && !hasMembership(groupId)) {
- ValuesDelta entry = EntityModifier.insertChild(mState, mKind);
- entry.put(GroupMembership.GROUP_ROW_ID, groupId);
+ ValuesDelta entry = RawContactModifier.insertChild(mState, mKind);
+ entry.setGroupRowId(groupId);
}
}
@@ -400,7 +398,7 @@
if (entries != null) {
for (ValuesDelta values : entries) {
if (!values.isDelete()) {
- Long id = values.getAsLong(GroupMembership.GROUP_ROW_ID);
+ Long id = values.getGroupRowId();
if (id != null && id == groupId) {
return true;
}
diff --git a/src/com/android/contacts/editor/KindSectionView.java b/src/com/android/contacts/editor/KindSectionView.java
index b474956..2d4263b 100644
--- a/src/com/android/contacts/editor/KindSectionView.java
+++ b/src/com/android/contacts/editor/KindSectionView.java
@@ -16,13 +16,6 @@
package com.android.contacts.editor;
-import com.android.contacts.R;
-import com.android.contacts.editor.Editor.EditorListener;
-import com.android.contacts.model.DataKind;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.model.EntityModifier;
-
import android.content.Context;
import android.provider.ContactsContract.Data;
import android.text.TextUtils;
@@ -33,6 +26,13 @@
import android.widget.LinearLayout;
import android.widget.TextView;
+import com.android.contacts.R;
+import com.android.contacts.editor.Editor.EditorListener;
+import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.dataitem.DataKind;
+
import java.util.ArrayList;
import java.util.List;
@@ -50,7 +50,7 @@
private String mTitleString;
private DataKind mKind;
- private EntityDelta mState;
+ private RawContactDelta mState;
private boolean mReadOnly;
private ViewIdGenerator mViewIdGenerator;
@@ -136,7 +136,7 @@
}
}
- public void setState(DataKind kind, EntityDelta state, boolean readOnly, ViewIdGenerator vig) {
+ public void setState(DataKind kind, RawContactDelta state, boolean readOnly, ViewIdGenerator vig) {
mKind = kind;
mState = state;
mReadOnly = readOnly;
@@ -237,7 +237,7 @@
updateEmptyEditors();
// If there are no existing empty editors and it's possible to add
// another field, then make the "add footer" field visible.
- if (!hasEmptyEditor() && EntityModifier.canInsert(mState, mKind)) {
+ if (!hasEmptyEditor() && RawContactModifier.canInsert(mState, mKind)) {
if (animate) {
EditorAnimator.getInstance().showAddFieldFooter(mAddFieldFooter);
} else {
@@ -364,7 +364,7 @@
// Insert a new child, create its view and set its focus
if (values == null) {
- values = EntityModifier.insertChild(mState, mKind);
+ values = RawContactModifier.insertChild(mState, mKind);
}
final View newField = createEditorView(values);
diff --git a/src/com/android/contacts/editor/LabeledEditorView.java b/src/com/android/contacts/editor/LabeledEditorView.java
index 6f10fa2..789f425 100644
--- a/src/com/android/contacts/editor/LabeledEditorView.java
+++ b/src/com/android/contacts/editor/LabeledEditorView.java
@@ -16,28 +16,17 @@
package com.android.contacts.editor;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountType.EditType;
-import com.android.contacts.model.DataKind;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.model.EntityModifier;
-import com.android.contacts.util.DialogManager;
-import com.android.contacts.util.DialogManager.DialogShowingView;
-
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
-import android.content.Entity;
import android.content.DialogInterface.OnShowListener;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextUtils;
-import android.text.TextWatcher;
import android.text.TextUtils.TruncateAt;
+import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -55,11 +44,21 @@
import android.widget.Spinner;
import android.widget.TextView;
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.R;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.model.account.AccountType.EditType;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.contacts.util.DialogManager;
+import com.android.contacts.util.DialogManager.DialogShowingView;
+
import java.util.List;
/**
* Base class for editors that handles labels and values. Uses
- * {@link ValuesDelta} to read any existing {@link Entity} values, and to
+ * {@link ValuesDelta} to read any existing {@link RawContact} values, and to
* correctly write any changes values.
*/
public abstract class LabeledEditorView extends LinearLayout implements Editor, DialogShowingView {
@@ -76,7 +75,7 @@
private DataKind mKind;
private ValuesDelta mEntry;
- private EntityDelta mState;
+ private RawContactDelta mState;
private boolean mReadOnly;
private boolean mWasEmpty = true;
private boolean mIsDeletable = true;
@@ -342,7 +341,7 @@
* structure and {@link ValuesDelta} describing the content to edit.
*/
@Override
- public void setValues(DataKind kind, ValuesDelta entry, EntityDelta state, boolean readOnly,
+ public void setValues(DataKind kind, ValuesDelta entry, RawContactDelta state, boolean readOnly,
ViewIdGenerator vig) {
mKind = kind;
mEntry = entry;
@@ -359,11 +358,11 @@
setVisibility(View.VISIBLE);
// Display label selector if multiple types available
- final boolean hasTypes = EntityModifier.hasEditTypes(kind);
+ final boolean hasTypes = RawContactModifier.hasEditTypes(kind);
setupLabelButton(hasTypes);
mLabel.setEnabled(!readOnly && isEnabled());
if (hasTypes) {
- mType = EntityModifier.getCurrentType(entry, kind);
+ mType = RawContactModifier.getCurrentType(entry, kind);
rebuildLabel();
}
}
@@ -398,7 +397,7 @@
final String customText = editText.getText().toString().trim();
if (ContactsUtils.isGraphic(customText)) {
final List<EditType> allTypes =
- EntityModifier.getValidTypes(mState, mKind, null);
+ RawContactModifier.getValidTypes(mState, mKind, null);
mType = null;
for (EditType editType : allTypes) {
if (editType.customColumn != null) {
@@ -534,7 +533,7 @@
}
}
- addAll(EntityModifier.getValidTypes(mState, mKind, mType));
+ addAll(RawContactModifier.getValidTypes(mState, mKind, mType));
}
public boolean hasCustomSelection() {
diff --git a/src/com/android/contacts/editor/PhoneticNameEditorView.java b/src/com/android/contacts/editor/PhoneticNameEditorView.java
index 5e47d89..8cbb921 100644
--- a/src/com/android/contacts/editor/PhoneticNameEditorView.java
+++ b/src/com/android/contacts/editor/PhoneticNameEditorView.java
@@ -16,16 +16,16 @@
package com.android.contacts.editor;
-import com.android.contacts.model.DataKind;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-
-import android.content.ContentValues;
import android.content.Context;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.text.TextUtils;
import android.util.AttributeSet;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.contacts.model.dataitem.StructuredNameDataItem;
+
/**
* A dedicated editor for phonetic name. It is similar to {@link StructuredNameEditorView}.
*/
@@ -61,19 +61,16 @@
}
private void parsePhoneticName(String value) {
- ContentValues values = PhoneticNameEditorView.parsePhoneticName(value, null);
- mValues.put(StructuredName.PHONETIC_FAMILY_NAME,
- values.getAsString(StructuredName.PHONETIC_FAMILY_NAME));
- mValues.put(StructuredName.PHONETIC_MIDDLE_NAME,
- values.getAsString(StructuredName.PHONETIC_MIDDLE_NAME));
- mValues.put(StructuredName.PHONETIC_GIVEN_NAME,
- values.getAsString(StructuredName.PHONETIC_GIVEN_NAME));
+ StructuredNameDataItem dataItem = PhoneticNameEditorView.parsePhoneticName(value, null);
+ mValues.setPhoneticFamilyName(dataItem.getPhoneticFamilyName());
+ mValues.setPhoneticMiddleName(dataItem.getPhoneticMiddleName());
+ mValues.setPhoneticGivenName(dataItem.getPhoneticGivenName());
}
private void buildPhoneticName() {
- String family = mValues.getAsString(StructuredName.PHONETIC_FAMILY_NAME);
- String middle = mValues.getAsString(StructuredName.PHONETIC_MIDDLE_NAME);
- String given = mValues.getAsString(StructuredName.PHONETIC_GIVEN_NAME);
+ String family = mValues.getPhoneticFamilyName();
+ String middle = mValues.getPhoneticMiddleName();
+ String given = mValues.getPhoneticGivenName();
mPhoneticName = PhoneticNameEditorView.buildPhoneticName(family, middle, given);
}
@@ -100,7 +97,8 @@
* created.
* @return ContentValues with parsed data. Those data can be null.
*/
- public static ContentValues parsePhoneticName(String phoneticName, ContentValues values) {
+ public static StructuredNameDataItem parsePhoneticName(String phoneticName,
+ StructuredNameDataItem item) {
String family = null;
String middle = null;
String given = null;
@@ -123,13 +121,13 @@
}
}
- if (values == null) {
- values = new ContentValues();
+ if (item == null) {
+ item = new StructuredNameDataItem();
}
- values.put(StructuredName.PHONETIC_FAMILY_NAME, family);
- values.put(StructuredName.PHONETIC_MIDDLE_NAME, middle);
- values.put(StructuredName.PHONETIC_GIVEN_NAME, given);
- return values;
+ item.setPhoneticFamilyName(family);
+ item.setPhoneticMiddleName(middle);
+ item.setPhoneticGivenName(given);
+ return item;
}
/**
@@ -172,7 +170,7 @@
}
@Override
- public void setValues(DataKind kind, ValuesDelta entry, EntityDelta state, boolean readOnly,
+ public void setValues(DataKind kind, ValuesDelta entry, RawContactDelta state, boolean readOnly,
ViewIdGenerator vig) {
if (!(entry instanceof PhoneticValuesDelta)) {
entry = new PhoneticValuesDelta(entry);
@@ -213,9 +211,9 @@
public boolean hasData() {
ValuesDelta entry = getEntry();
- String family = entry.getAsString(StructuredName.PHONETIC_FAMILY_NAME);
- String middle = entry.getAsString(StructuredName.PHONETIC_MIDDLE_NAME);
- String given = entry.getAsString(StructuredName.PHONETIC_GIVEN_NAME);
+ String family = entry.getPhoneticFamilyName();
+ String middle = entry.getPhoneticMiddleName();
+ String given = entry.getPhoneticGivenName();
return !TextUtils.isEmpty(family) || !TextUtils.isEmpty(middle)
|| !TextUtils.isEmpty(given);
diff --git a/src/com/android/contacts/editor/PhotoActionPopup.java b/src/com/android/contacts/editor/PhotoActionPopup.java
index a27dd8a..36a1340 100644
--- a/src/com/android/contacts/editor/PhotoActionPopup.java
+++ b/src/com/android/contacts/editor/PhotoActionPopup.java
@@ -16,8 +16,6 @@
package com.android.contacts.editor;
-import com.android.contacts.R;
-
import android.content.Context;
import android.view.View;
import android.widget.AdapterView;
@@ -26,6 +24,8 @@
import android.widget.ListAdapter;
import android.widget.ListPopupWindow;
+import com.android.contacts.R;
+
import java.util.ArrayList;
/**
diff --git a/src/com/android/contacts/editor/PhotoEditorView.java b/src/com/android/contacts/editor/PhotoEditorView.java
index 955554c..30c3bb4 100644
--- a/src/com/android/contacts/editor/PhotoEditorView.java
+++ b/src/com/android/contacts/editor/PhotoEditorView.java
@@ -16,13 +16,6 @@
package com.android.contacts.editor;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.R;
-import com.android.contacts.model.DataKind;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.util.ContactPhotoUtils;
-
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -32,6 +25,13 @@
import android.widget.ImageView;
import android.widget.LinearLayout;
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.R;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.contacts.util.ContactPhotoUtils;
+
/**
* Simple editor for {@link Photo}.
*/
@@ -92,7 +92,7 @@
/** {@inheritDoc} */
@Override
- public void setValues(DataKind kind, ValuesDelta values, EntityDelta state, boolean readOnly,
+ public void setValues(DataKind kind, ValuesDelta values, RawContactDelta state, boolean readOnly,
ViewIdGenerator vig) {
mEntry = values;
mReadOnly = readOnly;
@@ -143,7 +143,7 @@
mEntry.setFromTemplate(false);
// When the user chooses a new photo mark it as super primary
- mEntry.put(Photo.IS_SUPER_PRIMARY, 1);
+ mEntry.setSuperPrimary(true);
// Even though high-res photos cannot be saved by passing them via
// an EntityDeltaList (since they cause the Bundle size limit to be
@@ -154,7 +154,7 @@
final int size = ContactsUtils.getThumbnailSize(getContext());
final Bitmap scaled = Bitmap.createScaledBitmap(photo, size, size, false);
final byte[] compressed = ContactPhotoUtils.compressBitmap(scaled);
- if (compressed != null) mEntry.put(Photo.PHOTO, compressed);
+ if (compressed != null) mEntry.setPhoto(compressed);
}
/**
diff --git a/src/com/android/contacts/editor/RawContactEditorView.java b/src/com/android/contacts/editor/RawContactEditorView.java
index cb5e838..daccdd8 100644
--- a/src/com/android/contacts/editor/RawContactEditorView.java
+++ b/src/com/android/contacts/editor/RawContactEditorView.java
@@ -16,18 +16,7 @@
package com.android.contacts.editor;
-import com.android.contacts.GroupMetaDataLoader;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountType.EditType;
-import com.android.contacts.model.DataKind;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.model.EntityModifier;
-import com.android.internal.util.Objects;
-
import android.content.Context;
-import android.content.Entity;
import android.database.Cursor;
import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
import android.provider.ContactsContract.CommonDataKinds.Organization;
@@ -35,7 +24,6 @@
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.RawContacts;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
@@ -48,18 +36,28 @@
import android.widget.PopupMenu;
import android.widget.TextView;
+import com.android.contacts.GroupMetaDataLoader;
+import com.android.contacts.R;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountType.EditType;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.internal.util.Objects;
+
import java.util.ArrayList;
/**
* Custom view that provides all the editor interaction for a specific
- * {@link Contacts} represented through an {@link EntityDelta}. Callers can
+ * {@link Contacts} represented through an {@link RawContactDelta}. Callers can
* reuse this view and quickly rebuild its contents through
- * {@link #setState(EntityDelta, AccountType, ViewIdGenerator)}.
+ * {@link #setState(RawContactDelta, AccountType, ViewIdGenerator)}.
* <p>
* Internal updates are performed against {@link ValuesDelta} so that the
- * source {@link Entity} can be swapped out. Any state-based changes, such as
+ * source {@link RawContact} can be swapped out. Any state-based changes, such as
* adding {@link Data} rows or changing {@link EditType}, are performed through
- * {@link EntityModifier} to ensure that {@link AccountType} are enforced.
+ * {@link RawContactModifier} to ensure that {@link AccountType} are enforced.
*/
public class RawContactEditorView extends BaseRawContactEditorView {
private LayoutInflater mInflater;
@@ -80,7 +78,7 @@
private boolean mAutoAddToDefaultGroup = true;
private Cursor mGroupMetaData;
private DataKind mGroupMembershipKind;
- private EntityDelta mState;
+ private RawContactDelta mState;
private boolean mPhoneticNameAdded;
@@ -152,11 +150,11 @@
/**
* Set the internal state for this view, given a current
- * {@link EntityDelta} state and the {@link AccountType} that
+ * {@link RawContactDelta} state and the {@link AccountType} that
* apply to that state.
*/
@Override
- public void setState(EntityDelta state, AccountType type, ViewIdGenerator vig,
+ public void setState(RawContactDelta state, AccountType type, ViewIdGenerator vig,
boolean isProfile) {
mState = state;
@@ -170,15 +168,14 @@
setId(vig.getId(state, null, null, ViewIdGenerator.NO_VIEW_INDEX));
// Make sure we have a StructuredName and Organization
- EntityModifier.ensureKindExists(state, type, StructuredName.CONTENT_ITEM_TYPE);
- EntityModifier.ensureKindExists(state, type, Organization.CONTENT_ITEM_TYPE);
+ RawContactModifier.ensureKindExists(state, type, StructuredName.CONTENT_ITEM_TYPE);
+ RawContactModifier.ensureKindExists(state, type, Organization.CONTENT_ITEM_TYPE);
- ValuesDelta values = state.getValues();
- mRawContactId = values.getAsLong(RawContacts._ID);
+ mRawContactId = state.getRawContactId();
// Fill in the account info
if (isProfile) {
- String accountName = values.getAsString(RawContacts.ACCOUNT_NAME);
+ String accountName = state.getAccountName();
if (TextUtils.isEmpty(accountName)) {
mAccountNameTextView.setVisibility(View.GONE);
mAccountTypeTextView.setText(R.string.local_profile_title);
@@ -189,7 +186,7 @@
mAccountNameTextView.setText(accountName);
}
} else {
- String accountName = values.getAsString(RawContacts.ACCOUNT_NAME);
+ String accountName = state.getAccountName();
CharSequence accountType = type.getDisplayLabel(mContext);
if (TextUtils.isEmpty(accountType)) {
accountType = mContext.getString(R.string.account_phone);
@@ -208,7 +205,7 @@
mAccountIcon.setImageDrawable(type.getDisplayIcon(mContext));
// Show photo editor when supported
- EntityModifier.ensureKindExists(state, type, Photo.CONTENT_ITEM_TYPE);
+ RawContactModifier.ensureKindExists(state, type, Photo.CONTENT_ITEM_TYPE);
setHasPhotoEditor((type.getKindForMimetype(Photo.CONTENT_ITEM_TYPE) != null));
getPhotoEditor().setEnabled(isEnabled());
mName.setEnabled(isEnabled());
@@ -341,7 +338,7 @@
ArrayList<ValuesDelta> entries = mState.getMimeEntries(GroupMembership.CONTENT_ITEM_TYPE);
if (entries != null) {
for (ValuesDelta values : entries) {
- Long id = values.getAsLong(GroupMembership.GROUP_ROW_ID);
+ Long id = values.getGroupRowId();
if (id != null && id.longValue() != 0) {
hasGroupMembership = true;
break;
@@ -352,8 +349,8 @@
if (!hasGroupMembership) {
long defaultGroupId = getDefaultGroupId();
if (defaultGroupId != -1) {
- ValuesDelta entry = EntityModifier.insertChild(mState, mGroupMembershipKind);
- entry.put(GroupMembership.GROUP_ROW_ID, defaultGroupId);
+ ValuesDelta entry = RawContactModifier.insertChild(mState, mGroupMembershipKind);
+ entry.setGroupRowId(defaultGroupId);
}
}
}
@@ -363,9 +360,9 @@
* account. Returns -1 if there is no such group.
*/
private long getDefaultGroupId() {
- String accountType = mState.getValues().getAsString(RawContacts.ACCOUNT_TYPE);
- String accountName = mState.getValues().getAsString(RawContacts.ACCOUNT_NAME);
- String accountDataSet = mState.getValues().getAsString(RawContacts.DATA_SET);
+ String accountType = mState.getAccountType();
+ String accountName = mState.getAccountName();
+ String accountDataSet = mState.getDataSet();
mGroupMetaData.moveToPosition(-1);
while (mGroupMetaData.moveToNext()) {
String name = mGroupMetaData.getString(GroupMetaDataLoader.ACCOUNT_NAME);
diff --git a/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java b/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
index 58474ef..8e51d18 100644
--- a/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
+++ b/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
@@ -16,15 +16,6 @@
package com.android.contacts.editor;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountWithDataSet;
-import com.android.contacts.model.DataKind;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.model.EntityModifier;
-
import android.content.ContentUris;
import android.content.Context;
import android.content.res.Resources;
@@ -46,6 +37,15 @@
import android.widget.TextView;
import android.widget.Toast;
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.R;
+import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.model.dataitem.DataKind;
+
import java.util.ArrayList;
/**
@@ -108,11 +108,11 @@
/**
* Set the internal state for this view, given a current
- * {@link EntityDelta} state and the {@link AccountType} that
+ * {@link RawContactDelta} state and the {@link AccountType} that
* apply to that state.
*/
@Override
- public void setState(EntityDelta state, AccountType type, ViewIdGenerator vig,
+ public void setState(RawContactDelta state, AccountType type, ViewIdGenerator vig,
boolean isProfile) {
// Remove any existing sections
mGeneral.removeAllViews();
@@ -121,13 +121,12 @@
if (state == null || type == null) return;
// Make sure we have StructuredName
- EntityModifier.ensureKindExists(state, type, StructuredName.CONTENT_ITEM_TYPE);
+ RawContactModifier.ensureKindExists(state, type, StructuredName.CONTENT_ITEM_TYPE);
// Fill in the header info
- ValuesDelta values = state.getValues();
- mAccountName = values.getAsString(RawContacts.ACCOUNT_NAME);
- mAccountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
- mDataSet = values.getAsString(RawContacts.DATA_SET);
+ mAccountName = state.getAccountName();
+ mAccountType = state.getAccountType();
+ mDataSet = state.getDataSet();
if (isProfile) {
if (TextUtils.isEmpty(mAccountName)) {
@@ -162,14 +161,14 @@
mAccountIcon.setImageDrawable(type.getDisplayIcon(mContext));
- mRawContactId = values.getAsLong(RawContacts._ID);
+ mRawContactId = state.getRawContactId();
ValuesDelta primary;
// Photo
DataKind kind = type.getKindForMimetype(Photo.CONTENT_ITEM_TYPE);
if (kind != null) {
- EntityModifier.ensureKindExists(state, type, Photo.CONTENT_ITEM_TYPE);
+ RawContactModifier.ensureKindExists(state, type, Photo.CONTENT_ITEM_TYPE);
boolean hasPhotoEditor = type.getKindForMimetype(Photo.CONTENT_ITEM_TYPE) != null;
setHasPhotoEditor(hasPhotoEditor);
primary = state.getPrimaryEntry(Photo.CONTENT_ITEM_TYPE);
@@ -203,13 +202,13 @@
for (int i = 0; i < phones.size(); i++) {
ValuesDelta phone = phones.get(i);
final String phoneNumber = PhoneNumberUtils.formatNumber(
- phone.getAsString(Phone.NUMBER),
- phone.getAsString(Phone.NORMALIZED_NUMBER),
+ phone.getPhoneNumber(),
+ phone.getPhoneNormalizedNumber(),
ContactsUtils.getCurrentCountryIso(getContext()));
final CharSequence phoneType;
- if (phone.containsKey(Phone.TYPE)) {
+ if (phone.phoneHasType()) {
phoneType = Phone.getTypeLabel(
- res, phone.getAsInteger(Phone.TYPE), phone.getAsString(Phone.LABEL));
+ res, phone.getPhoneType(), phone.getPhoneLabel());
} else {
phoneType = null;
}
@@ -223,11 +222,11 @@
if (emails != null) {
for (int i = 0; i < emails.size(); i++) {
ValuesDelta email = emails.get(i);
- final String emailAddress = email.getAsString(Email.DATA);
+ final String emailAddress = email.getEmailData();
final CharSequence emailType;
- if (email.containsKey(Email.TYPE)) {
+ if (email.emailHasType()) {
emailType = Email.getTypeLabel(
- res, email.getAsInteger(Email.TYPE), email.getAsString(Email.LABEL));
+ res, email.getEmailType(), email.getEmailLabel());
} else {
emailType = null;
}
diff --git a/src/com/android/contacts/editor/SelectAccountDialogFragment.java b/src/com/android/contacts/editor/SelectAccountDialogFragment.java
index 42ac170..3e7ad0e 100644
--- a/src/com/android/contacts/editor/SelectAccountDialogFragment.java
+++ b/src/com/android/contacts/editor/SelectAccountDialogFragment.java
@@ -16,10 +16,6 @@
package com.android.contacts.editor;
-import com.android.contacts.model.AccountWithDataSet;
-import com.android.contacts.util.AccountsListAdapter;
-import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
-
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
@@ -28,6 +24,10 @@
import android.content.DialogInterface;
import android.os.Bundle;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.util.AccountsListAdapter;
+import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
+
/**
* Shows a dialog asking the user which account to chose.
*
diff --git a/src/com/android/contacts/editor/SplitContactConfirmationDialogFragment.java b/src/com/android/contacts/editor/SplitContactConfirmationDialogFragment.java
index 3259fd4..c790e0b 100644
--- a/src/com/android/contacts/editor/SplitContactConfirmationDialogFragment.java
+++ b/src/com/android/contacts/editor/SplitContactConfirmationDialogFragment.java
@@ -16,8 +16,6 @@
package com.android.contacts.editor;
-import com.android.contacts.R;
-
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
@@ -25,6 +23,8 @@
import android.content.DialogInterface;
import android.os.Bundle;
+import com.android.contacts.R;
+
/**
* Shows a dialog asking the user whether to split the contact. The result is passed back
* to the Fragment that is configured by {@link Fragment#setTargetFragment(Fragment, int)}, which
diff --git a/src/com/android/contacts/editor/StructuredNameEditorView.java b/src/com/android/contacts/editor/StructuredNameEditorView.java
index af1b3cf..3c4476d 100644
--- a/src/com/android/contacts/editor/StructuredNameEditorView.java
+++ b/src/com/android/contacts/editor/StructuredNameEditorView.java
@@ -16,11 +16,6 @@
package com.android.contacts.editor;
-import com.android.contacts.model.DataKind;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.util.NameConverter;
-
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
@@ -30,6 +25,13 @@
import android.text.TextUtils;
import android.util.AttributeSet;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.dataitem.DataItem;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.contacts.model.dataitem.StructuredNameDataItem;
+import com.android.contacts.util.NameConverter;
+
import java.util.HashMap;
import java.util.Map;
@@ -45,7 +47,7 @@
*/
public class StructuredNameEditorView extends TextFieldsEditorView {
- private ContentValues mSnapshot;
+ private StructuredNameDataItem mSnapshot;
private boolean mChanged;
public StructuredNameEditorView(Context context) {
@@ -61,11 +63,12 @@
}
@Override
- public void setValues(DataKind kind, ValuesDelta entry, EntityDelta state, boolean readOnly,
+ public void setValues(DataKind kind, ValuesDelta entry, RawContactDelta state, boolean readOnly,
ViewIdGenerator vig) {
super.setValues(kind, entry, state, readOnly, vig);
if (mSnapshot == null) {
- mSnapshot = new ContentValues(getValues().getCompleteValues());
+ mSnapshot = (StructuredNameDataItem) DataItem.createFrom(null,
+ new ContentValues(getValues().getCompleteValues()));
mChanged = entry.isInsert();
} else {
mChanged = false;
@@ -114,12 +117,12 @@
if (!mChanged) {
for (String field : NameConverter.STRUCTURED_NAME_FIELDS) {
- values.put(field, mSnapshot.getAsString(field));
+ values.put(field, mSnapshot.getContentValues().getAsString(field));
}
return;
}
- String displayName = values.getAsString(StructuredName.DISPLAY_NAME);
+ String displayName = values.getDisplayName();
Map<String, String> structuredNameMap = NameConverter.displayNameToStructuredName(
getContext(), displayName);
if (!structuredNameMap.isEmpty()) {
@@ -129,17 +132,16 @@
}
}
- mSnapshot.clear();
- mSnapshot.putAll(values.getCompleteValues());
- mSnapshot.put(StructuredName.DISPLAY_NAME, displayName);
+ mSnapshot.getContentValues().clear();
+ mSnapshot.getContentValues().putAll(values.getCompleteValues());
+ mSnapshot.setDisplayName(displayName);
}
private void switchFromStructuredNameToFullName() {
ValuesDelta values = getValues();
if (!mChanged) {
- values.put(StructuredName.DISPLAY_NAME,
- mSnapshot.getAsString(StructuredName.DISPLAY_NAME));
+ values.setDisplayName(mSnapshot.getDisplayName());
return;
}
@@ -151,10 +153,10 @@
values.put(StructuredName.DISPLAY_NAME, displayName);
}
- mSnapshot.clear();
- mSnapshot.put(StructuredName.DISPLAY_NAME, values.getAsString(StructuredName.DISPLAY_NAME));
+ mSnapshot.getContentValues().clear();
+ mSnapshot.setDisplayName(values.getDisplayName());
for (String field : structuredNameMap.keySet()) {
- mSnapshot.put(field, structuredNameMap.get(field));
+ mSnapshot.getContentValues().put(field, structuredNameMap.get(field));
}
}
@@ -167,14 +169,14 @@
}
private void eraseFullName(ValuesDelta values) {
- values.putNull(StructuredName.DISPLAY_NAME);
+ values.setDisplayName(null);
}
private void rebuildFullName(ValuesDelta values) {
Map<String, String> structuredNameMap = valuesToStructuredNameMap(values);
String displayName = NameConverter.structuredNameToDisplayName(getContext(),
structuredNameMap);
- values.put(StructuredName.DISPLAY_NAME, displayName);
+ values.setDisplayName(displayName);
}
private void eraseStructuredName(ValuesDelta values) {
@@ -184,7 +186,7 @@
}
private void rebuildStructuredName(ValuesDelta values) {
- String displayName = values.getAsString(StructuredName.DISPLAY_NAME);
+ String displayName = values.getDisplayName();
Map<String, String> structuredNameMap = NameConverter.displayNameToStructuredName(
getContext(), displayName);
for (String field : structuredNameMap.keySet()) {
@@ -202,7 +204,7 @@
protected Parcelable onSaveInstanceState() {
SavedState state = new SavedState(super.onSaveInstanceState());
state.mChanged = mChanged;
- state.mSnapshot = mSnapshot;
+ state.mSnapshot = mSnapshot.getContentValues();
return state;
}
@@ -212,7 +214,7 @@
super.onRestoreInstanceState(ss.mSuperState);
mChanged = ss.mChanged;
- mSnapshot = ss.mSnapshot;
+ mSnapshot = (StructuredNameDataItem) DataItem.createFrom(null, ss.mSnapshot);
}
private static class SavedState implements Parcelable {
diff --git a/src/com/android/contacts/editor/TextFieldsEditorView.java b/src/com/android/contacts/editor/TextFieldsEditorView.java
index a1f67a8..8558b11 100644
--- a/src/com/android/contacts/editor/TextFieldsEditorView.java
+++ b/src/com/android/contacts/editor/TextFieldsEditorView.java
@@ -16,16 +16,7 @@
package com.android.contacts.editor;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountType.EditField;
-import com.android.contacts.model.DataKind;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.util.PhoneNumberFormatter;
-
import android.content.Context;
-import android.content.Entity;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
@@ -44,9 +35,17 @@
import android.widget.ImageView;
import android.widget.LinearLayout;
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.R;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.account.AccountType.EditField;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.contacts.util.PhoneNumberFormatter;
+
/**
* Simple editor that handles labels and any {@link EditField} defined for the
- * entry. Uses {@link ValuesDelta} to read any existing {@link Entity} values,
+ * entry. Uses {@link ValuesDelta} to read any existing {@link RawContact} values,
* and to correctly write any changes values.
*/
public class TextFieldsEditorView extends LabeledEditorView {
@@ -171,7 +170,7 @@
}
@Override
- public void setValues(DataKind kind, ValuesDelta entry, EntityDelta state, boolean readOnly,
+ public void setValues(DataKind kind, ValuesDelta entry, RawContactDelta state, boolean readOnly,
ViewIdGenerator vig) {
super.setValues(kind, entry, state, readOnly, vig);
// Remove edit texts that we currently have
diff --git a/src/com/android/contacts/editor/ViewIdGenerator.java b/src/com/android/contacts/editor/ViewIdGenerator.java
index c3cd08b..55a42a7 100644
--- a/src/com/android/contacts/editor/ViewIdGenerator.java
+++ b/src/com/android/contacts/editor/ViewIdGenerator.java
@@ -16,14 +16,14 @@
package com.android.contacts.editor;
-import com.android.contacts.model.DataKind;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.dataitem.DataKind;
+
/**
* A class that provides unique view ids for {@link ContentEditorView}, {@link KindSectionView},
* {@link LabeledEditorView} and {@link EditView} on {@link EditContactActivity}.
@@ -62,13 +62,13 @@
/**
* Returns an id for a view associated with specified contact field.
*
- * @param entity {@link EntityDelta} associated with the view
+ * @param entity {@link RawContactDelta} associated with the view
* @param kind {@link DataKind} associated with the view, or null if none exists.
* @param values {@link ValuesDelta} associated with the view, or null if none exists.
* @param viewIndex index of the view in the parent {@link Editor}, if it's a leave view.
* Otherwise, pass {@link #NO_VIEW_INDEX}.
*/
- public int getId(EntityDelta entity, DataKind kind, ValuesDelta values,
+ public int getId(RawContactDelta entity, DataKind kind, ValuesDelta values,
int viewIndex) {
final String k = getMapKey(entity, kind, values, viewIndex);
@@ -81,7 +81,7 @@
return id;
}
- private static String getMapKey(EntityDelta entity, DataKind kind, ValuesDelta values,
+ private static String getMapKey(RawContactDelta entity, DataKind kind, ValuesDelta values,
int viewIndex) {
sWorkStringBuilder.setLength(0);
if (entity != null) {
diff --git a/src/com/android/contacts/format/FormatUtils.java b/src/com/android/contacts/format/FormatUtils.java
index 82bf78d..dd25c8d 100644
--- a/src/com/android/contacts/format/FormatUtils.java
+++ b/src/com/android/contacts/format/FormatUtils.java
@@ -15,13 +15,13 @@
*/
package com.android.contacts.format;
-import com.android.contacts.test.NeededForTesting;
-
import android.database.CharArrayBuffer;
import android.graphics.Typeface;
import android.text.SpannableString;
import android.text.style.StyleSpan;
+import com.android.contacts.test.NeededForTesting;
+
import java.util.Arrays;
/**
diff --git a/src/com/android/contacts/group/GroupBrowseListAdapter.java b/src/com/android/contacts/group/GroupBrowseListAdapter.java
index 8affab3..acea625 100644
--- a/src/com/android/contacts/group/GroupBrowseListAdapter.java
+++ b/src/com/android/contacts/group/GroupBrowseListAdapter.java
@@ -16,13 +16,6 @@
package com.android.contacts.group;
-import com.android.contacts.ContactPhotoManager;
-import com.android.contacts.GroupListLoader;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.internal.util.Objects;
-
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
@@ -34,6 +27,12 @@
import android.widget.BaseAdapter;
import android.widget.TextView;
+import com.android.contacts.GroupListLoader;
+import com.android.contacts.R;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountType;
+import com.android.internal.util.Objects;
+
/**
* Adapter to populate the list of groups.
*/
@@ -238,4 +237,4 @@
return mUri;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/contacts/group/GroupBrowseListFragment.java b/src/com/android/contacts/group/GroupBrowseListFragment.java
index 79bdd09..625615f 100644
--- a/src/com/android/contacts/group/GroupBrowseListFragment.java
+++ b/src/com/android/contacts/group/GroupBrowseListFragment.java
@@ -16,12 +16,6 @@
package com.android.contacts.group;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.GroupListLoader;
-import com.android.contacts.R;
-import com.android.contacts.group.GroupBrowseListAdapter.GroupListItemViewCache;
-import com.android.contacts.widget.AutoScrollListView;
-
import android.app.Activity;
import android.app.Fragment;
import android.app.LoaderManager;
@@ -33,10 +27,8 @@
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
-import android.os.Parcelable;
import android.provider.ContactsContract;
import android.provider.Settings;
-import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@@ -50,6 +42,12 @@
import android.widget.ListView;
import android.widget.TextView;
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.GroupListLoader;
+import com.android.contacts.R;
+import com.android.contacts.group.GroupBrowseListAdapter.GroupListItemViewCache;
+import com.android.contacts.widget.AutoScrollListView;
+
/**
* Fragment to display the list of groups.
*/
diff --git a/src/com/android/contacts/group/GroupDetailDisplayUtils.java b/src/com/android/contacts/group/GroupDetailDisplayUtils.java
index da5e0e9..d4e43a0 100644
--- a/src/com/android/contacts/group/GroupDetailDisplayUtils.java
+++ b/src/com/android/contacts/group/GroupDetailDisplayUtils.java
@@ -16,16 +16,16 @@
package com.android.contacts.group;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
+import com.android.contacts.R;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountType;
+
public class GroupDetailDisplayUtils {
private GroupDetailDisplayUtils() {
@@ -57,4 +57,4 @@
}
accountIcon.setImageDrawable(accountType.getDisplayIcon(context));
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/contacts/group/GroupDetailFragment.java b/src/com/android/contacts/group/GroupDetailFragment.java
index 9e19735..6294b40 100644
--- a/src/com/android/contacts/group/GroupDetailFragment.java
+++ b/src/com/android/contacts/group/GroupDetailFragment.java
@@ -16,17 +16,6 @@
package com.android.contacts.group;
-import com.android.contacts.ContactPhotoManager;
-import com.android.contacts.GroupMemberLoader;
-import com.android.contacts.GroupMetaDataLoader;
-import com.android.contacts.R;
-import com.android.contacts.interactions.GroupDeletionDialogFragment;
-import com.android.contacts.list.ContactTileAdapter;
-import com.android.contacts.list.ContactTileAdapter.DisplayType;
-import com.android.contacts.list.ContactTileView;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-
import android.app.Activity;
import android.app.Fragment;
import android.app.LoaderManager;
@@ -56,6 +45,17 @@
import android.widget.ListView;
import android.widget.TextView;
+import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.GroupMemberLoader;
+import com.android.contacts.GroupMetaDataLoader;
+import com.android.contacts.R;
+import com.android.contacts.interactions.GroupDeletionDialogFragment;
+import com.android.contacts.list.ContactTileAdapter;
+import com.android.contacts.list.ContactTileAdapter.DisplayType;
+import com.android.contacts.list.ContactTileView;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountType;
+
/**
* Displays the details of a group and shows a list of actions possible for the group.
*/
diff --git a/src/com/android/contacts/group/GroupEditorFragment.java b/src/com/android/contacts/group/GroupEditorFragment.java
index 6940efb..762867c 100644
--- a/src/com/android/contacts/group/GroupEditorFragment.java
+++ b/src/com/android/contacts/group/GroupEditorFragment.java
@@ -16,22 +16,6 @@
package com.android.contacts.group;
-import com.android.contacts.ContactPhotoManager;
-import com.android.contacts.ContactSaveService;
-import com.android.contacts.GroupMemberLoader;
-import com.android.contacts.GroupMemberLoader.GroupEditorQuery;
-import com.android.contacts.GroupMetaDataLoader;
-import com.android.contacts.R;
-import com.android.contacts.activities.GroupEditorActivity;
-import com.android.contacts.editor.SelectAccountDialogFragment;
-import com.android.contacts.group.SuggestedMemberListAdapter.SuggestedMember;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountWithDataSet;
-import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
-import com.android.contacts.util.ViewUtil;
-import com.android.internal.util.Objects;
-
import android.accounts.Account;
import android.app.Activity;
import android.app.AlertDialog;
@@ -73,6 +57,22 @@
import android.widget.TextView;
import android.widget.Toast;
+import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.ContactSaveService;
+import com.android.contacts.GroupMemberLoader;
+import com.android.contacts.GroupMemberLoader.GroupEditorQuery;
+import com.android.contacts.GroupMetaDataLoader;
+import com.android.contacts.R;
+import com.android.contacts.activities.GroupEditorActivity;
+import com.android.contacts.editor.SelectAccountDialogFragment;
+import com.android.contacts.group.SuggestedMemberListAdapter.SuggestedMember;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
+import com.android.contacts.util.ViewUtil;
+import com.android.internal.util.Objects;
+
import java.util.ArrayList;
import java.util.List;
diff --git a/src/com/android/contacts/group/SuggestedMemberListAdapter.java b/src/com/android/contacts/group/SuggestedMemberListAdapter.java
index 30718de..067c052 100644
--- a/src/com/android/contacts/group/SuggestedMemberListAdapter.java
+++ b/src/com/android/contacts/group/SuggestedMemberListAdapter.java
@@ -15,9 +15,6 @@
*/
package com.android.contacts.group;
-import com.android.contacts.R;
-import com.android.contacts.group.SuggestedMemberListAdapter.SuggestedMember;
-
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
@@ -39,6 +36,9 @@
import android.widget.ImageView;
import android.widget.TextView;
+import com.android.contacts.R;
+import com.android.contacts.group.SuggestedMemberListAdapter.SuggestedMember;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
diff --git a/src/com/android/contacts/interactions/ContactDeletionInteraction.java b/src/com/android/contacts/interactions/ContactDeletionInteraction.java
index 4aa4030..ea6e6dc 100644
--- a/src/com/android/contacts/interactions/ContactDeletionInteraction.java
+++ b/src/com/android/contacts/interactions/ContactDeletionInteraction.java
@@ -16,13 +16,6 @@
package com.android.contacts.interactions;
-import com.android.contacts.ContactSaveService;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-import com.google.android.collect.Sets;
-import com.google.common.annotations.VisibleForTesting;
-
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
@@ -39,7 +32,13 @@
import android.os.Bundle;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Contacts.Entity;
-import android.util.Log;
+
+import com.android.contacts.ContactSaveService;
+import com.android.contacts.R;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountType;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Sets;
import java.util.HashSet;
diff --git a/src/com/android/contacts/interactions/GroupCreationDialogFragment.java b/src/com/android/contacts/interactions/GroupCreationDialogFragment.java
index 051dc13..5731bc1 100644
--- a/src/com/android/contacts/interactions/GroupCreationDialogFragment.java
+++ b/src/com/android/contacts/interactions/GroupCreationDialogFragment.java
@@ -15,16 +15,16 @@
*/
package com.android.contacts.interactions;
-import com.android.contacts.ContactSaveService;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountWithDataSet;
-
import android.app.Activity;
import android.app.FragmentManager;
import android.content.Intent;
import android.os.Bundle;
import android.widget.EditText;
+import com.android.contacts.ContactSaveService;
+import com.android.contacts.R;
+import com.android.contacts.model.account.AccountWithDataSet;
+
/**
* A dialog for creating a new group.
*/
diff --git a/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java b/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java
index 09306f2..2df7fe2 100644
--- a/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java
+++ b/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java
@@ -15,9 +15,6 @@
*/
package com.android.contacts.interactions;
-import com.android.contacts.ContactSaveService;
-import com.android.contacts.R;
-
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
@@ -25,6 +22,9 @@
import android.content.DialogInterface;
import android.os.Bundle;
+import com.android.contacts.ContactSaveService;
+import com.android.contacts.R;
+
/**
* A dialog for deleting a group.
*/
diff --git a/src/com/android/contacts/interactions/GroupNameDialogFragment.java b/src/com/android/contacts/interactions/GroupNameDialogFragment.java
index 8798c59..b0ad9c9 100644
--- a/src/com/android/contacts/interactions/GroupNameDialogFragment.java
+++ b/src/com/android/contacts/interactions/GroupNameDialogFragment.java
@@ -15,8 +15,6 @@
*/
package com.android.contacts.interactions;
-import com.android.contacts.R;
-
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
@@ -32,6 +30,8 @@
import android.widget.Button;
import android.widget.EditText;
+import com.android.contacts.R;
+
/**
* A common superclass for creating and renaming groups.
*/
diff --git a/src/com/android/contacts/interactions/ImportExportDialogFragment.java b/src/com/android/contacts/interactions/ImportExportDialogFragment.java
index 521d2f0..f63f84c 100644
--- a/src/com/android/contacts/interactions/ImportExportDialogFragment.java
+++ b/src/com/android/contacts/interactions/ImportExportDialogFragment.java
@@ -16,14 +16,6 @@
package com.android.contacts.interactions;
-import com.android.contacts.R;
-import com.android.contacts.editor.SelectAccountDialogFragment;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountWithDataSet;
-import com.android.contacts.util.AccountSelectionUtil;
-import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
-import com.android.contacts.vcard.ExportVCardActivity;
-
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
@@ -45,6 +37,14 @@
import android.widget.TextView;
import android.widget.Toast;
+import com.android.contacts.R;
+import com.android.contacts.editor.SelectAccountDialogFragment;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.util.AccountSelectionUtil;
+import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
+import com.android.contacts.vcard.ExportVCardActivity;
+
import java.util.List;
/**
diff --git a/src/com/android/contacts/interactions/PhoneNumberInteraction.java b/src/com/android/contacts/interactions/PhoneNumberInteraction.java
index 3c3c347..207ceea 100644
--- a/src/com/android/contacts/interactions/PhoneNumberInteraction.java
+++ b/src/com/android/contacts/interactions/PhoneNumberInteraction.java
@@ -15,19 +15,6 @@
*/
package com.android.contacts.interactions;
-import com.android.contacts.Collapser;
-import com.android.contacts.Collapser.Collapsible;
-import com.android.contacts.ContactSaveService;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.R;
-import com.android.contacts.activities.DialtactsActivity;
-import com.android.contacts.activities.TransactionSafeActivity;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountType.StringInflater;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.DataKind;
-import com.google.common.annotations.VisibleForTesting;
-
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -59,6 +46,19 @@
import android.widget.ListAdapter;
import android.widget.TextView;
+import com.android.contacts.Collapser;
+import com.android.contacts.Collapser.Collapsible;
+import com.android.contacts.ContactSaveService;
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.R;
+import com.android.contacts.activities.DialtactsActivity;
+import com.android.contacts.activities.TransactionSafeActivity;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountType.StringInflater;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.contacts.model.AccountTypeManager;
+import com.google.common.annotations.VisibleForTesting;
+
import java.util.ArrayList;
import java.util.List;
diff --git a/src/com/android/contacts/interactions/TestLoaderManager.java b/src/com/android/contacts/interactions/TestLoaderManager.java
index 6c2d9e8..fb6a49b 100644
--- a/src/com/android/contacts/interactions/TestLoaderManager.java
+++ b/src/com/android/contacts/interactions/TestLoaderManager.java
@@ -16,8 +16,6 @@
package com.android.contacts.interactions;
-import com.google.common.annotations.VisibleForTesting;
-
import android.app.Activity;
import android.app.LoaderManager;
import android.content.AsyncTaskLoader;
@@ -25,14 +23,16 @@
import android.os.Bundle;
import android.util.Log;
+import com.google.common.annotations.VisibleForTesting;
+
+import junit.framework.Assert;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
-import junit.framework.Assert;
-
/**
* A {@link LoaderManager} that records which loaders have been completed.
* <p>
diff --git a/src/com/android/contacts/list/AccountFilterActivity.java b/src/com/android/contacts/list/AccountFilterActivity.java
index 2624e5d..af727a5 100644
--- a/src/com/android/contacts/list/AccountFilterActivity.java
+++ b/src/com/android/contacts/list/AccountFilterActivity.java
@@ -16,13 +16,6 @@
package com.android.contacts.list;
-import com.android.contacts.ContactsActivity;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountWithDataSet;
-import com.google.android.collect.Lists;
-
import android.app.ActionBar;
import android.app.Activity;
import android.app.LoaderManager.LoaderCallbacks;
@@ -41,6 +34,13 @@
import android.widget.BaseAdapter;
import android.widget.ListView;
+import com.android.contacts.ContactsActivity;
+import com.android.contacts.R;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.google.common.collect.Lists;
+
import java.util.ArrayList;
import java.util.List;
@@ -69,7 +69,7 @@
super.onCreate(icicle);
setContentView(R.layout.contact_list_filter);
- mListView = (ListView) findViewById(com.android.internal.R.id.list);
+ mListView = (ListView) findViewById(android.R.id.list);
mListView.setOnItemClickListener(this);
ActionBar actionBar = getActionBar();
diff --git a/src/com/android/contacts/list/ContactBrowseListFragment.java b/src/com/android/contacts/list/ContactBrowseListFragment.java
index a2b61c7..3e8e4a3 100644
--- a/src/com/android/contacts/list/ContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/ContactBrowseListFragment.java
@@ -15,11 +15,6 @@
*/
package com.android.contacts.list;
-import com.android.common.widget.CompositeCursorAdapter.Partition;
-import com.android.contacts.R;
-import com.android.contacts.util.ContactLoaderUtils;
-import com.android.contacts.widget.AutoScrollListView;
-
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
@@ -39,6 +34,11 @@
import android.text.TextUtils;
import android.util.Log;
+import com.android.common.widget.CompositeCursorAdapter.Partition;
+import com.android.contacts.R;
+import com.android.contacts.util.ContactLoaderUtils;
+import com.android.contacts.widget.AutoScrollListView;
+
import java.util.List;
/**
diff --git a/src/com/android/contacts/list/ContactEntryListAdapter.java b/src/com/android/contacts/list/ContactEntryListAdapter.java
index 78bf628..00c26ff 100644
--- a/src/com/android/contacts/list/ContactEntryListAdapter.java
+++ b/src/com/android/contacts/list/ContactEntryListAdapter.java
@@ -15,10 +15,6 @@
*/
package com.android.contacts.list;
-import com.android.contacts.ContactPhotoManager;
-import com.android.contacts.R;
-import com.android.contacts.widget.IndexerListAdapter;
-
import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor;
@@ -37,6 +33,10 @@
import android.widget.SectionIndexer;
import android.widget.TextView;
+import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.R;
+import com.android.contacts.widget.IndexerListAdapter;
+
import java.util.HashSet;
/**
diff --git a/src/com/android/contacts/list/ContactEntryListFragment.java b/src/com/android/contacts/list/ContactEntryListFragment.java
index 27fdada..e422d1b 100644
--- a/src/com/android/contacts/list/ContactEntryListFragment.java
+++ b/src/com/android/contacts/list/ContactEntryListFragment.java
@@ -16,13 +16,6 @@
package com.android.contacts.list;
-import com.android.common.widget.CompositeCursorAdapter.Partition;
-import com.android.contacts.ContactListEmptyView;
-import com.android.contacts.ContactPhotoManager;
-import com.android.contacts.R;
-import com.android.contacts.preference.ContactsPreferences;
-import com.android.contacts.widget.ContextMenuAdapter;
-
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
@@ -60,6 +53,13 @@
import android.widget.ListView;
import android.widget.TextView;
+import com.android.common.widget.CompositeCursorAdapter.Partition;
+import com.android.contacts.ContactListEmptyView;
+import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.R;
+import com.android.contacts.preference.ContactsPreferences;
+import com.android.contacts.widget.ContextMenuAdapter;
+
/**
* Common base class for various contact-related list fragments.
*/
@@ -744,7 +744,7 @@
"'android.R.id.list'");
}
- View emptyView = mView.findViewById(com.android.internal.R.id.empty);
+ View emptyView = mView.findViewById(android.R.id.empty);
if (emptyView != null) {
mListView.setEmptyView(emptyView);
if (emptyView instanceof ContactListEmptyView) {
diff --git a/src/com/android/contacts/list/ContactListAdapter.java b/src/com/android/contacts/list/ContactListAdapter.java
index 18f7e04..1eb2dae 100644
--- a/src/com/android/contacts/list/ContactListAdapter.java
+++ b/src/com/android/contacts/list/ContactListAdapter.java
@@ -15,8 +15,6 @@
*/
package com.android.contacts.list;
-import com.android.contacts.R;
-
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
@@ -30,6 +28,8 @@
import android.view.ViewGroup;
import android.widget.ListView;
+import com.android.contacts.R;
+
/**
* A cursor adapter for the {@link ContactsContract.Contacts#CONTENT_TYPE} content type.
* Also includes support for including the {@link ContactsContract.Profile} record in the
diff --git a/src/com/android/contacts/list/ContactListFilterController.java b/src/com/android/contacts/list/ContactListFilterController.java
index 9f483f1..ddcb1ae 100644
--- a/src/com/android/contacts/list/ContactListFilterController.java
+++ b/src/com/android/contacts/list/ContactListFilterController.java
@@ -15,13 +15,13 @@
*/
package com.android.contacts.list;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountWithDataSet;
-
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountWithDataSet;
+
import java.util.ArrayList;
import java.util.List;
diff --git a/src/com/android/contacts/list/ContactListFilterView.java b/src/com/android/contacts/list/ContactListFilterView.java
index 020952d..d0ecfe4 100644
--- a/src/com/android/contacts/list/ContactListFilterView.java
+++ b/src/com/android/contacts/list/ContactListFilterView.java
@@ -16,12 +16,6 @@
package com.android.contacts.list;
-import com.android.contacts.R;
-import com.android.contacts.editor.ContactEditorFragment;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.util.ThemeUtils;
-
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
@@ -31,6 +25,10 @@
import android.widget.RadioButton;
import android.widget.TextView;
+import com.android.contacts.R;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountType;
+
/**
* Contact list filter parameters.
*/
diff --git a/src/com/android/contacts/list/ContactListItemView.java b/src/com/android/contacts/list/ContactListItemView.java
index 191212b..bfe06b0 100644
--- a/src/com/android/contacts/list/ContactListItemView.java
+++ b/src/com/android/contacts/list/ContactListItemView.java
@@ -16,11 +16,6 @@
package com.android.contacts.list;
-import com.android.contacts.ContactPresenceIconUtil;
-import com.android.contacts.ContactStatusUtil;
-import com.android.contacts.R;
-import com.android.contacts.format.PrefixHighlighter;
-
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
@@ -49,6 +44,11 @@
import android.widget.QuickContactBadge;
import android.widget.TextView;
+import com.android.contacts.ContactPresenceIconUtil;
+import com.android.contacts.ContactStatusUtil;
+import com.android.contacts.R;
+import com.android.contacts.format.PrefixHighlighter;
+
/**
* A custom view for an item in the contact list.
* The view contains the contact's photo, a set of text views (for name, status, etc...) and
@@ -67,12 +67,8 @@
public class ContactListItemView extends ViewGroup
implements SelectionBoundsAdjuster {
- private static final int QUICK_CONTACT_BADGE_STYLE =
- com.android.internal.R.attr.quickContactBadgeStyleWindowMedium;
-
// Style values for layout and appearance
private final int mPreferredHeight;
- private final int mVerticalDividerMargin;
private final int mGapBetweenImageAndText;
private final int mGapBetweenLabelAndData;
private final int mPresenceIconMargin;
@@ -115,11 +111,6 @@
public static final PhotoPosition DEFAULT_PHOTO_POSITION = PhotoPosition.RIGHT;
private PhotoPosition mPhotoPosition = DEFAULT_PHOTO_POSITION;
- // Vertical divider between the call icon and the text.
- private boolean mVerticalDividerVisible;
- private Drawable mVerticalDividerDrawable;
- private int mVerticalDividerWidth;
-
// Header layout data
private boolean mHeaderVisible;
private View mHeaderDivider;
@@ -132,7 +123,6 @@
private ImageView mPhotoView;
private TextView mNameTextView;
private TextView mPhoneticNameTextView;
- private DontPressWithParentImageView mCallButton;
private TextView mLabelView;
private TextView mDataView;
private TextView mSnippetView;
@@ -200,27 +190,6 @@
private PrefixHighlighter mPrefixHighlighter;
private CharSequence mUnknownNameText;
- /**
- * Special class to allow the parent to be pressed without being pressed itself.
- * This way the line of a tab can be pressed, but the image itself is not.
- */
- // TODO: understand this
- private static class DontPressWithParentImageView extends ImageView {
-
- public DontPressWithParentImageView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- public void setPressed(boolean pressed) {
- // If the parent is pressed, do not set to pressed.
- if (pressed && ((View) getParent()).isPressed()) {
- return;
- }
- super.setPressed(pressed);
- }
- }
-
public ContactListItemView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
@@ -233,8 +202,6 @@
R.styleable.ContactListItemView_activated_background);
mHorizontalDividerDrawable = a.getDrawable(
R.styleable.ContactListItemView_list_item_divider);
- mVerticalDividerMargin = a.getDimensionPixelOffset(
- R.styleable.ContactListItemView_list_item_vertical_divider_margin, 0);
mGapBetweenImageAndText = a.getDimensionPixelOffset(
R.styleable.ContactListItemView_list_item_gap_between_image_and_text, 0);
@@ -428,11 +395,6 @@
mLabelAndDataViewMaxHeight +
mSnippetTextViewHeight + mStatusTextViewHeight);
- if (isVisible(mCallButton)) {
- mCallButton.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
- MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
- }
-
// Make sure the height is at least as high as the photo
height = Math.max(height, mPhotoViewHeight + getPaddingBottom() + getPaddingTop());
@@ -541,9 +503,6 @@
leftBound += mTextIndent;
}
- // Layout the call button.
- rightBound = layoutRightSide(height, topBound, bottomBound, rightBound);
-
// Center text vertically
final int totalTextHeight = mNameTextViewHeight + mPhoneticNameTextViewHeight +
mLabelAndDataViewMaxHeight + mSnippetTextViewHeight + mStatusTextViewHeight;
@@ -630,36 +589,6 @@
}
}
- /**
- * Performs layout of the right side of the view
- *
- * @return new right boundary
- */
- protected int layoutRightSide(int height, int topBound, int bottomBound, int rightBound) {
- // Put call button and vertical divider
- if (isVisible(mCallButton)) {
- int buttonWidth = mCallButton.getMeasuredWidth();
- rightBound -= buttonWidth;
- mCallButton.layout(
- rightBound,
- topBound,
- rightBound + buttonWidth,
- height - mHorizontalDividerHeight);
- mVerticalDividerVisible = true;
- ensureVerticalDivider();
- rightBound -= mVerticalDividerWidth;
- mVerticalDividerDrawable.setBounds(
- rightBound,
- topBound + mVerticalDividerMargin,
- rightBound + mVerticalDividerWidth,
- height - mVerticalDividerMargin);
- } else {
- mVerticalDividerVisible = false;
- }
-
- return rightBound;
- }
-
@Override
public void adjustListItemSelectionBounds(Rect bounds) {
bounds.top += mBoundsWithoutHeader.top;
@@ -673,38 +602,18 @@
}
/**
- * Loads the drawable for the vertical divider if it has not yet been loaded.
- */
- private void ensureVerticalDivider() {
- if (mVerticalDividerDrawable == null) {
- mVerticalDividerDrawable = mContext.getResources().getDrawable(
- R.drawable.divider_vertical_dark);
- mVerticalDividerWidth = mVerticalDividerDrawable.getIntrinsicWidth();
- }
- }
-
- /**
* Extracts width and height from the style
*/
private void ensurePhotoViewSize() {
if (!mPhotoViewWidthAndHeightAreReady) {
- if (mQuickContactEnabled) {
- TypedArray a = mContext.obtainStyledAttributes(null,
- com.android.internal.R.styleable.ViewGroup_Layout,
- QUICK_CONTACT_BADGE_STYLE, 0);
- mPhotoViewWidth = a.getLayoutDimension(
- android.R.styleable.ViewGroup_Layout_layout_width,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- mPhotoViewHeight = a.getLayoutDimension(
- android.R.styleable.ViewGroup_Layout_layout_height,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- a.recycle();
- } else if (mPhotoView != null) {
- mPhotoViewWidth = mPhotoViewHeight = getDefaultPhotoViewSize();
- } else {
- final int defaultPhotoViewSize = getDefaultPhotoViewSize();
- mPhotoViewWidth = mKeepHorizontalPaddingForPhotoView ? defaultPhotoViewSize : 0;
- mPhotoViewHeight = mKeepVerticalPaddingForPhotoView ? defaultPhotoViewSize : 0;
+ mPhotoViewWidth = mPhotoViewHeight = getDefaultPhotoViewSize();
+ if (!mQuickContactEnabled && mPhotoView == null) {
+ if (!mKeepHorizontalPaddingForPhotoView) {
+ mPhotoViewWidth = 0;
+ }
+ if (!mKeepVerticalPaddingForPhotoView) {
+ mPhotoViewHeight = 0;
+ }
}
mPhotoViewWidthAndHeightAreReady = true;
@@ -719,6 +628,18 @@
return mDefaultPhotoViewSize;
}
+ /**
+ * Gets a LayoutParam that corresponds to the default photo size.
+ *
+ * @return A new LayoutParam.
+ */
+ private LayoutParams getDefaultPhotoLayoutParams() {
+ LayoutParams params = generateDefaultLayoutParams();
+ params.width = getDefaultPhotoViewSize();
+ params.height = params.width;
+ return params;
+ }
+
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
@@ -748,9 +669,6 @@
if (mHorizontalDividerVisible) {
mHorizontalDividerDrawable.draw(canvas);
}
- if (mVerticalDividerVisible) {
- mVerticalDividerDrawable.draw(canvas);
- }
super.dispatchDraw(canvas);
}
@@ -805,7 +723,8 @@
throw new IllegalStateException("QuickContact is disabled for this view");
}
if (mQuickContact == null) {
- mQuickContact = new QuickContactBadge(mContext, null, QUICK_CONTACT_BADGE_STYLE);
+ mQuickContact = new QuickContactBadge(mContext);
+ mQuickContact.setLayoutParams(getDefaultPhotoLayoutParams());
if (mNameTextView != null) {
mQuickContact.setContentDescription(mContext.getString(
R.string.description_quick_contact_for, mNameTextView.getText()));
@@ -822,11 +741,8 @@
*/
public ImageView getPhotoView() {
if (mPhotoView == null) {
- if (mQuickContactEnabled) {
- mPhotoView = new ImageView(mContext, null, QUICK_CONTACT_BADGE_STYLE);
- } else {
- mPhotoView = new ImageView(mContext);
- }
+ mPhotoView = new ImageView(mContext);
+ mPhotoView.setLayoutParams(getDefaultPhotoLayoutParams());
// Quick contact style used above will set a background - remove it
mPhotoView.setBackground(null);
addView(mPhotoView);
diff --git a/src/com/android/contacts/list/ContactListPinnedHeaderView.java b/src/com/android/contacts/list/ContactListPinnedHeaderView.java
index aee77e1..34a56d6 100644
--- a/src/com/android/contacts/list/ContactListPinnedHeaderView.java
+++ b/src/com/android/contacts/list/ContactListPinnedHeaderView.java
@@ -16,8 +16,6 @@
package com.android.contacts.list;
-import com.android.contacts.R;
-
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
@@ -30,6 +28,8 @@
import android.view.ViewGroup;
import android.widget.TextView;
+import com.android.contacts.R;
+
/**
* A custom view for the pinned section header shown at the top of the contact list.
*/
diff --git a/src/com/android/contacts/list/ContactNameHighlightingAnimation.java b/src/com/android/contacts/list/ContactNameHighlightingAnimation.java
index 05881ce..ddea603 100644
--- a/src/com/android/contacts/list/ContactNameHighlightingAnimation.java
+++ b/src/com/android/contacts/list/ContactNameHighlightingAnimation.java
@@ -15,11 +15,11 @@
*/
package com.android.contacts.list;
-import com.android.contacts.widget.TextHighlightingAnimation;
-
import android.view.View;
import android.widget.ListView;
+import com.android.contacts.widget.TextHighlightingAnimation;
+
/**
* A {@link TextHighlightingAnimation} that redraws just the contact display name in a
* list item.
diff --git a/src/com/android/contacts/list/ContactPickerFragment.java b/src/com/android/contacts/list/ContactPickerFragment.java
index ef51732..bda62f3 100644
--- a/src/com/android/contacts/list/ContactPickerFragment.java
+++ b/src/com/android/contacts/list/ContactPickerFragment.java
@@ -15,10 +15,6 @@
*/
package com.android.contacts.list;
-import com.android.contacts.ContactsSearchManager;
-import com.android.contacts.R;
-import com.android.contacts.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
-
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
@@ -27,6 +23,9 @@
import android.view.ViewGroup;
import android.widget.AdapterView;
+import com.android.contacts.R;
+import com.android.contacts.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
+
/**
* Fragment for the contact list used for browsing contacts (as compared to
* picking a contact with one of the PICK or SHORTCUT intents).
diff --git a/src/com/android/contacts/list/ContactTileAdapter.java b/src/com/android/contacts/list/ContactTileAdapter.java
index ddf88b0..75e3149 100644
--- a/src/com/android/contacts/list/ContactTileAdapter.java
+++ b/src/com/android/contacts/list/ContactTileAdapter.java
@@ -15,15 +15,6 @@
*/
package com.android.contacts.list;
-import com.android.contacts.ContactPhotoManager;
-import com.android.contacts.ContactPresenceIconUtil;
-import com.android.contacts.ContactStatusUtil;
-import com.android.contacts.ContactTileLoaderFactory;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.GroupMemberLoader;
-import com.android.contacts.GroupMemberLoader.GroupDetailQuery;
-import com.android.contacts.R;
-
import android.content.ContentUris;
import android.content.Context;
import android.content.res.Resources;
@@ -37,6 +28,15 @@
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
+import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.ContactPresenceIconUtil;
+import com.android.contacts.ContactStatusUtil;
+import com.android.contacts.ContactTileLoaderFactory;
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.GroupMemberLoader;
+import com.android.contacts.GroupMemberLoader.GroupDetailQuery;
+import com.android.contacts.R;
+
import java.util.ArrayList;
/**
diff --git a/src/com/android/contacts/list/ContactTileFrequentFragment.java b/src/com/android/contacts/list/ContactTileFrequentFragment.java
index 73ff6cc..88ef1e8 100644
--- a/src/com/android/contacts/list/ContactTileFrequentFragment.java
+++ b/src/com/android/contacts/list/ContactTileFrequentFragment.java
@@ -15,14 +15,14 @@
*/
package com.android.contacts.list;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.R;
-
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.R;
+
/**
* Fragment containing a list of frequently contacted people.
*/
diff --git a/src/com/android/contacts/list/ContactTileFrequentView.java b/src/com/android/contacts/list/ContactTileFrequentView.java
index 0bd6729..ba240af 100644
--- a/src/com/android/contacts/list/ContactTileFrequentView.java
+++ b/src/com/android/contacts/list/ContactTileFrequentView.java
@@ -15,11 +15,11 @@
*/
package com.android.contacts.list;
-import com.android.contacts.util.ViewUtil;
-
import android.content.Context;
import android.util.AttributeSet;
+import com.android.contacts.util.ViewUtil;
+
/**
* A {@link ContactTileView} that is used for most frequently contacted in the People app
*/
diff --git a/src/com/android/contacts/list/ContactTileListFragment.java b/src/com/android/contacts/list/ContactTileListFragment.java
index 4ee20f5..f5de15f 100644
--- a/src/com/android/contacts/list/ContactTileListFragment.java
+++ b/src/com/android/contacts/list/ContactTileListFragment.java
@@ -15,12 +15,6 @@
*/
package com.android.contacts.list;
-import com.android.contacts.ContactPhotoManager;
-import com.android.contacts.ContactTileLoaderFactory;
-import com.android.contacts.R;
-import com.android.contacts.list.ContactTileAdapter.DisplayType;
-import com.android.contacts.util.PhoneCapabilityTester;
-
import android.app.Activity;
import android.app.Fragment;
import android.app.LoaderManager;
@@ -32,13 +26,17 @@
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.TextView;
+import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.ContactTileLoaderFactory;
+import com.android.contacts.R;
+import com.android.contacts.list.ContactTileAdapter.DisplayType;
+
/**
* Fragment containing a list of starred contacts followed by a list of frequently contacted.
*
diff --git a/src/com/android/contacts/list/ContactTilePhoneFrequentView.java b/src/com/android/contacts/list/ContactTilePhoneFrequentView.java
index 88796ba..7c3aef3 100644
--- a/src/com/android/contacts/list/ContactTilePhoneFrequentView.java
+++ b/src/com/android/contacts/list/ContactTilePhoneFrequentView.java
@@ -15,15 +15,15 @@
*/
package com.android.contacts.list;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.list.ContactTileAdapter.ContactEntry;
-import com.android.contacts.util.ViewUtil;
-
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.list.ContactTileAdapter.ContactEntry;
+import com.android.contacts.util.ViewUtil;
+
/**
* A dark version of the {@link ContactTileView} that is used in Dialtacts
* for frequently called contacts. Slightly different behavior from superclass...
diff --git a/src/com/android/contacts/list/ContactTilePhoneStarredView.java b/src/com/android/contacts/list/ContactTilePhoneStarredView.java
index fc53782..dc68688 100644
--- a/src/com/android/contacts/list/ContactTilePhoneStarredView.java
+++ b/src/com/android/contacts/list/ContactTilePhoneStarredView.java
@@ -15,14 +15,14 @@
*/
package com.android.contacts.list;
-import com.android.contacts.R;
-
import android.content.Context;
import android.content.Intent;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageButton;
+import com.android.contacts.R;
+
/**
* Displays the contact's picture overlayed with their name
* in a perfect square. It also has an additional touch target for a secondary action.
diff --git a/src/com/android/contacts/list/ContactTileView.java b/src/com/android/contacts/list/ContactTileView.java
index 528e7a3..c108827 100644
--- a/src/com/android/contacts/list/ContactTileView.java
+++ b/src/com/android/contacts/list/ContactTileView.java
@@ -15,11 +15,6 @@
*/
package com.android.contacts.list;
-import com.android.contacts.ContactPhotoManager;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.R;
-import com.android.contacts.list.ContactTileAdapter.ContactEntry;
-
import android.content.Context;
import android.graphics.Rect;
import android.net.Uri;
@@ -31,6 +26,11 @@
import android.widget.QuickContactBadge;
import android.widget.TextView;
+import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.R;
+import com.android.contacts.list.ContactTileAdapter.ContactEntry;
+
/**
* A ContactTile displays a contact's picture and name
*/
diff --git a/src/com/android/contacts/list/ContactsUnavailableFragment.java b/src/com/android/contacts/list/ContactsUnavailableFragment.java
index b645425..43a2d8e 100644
--- a/src/com/android/contacts/list/ContactsUnavailableFragment.java
+++ b/src/com/android/contacts/list/ContactsUnavailableFragment.java
@@ -15,8 +15,6 @@
*/
package com.android.contacts.list;
-import com.android.contacts.R;
-
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
@@ -30,6 +28,8 @@
import android.widget.ProgressBar;
import android.widget.TextView;
+import com.android.contacts.R;
+
/**
* Fragment shown when contacts are unavailable. It contains provider status
* messaging as well as instructions for the user.
diff --git a/src/com/android/contacts/list/CustomContactListFilterActivity.java b/src/com/android/contacts/list/CustomContactListFilterActivity.java
index d5395bd..c62b389 100644
--- a/src/com/android/contacts/list/CustomContactListFilterActivity.java
+++ b/src/com/android/contacts/list/CustomContactListFilterActivity.java
@@ -16,18 +16,6 @@
package com.android.contacts.list;
-import com.android.contacts.ContactsActivity;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountWithDataSet;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.model.GoogleAccountType;
-import com.android.contacts.util.EmptyService;
-import com.android.contacts.util.LocalizedNameResolver;
-import com.android.contacts.util.WeakAsyncTask;
-import com.google.android.collect.Lists;
-
import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
@@ -39,7 +27,6 @@
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
-import android.content.EntityIterator;
import android.content.Intent;
import android.content.Loader;
import android.content.OperationApplicationException;
@@ -66,6 +53,18 @@
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import android.widget.TextView;
+import com.android.contacts.ContactsActivity;
+import com.android.contacts.R;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.model.account.GoogleAccountType;
+import com.android.contacts.util.EmptyService;
+import com.android.contacts.util.LocalizedNameResolver;
+import com.android.contacts.util.WeakAsyncTask;
+import com.google.common.collect.Lists;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -93,7 +92,7 @@
super.onCreate(icicle);
setContentView(R.layout.contact_list_filter_custom);
- mList = (ExpandableListView) findViewById(com.android.internal.R.id.list);
+ mList = (ExpandableListView) findViewById(android.R.id.list);
mList.setOnChildClickListener(this);
mList.setHeaderDividersEnabled(true);
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
@@ -146,7 +145,8 @@
if (account.dataSet != null) {
groupsUri.appendQueryParameter(Groups.DATA_SET, account.dataSet).build();
}
- EntityIterator iterator = ContactsContract.Groups.newEntityIterator(resolver.query(
+ android.content.EntityIterator iterator =
+ ContactsContract.Groups.newEntityIterator(resolver.query(
groupsUri.build(), null, null, null, null));
try {
boolean hasGroups = false;
diff --git a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
index e358f6f..8f38045 100644
--- a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
@@ -15,10 +15,6 @@
*/
package com.android.contacts.list;
-import com.android.contacts.R;
-import com.android.contacts.editor.ContactEditorFragment;
-import com.android.contacts.util.AccountFilterUtil;
-
import android.content.CursorLoader;
import android.content.Intent;
import android.database.Cursor;
@@ -28,7 +24,6 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
-import android.view.View.OnLayoutChangeListener;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.widget.Button;
@@ -36,6 +31,10 @@
import android.widget.ListView;
import android.widget.TextView;
+import com.android.contacts.R;
+import com.android.contacts.editor.ContactEditorFragment;
+import com.android.contacts.util.AccountFilterUtil;
+
/**
* Fragment containing a contact list used for browsing (as compared to
* picking a contact with one of the PICK intents).
diff --git a/src/com/android/contacts/list/DefaultContactListAdapter.java b/src/com/android/contacts/list/DefaultContactListAdapter.java
index a53914d..88c1db0 100644
--- a/src/com/android/contacts/list/DefaultContactListAdapter.java
+++ b/src/com/android/contacts/list/DefaultContactListAdapter.java
@@ -15,8 +15,6 @@
*/
package com.android.contacts.list;
-import com.android.contacts.preference.ContactsPreferences;
-
import android.content.ContentUris;
import android.content.Context;
import android.content.CursorLoader;
@@ -28,11 +26,12 @@
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Directory;
-import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.SearchSnippetColumns;
import android.text.TextUtils;
import android.view.View;
+import com.android.contacts.preference.ContactsPreferences;
+
import java.util.ArrayList;
import java.util.List;
diff --git a/src/com/android/contacts/list/DirectoryListLoader.java b/src/com/android/contacts/list/DirectoryListLoader.java
index 0bb250a..f85cc5e 100644
--- a/src/com/android/contacts/list/DirectoryListLoader.java
+++ b/src/com/android/contacts/list/DirectoryListLoader.java
@@ -15,8 +15,6 @@
*/
package com.android.contacts.list;
-import com.android.contacts.R;
-
import android.content.AsyncTaskLoader;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -29,6 +27,8 @@
import android.text.TextUtils;
import android.util.Log;
+import com.android.contacts.R;
+
/**
* A specialized loader for the list of directories, see {@link Directory}.
*/
diff --git a/src/com/android/contacts/list/DirectoryPartition.java b/src/com/android/contacts/list/DirectoryPartition.java
index 47a1037..c1fd533 100644
--- a/src/com/android/contacts/list/DirectoryPartition.java
+++ b/src/com/android/contacts/list/DirectoryPartition.java
@@ -15,10 +15,10 @@
*/
package com.android.contacts.list;
-import com.android.common.widget.CompositeCursorAdapter;
-
import android.provider.ContactsContract.Directory;
+import com.android.common.widget.CompositeCursorAdapter;
+
/**
* Model object for a {@link Directory} row.
*/
diff --git a/src/com/android/contacts/list/EmailAddressPickerFragment.java b/src/com/android/contacts/list/EmailAddressPickerFragment.java
index 13fe541..41f470f 100644
--- a/src/com/android/contacts/list/EmailAddressPickerFragment.java
+++ b/src/com/android/contacts/list/EmailAddressPickerFragment.java
@@ -15,13 +15,13 @@
*/
package com.android.contacts.list;
-import com.android.contacts.R;
-
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import com.android.contacts.R;
+
/**
* Fragment containing an email list for picking.
*/
diff --git a/src/com/android/contacts/list/JoinContactListAdapter.java b/src/com/android/contacts/list/JoinContactListAdapter.java
index 80ddc83..6e1a6b2 100644
--- a/src/com/android/contacts/list/JoinContactListAdapter.java
+++ b/src/com/android/contacts/list/JoinContactListAdapter.java
@@ -15,8 +15,6 @@
*/
package com.android.contacts.list;
-import com.android.contacts.R;
-
import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor;
@@ -32,6 +30,8 @@
import android.view.ViewGroup;
import android.widget.TextView;
+import com.android.contacts.R;
+
public class JoinContactListAdapter extends ContactListAdapter {
/** Maximum number of suggestions shown for joining aggregates */
diff --git a/src/com/android/contacts/list/JoinContactListFragment.java b/src/com/android/contacts/list/JoinContactListFragment.java
index 1c526a5..9cfa4ae 100644
--- a/src/com/android/contacts/list/JoinContactListFragment.java
+++ b/src/com/android/contacts/list/JoinContactListFragment.java
@@ -15,9 +15,6 @@
*/
package com.android.contacts.list;
-import com.android.contacts.R;
-import com.android.contacts.list.JoinContactLoader.JoinContactLoaderResult;
-
import android.app.Activity;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.ContentUris;
@@ -34,6 +31,9 @@
import android.view.ViewGroup;
import android.widget.TextView;
+import com.android.contacts.R;
+import com.android.contacts.list.JoinContactLoader.JoinContactLoaderResult;
+
/**
* Fragment for the Join Contact list.
*/
diff --git a/src/com/android/contacts/list/PhoneFavoriteFragment.java b/src/com/android/contacts/list/PhoneFavoriteFragment.java
index 170790f..5ef19ff 100644
--- a/src/com/android/contacts/list/PhoneFavoriteFragment.java
+++ b/src/com/android/contacts/list/PhoneFavoriteFragment.java
@@ -15,14 +15,6 @@
*/
package com.android.contacts.list;
-import com.android.contacts.ContactPhotoManager;
-import com.android.contacts.ContactTileLoaderFactory;
-import com.android.contacts.R;
-import com.android.contacts.dialog.ClearFrequentsDialog;
-import com.android.contacts.interactions.ImportExportDialogFragment;
-import com.android.contacts.preference.ContactsPreferences;
-import com.android.contacts.util.AccountFilterUtil;
-
import android.app.Activity;
import android.app.Fragment;
import android.app.LoaderManager;
@@ -53,6 +45,14 @@
import android.widget.ListView;
import android.widget.TextView;
+import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.ContactTileLoaderFactory;
+import com.android.contacts.R;
+import com.android.contacts.dialog.ClearFrequentsDialog;
+import com.android.contacts.interactions.ImportExportDialogFragment;
+import com.android.contacts.preference.ContactsPreferences;
+import com.android.contacts.util.AccountFilterUtil;
+
/**
* Fragment for Phone UI's favorite screen.
*
diff --git a/src/com/android/contacts/list/PhoneFavoriteMergedAdapter.java b/src/com/android/contacts/list/PhoneFavoriteMergedAdapter.java
index d5b62e5..3aa9fe5 100644
--- a/src/com/android/contacts/list/PhoneFavoriteMergedAdapter.java
+++ b/src/com/android/contacts/list/PhoneFavoriteMergedAdapter.java
@@ -16,8 +16,6 @@
*/
package com.android.contacts.list;
-import com.android.contacts.R;
-
import android.content.Context;
import android.content.res.Resources;
import android.database.DataSetObserver;
@@ -27,6 +25,8 @@
import android.widget.FrameLayout;
import android.widget.SectionIndexer;
+import com.android.contacts.R;
+
/**
* An adapter that combines items from {@link ContactTileAdapter} and
* {@link ContactEntryListAdapter} into a single list. In between those two results,
@@ -295,4 +295,4 @@
final int contactTileAdapterCount = mContactTileAdapter.getCount();
return firstVisibleItem > contactTileAdapterCount;
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/contacts/list/PhoneNumberPickerFragment.java b/src/com/android/contacts/list/PhoneNumberPickerFragment.java
index 3785fa6..17b5500 100644
--- a/src/com/android/contacts/list/PhoneNumberPickerFragment.java
+++ b/src/com/android/contacts/list/PhoneNumberPickerFragment.java
@@ -15,10 +15,6 @@
*/
package com.android.contacts.list;
-import com.android.contacts.R;
-import com.android.contacts.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
-import com.android.contacts.util.AccountFilterUtil;
-
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
@@ -30,7 +26,10 @@
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
-import android.widget.TextView;
+
+import com.android.contacts.R;
+import com.android.contacts.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
+import com.android.contacts.util.AccountFilterUtil;
/**
* Fragment containing a phone number list for picking.
diff --git a/src/com/android/contacts/list/PostalAddressPickerFragment.java b/src/com/android/contacts/list/PostalAddressPickerFragment.java
index ddb8e9a..9bd4fc3 100644
--- a/src/com/android/contacts/list/PostalAddressPickerFragment.java
+++ b/src/com/android/contacts/list/PostalAddressPickerFragment.java
@@ -15,13 +15,13 @@
*/
package com.android.contacts.list;
-import com.android.contacts.R;
-
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import com.android.contacts.R;
+
/**
* Fragment containing a postal address list for picking.
*/
diff --git a/src/com/android/contacts/list/ProfileAndContactsLoader.java b/src/com/android/contacts/list/ProfileAndContactsLoader.java
index 7f85ea6..4291a40 100644
--- a/src/com/android/contacts/list/ProfileAndContactsLoader.java
+++ b/src/com/android/contacts/list/ProfileAndContactsLoader.java
@@ -15,8 +15,6 @@
*/
package com.android.contacts.list;
-import com.google.android.collect.Lists;
-
import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor;
@@ -25,6 +23,8 @@
import android.os.Bundle;
import android.provider.ContactsContract.Profile;
+import com.google.common.collect.Lists;
+
import java.util.List;
/**
diff --git a/src/com/android/contacts/list/ProviderStatusWatcher.java b/src/com/android/contacts/list/ProviderStatusWatcher.java
index ae0b779..3e8d3f5 100644
--- a/src/com/android/contacts/list/ProviderStatusWatcher.java
+++ b/src/com/android/contacts/list/ProviderStatusWatcher.java
@@ -15,8 +15,6 @@
*/
package com.android.contacts.list;
-import com.google.common.collect.Lists;
-
import android.content.ContentValues;
import android.content.Context;
import android.database.ContentObserver;
@@ -27,6 +25,8 @@
import android.provider.ContactsContract.ProviderStatus;
import android.util.Log;
+import com.google.common.collect.Lists;
+
import java.util.ArrayList;
/**
diff --git a/src/com/android/contacts/list/ShortcutIntentBuilder.java b/src/com/android/contacts/list/ShortcutIntentBuilder.java
index d71a0f5..1578524 100644
--- a/src/com/android/contacts/list/ShortcutIntentBuilder.java
+++ b/src/com/android/contacts/list/ShortcutIntentBuilder.java
@@ -15,9 +15,6 @@
*/
package com.android.contacts.list;
-import com.android.contacts.R;
-import com.android.contacts.util.Constants;
-
import android.app.ActivityManager;
import android.content.ContentResolver;
import android.content.Context;
@@ -43,6 +40,9 @@
import android.text.TextUtils;
import android.text.TextUtils.TruncateAt;
+import com.android.contacts.R;
+import com.android.contacts.util.Constants;
+
/**
* Constructs shortcut intents.
*/
diff --git a/src/com/android/contacts/model/AccountTypeManager.java b/src/com/android/contacts/model/AccountTypeManager.java
index d6f140e..64f3a91 100644
--- a/src/com/android/contacts/model/AccountTypeManager.java
+++ b/src/com/android/contacts/model/AccountTypeManager.java
@@ -16,16 +16,6 @@
package com.android.contacts.model;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.list.ContactListFilterController;
-import com.android.contacts.util.Constants;
-import com.android.i18n.phonenumbers.PhoneNumberUtil;
-import com.android.internal.util.Objects;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Maps;
-import com.google.android.collect.Sets;
-import com.google.common.annotations.VisibleForTesting;
-
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AuthenticatorDescription;
@@ -53,12 +43,28 @@
import android.util.Log;
import android.util.TimingLogger;
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.list.ContactListFilterController;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountTypeWithDataSet;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.model.account.ExchangeAccountType;
+import com.android.contacts.model.account.ExternalAccountType;
+import com.android.contacts.model.account.FallbackAccountType;
+import com.android.contacts.model.account.GoogleAccountType;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.contacts.util.Constants;
+import com.android.internal.util.Objects;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
-import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
diff --git a/src/com/android/contacts/model/Contact.java b/src/com/android/contacts/model/Contact.java
new file mode 100644
index 0000000..ede2101
--- /dev/null
+++ b/src/com/android/contacts/model/Contact.java
@@ -0,0 +1,495 @@
+/*
+ * 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.contacts.model;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.net.Uri;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Directory;
+import android.provider.ContactsContract.DisplayNameSources;
+
+import com.android.contacts.GroupMetaData;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.dataitem.DataItem;
+import com.android.contacts.util.DataStatus;
+import com.android.contacts.util.StreamItemEntry;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+import java.util.ArrayList;
+
+/**
+ * A Contact represents a single person or logical entity as perceived by the user. The information
+ * about a contact can come from multiple data sources, which are each represented by a RawContact
+ * object. Thus, a Contact is associated with a collection of RawContact objects.
+ *
+ * The aggregation of raw contacts into a single contact is performed automatically, and it is
+ * also possible for users to manually split and join raw contacts into various contacts.
+ *
+ * Only the {@link ContactLoader} class can create a Contact object with various flags to allow
+ * partial loading of contact data. Thus, an instance of this class should be treated as
+ * a read-only object.
+ */
+public class Contact {
+ private enum Status {
+ /** Contact is successfully loaded */
+ LOADED,
+ /** There was an error loading the contact */
+ ERROR,
+ /** Contact is not found */
+ NOT_FOUND,
+ }
+
+ private final Uri mRequestedUri;
+ private final Uri mLookupUri;
+ private final Uri mUri;
+ private final long mDirectoryId;
+ private final String mLookupKey;
+ private final long mId;
+ private final long mNameRawContactId;
+ private final int mDisplayNameSource;
+ private final long mPhotoId;
+ private final String mPhotoUri;
+ private final String mDisplayName;
+ private final String mAltDisplayName;
+ private final String mPhoneticName;
+ private final boolean mStarred;
+ private final Integer mPresence;
+ private ImmutableList<RawContact> mRawContacts;
+ private ImmutableList<StreamItemEntry> mStreamItems;
+ private ImmutableMap<Long,DataStatus> mStatuses;
+ private ImmutableList<AccountType> mInvitableAccountTypes;
+
+ private String mDirectoryDisplayName;
+ private String mDirectoryType;
+ private String mDirectoryAccountType;
+ private String mDirectoryAccountName;
+ private int mDirectoryExportSupport;
+
+ private ImmutableList<GroupMetaData> mGroups;
+
+ private byte[] mPhotoBinaryData;
+ private final boolean mSendToVoicemail;
+ private final String mCustomRingtone;
+ private final boolean mIsUserProfile;
+
+ private final Contact.Status mStatus;
+ private final Exception mException;
+
+ /**
+ * Constructor for special results, namely "no contact found" and "error".
+ */
+ private Contact(Uri requestedUri, Contact.Status status, Exception exception) {
+ if (status == Status.ERROR && exception == null) {
+ throw new IllegalArgumentException("ERROR result must have exception");
+ }
+ mStatus = status;
+ mException = exception;
+ mRequestedUri = requestedUri;
+ mLookupUri = null;
+ mUri = null;
+ mDirectoryId = -1;
+ mLookupKey = null;
+ mId = -1;
+ mRawContacts = null;
+ mStreamItems = null;
+ mStatuses = null;
+ mNameRawContactId = -1;
+ mDisplayNameSource = DisplayNameSources.UNDEFINED;
+ mPhotoId = -1;
+ mPhotoUri = null;
+ mDisplayName = null;
+ mAltDisplayName = null;
+ mPhoneticName = null;
+ mStarred = false;
+ mPresence = null;
+ mInvitableAccountTypes = null;
+ mSendToVoicemail = false;
+ mCustomRingtone = null;
+ mIsUserProfile = false;
+ }
+
+ public static Contact forError(Uri requestedUri, Exception exception) {
+ return new Contact(requestedUri, Status.ERROR, exception);
+ }
+
+ public static Contact forNotFound(Uri requestedUri) {
+ return new Contact(requestedUri, Status.NOT_FOUND, null);
+ }
+
+ /**
+ * Constructor to call when contact was found
+ */
+ public Contact(Uri requestedUri, Uri uri, Uri lookupUri, long directoryId, String lookupKey,
+ long id, long nameRawContactId, int displayNameSource, long photoId,
+ String photoUri, String displayName, String altDisplayName, String phoneticName,
+ boolean starred, Integer presence, boolean sendToVoicemail, String customRingtone,
+ boolean isUserProfile) {
+ mStatus = Status.LOADED;
+ mException = null;
+ mRequestedUri = requestedUri;
+ mLookupUri = lookupUri;
+ mUri = uri;
+ mDirectoryId = directoryId;
+ mLookupKey = lookupKey;
+ mId = id;
+ mRawContacts = null;
+ mStreamItems = null;
+ mStatuses = null;
+ mNameRawContactId = nameRawContactId;
+ mDisplayNameSource = displayNameSource;
+ mPhotoId = photoId;
+ mPhotoUri = photoUri;
+ mDisplayName = displayName;
+ mAltDisplayName = altDisplayName;
+ mPhoneticName = phoneticName;
+ mStarred = starred;
+ mPresence = presence;
+ mInvitableAccountTypes = null;
+ mSendToVoicemail = sendToVoicemail;
+ mCustomRingtone = customRingtone;
+ mIsUserProfile = isUserProfile;
+ }
+
+ public Contact(Uri requestedUri, Contact from) {
+ mRequestedUri = requestedUri;
+
+ mStatus = from.mStatus;
+ mException = from.mException;
+ mLookupUri = from.mLookupUri;
+ mUri = from.mUri;
+ mDirectoryId = from.mDirectoryId;
+ mLookupKey = from.mLookupKey;
+ mId = from.mId;
+ mNameRawContactId = from.mNameRawContactId;
+ mDisplayNameSource = from.mDisplayNameSource;
+ mPhotoId = from.mPhotoId;
+ mPhotoUri = from.mPhotoUri;
+ mDisplayName = from.mDisplayName;
+ mAltDisplayName = from.mAltDisplayName;
+ mPhoneticName = from.mPhoneticName;
+ mStarred = from.mStarred;
+ mPresence = from.mPresence;
+ mRawContacts = from.mRawContacts;
+ mStreamItems = from.mStreamItems;
+ mStatuses = from.mStatuses;
+ mInvitableAccountTypes = from.mInvitableAccountTypes;
+
+ mDirectoryDisplayName = from.mDirectoryDisplayName;
+ mDirectoryType = from.mDirectoryType;
+ mDirectoryAccountType = from.mDirectoryAccountType;
+ mDirectoryAccountName = from.mDirectoryAccountName;
+ mDirectoryExportSupport = from.mDirectoryExportSupport;
+
+ mGroups = from.mGroups;
+
+ mPhotoBinaryData = from.mPhotoBinaryData;
+ mSendToVoicemail = from.mSendToVoicemail;
+ mCustomRingtone = from.mCustomRingtone;
+ mIsUserProfile = from.mIsUserProfile;
+ }
+
+ /**
+ * @param exportSupport See {@link Directory#EXPORT_SUPPORT}.
+ */
+ public void setDirectoryMetaData(String displayName, String directoryType,
+ String accountType, String accountName, int exportSupport) {
+ mDirectoryDisplayName = displayName;
+ mDirectoryType = directoryType;
+ mDirectoryAccountType = accountType;
+ mDirectoryAccountName = accountName;
+ mDirectoryExportSupport = exportSupport;
+ }
+
+ /* package */ void setPhotoBinaryData(byte[] photoBinaryData) {
+ mPhotoBinaryData = photoBinaryData;
+ }
+
+ /**
+ * Returns the URI for the contact that contains both the lookup key and the ID. This is
+ * the best URI to reference a contact.
+ * For directory contacts, this is the same a the URI as returned by {@link #getUri()}
+ */
+ public Uri getLookupUri() {
+ return mLookupUri;
+ }
+
+ public String getLookupKey() {
+ return mLookupKey;
+ }
+
+ /**
+ * Returns the contact Uri that was passed to the provider to make the query. This is
+ * the same as the requested Uri, unless the requested Uri doesn't specify a Contact:
+ * If it either references a Raw-Contact or a Person (a pre-Eclair style Uri), this Uri will
+ * always reference the full aggregate contact.
+ */
+ public Uri getUri() {
+ return mUri;
+ }
+
+ /**
+ * Returns the URI for which this {@link ContactLoader) was initially requested.
+ */
+ public Uri getRequestedUri() {
+ return mRequestedUri;
+ }
+
+ /**
+ * Instantiate a new RawContactDeltaList for this contact.
+ */
+ public RawContactDeltaList createRawContactDeltaList() {
+ return RawContactDeltaList.fromIterator(getRawContacts().iterator());
+ }
+
+ /**
+ * Returns the contact ID.
+ */
+ @VisibleForTesting
+ /* package */ long getId() {
+ return mId;
+ }
+
+ /**
+ * @return true when an exception happened during loading, in which case
+ * {@link #getException} returns the actual exception object.
+ * Note {@link #isNotFound()} and {@link #isError()} are mutually exclusive; If
+ * {@link #isError()} is {@code true}, {@link #isNotFound()} is always {@code false},
+ * and vice versa.
+ */
+ public boolean isError() {
+ return mStatus == Status.ERROR;
+ }
+
+ public Exception getException() {
+ return mException;
+ }
+
+ /**
+ * @return true when the specified contact is not found.
+ * Note {@link #isNotFound()} and {@link #isError()} are mutually exclusive; If
+ * {@link #isError()} is {@code true}, {@link #isNotFound()} is always {@code false},
+ * and vice versa.
+ */
+ public boolean isNotFound() {
+ return mStatus == Status.NOT_FOUND;
+ }
+
+ /**
+ * @return true if the specified contact is successfully loaded.
+ * i.e. neither {@link #isError()} nor {@link #isNotFound()}.
+ */
+ public boolean isLoaded() {
+ return mStatus == Status.LOADED;
+ }
+
+ public long getNameRawContactId() {
+ return mNameRawContactId;
+ }
+
+ public int getDisplayNameSource() {
+ return mDisplayNameSource;
+ }
+
+ public long getPhotoId() {
+ return mPhotoId;
+ }
+
+ public String getPhotoUri() {
+ return mPhotoUri;
+ }
+
+ public String getDisplayName() {
+ return mDisplayName;
+ }
+
+ public String getAltDisplayName() {
+ return mAltDisplayName;
+ }
+
+ public String getPhoneticName() {
+ return mPhoneticName;
+ }
+
+ public boolean getStarred() {
+ return mStarred;
+ }
+
+ public Integer getPresence() {
+ return mPresence;
+ }
+
+ /**
+ * This can return non-null invitable account types only if the {@link ContactLoader} was
+ * configured to load invitable account types in its constructor.
+ * @return
+ */
+ public ImmutableList<AccountType> getInvitableAccountTypes() {
+ return mInvitableAccountTypes;
+ }
+
+ public ImmutableList<RawContact> getRawContacts() {
+ return mRawContacts;
+ }
+
+ /**
+ * This can return non-null stream items only if the {@link ContactLoader} was
+ * configured to load stream items in its constructor.
+ * @return
+ */
+ public ImmutableList<StreamItemEntry> getStreamItems() {
+ return mStreamItems;
+ }
+
+ public ImmutableMap<Long, DataStatus> getStatuses() {
+ return mStatuses;
+ }
+
+ public long getDirectoryId() {
+ return mDirectoryId;
+ }
+
+ public boolean isDirectoryEntry() {
+ return mDirectoryId != -1 && mDirectoryId != Directory.DEFAULT
+ && mDirectoryId != Directory.LOCAL_INVISIBLE;
+ }
+
+ /**
+ * @return true if this is a contact (not group, etc.) with at least one
+ * writable raw-contact, and false otherwise.
+ */
+ public boolean isWritableContact(final Context context) {
+ return getFirstWritableRawContactId(context) != -1;
+ }
+
+ /**
+ * Return the ID of the first raw-contact in the contact data that belongs to a
+ * contact-writable account, or -1 if no such entity exists.
+ */
+ public long getFirstWritableRawContactId(final Context context) {
+ // Directory entries are non-writable
+ if (isDirectoryEntry()) return -1;
+
+ // Iterate through raw-contacts; if we find a writable on, return its ID.
+ for (RawContact rawContact : getRawContacts()) {
+ AccountType accountType = rawContact.getAccountType();
+ if (accountType != null && accountType.areContactsWritable()) {
+ return rawContact.getId();
+ }
+ }
+ // No writable raw-contact was found.
+ return -1;
+ }
+
+ public int getDirectoryExportSupport() {
+ return mDirectoryExportSupport;
+ }
+
+ public String getDirectoryDisplayName() {
+ return mDirectoryDisplayName;
+ }
+
+ public String getDirectoryType() {
+ return mDirectoryType;
+ }
+
+ public String getDirectoryAccountType() {
+ return mDirectoryAccountType;
+ }
+
+ public String getDirectoryAccountName() {
+ return mDirectoryAccountName;
+ }
+
+ public byte[] getPhotoBinaryData() {
+ return mPhotoBinaryData;
+ }
+
+ public ArrayList<ContentValues> getContentValues() {
+ if (mRawContacts.size() != 1) {
+ throw new IllegalStateException(
+ "Cannot extract content values from an aggregated contact");
+ }
+
+ RawContact rawContact = mRawContacts.get(0);
+ ArrayList<ContentValues> result = new ArrayList<ContentValues>();
+ for (DataItem dataItem : rawContact.getDataItems()) {
+ result.add(dataItem.getContentValues());
+ }
+
+ // If the photo was loaded using the URI, create an entry for the photo
+ // binary data.
+ if (mPhotoId == 0 && mPhotoBinaryData != null) {
+ ContentValues photo = new ContentValues();
+ photo.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
+ photo.put(Photo.PHOTO, mPhotoBinaryData);
+ result.add(photo);
+ }
+
+ return result;
+ }
+
+ /**
+ * This can return non-null group meta-data only if the {@link ContactLoader} was configured to
+ * load group metadata in its constructor.
+ * @return
+ */
+ public ImmutableList<GroupMetaData> getGroupMetaData() {
+ return mGroups;
+ }
+
+ public boolean isSendToVoicemail() {
+ return mSendToVoicemail;
+ }
+
+ public String getCustomRingtone() {
+ return mCustomRingtone;
+ }
+
+ public boolean isUserProfile() {
+ return mIsUserProfile;
+ }
+
+ @Override
+ public String toString() {
+ return "{requested=" + mRequestedUri + ",lookupkey=" + mLookupKey +
+ ",uri=" + mUri + ",status=" + mStatus + "}";
+ }
+
+ /* package */ void setRawContacts(ImmutableList<RawContact> rawContacts) {
+ mRawContacts = rawContacts;
+ }
+
+ /* package */ void setStatuses(ImmutableMap<Long, DataStatus> statuses) {
+ mStatuses = statuses;
+ }
+
+ /* package */ void setInvitableAccountTypes(ImmutableList<AccountType> accountTypes) {
+ mInvitableAccountTypes = accountTypes;
+ }
+
+ /* package */ void setGroupMetaData(ImmutableList<GroupMetaData> groups) {
+ mGroups = groups;
+ }
+
+ /* package */ void setStreamItems(ImmutableList<StreamItemEntry> streamItems) {
+ mStreamItems = streamItems;
+ }
+}
diff --git a/src/com/android/contacts/model/ContactLoader.java b/src/com/android/contacts/model/ContactLoader.java
new file mode 100644
index 0000000..28000a6
--- /dev/null
+++ b/src/com/android/contacts/model/ContactLoader.java
@@ -0,0 +1,938 @@
+/*
+ * 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.contacts.model;
+
+import android.content.AsyncTaskLoader;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Directory;
+import android.provider.ContactsContract.Groups;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.StreamItemPhotos;
+import android.provider.ContactsContract.StreamItems;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.LongSparseArray;
+
+import com.android.contacts.GroupMetaData;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountTypeWithDataSet;
+import com.android.contacts.model.dataitem.DataItem;
+import com.android.contacts.model.dataitem.PhotoDataItem;
+import com.android.contacts.util.ContactLoaderUtils;
+import com.android.contacts.util.DataStatus;
+import com.android.contacts.util.StreamItemEntry;
+import com.android.contacts.util.StreamItemPhotoEntry;
+import com.android.contacts.util.UriUtils;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Loads a single Contact and all it constituent RawContacts.
+ */
+public class ContactLoader extends AsyncTaskLoader<Contact> {
+ private static final String TAG = ContactLoader.class.getSimpleName();
+
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ /** A short-lived cache that can be set by {@link #cacheResult()} */
+ private static Contact sCachedResult = null;
+
+ private final Uri mRequestedUri;
+ private Uri mLookupUri;
+ private boolean mLoadGroupMetaData;
+ private boolean mLoadStreamItems;
+ private boolean mLoadInvitableAccountTypes;
+ private boolean mPostViewNotification;
+ private Contact mContact;
+ private ForceLoadContentObserver mObserver;
+ private final Set<Long> mNotifiedRawContactIds = Sets.newHashSet();
+
+ public ContactLoader(Context context, Uri lookupUri, boolean postViewNotification) {
+ this(context, lookupUri, false, false, false, postViewNotification);
+ }
+
+ public ContactLoader(Context context, Uri lookupUri, boolean loadGroupMetaData,
+ boolean loadStreamItems, boolean loadInvitableAccountTypes,
+ boolean postViewNotification) {
+ super(context);
+ mLookupUri = lookupUri;
+ mRequestedUri = lookupUri;
+ mLoadGroupMetaData = loadGroupMetaData;
+ mLoadStreamItems = loadStreamItems;
+ mLoadInvitableAccountTypes = loadInvitableAccountTypes;
+ mPostViewNotification = postViewNotification;
+ }
+
+ /**
+ * Projection used for the query that loads all data for the entire contact (except for
+ * social stream items).
+ */
+ private static class ContactQuery {
+ static final String[] COLUMNS = new String[] {
+ Contacts.NAME_RAW_CONTACT_ID,
+ Contacts.DISPLAY_NAME_SOURCE,
+ Contacts.LOOKUP_KEY,
+ Contacts.DISPLAY_NAME,
+ Contacts.DISPLAY_NAME_ALTERNATIVE,
+ Contacts.PHONETIC_NAME,
+ Contacts.PHOTO_ID,
+ Contacts.STARRED,
+ Contacts.CONTACT_PRESENCE,
+ Contacts.CONTACT_STATUS,
+ Contacts.CONTACT_STATUS_TIMESTAMP,
+ Contacts.CONTACT_STATUS_RES_PACKAGE,
+ Contacts.CONTACT_STATUS_LABEL,
+ Contacts.Entity.CONTACT_ID,
+ Contacts.Entity.RAW_CONTACT_ID,
+
+ RawContacts.ACCOUNT_NAME,
+ RawContacts.ACCOUNT_TYPE,
+ RawContacts.DATA_SET,
+ RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
+ RawContacts.DIRTY,
+ RawContacts.VERSION,
+ RawContacts.SOURCE_ID,
+ RawContacts.SYNC1,
+ RawContacts.SYNC2,
+ RawContacts.SYNC3,
+ RawContacts.SYNC4,
+ RawContacts.DELETED,
+ RawContacts.NAME_VERIFIED,
+
+ Contacts.Entity.DATA_ID,
+ Data.DATA1,
+ Data.DATA2,
+ Data.DATA3,
+ Data.DATA4,
+ Data.DATA5,
+ Data.DATA6,
+ Data.DATA7,
+ Data.DATA8,
+ Data.DATA9,
+ Data.DATA10,
+ Data.DATA11,
+ Data.DATA12,
+ Data.DATA13,
+ Data.DATA14,
+ Data.DATA15,
+ Data.SYNC1,
+ Data.SYNC2,
+ Data.SYNC3,
+ Data.SYNC4,
+ Data.DATA_VERSION,
+ Data.IS_PRIMARY,
+ Data.IS_SUPER_PRIMARY,
+ Data.MIMETYPE,
+ Data.RES_PACKAGE,
+
+ GroupMembership.GROUP_SOURCE_ID,
+
+ Data.PRESENCE,
+ Data.CHAT_CAPABILITY,
+ Data.STATUS,
+ Data.STATUS_RES_PACKAGE,
+ Data.STATUS_ICON,
+ Data.STATUS_LABEL,
+ Data.STATUS_TIMESTAMP,
+
+ Contacts.PHOTO_URI,
+ Contacts.SEND_TO_VOICEMAIL,
+ Contacts.CUSTOM_RINGTONE,
+ Contacts.IS_USER_PROFILE,
+ };
+
+ public static final int NAME_RAW_CONTACT_ID = 0;
+ public static final int DISPLAY_NAME_SOURCE = 1;
+ public static final int LOOKUP_KEY = 2;
+ public static final int DISPLAY_NAME = 3;
+ public static final int ALT_DISPLAY_NAME = 4;
+ public static final int PHONETIC_NAME = 5;
+ public static final int PHOTO_ID = 6;
+ public static final int STARRED = 7;
+ public static final int CONTACT_PRESENCE = 8;
+ public static final int CONTACT_STATUS = 9;
+ public static final int CONTACT_STATUS_TIMESTAMP = 10;
+ public static final int CONTACT_STATUS_RES_PACKAGE = 11;
+ public static final int CONTACT_STATUS_LABEL = 12;
+ public static final int CONTACT_ID = 13;
+ public static final int RAW_CONTACT_ID = 14;
+
+ public static final int ACCOUNT_NAME = 15;
+ public static final int ACCOUNT_TYPE = 16;
+ public static final int DATA_SET = 17;
+ public static final int ACCOUNT_TYPE_AND_DATA_SET = 18;
+ public static final int DIRTY = 19;
+ public static final int VERSION = 20;
+ public static final int SOURCE_ID = 21;
+ public static final int SYNC1 = 22;
+ public static final int SYNC2 = 23;
+ public static final int SYNC3 = 24;
+ public static final int SYNC4 = 25;
+ public static final int DELETED = 26;
+ public static final int NAME_VERIFIED = 27;
+
+ public static final int DATA_ID = 28;
+ public static final int DATA1 = 29;
+ public static final int DATA2 = 30;
+ public static final int DATA3 = 31;
+ public static final int DATA4 = 32;
+ public static final int DATA5 = 33;
+ public static final int DATA6 = 34;
+ public static final int DATA7 = 35;
+ public static final int DATA8 = 36;
+ public static final int DATA9 = 37;
+ public static final int DATA10 = 38;
+ public static final int DATA11 = 39;
+ public static final int DATA12 = 40;
+ public static final int DATA13 = 41;
+ public static final int DATA14 = 42;
+ public static final int DATA15 = 43;
+ public static final int DATA_SYNC1 = 44;
+ public static final int DATA_SYNC2 = 45;
+ public static final int DATA_SYNC3 = 46;
+ public static final int DATA_SYNC4 = 47;
+ public static final int DATA_VERSION = 48;
+ public static final int IS_PRIMARY = 49;
+ public static final int IS_SUPERPRIMARY = 50;
+ public static final int MIMETYPE = 51;
+ public static final int RES_PACKAGE = 52;
+
+ public static final int GROUP_SOURCE_ID = 53;
+
+ public static final int PRESENCE = 54;
+ public static final int CHAT_CAPABILITY = 55;
+ public static final int STATUS = 56;
+ public static final int STATUS_RES_PACKAGE = 57;
+ public static final int STATUS_ICON = 58;
+ public static final int STATUS_LABEL = 59;
+ public static final int STATUS_TIMESTAMP = 60;
+
+ public static final int PHOTO_URI = 61;
+ public static final int SEND_TO_VOICEMAIL = 62;
+ public static final int CUSTOM_RINGTONE = 63;
+ public static final int IS_USER_PROFILE = 64;
+ }
+
+ /**
+ * Projection used for the query that loads all data for the entire contact.
+ */
+ private static class DirectoryQuery {
+ static final String[] COLUMNS = new String[] {
+ Directory.DISPLAY_NAME,
+ Directory.PACKAGE_NAME,
+ Directory.TYPE_RESOURCE_ID,
+ Directory.ACCOUNT_TYPE,
+ Directory.ACCOUNT_NAME,
+ Directory.EXPORT_SUPPORT,
+ };
+
+ public static final int DISPLAY_NAME = 0;
+ public static final int PACKAGE_NAME = 1;
+ public static final int TYPE_RESOURCE_ID = 2;
+ public static final int ACCOUNT_TYPE = 3;
+ public static final int ACCOUNT_NAME = 4;
+ public static final int EXPORT_SUPPORT = 5;
+ }
+
+ private static class GroupQuery {
+ static final String[] COLUMNS = new String[] {
+ Groups.ACCOUNT_NAME,
+ Groups.ACCOUNT_TYPE,
+ Groups.DATA_SET,
+ Groups.ACCOUNT_TYPE_AND_DATA_SET,
+ Groups._ID,
+ Groups.TITLE,
+ Groups.AUTO_ADD,
+ Groups.FAVORITES,
+ };
+
+ public static final int ACCOUNT_NAME = 0;
+ public static final int ACCOUNT_TYPE = 1;
+ public static final int DATA_SET = 2;
+ public static final int ACCOUNT_TYPE_AND_DATA_SET = 3;
+ public static final int ID = 4;
+ public static final int TITLE = 5;
+ public static final int AUTO_ADD = 6;
+ public static final int FAVORITES = 7;
+ }
+
+ @Override
+ public Contact loadInBackground() {
+ try {
+ final ContentResolver resolver = getContext().getContentResolver();
+ final Uri uriCurrentFormat = ContactLoaderUtils.ensureIsContactUri(
+ resolver, mLookupUri);
+ final Contact cachedResult = sCachedResult;
+ sCachedResult = null;
+ // Is this the same Uri as what we had before already? In that case, reuse that result
+ final Contact result;
+ final boolean resultIsCached;
+ if (cachedResult != null &&
+ UriUtils.areEqual(cachedResult.getLookupUri(), mLookupUri)) {
+ // We are using a cached result from earlier. Below, we should make sure
+ // we are not doing any more network or disc accesses
+ result = new Contact(mRequestedUri, cachedResult);
+ resultIsCached = true;
+ } else {
+ result = loadContactEntity(resolver, uriCurrentFormat);
+ resultIsCached = false;
+ }
+ if (result.isLoaded()) {
+ if (result.isDirectoryEntry()) {
+ if (!resultIsCached) {
+ loadDirectoryMetaData(result);
+ }
+ } else if (mLoadGroupMetaData) {
+ if (result.getGroupMetaData() == null) {
+ loadGroupMetaData(result);
+ }
+ }
+ if (mLoadStreamItems && result.getStreamItems() == null) {
+ loadStreamItems(result);
+ }
+ if (!resultIsCached) loadPhotoBinaryData(result);
+
+ // Note ME profile should never have "Add connection"
+ if (mLoadInvitableAccountTypes && result.getInvitableAccountTypes() == null) {
+ loadInvitableAccountTypes(result);
+ }
+ }
+ return result;
+ } catch (Exception e) {
+ Log.e(TAG, "Error loading the contact: " + mLookupUri, e);
+ return Contact.forError(mRequestedUri, e);
+ }
+ }
+
+ private Contact loadContactEntity(ContentResolver resolver, Uri contactUri) {
+ Uri entityUri = Uri.withAppendedPath(contactUri, Contacts.Entity.CONTENT_DIRECTORY);
+ Cursor cursor = resolver.query(entityUri, ContactQuery.COLUMNS, null, null,
+ Contacts.Entity.RAW_CONTACT_ID);
+ if (cursor == null) {
+ Log.e(TAG, "No cursor returned in loadContactEntity");
+ return Contact.forNotFound(mRequestedUri);
+ }
+
+ try {
+ if (!cursor.moveToFirst()) {
+ cursor.close();
+ return Contact.forNotFound(mRequestedUri);
+ }
+
+ // Create the loaded contact starting with the header data.
+ Contact contact = loadContactHeaderData(cursor, contactUri);
+
+ // Fill in the raw contacts, which is wrapped in an Entity and any
+ // status data. Initially, result has empty entities and statuses.
+ long currentRawContactId = -1;
+ RawContact rawContact = null;
+ ImmutableList.Builder<RawContact> rawContactsBuilder =
+ new ImmutableList.Builder<RawContact>();
+ ImmutableMap.Builder<Long, DataStatus> statusesBuilder =
+ new ImmutableMap.Builder<Long, DataStatus>();
+ do {
+ long rawContactId = cursor.getLong(ContactQuery.RAW_CONTACT_ID);
+ if (rawContactId != currentRawContactId) {
+ // First time to see this raw contact id, so create a new entity, and
+ // add it to the result's entities.
+ currentRawContactId = rawContactId;
+ rawContact = new RawContact(getContext(), loadRawContactValues(cursor));
+ rawContactsBuilder.add(rawContact);
+ }
+ if (!cursor.isNull(ContactQuery.DATA_ID)) {
+ ContentValues data = loadDataValues(cursor);
+ rawContact.addDataItemValues(data);
+
+ if (!cursor.isNull(ContactQuery.PRESENCE)
+ || !cursor.isNull(ContactQuery.STATUS)) {
+ final DataStatus status = new DataStatus(cursor);
+ final long dataId = cursor.getLong(ContactQuery.DATA_ID);
+ statusesBuilder.put(dataId, status);
+ }
+ }
+ } while (cursor.moveToNext());
+
+ contact.setRawContacts(rawContactsBuilder.build());
+ contact.setStatuses(statusesBuilder.build());
+
+ return contact;
+ } finally {
+ cursor.close();
+ }
+ }
+
+ /**
+ * Looks for the photo data item in entities. If found, creates a new Bitmap instance. If
+ * not found, returns null
+ */
+ private void loadPhotoBinaryData(Contact contactData) {
+
+ // If we have a photo URI, try loading that first.
+ String photoUri = contactData.getPhotoUri();
+ if (photoUri != null) {
+ try {
+ AssetFileDescriptor fd = getContext().getContentResolver()
+ .openAssetFileDescriptor(Uri.parse(photoUri), "r");
+ byte[] buffer = new byte[16 * 1024];
+ FileInputStream fis = fd.createInputStream();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try {
+ int size;
+ while ((size = fis.read(buffer)) != -1) {
+ baos.write(buffer, 0, size);
+ }
+ contactData.setPhotoBinaryData(baos.toByteArray());
+ } finally {
+ fis.close();
+ fd.close();
+ }
+ return;
+ } catch (IOException ioe) {
+ // Just fall back to the case below.
+ }
+ }
+
+ // If we couldn't load from a file, fall back to the data blob.
+ final long photoId = contactData.getPhotoId();
+ if (photoId <= 0) {
+ // No photo ID
+ return;
+ }
+
+ for (RawContact rawContact : contactData.getRawContacts()) {
+ for (DataItem dataItem : rawContact.getDataItems()) {
+ if (dataItem.getId() == photoId) {
+ if (!(dataItem instanceof PhotoDataItem)) {
+ break;
+ }
+
+ final PhotoDataItem photo = (PhotoDataItem) dataItem;
+ contactData.setPhotoBinaryData(photo.getPhoto());
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets the "invitable" account types to {@link Contact#mInvitableAccountTypes}.
+ */
+ private void loadInvitableAccountTypes(Contact contactData) {
+ final ImmutableList.Builder<AccountType> resultListBuilder =
+ new ImmutableList.Builder<AccountType>();
+ if (!contactData.isUserProfile()) {
+ Map<AccountTypeWithDataSet, AccountType> invitables =
+ AccountTypeManager.getInstance(getContext()).getUsableInvitableAccountTypes();
+ if (!invitables.isEmpty()) {
+ final Map<AccountTypeWithDataSet, AccountType> resultMap =
+ Maps.newHashMap(invitables);
+
+ // Remove the ones that already have a raw contact in the current contact
+ for (RawContact rawContact : contactData.getRawContacts()) {
+ final AccountTypeWithDataSet type = AccountTypeWithDataSet.get(
+ rawContact.getAccountTypeString(),
+ rawContact.getDataSet());
+ resultMap.remove(type);
+ }
+
+ resultListBuilder.addAll(resultMap.values());
+ }
+ }
+
+ // Set to mInvitableAccountTypes
+ contactData.setInvitableAccountTypes(resultListBuilder.build());
+ }
+
+ /**
+ * Extracts Contact level columns from the cursor.
+ */
+ private Contact loadContactHeaderData(final Cursor cursor, Uri contactUri) {
+ final String directoryParameter =
+ contactUri.getQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY);
+ final long directoryId = directoryParameter == null
+ ? Directory.DEFAULT
+ : Long.parseLong(directoryParameter);
+ final long contactId = cursor.getLong(ContactQuery.CONTACT_ID);
+ final String lookupKey = cursor.getString(ContactQuery.LOOKUP_KEY);
+ final long nameRawContactId = cursor.getLong(ContactQuery.NAME_RAW_CONTACT_ID);
+ final int displayNameSource = cursor.getInt(ContactQuery.DISPLAY_NAME_SOURCE);
+ final String displayName = cursor.getString(ContactQuery.DISPLAY_NAME);
+ final String altDisplayName = cursor.getString(ContactQuery.ALT_DISPLAY_NAME);
+ final String phoneticName = cursor.getString(ContactQuery.PHONETIC_NAME);
+ final long photoId = cursor.getLong(ContactQuery.PHOTO_ID);
+ final String photoUri = cursor.getString(ContactQuery.PHOTO_URI);
+ final boolean starred = cursor.getInt(ContactQuery.STARRED) != 0;
+ final Integer presence = cursor.isNull(ContactQuery.CONTACT_PRESENCE)
+ ? null
+ : cursor.getInt(ContactQuery.CONTACT_PRESENCE);
+ final boolean sendToVoicemail = cursor.getInt(ContactQuery.SEND_TO_VOICEMAIL) == 1;
+ final String customRingtone = cursor.getString(ContactQuery.CUSTOM_RINGTONE);
+ final boolean isUserProfile = cursor.getInt(ContactQuery.IS_USER_PROFILE) == 1;
+
+ Uri lookupUri;
+ if (directoryId == Directory.DEFAULT || directoryId == Directory.LOCAL_INVISIBLE) {
+ lookupUri = ContentUris.withAppendedId(
+ Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey), contactId);
+ } else {
+ lookupUri = contactUri;
+ }
+
+ return new Contact(mRequestedUri, contactUri, lookupUri, directoryId, lookupKey,
+ contactId, nameRawContactId, displayNameSource, photoId, photoUri, displayName,
+ altDisplayName, phoneticName, starred, presence, sendToVoicemail,
+ customRingtone, isUserProfile);
+ }
+
+ /**
+ * Extracts RawContact level columns from the cursor.
+ */
+ private ContentValues loadRawContactValues(Cursor cursor) {
+ ContentValues cv = new ContentValues();
+
+ cv.put(RawContacts._ID, cursor.getLong(ContactQuery.RAW_CONTACT_ID));
+
+ cursorColumnToContentValues(cursor, cv, ContactQuery.ACCOUNT_NAME);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.ACCOUNT_TYPE);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SET);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.ACCOUNT_TYPE_AND_DATA_SET);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DIRTY);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.VERSION);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.SOURCE_ID);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC1);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC2);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC3);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC4);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DELETED);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.CONTACT_ID);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.STARRED);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.NAME_VERIFIED);
+
+ return cv;
+ }
+
+ /**
+ * Extracts Data level columns from the cursor.
+ */
+ private ContentValues loadDataValues(Cursor cursor) {
+ ContentValues cv = new ContentValues();
+
+ cv.put(Data._ID, cursor.getLong(ContactQuery.DATA_ID));
+
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA1);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA2);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA3);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA4);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA5);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA6);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA7);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA8);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA9);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA10);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA11);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA12);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA13);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA14);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA15);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC1);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC2);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC3);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC4);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_VERSION);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.IS_PRIMARY);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.IS_SUPERPRIMARY);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.MIMETYPE);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.RES_PACKAGE);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.GROUP_SOURCE_ID);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.CHAT_CAPABILITY);
+
+ return cv;
+ }
+
+ private void cursorColumnToContentValues(
+ Cursor cursor, ContentValues values, int index) {
+ switch (cursor.getType(index)) {
+ case Cursor.FIELD_TYPE_NULL:
+ // don't put anything in the content values
+ break;
+ case Cursor.FIELD_TYPE_INTEGER:
+ values.put(ContactQuery.COLUMNS[index], cursor.getLong(index));
+ break;
+ case Cursor.FIELD_TYPE_STRING:
+ values.put(ContactQuery.COLUMNS[index], cursor.getString(index));
+ break;
+ case Cursor.FIELD_TYPE_BLOB:
+ values.put(ContactQuery.COLUMNS[index], cursor.getBlob(index));
+ break;
+ default:
+ throw new IllegalStateException("Invalid or unhandled data type");
+ }
+ }
+
+ private void loadDirectoryMetaData(Contact result) {
+ long directoryId = result.getDirectoryId();
+
+ Cursor cursor = getContext().getContentResolver().query(
+ ContentUris.withAppendedId(Directory.CONTENT_URI, directoryId),
+ DirectoryQuery.COLUMNS, null, null, null);
+ if (cursor == null) {
+ return;
+ }
+ try {
+ if (cursor.moveToFirst()) {
+ final String displayName = cursor.getString(DirectoryQuery.DISPLAY_NAME);
+ final String packageName = cursor.getString(DirectoryQuery.PACKAGE_NAME);
+ final int typeResourceId = cursor.getInt(DirectoryQuery.TYPE_RESOURCE_ID);
+ final String accountType = cursor.getString(DirectoryQuery.ACCOUNT_TYPE);
+ final String accountName = cursor.getString(DirectoryQuery.ACCOUNT_NAME);
+ final int exportSupport = cursor.getInt(DirectoryQuery.EXPORT_SUPPORT);
+ String directoryType = null;
+ if (!TextUtils.isEmpty(packageName)) {
+ PackageManager pm = getContext().getPackageManager();
+ try {
+ Resources resources = pm.getResourcesForApplication(packageName);
+ directoryType = resources.getString(typeResourceId);
+ } catch (NameNotFoundException e) {
+ Log.w(TAG, "Contact directory resource not found: "
+ + packageName + "." + typeResourceId);
+ }
+ }
+
+ result.setDirectoryMetaData(
+ displayName, directoryType, accountType, accountName, exportSupport);
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+
+ /**
+ * Loads groups meta-data for all groups associated with all constituent raw contacts'
+ * accounts.
+ */
+ private void loadGroupMetaData(Contact result) {
+ StringBuilder selection = new StringBuilder();
+ ArrayList<String> selectionArgs = new ArrayList<String>();
+ for (RawContact rawContact : result.getRawContacts()) {
+ final String accountName = rawContact.getAccountName();
+ final String accountType = rawContact.getAccountTypeString();
+ final String dataSet = rawContact.getDataSet();
+ if (accountName != null && accountType != null) {
+ if (selection.length() != 0) {
+ selection.append(" OR ");
+ }
+ selection.append(
+ "(" + Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=?");
+ selectionArgs.add(accountName);
+ selectionArgs.add(accountType);
+
+ if (dataSet != null) {
+ selection.append(" AND " + Groups.DATA_SET + "=?");
+ selectionArgs.add(dataSet);
+ } else {
+ selection.append(" AND " + Groups.DATA_SET + " IS NULL");
+ }
+ selection.append(")");
+ }
+ }
+ final ImmutableList.Builder<GroupMetaData> groupListBuilder =
+ new ImmutableList.Builder<GroupMetaData>();
+ final Cursor cursor = getContext().getContentResolver().query(Groups.CONTENT_URI,
+ GroupQuery.COLUMNS, selection.toString(), selectionArgs.toArray(new String[0]),
+ null);
+ try {
+ while (cursor.moveToNext()) {
+ final String accountName = cursor.getString(GroupQuery.ACCOUNT_NAME);
+ final String accountType = cursor.getString(GroupQuery.ACCOUNT_TYPE);
+ final String dataSet = cursor.getString(GroupQuery.DATA_SET);
+ final long groupId = cursor.getLong(GroupQuery.ID);
+ final String title = cursor.getString(GroupQuery.TITLE);
+ final boolean defaultGroup = cursor.isNull(GroupQuery.AUTO_ADD)
+ ? false
+ : cursor.getInt(GroupQuery.AUTO_ADD) != 0;
+ final boolean favorites = cursor.isNull(GroupQuery.FAVORITES)
+ ? false
+ : cursor.getInt(GroupQuery.FAVORITES) != 0;
+
+ groupListBuilder.add(new GroupMetaData(
+ accountName, accountType, dataSet, groupId, title, defaultGroup,
+ favorites));
+ }
+ } finally {
+ cursor.close();
+ }
+ result.setGroupMetaData(groupListBuilder.build());
+ }
+
+ /**
+ * Loads all stream items and stream item photos belonging to this contact.
+ */
+ private void loadStreamItems(Contact result) {
+ final Cursor cursor = getContext().getContentResolver().query(
+ Contacts.CONTENT_LOOKUP_URI.buildUpon()
+ .appendPath(result.getLookupKey())
+ .appendPath(Contacts.StreamItems.CONTENT_DIRECTORY).build(),
+ null, null, null, null);
+ final LongSparseArray<StreamItemEntry> streamItemsById =
+ new LongSparseArray<StreamItemEntry>();
+ final ArrayList<StreamItemEntry> streamItems = new ArrayList<StreamItemEntry>();
+ try {
+ while (cursor.moveToNext()) {
+ StreamItemEntry streamItem = new StreamItemEntry(cursor);
+ streamItemsById.put(streamItem.getId(), streamItem);
+ streamItems.add(streamItem);
+ }
+ } finally {
+ cursor.close();
+ }
+
+ // Pre-decode all HTMLs
+ final long start = System.currentTimeMillis();
+ for (StreamItemEntry streamItem : streamItems) {
+ streamItem.decodeHtml(getContext());
+ }
+ final long end = System.currentTimeMillis();
+ if (DEBUG) {
+ Log.d(TAG, "Decoded HTML for " + streamItems.size() + " items, took "
+ + (end - start) + " ms");
+ }
+
+ // Now retrieve any photo records associated with the stream items.
+ if (!streamItems.isEmpty()) {
+ if (result.isUserProfile()) {
+ // If the stream items we're loading are for the profile, we can't bulk-load the
+ // stream items with a custom selection.
+ for (StreamItemEntry entry : streamItems) {
+ Cursor siCursor = getContext().getContentResolver().query(
+ Uri.withAppendedPath(
+ ContentUris.withAppendedId(
+ StreamItems.CONTENT_URI, entry.getId()),
+ StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
+ null, null, null, null);
+ try {
+ while (siCursor.moveToNext()) {
+ entry.addPhoto(new StreamItemPhotoEntry(siCursor));
+ }
+ } finally {
+ siCursor.close();
+ }
+ }
+ } else {
+ String[] streamItemIdArr = new String[streamItems.size()];
+ StringBuilder streamItemPhotoSelection = new StringBuilder();
+ streamItemPhotoSelection.append(StreamItemPhotos.STREAM_ITEM_ID + " IN (");
+ for (int i = 0; i < streamItems.size(); i++) {
+ if (i > 0) {
+ streamItemPhotoSelection.append(",");
+ }
+ streamItemPhotoSelection.append("?");
+ streamItemIdArr[i] = String.valueOf(streamItems.get(i).getId());
+ }
+ streamItemPhotoSelection.append(")");
+ Cursor sipCursor = getContext().getContentResolver().query(
+ StreamItems.CONTENT_PHOTO_URI,
+ null, streamItemPhotoSelection.toString(), streamItemIdArr,
+ StreamItemPhotos.STREAM_ITEM_ID);
+ try {
+ while (sipCursor.moveToNext()) {
+ long streamItemId = sipCursor.getLong(
+ sipCursor.getColumnIndex(StreamItemPhotos.STREAM_ITEM_ID));
+ StreamItemEntry streamItem = streamItemsById.get(streamItemId);
+ streamItem.addPhoto(new StreamItemPhotoEntry(sipCursor));
+ }
+ } finally {
+ sipCursor.close();
+ }
+ }
+ }
+
+ // Set the sorted stream items on the result.
+ Collections.sort(streamItems);
+ result.setStreamItems(new ImmutableList.Builder<StreamItemEntry>()
+ .addAll(streamItems.iterator())
+ .build());
+ }
+
+ @Override
+ public void deliverResult(Contact result) {
+ unregisterObserver();
+
+ // The creator isn't interested in any further updates
+ if (isReset() || result == null) {
+ return;
+ }
+
+ mContact = result;
+
+ if (result.isLoaded()) {
+ mLookupUri = result.getLookupUri();
+
+ if (!result.isDirectoryEntry()) {
+ Log.i(TAG, "Registering content observer for " + mLookupUri);
+ if (mObserver == null) {
+ mObserver = new ForceLoadContentObserver();
+ }
+ getContext().getContentResolver().registerContentObserver(
+ mLookupUri, true, mObserver);
+ }
+
+ if (mPostViewNotification) {
+ // inform the source of the data that this contact is being looked at
+ postViewNotificationToSyncAdapter();
+ }
+ }
+
+ super.deliverResult(mContact);
+ }
+
+ /**
+ * Posts a message to the contributing sync adapters that have opted-in, notifying them
+ * that the contact has just been loaded
+ */
+ private void postViewNotificationToSyncAdapter() {
+ Context context = getContext();
+ for (RawContact rawContact : mContact.getRawContacts()) {
+ final long rawContactId = rawContact.getId();
+ if (mNotifiedRawContactIds.contains(rawContactId)) {
+ continue; // Already notified for this raw contact.
+ }
+ mNotifiedRawContactIds.add(rawContactId);
+ final AccountType accountType = rawContact.getAccountType();
+ final String serviceName = accountType.getViewContactNotifyServiceClassName();
+ final String servicePackageName = accountType.getViewContactNotifyServicePackageName();
+ if (!TextUtils.isEmpty(serviceName) && !TextUtils.isEmpty(servicePackageName)) {
+ final Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
+ final Intent intent = new Intent();
+ intent.setClassName(servicePackageName, serviceName);
+ intent.setAction(Intent.ACTION_VIEW);
+ intent.setDataAndType(uri, RawContacts.CONTENT_ITEM_TYPE);
+ try {
+ context.startService(intent);
+ } catch (Exception e) {
+ Log.e(TAG, "Error sending message to source-app", e);
+ }
+ }
+ }
+ }
+
+ private void unregisterObserver() {
+ if (mObserver != null) {
+ getContext().getContentResolver().unregisterContentObserver(mObserver);
+ mObserver = null;
+ }
+ }
+
+ /**
+ * Sets whether to load stream items. Will trigger a reload if the value has changed.
+ * At the moment, this is only used for debugging purposes
+ */
+ public void setLoadStreamItems(boolean value) {
+ if (mLoadStreamItems != value) {
+ mLoadStreamItems = value;
+ onContentChanged();
+ }
+ }
+
+ /**
+ * Fully upgrades this ContactLoader to one with all lists fully loaded. When done, the
+ * new result will be delivered
+ */
+ public void upgradeToFullContact() {
+ // Everything requested already? Nothing to do, so let's bail out
+ if (mLoadGroupMetaData && mLoadInvitableAccountTypes && mLoadStreamItems
+ && mPostViewNotification) return;
+
+ mLoadGroupMetaData = true;
+ mLoadInvitableAccountTypes = true;
+ mLoadStreamItems = true;
+ mPostViewNotification = true;
+
+ // Cache the current result, so that we only load the "missing" parts of the contact.
+ cacheResult();
+
+ // Our load parameters have changed, so let's pretend the data has changed. Its the same
+ // thing, essentially.
+ onContentChanged();
+ }
+
+ public boolean getLoadStreamItems() {
+ return mLoadStreamItems;
+ }
+
+ public Uri getLookupUri() {
+ return mLookupUri;
+ }
+
+ @Override
+ protected void onStartLoading() {
+ if (mContact != null) {
+ deliverResult(mContact);
+ }
+
+ if (takeContentChanged() || mContact == null) {
+ forceLoad();
+ }
+ }
+
+ @Override
+ protected void onStopLoading() {
+ cancelLoad();
+ }
+
+ @Override
+ protected void onReset() {
+ super.onReset();
+ cancelLoad();
+ unregisterObserver();
+ mContact = null;
+ }
+
+ /**
+ * Caches the result, which is useful when we switch from activity to activity, using the same
+ * contact. If the next load is for a different contact, the cached result will be dropped
+ */
+ public void cacheResult() {
+ if (mContact == null || !mContact.isLoaded()) {
+ sCachedResult = null;
+ } else {
+ sCachedResult = mContact;
+ }
+ }
+}
diff --git a/src/com/android/contacts/model/RawContact.java b/src/com/android/contacts/model/RawContact.java
new file mode 100644
index 0000000..d884198
--- /dev/null
+++ b/src/com/android/contacts/model/RawContact.java
@@ -0,0 +1,262 @@
+/*
+ * 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.contacts.model;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Entity;
+import android.net.Uri;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.RawContacts;
+
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.model.dataitem.DataItem;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * RawContact represents a single raw contact in the raw contacts database.
+ * It has specialized getters/setters for raw contact
+ * items, and also contains a collection of DataItem objects. A RawContact contains the information
+ * from a single account.
+ *
+ * This allows RawContact objects to be thought of as a class with raw contact
+ * fields (like account type, name, data set, sync state, etc.) and a list of
+ * DataItem objects that represent contact information elements (like phone
+ * numbers, email, address, etc.).
+ */
+public class RawContact {
+
+ private final Context mContext;
+ private AccountTypeManager mAccountTypeManager;
+ private final ContentValues mValues;
+ private final ArrayList<NamedDataItem> mDataItems;
+
+ public static class NamedDataItem {
+ public final Uri uri;
+ public final DataItem dataItem;
+
+ public NamedDataItem(Uri uri, DataItem dataItem) {
+ this.uri = uri;
+ this.dataItem = dataItem;
+ }
+ }
+
+ public static RawContact createFrom(Entity entity) {
+ final ContentValues values = entity.getEntityValues();
+ final ArrayList<Entity.NamedContentValues> subValues = entity.getSubValues();
+
+ RawContact rawContact = new RawContact(null, values);
+ for (Entity.NamedContentValues subValue : subValues) {
+ rawContact.addNamedDataItemValues(subValue.uri, subValue.values);
+ }
+ return rawContact;
+ }
+
+ /**
+ * A RawContact object can be created with or without a context.
+ *
+ * The context is used for the buildString() member function in DataItem objects,
+ * specifically for retrieving an instance of AccountTypeManager. It is okay to
+ * pass in null for the context in which case, you will not be able to call buildString(),
+ * getDataKind(), or getAccountType() from a DataItem object.
+ */
+ public RawContact(Context context) {
+ this(context, new ContentValues());
+ }
+
+ public RawContact(Context context, ContentValues values) {
+ mContext = context;
+ mValues = values;
+ mDataItems = new ArrayList<NamedDataItem>();
+ }
+
+ public AccountTypeManager getAccountTypeManager() {
+ if (mAccountTypeManager == null) {
+ mAccountTypeManager = AccountTypeManager.getInstance(mContext);
+ }
+ return mAccountTypeManager;
+ }
+
+ public Context getContext() {
+ return mContext;
+ }
+
+ public ContentValues getValues() {
+ return mValues;
+ }
+
+ /**
+ * Returns the id of the raw contact.
+ */
+ public Long getId() {
+ return getValues().getAsLong(RawContacts._ID);
+ }
+
+ /**
+ * Returns the account name of the raw contact.
+ */
+ public String getAccountName() {
+ return getValues().getAsString(RawContacts.ACCOUNT_NAME);
+ }
+
+ /**
+ * Returns the account type of the raw contact.
+ */
+ public String getAccountTypeString() {
+ return getValues().getAsString(RawContacts.ACCOUNT_TYPE);
+ }
+
+ /**
+ * Returns the data set of the raw contact.
+ */
+ public String getDataSet() {
+ return getValues().getAsString(RawContacts.DATA_SET);
+ }
+
+ /**
+ * Returns the account type and data set of the raw contact.
+ */
+ public String getAccountTypeAndDataSetString() {
+ return getValues().getAsString(RawContacts.ACCOUNT_TYPE_AND_DATA_SET);
+ }
+
+ public boolean isDirty() {
+ return getValues().getAsBoolean(RawContacts.DIRTY);
+ }
+
+ public long getVersion() {
+ return getValues().getAsLong(RawContacts.DIRTY);
+ }
+
+ public String getSourceId() {
+ return getValues().getAsString(RawContacts.SOURCE_ID);
+ }
+
+ public String getSync1() {
+ return getValues().getAsString(RawContacts.SYNC1);
+ }
+
+ public String getSync2() {
+ return getValues().getAsString(RawContacts.SYNC2);
+ }
+
+ public String getSync3() {
+ return getValues().getAsString(RawContacts.SYNC3);
+ }
+
+ public String getSync4() {
+ return getValues().getAsString(RawContacts.SYNC4);
+ }
+
+ public boolean isDeleted() {
+ return getValues().getAsBoolean(RawContacts.DELETED);
+ }
+
+ public boolean isNameVerified() {
+ return getValues().getAsBoolean(RawContacts.NAME_VERIFIED);
+ }
+
+ public long getContactId() {
+ return getValues().getAsLong(Contacts.Entity.CONTACT_ID);
+ }
+
+ public boolean isStarred() {
+ return getValues().getAsBoolean(Contacts.STARRED);
+ }
+
+ public AccountType getAccountType() {
+ return getAccountTypeManager().getAccountType(getAccountTypeString(), getDataSet());
+ }
+
+ /**
+ * Sets the account name, account type, and data set strings.
+ * Valid combinations for account-name, account-type, data-set
+ * 1) null, null, null (local account)
+ * 2) non-null, non-null, null (valid account without data-set)
+ * 3) non-null, non-null, non-null (valid account with data-set)
+ */
+ private void setAccount(String accountName, String accountType, String dataSet) {
+ final ContentValues values = getValues();
+ if (accountName == null) {
+ if (accountType == null && dataSet == null) {
+ // This is a local account
+ values.putNull(RawContacts.ACCOUNT_NAME);
+ values.putNull(RawContacts.ACCOUNT_TYPE);
+ values.putNull(RawContacts.DATA_SET);
+ return;
+ }
+ } else {
+ if (accountType != null) {
+ // This is a valid account, either with or without a dataSet.
+ values.put(RawContacts.ACCOUNT_NAME, accountName);
+ values.put(RawContacts.ACCOUNT_TYPE, accountType);
+ if (dataSet == null) {
+ values.putNull(RawContacts.DATA_SET);
+ } else {
+ values.put(RawContacts.DATA_SET, dataSet);
+ }
+ return;
+ }
+ }
+ throw new IllegalArgumentException(
+ "Not a valid combination of account name, type, and data set.");
+ }
+
+ public void setAccount(AccountWithDataSet accountWithDataSet) {
+ setAccount(accountWithDataSet.name, accountWithDataSet.type, accountWithDataSet.dataSet);
+ }
+
+ public void setAccountToLocal() {
+ setAccount(null, null, null);
+ }
+
+ public void addDataItemValues(ContentValues values) {
+ addNamedDataItemValues(Data.CONTENT_URI, values);
+ }
+
+ public void addNamedDataItemValues(Uri uri, ContentValues values) {
+ mDataItems.add(new NamedDataItem(uri, DataItem.createFrom(this, values)));
+ }
+
+ public List<DataItem> getDataItems() {
+ final ArrayList<DataItem> list = new ArrayList<DataItem>();
+ for (NamedDataItem dataItem : mDataItems) {
+ if (Data.CONTENT_URI.equals(dataItem.uri)) {
+ list.add(dataItem.dataItem);
+ }
+ }
+ return list;
+ }
+
+ public List<NamedDataItem> getNamedDataItems() {
+ return mDataItems;
+ }
+
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("RawContact: ").append(mValues);
+ for (RawContact.NamedDataItem namedDataItem : mDataItems) {
+ sb.append("\n ").append(namedDataItem.uri);
+ sb.append("\n -> ").append(namedDataItem.dataItem.getContentValues());
+ }
+ return sb.toString();
+ }
+}
diff --git a/src/com/android/contacts/model/EntityDelta.java b/src/com/android/contacts/model/RawContactDelta.java
similarity index 83%
rename from src/com/android/contacts/model/EntityDelta.java
rename to src/com/android/contacts/model/RawContactDelta.java
index 0f45a4b..2ee9d5c 100644
--- a/src/com/android/contacts/model/EntityDelta.java
+++ b/src/com/android/contacts/model/RawContactDelta.java
@@ -16,48 +16,50 @@
package com.android.contacts.model;
-import com.android.contacts.test.NeededForTesting;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Maps;
-import com.google.android.collect.Sets;
-
import android.content.ContentProviderOperation;
import android.content.ContentProviderOperation.Builder;
import android.content.ContentValues;
import android.content.Context;
-import android.content.Entity;
-import android.content.Entity.NamedContentValues;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.BaseColumns;
+import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Profile;
import android.provider.ContactsContract.RawContacts;
import android.util.Log;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.dataitem.DataItem;
+import com.android.contacts.test.NeededForTesting;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Set;
-
/**
- * Contains an {@link Entity} and records any modifications separately so the
- * original {@link Entity} can be swapped out with a newer version and the
+ * Contains a {@link RawContact} and records any modifications separately so the
+ * original {@link RawContact} can be swapped out with a newer version and the
* changes still cleanly applied.
* <p>
* One benefit of this approach is that we can build changes entirely on an
- * empty {@link Entity}, which then becomes an insert {@link RawContacts} case.
+ * empty {@link RawContact}, which then becomes an insert {@link RawContacts} case.
* <p>
- * When applying modifications over an {@link Entity}, we try finding the
+ * When applying modifications over an {@link RawContact}, we try finding the
* original {@link Data#_ID} rows where the modifications took place. If those
- * rows are missing from the new {@link Entity}, we know the original data must
+ * rows are missing from the new {@link RawContact}, we know the original data must
* be deleted, but to preserve the user modifications we treat as an insert.
*/
-public class EntityDelta implements Parcelable {
+public class RawContactDelta implements Parcelable {
// TODO: optimize by using contentvalues pool, since we allocate so many of them
private static final String TAG = "EntityDelta";
@@ -80,40 +82,40 @@
*/
private final HashMap<String, ArrayList<ValuesDelta>> mEntries = Maps.newHashMap();
- public EntityDelta() {
+ public RawContactDelta() {
}
- public EntityDelta(ValuesDelta values) {
+ public RawContactDelta(ValuesDelta values) {
mValues = values;
}
/**
- * Build an {@link EntityDelta} using the given {@link Entity} as a
+ * Build an {@link RawContactDelta} using the given {@link RawContact} as a
* starting point; the "before" snapshot.
*/
- public static EntityDelta fromBefore(Entity before) {
- final EntityDelta entity = new EntityDelta();
- entity.mValues = ValuesDelta.fromBefore(before.getEntityValues());
- entity.mValues.setIdColumn(RawContacts._ID);
- for (NamedContentValues namedValues : before.getSubValues()) {
- entity.addEntry(ValuesDelta.fromBefore(namedValues.values));
+ public static RawContactDelta fromBefore(RawContact before) {
+ final RawContactDelta rawContactDelta = new RawContactDelta();
+ rawContactDelta.mValues = ValuesDelta.fromBefore(before.getValues());
+ rawContactDelta.mValues.setIdColumn(RawContacts._ID);
+ for (DataItem dataItem : before.getDataItems()) {
+ rawContactDelta.addEntry(ValuesDelta.fromBefore(dataItem.getContentValues()));
}
- return entity;
+ return rawContactDelta;
}
/**
- * Merge the "after" values from the given {@link EntityDelta} onto the
- * "before" state represented by this {@link EntityDelta}, discarding any
+ * Merge the "after" values from the given {@link RawContactDelta} onto the
+ * "before" state represented by this {@link RawContactDelta}, discarding any
* existing "after" states. This is typically used when re-parenting changes
* onto an updated {@link Entity}.
*/
- public static EntityDelta mergeAfter(EntityDelta local, EntityDelta remote) {
+ public static RawContactDelta mergeAfter(RawContactDelta local, RawContactDelta remote) {
// Bail early if trying to merge delete with missing local
final ValuesDelta remoteValues = remote.mValues;
if (local == null && (remoteValues.isDelete() || remoteValues.isTransient())) return null;
// Create local version if none exists yet
- if (local == null) local = new EntityDelta();
+ if (local == null) local = new RawContactDelta();
if (LOGV) {
final Long localVersion = (local.mValues == null) ? null : local.mValues
@@ -224,6 +226,26 @@
return getValues().getAsLong(RawContacts._ID);
}
+ public String getAccountName() {
+ return getValues().getAsString(RawContacts.ACCOUNT_NAME);
+ }
+
+ public String getAccountType() {
+ return getValues().getAsString(RawContacts.ACCOUNT_TYPE);
+ }
+
+ public String getDataSet() {
+ return getValues().getAsString(RawContacts.DATA_SET);
+ }
+
+ public AccountType getAccountType(AccountTypeManager manager) {
+ return manager.getAccountType(getAccountType(), getDataSet());
+ }
+
+ public boolean isVisible() {
+ return getValues().isVisible();
+ }
+
/**
* Return the list of child {@link ValuesDelta} from our optimized map,
* creating the list if requested.
@@ -309,8 +331,8 @@
@Override
public boolean equals(Object object) {
- if (object instanceof EntityDelta) {
- final EntityDelta other = (EntityDelta)object;
+ if (object instanceof RawContactDelta) {
+ final RawContactDelta other = (RawContactDelta)object;
// Equality failed if parent values different
if (!other.mValues.equals(mValues)) return false;
@@ -404,7 +426,7 @@
/**
* Build a list of {@link ContentProviderOperation} that will transform the
* current "before" {@link Entity} state into the modified state which this
- * {@link EntityDelta} represents.
+ * {@link RawContactDelta} represents.
*/
public void buildDiff(ArrayList<ContentProviderOperation> buildInto) {
final int firstIndex = buildInto.size();
@@ -525,15 +547,16 @@
mContactsQueryUri = Profile.CONTENT_RAW_CONTACTS_URI;
}
- public static final Parcelable.Creator<EntityDelta> CREATOR = new Parcelable.Creator<EntityDelta>() {
- public EntityDelta createFromParcel(Parcel in) {
- final EntityDelta state = new EntityDelta();
+ public static final Parcelable.Creator<RawContactDelta> CREATOR =
+ new Parcelable.Creator<RawContactDelta>() {
+ public RawContactDelta createFromParcel(Parcel in) {
+ final RawContactDelta state = new RawContactDelta();
state.readFromParcel(in);
return state;
}
- public EntityDelta[] newArray(int size) {
- return new EntityDelta[size];
+ public RawContactDelta[] newArray(int size) {
+ return new RawContactDelta[size];
}
};
@@ -963,5 +986,118 @@
return new ValuesDelta[size];
}
};
+
+ public void setGroupRowId(long groupId) {
+ put(GroupMembership.GROUP_ROW_ID, groupId);
+ }
+
+ public Long getGroupRowId() {
+ return getAsLong(GroupMembership.GROUP_ROW_ID);
+ }
+
+ public void setPhoto(byte[] value) {
+ put(Photo.PHOTO, value);
+ }
+
+ public byte[] getPhoto() {
+ return getAsByteArray(Photo.PHOTO);
+ }
+
+ public void setSuperPrimary(boolean val) {
+ if (val) {
+ put(Data.IS_SUPER_PRIMARY, 1);
+ } else {
+ put(Data.IS_SUPER_PRIMARY, 0);
+ }
+ }
+
+ public void setPhoneticFamilyName(String value) {
+ put(StructuredName.PHONETIC_FAMILY_NAME, value);
+ }
+
+ public void setPhoneticMiddleName(String value) {
+ put(StructuredName.PHONETIC_MIDDLE_NAME, value);
+ }
+
+ public void setPhoneticGivenName(String value) {
+ put(StructuredName.PHONETIC_GIVEN_NAME, value);
+ }
+
+ public String getPhoneticFamilyName() {
+ return getAsString(StructuredName.PHONETIC_FAMILY_NAME);
+ }
+
+ public String getPhoneticMiddleName() {
+ return getAsString(StructuredName.PHONETIC_MIDDLE_NAME);
+ }
+
+ public String getPhoneticGivenName() {
+ return getAsString(StructuredName.PHONETIC_GIVEN_NAME);
+ }
+
+ public String getDisplayName() {
+ return getAsString(StructuredName.DISPLAY_NAME);
+ }
+
+ public void setDisplayName(String name) {
+ if (name == null) {
+ putNull(StructuredName.DISPLAY_NAME);
+ } else {
+ put(StructuredName.DISPLAY_NAME, name);
+ }
+ }
+
+ public void copyStructuredNameFieldsFrom(ValuesDelta name) {
+ copyStringFrom(name, StructuredName.DISPLAY_NAME);
+
+ copyStringFrom(name, StructuredName.GIVEN_NAME);
+ copyStringFrom(name, StructuredName.FAMILY_NAME);
+ copyStringFrom(name, StructuredName.PREFIX);
+ copyStringFrom(name, StructuredName.MIDDLE_NAME);
+ copyStringFrom(name, StructuredName.SUFFIX);
+
+ copyStringFrom(name, StructuredName.PHONETIC_GIVEN_NAME);
+ copyStringFrom(name, StructuredName.PHONETIC_MIDDLE_NAME);
+ copyStringFrom(name, StructuredName.PHONETIC_FAMILY_NAME);
+
+ copyStringFrom(name, StructuredName.FULL_NAME_STYLE);
+ copyStringFrom(name, StructuredName.PHONETIC_NAME_STYLE);
+ }
+
+ public String getPhoneNumber() {
+ return getAsString(Phone.NUMBER);
+ }
+
+ public String getPhoneNormalizedNumber() {
+ return getAsString(Phone.NORMALIZED_NUMBER);
+ }
+
+ public boolean phoneHasType() {
+ return containsKey(Phone.TYPE);
+ }
+
+ public int getPhoneType() {
+ return getAsInteger(Phone.TYPE);
+ }
+
+ public String getPhoneLabel() {
+ return getAsString(Phone.LABEL);
+ }
+
+ public String getEmailData() {
+ return getAsString(Email.DATA);
+ }
+
+ public boolean emailHasType() {
+ return containsKey(Email.TYPE);
+ }
+
+ public int getEmailType() {
+ return getAsInteger(Email.TYPE);
+ }
+
+ public String getEmailLabel() {
+ return getAsString(Email.LABEL);
+ }
}
}
diff --git a/src/com/android/contacts/model/EntityDeltaList.java b/src/com/android/contacts/model/RawContactDeltaList.java
similarity index 78%
rename from src/com/android/contacts/model/EntityDeltaList.java
rename to src/com/android/contacts/model/RawContactDeltaList.java
index 47fd9c6..82dd494 100644
--- a/src/com/android/contacts/model/EntityDeltaList.java
+++ b/src/com/android/contacts/model/RawContactDeltaList.java
@@ -16,9 +16,6 @@
package com.android.contacts.model;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.google.android.collect.Lists;
-
import android.content.ContentProviderOperation;
import android.content.ContentProviderOperation.Builder;
import android.content.ContentResolver;
@@ -33,45 +30,47 @@
import android.provider.ContactsContract.RawContacts;
import android.util.Log;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.google.common.collect.Lists;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
/**
- * Container for multiple {@link EntityDelta} objects, usually when editing
+ * Container for multiple {@link RawContactDelta} objects, usually when editing
* together as an entire aggregate. Provides convenience methods for parceling
- * and applying another {@link EntityDeltaList} over it.
+ * and applying another {@link RawContactDeltaList} over it.
*/
-public class EntityDeltaList extends ArrayList<EntityDelta> implements Parcelable {
- private static final String TAG = "EntityDeltaList";
+public class RawContactDeltaList extends ArrayList<RawContactDelta> implements Parcelable {
+ private static final String TAG = RawContactDeltaList.class.getSimpleName();
private static final boolean VERBOSE_LOGGING = Log.isLoggable(TAG, Log.VERBOSE);
private boolean mSplitRawContacts;
private long[] mJoinWithRawContactIds;
- private EntityDeltaList() {
+ private RawContactDeltaList() {
}
/**
- * Create an {@link EntityDeltaList} that contains the given {@link EntityDelta},
+ * Create an {@link RawContactDeltaList} that contains the given {@link RawContactDelta},
* usually when inserting a new {@link Contacts} entry.
*/
- public static EntityDeltaList fromSingle(EntityDelta delta) {
- final EntityDeltaList state = new EntityDeltaList();
+ public static RawContactDeltaList fromSingle(RawContactDelta delta) {
+ final RawContactDeltaList state = new RawContactDeltaList();
state.add(delta);
return state;
}
/**
- * Create an {@link EntityDeltaList} based on {@link Contacts} specified by the
+ * Create an {@link RawContactDeltaList} based on {@link Contacts} specified by the
* given query parameters. This closes the {@link EntityIterator} when
* finished, so it doesn't subscribe to updates.
*/
- public static EntityDeltaList fromQuery(Uri entityUri, ContentResolver resolver,
+ public static RawContactDeltaList fromQuery(Uri entityUri, ContentResolver resolver,
String selection, String[] selectionArgs, String sortOrder) {
- final EntityIterator iterator = RawContacts.newEntityIterator(resolver.query(
- entityUri, null, selection, selectionArgs,
- sortOrder));
+ final EntityIterator iterator = RawContacts.newEntityIterator(
+ resolver.query(entityUri, null, selection, selectionArgs, sortOrder));
try {
return fromIterator(iterator);
} finally {
@@ -80,36 +79,41 @@
}
/**
- * Create an {@link EntityDeltaList} that contains the entities of the Iterator as before
- * values.
+ * Create an {@link RawContactDeltaList} that contains the entities of the Iterator as before
+ * values. This function can be passed an iterator of Entity objects or an iterator of
+ * RawContact objects.
*/
- public static EntityDeltaList fromIterator(Iterator<Entity> iterator) {
- final EntityDeltaList state = new EntityDeltaList();
+ public static RawContactDeltaList fromIterator(Iterator<?> iterator) {
+ final RawContactDeltaList state = new RawContactDeltaList();
// Perform background query to pull contact details
while (iterator.hasNext()) {
// Read all contacts into local deltas to prepare for edits
- final Entity before = iterator.next();
- final EntityDelta entity = EntityDelta.fromBefore(before);
- state.add(entity);
+ Object nextObject = iterator.next();
+ final RawContact before = nextObject instanceof Entity
+ ? RawContact.createFrom((Entity) nextObject)
+ : (RawContact) nextObject;
+ final RawContactDelta rawContactDelta = RawContactDelta.fromBefore(before);
+ state.add(rawContactDelta);
}
return state;
}
/**
- * Merge the "after" values from the given {@link EntityDeltaList}, discarding any
+ * Merge the "after" values from the given {@link RawContactDeltaList}, discarding any
* previous "after" states. This is typically used when re-parenting user
- * edits onto an updated {@link EntityDeltaList}.
+ * edits onto an updated {@link RawContactDeltaList}.
*/
- public static EntityDeltaList mergeAfter(EntityDeltaList local, EntityDeltaList remote) {
- if (local == null) local = new EntityDeltaList();
+ public static RawContactDeltaList mergeAfter(RawContactDeltaList local,
+ RawContactDeltaList remote) {
+ if (local == null) local = new RawContactDeltaList();
// For each entity in the remote set, try matching over existing
- for (EntityDelta remoteEntity : remote) {
+ for (RawContactDelta remoteEntity : remote) {
final Long rawContactId = remoteEntity.getValues().getId();
// Find or create local match and merge
- final EntityDelta localEntity = local.getByRawContactId(rawContactId);
- final EntityDelta merged = EntityDelta.mergeAfter(localEntity, remoteEntity);
+ final RawContactDelta localEntity = local.getByRawContactId(rawContactId);
+ final RawContactDelta merged = RawContactDelta.mergeAfter(localEntity, remoteEntity);
if (localEntity == null && merged != null) {
// No local entry before, so insert
@@ -123,7 +127,7 @@
/**
* Build a list of {@link ContentProviderOperation} that will transform all
* the "before" {@link Entity} states into the modified state which all
- * {@link EntityDelta} objects represent. This method specifically creates
+ * {@link RawContactDelta} objects represent. This method specifically creates
* any {@link AggregationExceptions} rules needed to groups edits together.
*/
public ArrayList<ContentProviderOperation> buildDiff() {
@@ -136,7 +140,7 @@
int firstInsertRow = -1;
// First pass enforces versions remain consistent
- for (EntityDelta delta : this) {
+ for (RawContactDelta delta : this) {
delta.buildAssert(diff);
}
@@ -146,7 +150,7 @@
int rawContactIndex = 0;
// Second pass builds actual operations
- for (EntityDelta delta : this) {
+ for (RawContactDelta delta : this) {
final int firstBatch = diff.size();
final boolean isInsert = delta.isContactInsert();
backRefs[rawContactIndex++] = isInsert ? firstBatch : -1;
@@ -281,12 +285,12 @@
}
/**
- * Search all contained {@link EntityDelta} for the first one with an
+ * Search all contained {@link RawContactDelta} for the first one with an
* existing {@link RawContacts#_ID} value. Usually used when creating
* {@link AggregationExceptions} during an update.
*/
public long findRawContactId() {
- for (EntityDelta delta : this) {
+ for (RawContactDelta delta : this) {
final Long rawContactId = delta.getValues().getAsLong(RawContacts._ID);
if (rawContactId != null && rawContactId >= 0) {
return rawContactId;
@@ -296,11 +300,11 @@
}
/**
- * Find {@link RawContacts#_ID} of the requested {@link EntityDelta}.
+ * Find {@link RawContacts#_ID} of the requested {@link RawContactDelta}.
*/
public Long getRawContactId(int index) {
if (index >= 0 && index < this.size()) {
- final EntityDelta delta = this.get(index);
+ final RawContactDelta delta = this.get(index);
final ValuesDelta values = delta.getValues();
if (values.isVisible()) {
return values.getAsLong(RawContacts._ID);
@@ -310,9 +314,9 @@
}
/**
- * Find the raw-contact (an {@link EntityDelta}) with the specified ID.
+ * Find the raw-contact (an {@link RawContactDelta}) with the specified ID.
*/
- public EntityDelta getByRawContactId(Long rawContactId) {
+ public RawContactDelta getByRawContactId(Long rawContactId) {
final int index = this.indexOfRawContactId(rawContactId);
return (index == -1) ? null : this.get(index);
}
@@ -332,19 +336,21 @@
return -1;
}
- /** Return the index of the first EntityDelta corresponding to a writable raw-contact, or -1. */
+ /**
+ * Return the index of the first RawContactDelta corresponding to a writable raw-contact, or -1.
+ * */
public int indexOfFirstWritableRawContact(Context context) {
// Find the first writable entity.
int entityIndex = 0;
- for (EntityDelta delta : this) {
+ for (RawContactDelta delta : this) {
if (delta.getRawContactAccountType(context).areContactsWritable()) return entityIndex;
entityIndex++;
}
return -1;
}
- /** Return the first EntityDelta corresponding to a writable raw-contact, or null. */
- public EntityDelta getFirstWritableRawContact(Context context) {
+ /** Return the first RawContactDelta corresponding to a writable raw-contact, or null. */
+ public RawContactDelta getFirstWritableRawContact(Context context) {
final int index = indexOfFirstWritableRawContact(context);
return (index == -1) ? null : get(index);
}
@@ -352,7 +358,7 @@
public ValuesDelta getSuperPrimaryEntry(final String mimeType) {
ValuesDelta primary = null;
ValuesDelta randomEntry = null;
- for (EntityDelta delta : this) {
+ for (RawContactDelta delta : this) {
final ArrayList<ValuesDelta> mimeEntries = delta.getMimeEntries(mimeType);
if (mimeEntries == null) return null;
@@ -404,7 +410,7 @@
public void writeToParcel(Parcel dest, int flags) {
final int size = this.size();
dest.writeInt(size);
- for (EntityDelta delta : this) {
+ for (RawContactDelta delta : this) {
dest.writeParcelable(delta, flags);
}
dest.writeLongArray(mJoinWithRawContactIds);
@@ -416,24 +422,24 @@
final ClassLoader loader = getClass().getClassLoader();
final int size = source.readInt();
for (int i = 0; i < size; i++) {
- this.add(source.<EntityDelta> readParcelable(loader));
+ this.add(source.<RawContactDelta> readParcelable(loader));
}
mJoinWithRawContactIds = source.createLongArray();
mSplitRawContacts = source.readInt() != 0;
}
- public static final Parcelable.Creator<EntityDeltaList> CREATOR =
- new Parcelable.Creator<EntityDeltaList>() {
+ public static final Parcelable.Creator<RawContactDeltaList> CREATOR =
+ new Parcelable.Creator<RawContactDeltaList>() {
@Override
- public EntityDeltaList createFromParcel(Parcel in) {
- final EntityDeltaList state = new EntityDeltaList();
+ public RawContactDeltaList createFromParcel(Parcel in) {
+ final RawContactDeltaList state = new RawContactDeltaList();
state.readFromParcel(in);
return state;
}
@Override
- public EntityDeltaList[] newArray(int size) {
- return new EntityDeltaList[size];
+ public RawContactDeltaList[] newArray(int size) {
+ return new RawContactDeltaList[size];
}
};
diff --git a/src/com/android/contacts/model/EntityModifier.java b/src/com/android/contacts/model/RawContactModifier.java
similarity index 90%
rename from src/com/android/contacts/model/EntityModifier.java
rename to src/com/android/contacts/model/RawContactModifier.java
index 2d87ff0..0c12c94 100644
--- a/src/com/android/contacts/model/EntityModifier.java
+++ b/src/com/android/contacts/model/RawContactModifier.java
@@ -16,16 +16,6 @@
package com.android.contacts.model;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.editor.EventFieldEditorView;
-import com.android.contacts.util.NameConverter;
-import com.android.contacts.editor.PhoneticNameEditorView;
-import com.android.contacts.model.AccountType.EditField;
-import com.android.contacts.model.AccountType.EditType;
-import com.android.contacts.model.AccountType.EventEditType;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.util.DateUtils;
-
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
@@ -56,6 +46,20 @@
import android.util.SparseArray;
import android.util.SparseIntArray;
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.editor.EventFieldEditorView;
+import com.android.contacts.editor.PhoneticNameEditorView;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountType.EditField;
+import com.android.contacts.model.account.AccountType.EditType;
+import com.android.contacts.model.account.AccountType.EventEditType;
+import com.android.contacts.model.account.GoogleAccountType;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.contacts.model.dataitem.StructuredNameDataItem;
+import com.android.contacts.util.DateUtils;
+import com.android.contacts.util.NameConverter;
+
import java.text.ParsePosition;
import java.util.ArrayList;
import java.util.Arrays;
@@ -68,21 +72,21 @@
import java.util.Set;
/**
- * Helper methods for modifying an {@link EntityDelta}, such as inserting
+ * Helper methods for modifying an {@link RawContactDelta}, such as inserting
* new rows, or enforcing {@link AccountType}.
*/
-public class EntityModifier {
- private static final String TAG = "EntityModifier";
+public class RawContactModifier {
+ private static final String TAG = RawContactModifier.class.getSimpleName();
/** Set to true in order to view logs on entity operations */
private static final boolean DEBUG = false;
/**
- * For the given {@link EntityDelta}, determine if the given
+ * For the given {@link RawContactDelta}, determine if the given
* {@link DataKind} could be inserted under specific
* {@link AccountType}.
*/
- public static boolean canInsert(EntityDelta state, DataKind kind) {
+ public static boolean canInsert(RawContactDelta state, DataKind kind) {
// Insert possible when have valid types and under overall maximum
final int visibleCount = state.getMimeEntriesCount(kind.mimeType, true);
final boolean validTypes = hasValidTypes(state, kind);
@@ -91,8 +95,8 @@
return (validTypes && validOverall);
}
- public static boolean hasValidTypes(EntityDelta state, DataKind kind) {
- if (EntityModifier.hasEditTypes(kind)) {
+ public static boolean hasValidTypes(RawContactDelta state, DataKind kind) {
+ if (RawContactModifier.hasEditTypes(kind)) {
return (getValidTypes(state, kind).size() > 0);
} else {
return true;
@@ -101,12 +105,12 @@
/**
* Ensure that at least one of the given {@link DataKind} exists in the
- * given {@link EntityDelta} state, and try creating one if none exist.
+ * given {@link RawContactDelta} state, and try creating one if none exist.
* @return The child (either newly created or the first existing one), or null if the
* account doesn't support this {@link DataKind}.
*/
public static ValuesDelta ensureKindExists(
- EntityDelta state, AccountType accountType, String mimeType) {
+ RawContactDelta state, AccountType accountType, String mimeType) {
final DataKind kind = accountType.getKindForMimetype(mimeType);
final boolean hasChild = state.getMimeEntriesCount(mimeType, true) > 0;
@@ -127,16 +131,16 @@
}
/**
- * For the given {@link EntityDelta} and {@link DataKind}, return the
+ * For the given {@link RawContactDelta} and {@link DataKind}, return the
* list possible {@link EditType} options available based on
* {@link AccountType}.
*/
- public static ArrayList<EditType> getValidTypes(EntityDelta state, DataKind kind) {
+ public static ArrayList<EditType> getValidTypes(RawContactDelta state, DataKind kind) {
return getValidTypes(state, kind, null, true, null);
}
/**
- * For the given {@link EntityDelta} and {@link DataKind}, return the
+ * For the given {@link RawContactDelta} and {@link DataKind}, return the
* list possible {@link EditType} options available based on
* {@link AccountType}.
*
@@ -144,13 +148,13 @@
* list, even when an otherwise-invalid choice. This is useful
* when showing a dialog that includes the current type.
*/
- public static ArrayList<EditType> getValidTypes(EntityDelta state, DataKind kind,
+ public static ArrayList<EditType> getValidTypes(RawContactDelta state, DataKind kind,
EditType forceInclude) {
return getValidTypes(state, kind, forceInclude, true, null);
}
/**
- * For the given {@link EntityDelta} and {@link DataKind}, return the
+ * For the given {@link RawContactDelta} and {@link DataKind}, return the
* list possible {@link EditType} options available based on
* {@link AccountType}.
*
@@ -161,9 +165,9 @@
* {@link EditType#secondary}.
* @param typeCount When provided, will be used for the frequency count of
* each {@link EditType}, otherwise built using
- * {@link #getTypeFrequencies(EntityDelta, DataKind)}.
+ * {@link #getTypeFrequencies(RawContactDelta, DataKind)}.
*/
- private static ArrayList<EditType> getValidTypes(EntityDelta state, DataKind kind,
+ private static ArrayList<EditType> getValidTypes(RawContactDelta state, DataKind kind,
EditType forceInclude, boolean includeSecondary, SparseIntArray typeCount) {
final ArrayList<EditType> validTypes = new ArrayList<EditType>();
@@ -197,11 +201,11 @@
/**
* Count up the frequency that each {@link EditType} appears in the given
- * {@link EntityDelta}. The returned {@link SparseIntArray} maps from
+ * {@link RawContactDelta}. The returned {@link SparseIntArray} maps from
* {@link EditType#rawValue} to counts, with the total overall count stored
* as {@link #FREQUENCY_TOTAL}.
*/
- private static SparseIntArray getTypeFrequencies(EntityDelta state, DataKind kind) {
+ private static SparseIntArray getTypeFrequencies(RawContactDelta state, DataKind kind) {
final SparseIntArray typeCount = new SparseIntArray();
// Find all entries for this kind, bailing early if none found
@@ -297,7 +301,7 @@
* first primary type that doesn't already exist. When all valid types
* exist, we pick the last valid option.
*/
- public static EditType getBestValidType(EntityDelta state, DataKind kind,
+ public static EditType getBestValidType(RawContactDelta state, DataKind kind,
boolean includeSecondary, int exactValue) {
// Shortcut when no types
if (kind.typeColumn == null) return null;
@@ -338,10 +342,10 @@
/**
* Insert a new child of kind {@link DataKind} into the given
- * {@link EntityDelta}. Tries using the best {@link EditType} found using
- * {@link #getBestValidType(EntityDelta, DataKind, boolean, int)}.
+ * {@link RawContactDelta}. Tries using the best {@link EditType} found using
+ * {@link #getBestValidType(RawContactDelta, DataKind, boolean, int)}.
*/
- public static ValuesDelta insertChild(EntityDelta state, DataKind kind) {
+ public static ValuesDelta insertChild(RawContactDelta state, DataKind kind) {
// First try finding a valid primary
EditType bestType = getBestValidType(state, kind, false, Integer.MIN_VALUE);
if (bestType == null) {
@@ -353,9 +357,9 @@
/**
* Insert a new child of kind {@link DataKind} into the given
- * {@link EntityDelta}, marked with the given {@link EditType}.
+ * {@link RawContactDelta}, marked with the given {@link EditType}.
*/
- public static ValuesDelta insertChild(EntityDelta state, DataKind kind, EditType type) {
+ public static ValuesDelta insertChild(RawContactDelta state, DataKind kind, EditType type) {
// Bail early if invalid kind
if (kind == null) return null;
final ContentValues after = new ContentValues();
@@ -379,13 +383,13 @@
}
/**
- * Processing to trim any empty {@link ValuesDelta} and {@link EntityDelta}
- * from the given {@link EntityDeltaList}, assuming the given {@link AccountTypeManager}
+ * Processing to trim any empty {@link ValuesDelta} and {@link RawContactDelta}
+ * from the given {@link RawContactDeltaList}, assuming the given {@link AccountTypeManager}
* dictates the structure for various fields. This method ignores rows not
* described by the {@link AccountType}.
*/
- public static void trimEmpty(EntityDeltaList set, AccountTypeManager accountTypes) {
- for (EntityDelta state : set) {
+ public static void trimEmpty(RawContactDeltaList set, AccountTypeManager accountTypes) {
+ for (RawContactDelta state : set) {
ValuesDelta values = state.getValues();
final String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
final String dataSet = values.getAsString(RawContacts.DATA_SET);
@@ -394,12 +398,12 @@
}
}
- public static boolean hasChanges(EntityDeltaList set, AccountTypeManager accountTypes) {
+ public static boolean hasChanges(RawContactDeltaList set, AccountTypeManager accountTypes) {
if (set.isMarkedForSplitting() || set.isMarkedForJoining()) {
return true;
}
- for (EntityDelta state : set) {
+ for (RawContactDelta state : set) {
ValuesDelta values = state.getValues();
final String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
final String dataSet = values.getAsString(RawContacts.DATA_SET);
@@ -413,11 +417,11 @@
/**
* Processing to trim any empty {@link ValuesDelta} rows from the given
- * {@link EntityDelta}, assuming the given {@link AccountType} dictates
+ * {@link RawContactDelta}, assuming the given {@link AccountType} dictates
* the structure for various fields. This method ignores rows not described
* by the {@link AccountType}.
*/
- public static void trimEmpty(EntityDelta state, AccountType accountType) {
+ public static void trimEmpty(RawContactDelta state, AccountType accountType) {
boolean hasValues = false;
// Walk through entries for each well-known kind
@@ -440,7 +444,7 @@
final boolean isPhoto = TextUtils.equals(Photo.CONTENT_ITEM_TYPE, kind.mimeType);
final boolean isGooglePhoto = isPhoto && isGoogleAccount;
- if (EntityModifier.isEmpty(entry, kind) && !isGooglePhoto) {
+ if (RawContactModifier.isEmpty(entry, kind) && !isGooglePhoto) {
if (DEBUG) {
Log.v(TAG, "Trimming: " + entry.toString());
}
@@ -456,7 +460,7 @@
}
}
- private static boolean hasChanges(EntityDelta state, AccountType accountType) {
+ private static boolean hasChanges(RawContactDelta state, AccountType accountType) {
for (DataKind kind : accountType.getSortedDataKinds()) {
final String mimeType = kind.mimeType;
final ArrayList<ValuesDelta> entries = state.getMimeEntries(mimeType);
@@ -516,10 +520,10 @@
}
/**
- * Parse the given {@link Bundle} into the given {@link EntityDelta} state,
+ * Parse the given {@link Bundle} into the given {@link RawContactDelta} state,
* assuming the extras defined through {@link Intents}.
*/
- public static void parseExtras(Context context, AccountType accountType, EntityDelta state,
+ public static void parseExtras(Context context, AccountType accountType, RawContactDelta state,
Bundle extras) {
if (extras == null || extras.size() == 0) {
// Bail early if no useful data
@@ -560,8 +564,8 @@
final boolean hasOrg = extras.containsKey(Insert.COMPANY)
|| extras.containsKey(Insert.JOB_TITLE);
final DataKind kindOrg = accountType.getKindForMimetype(Organization.CONTENT_ITEM_TYPE);
- if (hasOrg && EntityModifier.canInsert(state, kindOrg)) {
- final ValuesDelta child = EntityModifier.insertChild(state, kindOrg);
+ if (hasOrg && RawContactModifier.canInsert(state, kindOrg)) {
+ final ValuesDelta child = RawContactModifier.insertChild(state, kindOrg);
final String company = extras.getString(Insert.COMPANY);
if (ContactsUtils.isGraphic(company)) {
@@ -577,8 +581,8 @@
// Notes
final boolean hasNotes = extras.containsKey(Insert.NOTES);
final DataKind kindNotes = accountType.getKindForMimetype(Note.CONTENT_ITEM_TYPE);
- if (hasNotes && EntityModifier.canInsert(state, kindNotes)) {
- final ValuesDelta child = EntityModifier.insertChild(state, kindNotes);
+ if (hasNotes && RawContactModifier.canInsert(state, kindNotes)) {
+ final ValuesDelta child = RawContactModifier.insertChild(state, kindNotes);
final String notes = extras.getString(Insert.NOTES);
if (ContactsUtils.isGraphic(notes)) {
@@ -594,9 +598,9 @@
}
private static void parseStructuredNameExtra(
- Context context, AccountType accountType, EntityDelta state, Bundle extras) {
+ Context context, AccountType accountType, RawContactDelta state, Bundle extras) {
// StructuredName
- EntityModifier.ensureKindExists(state, accountType, StructuredName.CONTENT_ITEM_TYPE);
+ RawContactModifier.ensureKindExists(state, accountType, StructuredName.CONTENT_ITEM_TYPE);
final ValuesDelta child = state.getPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE);
final String name = extras.getString(Insert.NAME);
@@ -649,7 +653,7 @@
}
private static void parseStructuredPostalExtra(
- AccountType accountType, EntityDelta state, Bundle extras) {
+ AccountType accountType, RawContactDelta state, Bundle extras) {
// StructuredPostal
final DataKind kind = accountType.getKindForMimetype(StructuredPostal.CONTENT_ITEM_TYPE);
final ValuesDelta child = parseExtras(state, kind, extras, Insert.POSTAL_TYPE,
@@ -675,7 +679,8 @@
}
private static void parseValues(
- EntityDelta state, AccountType accountType, ArrayList<ContentValues> dataValueList) {
+ RawContactDelta state, AccountType accountType,
+ ArrayList<ContentValues> dataValueList) {
for (ContentValues values : dataValueList) {
String mimeType = values.getAsString(Data.MIMETYPE);
if (TextUtils.isEmpty(mimeType)) {
@@ -835,15 +840,19 @@
/**
* Counts occurrences of the specified type in the supplied entry list.
+ *
+ * @return The count of occurrences of the type in the entry list. 0 if entries is
+ * {@literal null}
*/
- private static int getEntryCountByType(
- ArrayList<ValuesDelta> entries, String typeColumn, int type) {
+ private static int getEntryCountByType(ArrayList<ValuesDelta> entries, String typeColumn,
+ int type) {
int count = 0;
- int size = entries.size();
- for (int i = 0; i < size; i++) {
- Integer typeInteger = entries.get(i).getAsInteger(typeColumn);
- if (typeInteger != null && typeInteger == type) {
- count++;
+ if (entries != null) {
+ for (ValuesDelta entry : entries) {
+ Integer typeInteger = entry.getAsInteger(typeColumn);
+ if (typeInteger != null && typeInteger == type) {
+ count++;
+ }
}
}
return count;
@@ -873,7 +882,7 @@
/**
* Parse a specific entry from the given {@link Bundle} and insert into the
- * given {@link EntityDelta}. Silently skips the insert when missing value
+ * given {@link RawContactDelta}. Silently skips the insert when missing value
* or no valid {@link EditType} found.
*
* @param typeExtra {@link Bundle} key that holds the incoming
@@ -881,7 +890,7 @@
* @param valueExtra {@link Bundle} key that holds the incoming value.
* @param valueColumn Column to write value into {@link ValuesDelta}.
*/
- public static ValuesDelta parseExtras(EntityDelta state, DataKind kind, Bundle extras,
+ public static ValuesDelta parseExtras(RawContactDelta state, DataKind kind, Bundle extras,
String typeExtra, String valueExtra, String valueColumn) {
final CharSequence value = extras.getCharSequence(valueExtra);
@@ -889,7 +898,7 @@
if (kind == null) return null;
// Bail when can't insert type, or value missing
- final boolean canInsert = EntityModifier.canInsert(state, kind);
+ final boolean canInsert = RawContactModifier.canInsert(state, kind);
final boolean validValue = (value != null && TextUtils.isGraphic(value));
if (!validValue || !canInsert) return null;
@@ -897,10 +906,10 @@
final boolean hasType = extras.containsKey(typeExtra);
final int typeValue = extras.getInt(typeExtra, hasType ? BaseTypes.TYPE_CUSTOM
: Integer.MIN_VALUE);
- final EditType editType = EntityModifier.getBestValidType(state, kind, true, typeValue);
+ final EditType editType = RawContactModifier.getBestValidType(state, kind, true, typeValue);
// Create data row and fill with value
- final ValuesDelta child = EntityModifier.insertChild(state, kind, editType);
+ final ValuesDelta child = RawContactModifier.insertChild(state, kind, editType);
child.put(valueColumn, value.toString());
if (editType != null && editType.customColumn != null) {
@@ -937,13 +946,13 @@
private static final int TYPE_CUSTOM = Phone.TYPE_CUSTOM;
/**
- * Migrates old EntityDelta to newly created one with a new restriction supplied from
+ * Migrates old RawContactDelta to newly created one with a new restriction supplied from
* newAccountType.
*
* This is only for account switch during account creation (which must be insert operation).
*/
public static void migrateStateForNewContact(Context context,
- EntityDelta oldState, EntityDelta newState,
+ RawContactDelta oldState, RawContactDelta newState,
AccountType oldAccountType, AccountType newAccountType) {
if (newAccountType == oldAccountType) {
// Just copying all data in oldState isn't enough, but we can still rely on a lot of
@@ -996,8 +1005,8 @@
* Checks {@link DataKind#isList} and {@link DataKind#typeOverallMax}, and restricts
* the number of entries (ValuesDelta) inside newState.
*/
- private static ArrayList<ValuesDelta> ensureEntryMaxSize(EntityDelta newState, DataKind kind,
- ArrayList<ValuesDelta> mimeEntries) {
+ private static ArrayList<ValuesDelta> ensureEntryMaxSize(RawContactDelta newState,
+ DataKind kind, ArrayList<ValuesDelta> mimeEntries) {
if (mimeEntries == null) {
return null;
}
@@ -1015,7 +1024,8 @@
/** @hide Public only for testing. */
public static void migrateStructuredName(
- Context context, EntityDelta oldState, EntityDelta newState, DataKind newDataKind) {
+ Context context, RawContactDelta oldState, RawContactDelta newState,
+ DataKind newDataKind) {
final ContentValues values =
oldState.getPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE).getAfter();
if (values == null) {
@@ -1071,24 +1081,24 @@
if (!TextUtils.isEmpty(phoneticFullName)) {
if (!supportPhoneticFullName) {
// Old data has a phonetic (full) name, while the new account doesn't allow it.
- final ContentValues tmpValues =
+ final StructuredNameDataItem tmpItem =
PhoneticNameEditorView.parsePhoneticName(phoneticFullName, null);
values.remove(DataKind.PSEUDO_COLUMN_PHONETIC_NAME);
if (supportPhoneticFamilyName) {
values.put(StructuredName.PHONETIC_FAMILY_NAME,
- tmpValues.getAsString(StructuredName.PHONETIC_FAMILY_NAME));
+ tmpItem.getPhoneticFamilyName());
} else {
values.remove(StructuredName.PHONETIC_FAMILY_NAME);
}
if (supportPhoneticMiddleName) {
values.put(StructuredName.PHONETIC_MIDDLE_NAME,
- tmpValues.getAsString(StructuredName.PHONETIC_MIDDLE_NAME));
+ tmpItem.getPhoneticMiddleName());
} else {
values.remove(StructuredName.PHONETIC_MIDDLE_NAME);
}
if (supportPhoneticGivenName) {
values.put(StructuredName.PHONETIC_GIVEN_NAME,
- tmpValues.getAsString(StructuredName.PHONETIC_GIVEN_NAME));
+ tmpItem.getPhoneticGivenName());
} else {
values.remove(StructuredName.PHONETIC_GIVEN_NAME);
}
@@ -1117,7 +1127,7 @@
}
/** @hide Public only for testing. */
- public static void migratePostal(EntityDelta oldState, EntityDelta newState,
+ public static void migratePostal(RawContactDelta oldState, RawContactDelta newState,
DataKind newDataKind) {
final ArrayList<ValuesDelta> mimeEntries = ensureEntryMaxSize(newState, newDataKind,
oldState.getMimeEntries(StructuredPostal.CONTENT_ITEM_TYPE));
@@ -1228,7 +1238,7 @@
}
/** @hide Public only for testing. */
- public static void migrateEvent(EntityDelta oldState, EntityDelta newState,
+ public static void migrateEvent(RawContactDelta oldState, RawContactDelta newState,
DataKind newDataKind, Integer defaultYear) {
final ArrayList<ValuesDelta> mimeEntries = ensureEntryMaxSize(newState, newDataKind,
oldState.getMimeEntries(Event.CONTENT_ITEM_TYPE));
@@ -1285,7 +1295,7 @@
/** @hide Public only for testing. */
public static void migrateGenericWithoutTypeColumn(
- EntityDelta oldState, EntityDelta newState, DataKind newDataKind) {
+ RawContactDelta oldState, RawContactDelta newState, DataKind newDataKind) {
final ArrayList<ValuesDelta> mimeEntries = ensureEntryMaxSize(newState, newDataKind,
oldState.getMimeEntries(newDataKind.mimeType));
if (mimeEntries == null || mimeEntries.isEmpty()) {
@@ -1302,7 +1312,7 @@
/** @hide Public only for testing. */
public static void migrateGenericWithTypeColumn(
- EntityDelta oldState, EntityDelta newState, DataKind newDataKind) {
+ RawContactDelta oldState, RawContactDelta newState, DataKind newDataKind) {
final ArrayList<ValuesDelta> mimeEntries = oldState.getMimeEntries(newDataKind.mimeType);
if (mimeEntries == null || mimeEntries.isEmpty()) {
return;
diff --git a/src/com/android/contacts/model/AccountType.java b/src/com/android/contacts/model/account/AccountType.java
similarity index 98%
rename from src/com/android/contacts/model/AccountType.java
rename to src/com/android/contacts/model/account/AccountType.java
index 7e48d83..edd17a0 100644
--- a/src/com/android/contacts/model/AccountType.java
+++ b/src/com/android/contacts/model/account/AccountType.java
@@ -14,12 +14,7 @@
* limitations under the License.
*/
-package com.android.contacts.model;
-
-import com.android.contacts.R;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Maps;
-import com.google.common.annotations.VisibleForTesting;
+package com.android.contacts.model.account;
import android.content.ContentValues;
import android.content.Context;
@@ -32,6 +27,13 @@
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
+import com.android.contacts.R;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.dataitem.DataKind;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
diff --git a/src/com/android/contacts/model/AccountTypeWithDataSet.java b/src/com/android/contacts/model/account/AccountTypeWithDataSet.java
similarity index 98%
rename from src/com/android/contacts/model/AccountTypeWithDataSet.java
rename to src/com/android/contacts/model/account/AccountTypeWithDataSet.java
index b103755..ab0a891 100644
--- a/src/com/android/contacts/model/AccountTypeWithDataSet.java
+++ b/src/com/android/contacts/model/account/AccountTypeWithDataSet.java
@@ -14,9 +14,7 @@
* limitations under the License.
*/
-package com.android.contacts.model;
-
-import com.google.common.base.Objects;
+package com.android.contacts.model.account;
import android.content.Context;
import android.database.Cursor;
@@ -26,6 +24,8 @@
import android.provider.ContactsContract.RawContacts;
import android.text.TextUtils;
+import com.google.common.base.Objects;
+
/**
* Encapsulates an "account type" string and a "data set" string.
diff --git a/src/com/android/contacts/model/AccountWithDataSet.java b/src/com/android/contacts/model/account/AccountWithDataSet.java
similarity index 98%
rename from src/com/android/contacts/model/AccountWithDataSet.java
rename to src/com/android/contacts/model/account/AccountWithDataSet.java
index 784e870..03fcc02 100644
--- a/src/com/android/contacts/model/AccountWithDataSet.java
+++ b/src/com/android/contacts/model/account/AccountWithDataSet.java
@@ -14,22 +14,21 @@
* limitations under the License.
*/
-package com.android.contacts.model;
-
-import com.android.internal.util.Objects;
-import com.google.common.collect.Lists;
+package com.android.contacts.model.account;
import android.accounts.Account;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Parcel;
-import android.os.Parcelable.Creator;
import android.provider.BaseColumns;
import android.provider.ContactsContract;
import android.provider.ContactsContract.RawContacts;
import android.text.TextUtils;
+import com.android.internal.util.Objects;
+import com.google.common.collect.Lists;
+
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
diff --git a/src/com/android/contacts/model/BaseAccountType.java b/src/com/android/contacts/model/account/BaseAccountType.java
similarity index 99%
rename from src/com/android/contacts/model/BaseAccountType.java
rename to src/com/android/contacts/model/account/BaseAccountType.java
index 1e830e2..7f9e1ef 100644
--- a/src/com/android/contacts/model/BaseAccountType.java
+++ b/src/com/android/contacts/model/account/BaseAccountType.java
@@ -14,13 +14,7 @@
* limitations under the License.
*/
-package com.android.contacts.model;
-
-import com.android.contacts.R;
-import com.android.contacts.test.NeededForTesting;
-import com.android.contacts.util.DateUtils;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Maps;
+package com.android.contacts.model.account;
import android.content.ContentValues;
import android.content.Context;
@@ -44,6 +38,13 @@
import android.util.Log;
import android.view.inputmethod.EditorInfo;
+import com.android.contacts.R;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.contacts.test.NeededForTesting;
+import com.android.contacts.util.DateUtils;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
diff --git a/src/com/android/contacts/model/ExchangeAccountType.java b/src/com/android/contacts/model/account/ExchangeAccountType.java
similarity index 98%
rename from src/com/android/contacts/model/ExchangeAccountType.java
rename to src/com/android/contacts/model/account/ExchangeAccountType.java
index 1e3f6ee..5ca3308 100644
--- a/src/com/android/contacts/model/ExchangeAccountType.java
+++ b/src/com/android/contacts/model/account/ExchangeAccountType.java
@@ -14,12 +14,7 @@
* limitations under the License.
*/
-package com.android.contacts.model;
-
-import com.android.contacts.R;
-import com.android.contacts.model.AccountType.DefinitionException;
-import com.android.contacts.util.DateUtils;
-import com.google.android.collect.Lists;
+package com.android.contacts.model.account;
import android.content.ContentValues;
import android.content.Context;
@@ -36,6 +31,11 @@
import android.provider.ContactsContract.CommonDataKinds.Website;
import android.util.Log;
+import com.android.contacts.R;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.contacts.util.DateUtils;
+import com.google.common.collect.Lists;
+
import java.util.Locale;
public class ExchangeAccountType extends BaseAccountType {
diff --git a/src/com/android/contacts/model/ExternalAccountType.java b/src/com/android/contacts/model/account/ExternalAccountType.java
similarity index 99%
rename from src/com/android/contacts/model/ExternalAccountType.java
rename to src/com/android/contacts/model/account/ExternalAccountType.java
index d7420af..71dbebf 100644
--- a/src/com/android/contacts/model/ExternalAccountType.java
+++ b/src/com/android/contacts/model/account/ExternalAccountType.java
@@ -14,12 +14,7 @@
* limitations under the License.
*/
-package com.android.contacts.model;
-
-import com.google.common.annotations.VisibleForTesting;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
+package com.android.contacts.model.account;
import android.content.Context;
import android.content.pm.PackageInfo;
@@ -36,6 +31,12 @@
import android.util.Log;
import android.util.Xml;
+import com.android.contacts.model.dataitem.DataKind;
+import com.google.common.annotations.VisibleForTesting;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
diff --git a/src/com/android/contacts/model/FallbackAccountType.java b/src/com/android/contacts/model/account/FallbackAccountType.java
similarity index 96%
rename from src/com/android/contacts/model/FallbackAccountType.java
rename to src/com/android/contacts/model/account/FallbackAccountType.java
index 892c049..dae288d 100644
--- a/src/com/android/contacts/model/FallbackAccountType.java
+++ b/src/com/android/contacts/model/account/FallbackAccountType.java
@@ -14,14 +14,15 @@
* limitations under the License.
*/
-package com.android.contacts.model;
-
-import com.android.contacts.R;
-import com.android.contacts.test.NeededForTesting;
+package com.android.contacts.model.account;
import android.content.Context;
import android.util.Log;
+import com.android.contacts.R;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.contacts.test.NeededForTesting;
+
public class FallbackAccountType extends BaseAccountType {
private static final String TAG = "FallbackAccountType";
diff --git a/src/com/android/contacts/model/GoogleAccountType.java b/src/com/android/contacts/model/account/GoogleAccountType.java
similarity index 97%
rename from src/com/android/contacts/model/GoogleAccountType.java
rename to src/com/android/contacts/model/account/GoogleAccountType.java
index a8a4069..192c3d0 100644
--- a/src/com/android/contacts/model/GoogleAccountType.java
+++ b/src/com/android/contacts/model/account/GoogleAccountType.java
@@ -14,12 +14,7 @@
* limitations under the License.
*/
-package com.android.contacts.model;
-
-import com.android.contacts.R;
-import com.android.contacts.model.AccountType.DefinitionException;
-import com.android.contacts.util.DateUtils;
-import com.google.android.collect.Lists;
+package com.android.contacts.model.account;
import android.content.ContentValues;
import android.content.Context;
@@ -29,6 +24,11 @@
import android.provider.ContactsContract.CommonDataKinds.Relation;
import android.util.Log;
+import com.android.contacts.R;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.contacts.util.DateUtils;
+import com.google.common.collect.Lists;
+
import java.util.List;
public class GoogleAccountType extends BaseAccountType {
diff --git a/src/com/android/contacts/model/dataitem/DataItem.java b/src/com/android/contacts/model/dataitem/DataItem.java
new file mode 100644
index 0000000..25c44cb
--- /dev/null
+++ b/src/com/android/contacts/model/dataitem/DataItem.java
@@ -0,0 +1,214 @@
+/*
+ * 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.contacts.model.dataitem;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Event;
+import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
+import android.provider.ContactsContract.CommonDataKinds.Identity;
+import android.provider.ContactsContract.CommonDataKinds.Im;
+import android.provider.ContactsContract.CommonDataKinds.Nickname;
+import android.provider.ContactsContract.CommonDataKinds.Note;
+import android.provider.ContactsContract.CommonDataKinds.Organization;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.provider.ContactsContract.CommonDataKinds.Relation;
+import android.provider.ContactsContract.CommonDataKinds.SipAddress;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
+import android.provider.ContactsContract.CommonDataKinds.Website;
+import android.provider.ContactsContract.Contacts.Data;
+
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.RawContact;
+import com.android.contacts.model.account.AccountType;
+
+/**
+ * This is the base class for data items, which represents a row from the Data table.
+ */
+public class DataItem {
+
+ private final ContentValues mContentValues;
+
+ /**
+ * The raw contact that this data item is associated with. This can be null.
+ */
+ private final RawContact mRawContact;
+ private DataKind mDataKind;
+
+ protected DataItem(RawContact rawContact, ContentValues values) {
+ mContentValues = values;
+ mRawContact = rawContact;
+ }
+
+ /**
+ * Factory for creating subclasses of DataItem objects based on the mimetype in the
+ * content values. Raw contact is the raw contact that this data item is associated with.
+ */
+ public static DataItem createFrom(RawContact rawContact, ContentValues values) {
+ final String mimeType = values.getAsString(Data.MIMETYPE);
+ if (GroupMembership.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ return new GroupMembershipDataItem(rawContact, values);
+ } else if (StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ return new StructuredNameDataItem(rawContact, values);
+ } else if (Phone.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ return new PhoneDataItem(rawContact, values);
+ } else if (Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ return new EmailDataItem(rawContact, values);
+ } else if (StructuredPostal.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ return new StructuredPostalDataItem(rawContact, values);
+ } else if (Im.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ return new ImDataItem(rawContact, values);
+ } else if (Organization.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ return new OrganizationDataItem(rawContact, values);
+ } else if (Nickname.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ return new NicknameDataItem(rawContact, values);
+ } else if (Note.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ return new NoteDataItem(rawContact, values);
+ } else if (Website.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ return new WebsiteDataItem(rawContact, values);
+ } else if (SipAddress.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ return new SipAddressDataItem(rawContact, values);
+ } else if (Event.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ return new EventDataItem(rawContact, values);
+ } else if (Relation.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ return new RelationDataItem(rawContact, values);
+ } else if (Identity.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ return new IdentityDataItem(rawContact, values);
+ } else if (Photo.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ return new PhotoDataItem(rawContact, values);
+ }
+
+ // generic
+ return new DataItem(rawContact, values);
+ }
+
+ public ContentValues getContentValues() {
+ return mContentValues;
+ }
+
+ protected RawContact getRawContact() {
+ return mRawContact;
+ }
+
+ public void setRawContactId(long rawContactId) {
+ mContentValues.put(Data.RAW_CONTACT_ID, rawContactId);
+ }
+
+ /**
+ * Returns the data id.
+ */
+ public long getId() {
+ return mContentValues.getAsLong(Data._ID);
+ }
+
+ public long getRawContactId() {
+ return mContentValues.getAsLong(Data.RAW_CONTACT_ID);
+ }
+ /**
+ * Returns the mimetype of the data.
+ */
+ public String getMimeType() {
+ return mContentValues.getAsString(Data.MIMETYPE);
+ }
+
+ public void setMimeType(String mimeType) {
+ mContentValues.put(Data.MIMETYPE, mimeType);
+ }
+
+ public boolean isPrimary() {
+ Integer primary = mContentValues.getAsInteger(Data.IS_PRIMARY);
+ return primary != null && primary != 0;
+ }
+
+ public boolean isSuperPrimary() {
+ Integer superPrimary = mContentValues.getAsInteger(Data.IS_SUPER_PRIMARY);
+ return superPrimary != null && superPrimary != 0;
+ }
+
+ public int getDataVersion() {
+ return mContentValues.getAsInteger(Data.DATA_VERSION);
+ }
+
+ public AccountTypeManager getAccountTypeManager() {
+ if (mRawContact == null) {
+ return null;
+ } else {
+ return mRawContact.getAccountTypeManager();
+ }
+ }
+
+ public AccountType getAccountType() {
+ if (mRawContact == null) {
+ return null;
+ } else {
+ return mRawContact.getAccountType();
+ }
+ }
+
+ /**
+ * This method can only be invoked if the raw contact is non-null.
+ */
+ public DataKind getDataKind() {
+ if (mRawContact == null) {
+ throw new IllegalStateException("mRawContact must be non-null to call getDataKind()");
+ }
+
+ if (mDataKind == null) {
+ mDataKind = getAccountTypeManager().getKindOrFallback(
+ mRawContact.getAccountTypeString(), mRawContact.getDataSet(), getMimeType());
+ }
+
+ return mDataKind;
+ }
+
+ public boolean hasKindTypeColumn() {
+ final String key = getDataKind().typeColumn;
+ return key != null && mContentValues.containsKey(key);
+ }
+
+ public int getKindTypeColumn() {
+ final String key = getDataKind().typeColumn;
+ return mContentValues.getAsInteger(key);
+ }
+
+ /**
+ * This builds the data string depending on the type of data item by using the generic
+ * DataKind object underneath. This DataItem object must be associated with a raw contact
+ * for this function to work.
+ */
+ public String buildDataString() {
+ if (mRawContact == null) {
+ throw new IllegalStateException("mRawContact must be non-null to call getDataKind()");
+ }
+ final DataKind kind = getDataKind();
+
+ if (kind.actionBody == null) {
+ return null;
+ }
+ CharSequence actionBody = kind.actionBody.inflateUsing(mRawContact.getContext(),
+ mContentValues);
+ return actionBody == null ? null : actionBody.toString();
+ }
+
+ public String getKindString() {
+ final DataKind kind = getDataKind();
+ return (kind.titleRes == -1 || kind.titleRes == 0) ? ""
+ : mRawContact.getContext().getString(kind.titleRes);
+ }
+}
diff --git a/src/com/android/contacts/model/DataKind.java b/src/com/android/contacts/model/dataitem/DataKind.java
similarity index 95%
rename from src/com/android/contacts/model/DataKind.java
rename to src/com/android/contacts/model/dataitem/DataKind.java
index 0d60317..8707012 100644
--- a/src/com/android/contacts/model/DataKind.java
+++ b/src/com/android/contacts/model/dataitem/DataKind.java
@@ -14,17 +14,17 @@
* limitations under the License.
*/
-package com.android.contacts.model;
-
-import com.android.contacts.R;
-import com.android.contacts.model.AccountType.EditField;
-import com.android.contacts.model.AccountType.EditType;
-import com.android.contacts.model.AccountType.StringInflater;
-import com.google.common.collect.Iterators;
+package com.android.contacts.model.dataitem;
import android.content.ContentValues;
import android.provider.ContactsContract.Data;
+import com.android.contacts.R;
+import com.android.contacts.model.account.AccountType.EditField;
+import com.android.contacts.model.account.AccountType.EditType;
+import com.android.contacts.model.account.AccountType.StringInflater;
+import com.google.common.collect.Iterators;
+
import java.text.SimpleDateFormat;
import java.util.List;
@@ -144,4 +144,4 @@
return Iterators.toString(list.iterator());
}
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/contacts/model/dataitem/EmailDataItem.java b/src/com/android/contacts/model/dataitem/EmailDataItem.java
new file mode 100644
index 0000000..a535c73
--- /dev/null
+++ b/src/com/android/contacts/model/dataitem/EmailDataItem.java
@@ -0,0 +1,57 @@
+/*
+ * 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.contacts.model.dataitem;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+
+import com.android.contacts.model.RawContact;
+
+/**
+ * Represents an email data item, wrapping the columns in
+ * {@link ContactsContract.CommonDataKinds.Email}.
+ */
+public class EmailDataItem extends DataItem {
+
+ /* package */ EmailDataItem(RawContact rawContact, ContentValues values) {
+ super(rawContact, values);
+ }
+
+ public String getAddress() {
+ return getContentValues().getAsString(Email.ADDRESS);
+ }
+
+ public String getDisplayName() {
+ return getContentValues().getAsString(Email.DISPLAY_NAME);
+ }
+
+ public String getData() {
+ return getContentValues().getAsString(Email.DATA);
+ }
+
+ /**
+ * Values is one of Email.TYPE_*
+ */
+ public int getType() {
+ return getContentValues().getAsInteger(Email.TYPE);
+ }
+
+ public String getLabel() {
+ return getContentValues().getAsString(Email.LABEL);
+ }
+}
diff --git a/src/com/android/contacts/model/dataitem/EventDataItem.java b/src/com/android/contacts/model/dataitem/EventDataItem.java
new file mode 100644
index 0000000..2114279
--- /dev/null
+++ b/src/com/android/contacts/model/dataitem/EventDataItem.java
@@ -0,0 +1,49 @@
+/*
+ * 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.contacts.model.dataitem;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Event;
+
+import com.android.contacts.model.RawContact;
+
+/**
+ * Represents an event data item, wrapping the columns in
+ * {@link ContactsContract.CommonDataKinds.Event}.
+ */
+public class EventDataItem extends DataItem {
+
+ /* package */ EventDataItem(RawContact rawContact, ContentValues values) {
+ super(rawContact, values);
+ }
+
+ public String getStartDate() {
+ return getContentValues().getAsString(Event.START_DATE);
+ }
+
+ /**
+ * Values are one of Event.TYPE_*
+ */
+ public int getType() {
+ return getContentValues().getAsInteger(Event.TYPE);
+ }
+
+ public String getLabel() {
+ return getContentValues().getAsString(Event.LABEL);
+ }
+}
diff --git a/src/com/android/contacts/model/dataitem/GroupMembershipDataItem.java b/src/com/android/contacts/model/dataitem/GroupMembershipDataItem.java
new file mode 100644
index 0000000..aea9bca
--- /dev/null
+++ b/src/com/android/contacts/model/dataitem/GroupMembershipDataItem.java
@@ -0,0 +1,42 @@
+/*
+ * 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.contacts.model.dataitem;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
+
+import com.android.contacts.model.RawContact;
+
+/**
+ * Represents a group memebership data item, wrapping the columns in
+ * {@link ContactsContract.CommonDataKinds.GroupMembership}.
+ */
+public class GroupMembershipDataItem extends DataItem {
+
+ /* package */ GroupMembershipDataItem(RawContact rawContact, ContentValues values) {
+ super(rawContact, values);
+ }
+
+ public long getGroupRowId() {
+ return getContentValues().getAsLong(GroupMembership.GROUP_ROW_ID);
+ }
+
+ public String getGroupSourceId() {
+ return getContentValues().getAsString(GroupMembership.GROUP_SOURCE_ID);
+ }
+}
diff --git a/src/com/android/contacts/model/dataitem/IdentityDataItem.java b/src/com/android/contacts/model/dataitem/IdentityDataItem.java
new file mode 100644
index 0000000..fd4b836
--- /dev/null
+++ b/src/com/android/contacts/model/dataitem/IdentityDataItem.java
@@ -0,0 +1,42 @@
+/*
+ * 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.contacts.model.dataitem;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Identity;
+
+import com.android.contacts.model.RawContact;
+
+/**
+ * Represents an identity data item, wrapping the columns in
+ * {@link ContactsContract.CommonDataKinds.Identity}.
+ */
+public class IdentityDataItem extends DataItem {
+
+ /* package */ IdentityDataItem(RawContact rawContact, ContentValues values) {
+ super(rawContact, values);
+ }
+
+ public String getIdentity() {
+ return getContentValues().getAsString(Identity.IDENTITY);
+ }
+
+ public String getNamespace() {
+ return getContentValues().getAsString(Identity.NAMESPACE);
+ }
+}
diff --git a/src/com/android/contacts/model/dataitem/ImDataItem.java b/src/com/android/contacts/model/dataitem/ImDataItem.java
new file mode 100644
index 0000000..3a08325
--- /dev/null
+++ b/src/com/android/contacts/model/dataitem/ImDataItem.java
@@ -0,0 +1,94 @@
+/*
+ * 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.contacts.model.dataitem;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Im;
+
+import com.android.contacts.model.RawContact;
+
+/**
+ * Represents an IM data item, wrapping the columns in
+ * {@link ContactsContract.CommonDataKinds.Im}.
+ */
+public class ImDataItem extends DataItem {
+
+ private final boolean mCreatedFromEmail;
+
+ /* package */ ImDataItem(RawContact rawContact, ContentValues values) {
+ super(rawContact, values);
+ mCreatedFromEmail = false;
+ }
+
+ private ImDataItem(RawContact rawContact, ContentValues values,
+ boolean createdFromEmail) {
+ super(rawContact, values);
+ mCreatedFromEmail = createdFromEmail;
+ }
+
+ public static ImDataItem createFromEmail(EmailDataItem item) {
+ ImDataItem im = new ImDataItem(item.getRawContact(),
+ new ContentValues(item.getContentValues()), true);
+ im.setMimeType(Im.CONTENT_ITEM_TYPE);
+ return im;
+ }
+
+ public String getData() {
+ if (mCreatedFromEmail) {
+ return getContentValues().getAsString(Email.DATA);
+ } else {
+ return getContentValues().getAsString(Im.DATA);
+ }
+ }
+
+ /**
+ * Values are one of Im.TYPE_*
+ */
+ public int getType() {
+ return getContentValues().getAsInteger(Im.TYPE);
+ }
+
+ public String getLabel() {
+ return getContentValues().getAsString(Im.LABEL);
+ }
+
+ /**
+ * Values are one of Im.PROTOCOL_
+ */
+ public Integer getProtocol() {
+ return getContentValues().getAsInteger(Im.PROTOCOL);
+ }
+
+ public boolean isProtocolValid() {
+ return getProtocol() != null;
+ }
+
+ public String getCustomProtocol() {
+ return getContentValues().getAsString(Im.CUSTOM_PROTOCOL);
+ }
+
+ public int getChatCapability() {
+ Integer result = getContentValues().getAsInteger(Im.CHAT_CAPABILITY);
+ return result == null ? 0 : result;
+ }
+
+ public boolean isCreatedFromEmail() {
+ return mCreatedFromEmail;
+ }
+}
diff --git a/src/com/android/contacts/model/dataitem/NicknameDataItem.java b/src/com/android/contacts/model/dataitem/NicknameDataItem.java
new file mode 100644
index 0000000..7b52510
--- /dev/null
+++ b/src/com/android/contacts/model/dataitem/NicknameDataItem.java
@@ -0,0 +1,49 @@
+/*
+ * 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.contacts.model.dataitem;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Nickname;
+
+import com.android.contacts.model.RawContact;
+
+/**
+ * Represents a nickname data item, wrapping the columns in
+ * {@link ContactsContract.CommonDataKinds.Nickname}.
+ */
+public class NicknameDataItem extends DataItem {
+
+ public NicknameDataItem(RawContact rawContact, ContentValues values) {
+ super(rawContact, values);
+ }
+
+ public String getName() {
+ return getContentValues().getAsString(Nickname.NAME);
+ }
+
+ /**
+ * Types are defined as Nickname.TYPE_*
+ */
+ public int getType() {
+ return getContentValues().getAsInteger(Nickname.TYPE);
+ }
+
+ public String getLabel() {
+ return getContentValues().getAsString(Nickname.LABEL);
+ }
+}
diff --git a/src/com/android/contacts/model/dataitem/NoteDataItem.java b/src/com/android/contacts/model/dataitem/NoteDataItem.java
new file mode 100644
index 0000000..0d0fa24
--- /dev/null
+++ b/src/com/android/contacts/model/dataitem/NoteDataItem.java
@@ -0,0 +1,38 @@
+/*
+ * 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.contacts.model.dataitem;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Note;
+
+import com.android.contacts.model.RawContact;
+
+/**
+ * Represents a note data item, wrapping the columns in
+ * {@link ContactsContract.CommonDataKinds.Note}.
+ */
+public class NoteDataItem extends DataItem {
+
+ /* package */ NoteDataItem(RawContact rawContact, ContentValues values) {
+ super(rawContact, values);
+ }
+
+ public String getNote() {
+ return getContentValues().getAsString(Note.NOTE);
+ }
+}
diff --git a/src/com/android/contacts/model/dataitem/OrganizationDataItem.java b/src/com/android/contacts/model/dataitem/OrganizationDataItem.java
new file mode 100644
index 0000000..1326bdb
--- /dev/null
+++ b/src/com/android/contacts/model/dataitem/OrganizationDataItem.java
@@ -0,0 +1,77 @@
+/*
+ * 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.contacts.model.dataitem;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Organization;
+
+import com.android.contacts.model.RawContact;
+
+/**
+ * Represents an organization data item, wrapping the columns in
+ * {@link ContactsContract.CommonDataKinds.Organization}.
+ */
+public class OrganizationDataItem extends DataItem {
+
+ /* package */ OrganizationDataItem(RawContact rawContact, ContentValues values) {
+ super(rawContact, values);
+ }
+
+ public String getCompany() {
+ return getContentValues().getAsString(Organization.COMPANY);
+ }
+
+ /**
+ * Values are one of Organization.TYPE_*
+ */
+ public int getType() {
+ return getContentValues().getAsInteger(Organization.TYPE);
+ }
+
+ public String getLabel() {
+ return getContentValues().getAsString(Organization.LABEL);
+ }
+
+ public String getTitle() {
+ return getContentValues().getAsString(Organization.TITLE);
+ }
+
+ public String getDepartment() {
+ return getContentValues().getAsString(Organization.DEPARTMENT);
+ }
+
+ public String getJobDescription() {
+ return getContentValues().getAsString(Organization.JOB_DESCRIPTION);
+ }
+
+ public String getSymbol() {
+ return getContentValues().getAsString(Organization.SYMBOL);
+ }
+
+ public String getPhoneticName() {
+ return getContentValues().getAsString(Organization.PHONETIC_NAME);
+ }
+
+ public String getOfficeLocation() {
+ return getContentValues().getAsString(Organization.OFFICE_LOCATION);
+ }
+
+ public String getPhoneticNameStyle() {
+ return getContentValues().getAsString(Organization.PHONETIC_NAME_STYLE);
+ }
+}
diff --git a/src/com/android/contacts/model/dataitem/PhoneDataItem.java b/src/com/android/contacts/model/dataitem/PhoneDataItem.java
new file mode 100644
index 0000000..94a0054
--- /dev/null
+++ b/src/com/android/contacts/model/dataitem/PhoneDataItem.java
@@ -0,0 +1,57 @@
+/*
+ * 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.contacts.model.dataitem;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+
+import com.android.contacts.model.RawContact;
+
+/**
+ * Represents a phone data item, wrapping the columns in
+ * {@link ContactsContract.CommonDataKinds.Phone}.
+ */
+public class PhoneDataItem extends DataItem {
+
+ /* package */ PhoneDataItem(RawContact rawContact, ContentValues values) {
+ super(rawContact, values);
+ }
+
+ public String getNumber() {
+ return getContentValues().getAsString(Phone.NUMBER);
+ }
+
+ /**
+ * Returns the normalized phone number in E164 format.
+ */
+ public String getNormalizedNumber() {
+ return getContentValues().getAsString(Phone.NORMALIZED_NUMBER);
+ }
+
+ /**
+ * Values are Phone.TYPE_*
+ */
+ public int getType() {
+ return getContentValues().getAsInteger(Phone.TYPE);
+ }
+
+ public String getLabel() {
+ return getContentValues().getAsString(Phone.LABEL);
+ }
+
+}
diff --git a/src/com/android/contacts/model/dataitem/PhotoDataItem.java b/src/com/android/contacts/model/dataitem/PhotoDataItem.java
new file mode 100644
index 0000000..5e355fa
--- /dev/null
+++ b/src/com/android/contacts/model/dataitem/PhotoDataItem.java
@@ -0,0 +1,42 @@
+/*
+ * 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.contacts.model.dataitem;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.Contacts.Photo;
+
+import com.android.contacts.model.RawContact;
+
+/**
+ * Represents a photo data item, wrapping the columns in
+ * {@link ContactsContract.Contacts.Photo}.
+ */
+public class PhotoDataItem extends DataItem {
+
+ /* package */ PhotoDataItem(RawContact rawContact, ContentValues values) {
+ super(rawContact, values);
+ }
+
+ public long getPhotoFileId() {
+ return getContentValues().getAsLong(Photo.PHOTO_FILE_ID);
+ }
+
+ public byte[] getPhoto() {
+ return getContentValues().getAsByteArray(Photo.PHOTO);
+ }
+}
diff --git a/src/com/android/contacts/model/dataitem/RelationDataItem.java b/src/com/android/contacts/model/dataitem/RelationDataItem.java
new file mode 100644
index 0000000..7c22cf5
--- /dev/null
+++ b/src/com/android/contacts/model/dataitem/RelationDataItem.java
@@ -0,0 +1,49 @@
+/*
+ * 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.contacts.model.dataitem;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Relation;
+
+import com.android.contacts.model.RawContact;
+
+/**
+ * Represents a relation data item, wrapping the columns in
+ * {@link ContactsContract.CommonDataKinds.Relation}.
+ */
+public class RelationDataItem extends DataItem {
+
+ /* package */ RelationDataItem(RawContact rawContact, ContentValues values) {
+ super(rawContact, values);
+ }
+
+ public String getName() {
+ return getContentValues().getAsString(Relation.NAME);
+ }
+
+ /**
+ * Values are one of Relation.TYPE_*
+ */
+ public int getType() {
+ return getContentValues().getAsInteger(Relation.TYPE);
+ }
+
+ public String getLabel() {
+ return getContentValues().getAsString(Relation.LABEL);
+ }
+}
diff --git a/src/com/android/contacts/model/dataitem/SipAddressDataItem.java b/src/com/android/contacts/model/dataitem/SipAddressDataItem.java
new file mode 100644
index 0000000..6b8e93d
--- /dev/null
+++ b/src/com/android/contacts/model/dataitem/SipAddressDataItem.java
@@ -0,0 +1,49 @@
+/*
+ * 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.contacts.model.dataitem;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.SipAddress;
+
+import com.android.contacts.model.RawContact;
+
+/**
+ * Represents a sip address data item, wrapping the columns in
+ * {@link ContactsContract.CommonDataKinds.SipAddress}.
+ */
+public class SipAddressDataItem extends DataItem {
+
+ /* package */ SipAddressDataItem(RawContact rawContact, ContentValues values) {
+ super(rawContact, values);
+ }
+
+ public String getSipAddress() {
+ return getContentValues().getAsString(SipAddress.SIP_ADDRESS);
+ }
+
+ /**
+ * Value is one of SipAddress.TYPE_*
+ */
+ public int getType() {
+ return getContentValues().getAsInteger(SipAddress.TYPE);
+ }
+
+ public String getLabel() {
+ return getContentValues().getAsString(SipAddress.LABEL);
+ }
+}
diff --git a/src/com/android/contacts/model/dataitem/StructuredNameDataItem.java b/src/com/android/contacts/model/dataitem/StructuredNameDataItem.java
new file mode 100644
index 0000000..4654a6f
--- /dev/null
+++ b/src/com/android/contacts/model/dataitem/StructuredNameDataItem.java
@@ -0,0 +1,100 @@
+/*
+ * 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.contacts.model.dataitem;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.Contacts.Data;
+
+import com.android.contacts.model.RawContact;
+
+/**
+ * Represents a structured name data item, wrapping the columns in
+ * {@link ContactsContract.CommonDataKinds.StructuredName}.
+ */
+public class StructuredNameDataItem extends DataItem {
+
+ public StructuredNameDataItem() {
+ super(null, new ContentValues());
+ getContentValues().put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
+ }
+
+ /* package */ StructuredNameDataItem(RawContact rawContact, ContentValues values) {
+ super(rawContact, values);
+ }
+
+ public String getDisplayName() {
+ return getContentValues().getAsString(StructuredName.DISPLAY_NAME);
+ }
+
+ public void setDisplayName(String name) {
+ getContentValues().put(StructuredName.DISPLAY_NAME, name);
+ }
+
+ public String getGivenName() {
+ return getContentValues().getAsString(StructuredName.GIVEN_NAME);
+ }
+
+ public String getFamilyName() {
+ return getContentValues().getAsString(StructuredName.FAMILY_NAME);
+ }
+
+ public String getPrefix() {
+ return getContentValues().getAsString(StructuredName.PREFIX);
+ }
+
+ public String getMiddleName() {
+ return getContentValues().getAsString(StructuredName.MIDDLE_NAME);
+ }
+
+ public String getSuffix() {
+ return getContentValues().getAsString(StructuredName.SUFFIX);
+ }
+
+ public String getPhoneticGivenName() {
+ return getContentValues().getAsString(StructuredName.PHONETIC_GIVEN_NAME);
+ }
+
+ public String getPhoneticMiddleName() {
+ return getContentValues().getAsString(StructuredName.PHONETIC_MIDDLE_NAME);
+ }
+
+ public String getPhoneticFamilyName() {
+ return getContentValues().getAsString(StructuredName.PHONETIC_FAMILY_NAME);
+ }
+
+ public String getFullNameStyle() {
+ return getContentValues().getAsString(StructuredName.FULL_NAME_STYLE);
+ }
+
+ public String getPhoneticNameStyle() {
+ return getContentValues().getAsString(StructuredName.PHONETIC_NAME_STYLE);
+ }
+
+ public void setPhoneticFamilyName(String name) {
+ getContentValues().put(StructuredName.PHONETIC_FAMILY_NAME, name);
+ }
+
+ public void setPhoneticMiddleName(String name) {
+ getContentValues().put(StructuredName.PHONETIC_MIDDLE_NAME, name);
+ }
+
+ public void setPhoneticGivenName(String name) {
+ getContentValues().put(StructuredName.PHONETIC_GIVEN_NAME, name);
+ }
+}
diff --git a/src/com/android/contacts/model/dataitem/StructuredPostalDataItem.java b/src/com/android/contacts/model/dataitem/StructuredPostalDataItem.java
new file mode 100644
index 0000000..cc2cf56
--- /dev/null
+++ b/src/com/android/contacts/model/dataitem/StructuredPostalDataItem.java
@@ -0,0 +1,77 @@
+/*
+ * 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.contacts.model.dataitem;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
+
+import com.android.contacts.model.RawContact;
+
+/**
+ * Represents a structured postal data item, wrapping the columns in
+ * {@link ContactsContract.CommonDataKinds.StructuredPostal}.
+ */
+public class StructuredPostalDataItem extends DataItem {
+
+ /* package */ StructuredPostalDataItem(RawContact rawContact, ContentValues values) {
+ super(rawContact, values);
+ }
+
+ public String getFormattedAddress() {
+ return getContentValues().getAsString(StructuredPostal.FORMATTED_ADDRESS);
+ }
+
+ /**
+ * Values are one of StructuredPostal.TYPE_*
+ */
+ public int getType() {
+ return getContentValues().getAsInteger(StructuredPostal.TYPE);
+ }
+
+ public String getLabel() {
+ return getContentValues().getAsString(StructuredPostal.LABEL);
+ }
+
+ public String getStreet() {
+ return getContentValues().getAsString(StructuredPostal.STREET);
+ }
+
+ public String getPOBox() {
+ return getContentValues().getAsString(StructuredPostal.POBOX);
+ }
+
+ public String getNeighborhood() {
+ return getContentValues().getAsString(StructuredPostal.NEIGHBORHOOD);
+ }
+
+ public String getCity() {
+ return getContentValues().getAsString(StructuredPostal.CITY);
+ }
+
+ public String getRegion() {
+ return getContentValues().getAsString(StructuredPostal.REGION);
+ }
+
+ public String getPostcode() {
+ return getContentValues().getAsString(StructuredPostal.POSTCODE);
+ }
+
+ public String getCountry() {
+ return getContentValues().getAsString(StructuredPostal.COUNTRY);
+ }
+}
diff --git a/src/com/android/contacts/model/dataitem/WebsiteDataItem.java b/src/com/android/contacts/model/dataitem/WebsiteDataItem.java
new file mode 100644
index 0000000..c3aadf3
--- /dev/null
+++ b/src/com/android/contacts/model/dataitem/WebsiteDataItem.java
@@ -0,0 +1,49 @@
+/*
+ * 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.contacts.model.dataitem;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Website;
+
+import com.android.contacts.model.RawContact;
+
+/**
+ * Represents a website data item, wrapping the columns in
+ * {@link ContactsContract.CommonDataKinds.Website}.
+ */
+public class WebsiteDataItem extends DataItem {
+
+ /* package */ WebsiteDataItem(RawContact rawContact, ContentValues values) {
+ super(rawContact, values);
+ }
+
+ public String getUrl() {
+ return getContentValues().getAsString(Website.URL);
+ }
+
+ /**
+ * Value is one of Website.TYPE_*
+ */
+ public int getType() {
+ return getContentValues().getAsInteger(Website.TYPE);
+ }
+
+ public String getLabel() {
+ return getContentValues().getAsString(Website.LABEL);
+ }
+}
diff --git a/src/com/android/contacts/preference/ContactsPreferenceActivity.java b/src/com/android/contacts/preference/ContactsPreferenceActivity.java
index 0b1970e..79557ba 100644
--- a/src/com/android/contacts/preference/ContactsPreferenceActivity.java
+++ b/src/com/android/contacts/preference/ContactsPreferenceActivity.java
@@ -16,9 +16,6 @@
package com.android.contacts.preference;
-import com.android.contacts.R;
-import com.android.contacts.activities.PeopleActivity;
-
import android.app.ActionBar;
import android.content.Context;
import android.content.Intent;
@@ -26,6 +23,9 @@
import android.preference.PreferenceActivity;
import android.view.MenuItem;
+import com.android.contacts.R;
+import com.android.contacts.activities.PeopleActivity;
+
import java.util.List;
/**
diff --git a/src/com/android/contacts/preference/ContactsPreferences.java b/src/com/android/contacts/preference/ContactsPreferences.java
index 540158d..e88417f 100644
--- a/src/com/android/contacts/preference/ContactsPreferences.java
+++ b/src/com/android/contacts/preference/ContactsPreferences.java
@@ -16,8 +16,6 @@
package com.android.contacts.preference;
-import com.android.contacts.R;
-
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
@@ -26,6 +24,8 @@
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
+import com.android.contacts.R;
+
/**
* Manages user preferences for contacts.
*/
diff --git a/src/com/android/contacts/preference/DisplayOptionsPreferenceFragment.java b/src/com/android/contacts/preference/DisplayOptionsPreferenceFragment.java
index db4a94e..02177d2 100644
--- a/src/com/android/contacts/preference/DisplayOptionsPreferenceFragment.java
+++ b/src/com/android/contacts/preference/DisplayOptionsPreferenceFragment.java
@@ -16,11 +16,11 @@
package com.android.contacts.preference;
-import com.android.contacts.R;
-
import android.os.Bundle;
import android.preference.PreferenceFragment;
+import com.android.contacts.R;
+
/**
* This fragment shows the preferences for the first header.
*/
diff --git a/src/com/android/contacts/preference/DisplayOrderPreference.java b/src/com/android/contacts/preference/DisplayOrderPreference.java
index bedce48..8629384 100644
--- a/src/com/android/contacts/preference/DisplayOrderPreference.java
+++ b/src/com/android/contacts/preference/DisplayOrderPreference.java
@@ -16,14 +16,14 @@
package com.android.contacts.preference;
-import com.android.contacts.R;
-
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.preference.ListPreference;
import android.provider.ContactsContract;
import android.util.AttributeSet;
+import com.android.contacts.R;
+
/**
* Custom preference: view-name-as (first name first or last name first).
*/
diff --git a/src/com/android/contacts/preference/SortOrderPreference.java b/src/com/android/contacts/preference/SortOrderPreference.java
index 2ac9557..6ad4aad 100644
--- a/src/com/android/contacts/preference/SortOrderPreference.java
+++ b/src/com/android/contacts/preference/SortOrderPreference.java
@@ -16,14 +16,14 @@
package com.android.contacts.preference;
-import com.android.contacts.R;
-
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.preference.ListPreference;
import android.provider.ContactsContract;
import android.util.AttributeSet;
+import com.android.contacts.R;
+
/**
* Custom preference: sort-by.
*/
diff --git a/src/com/android/contacts/quickcontact/Action.java b/src/com/android/contacts/quickcontact/Action.java
index 3a283fb..08fbce4 100644
--- a/src/com/android/contacts/quickcontact/Action.java
+++ b/src/com/android/contacts/quickcontact/Action.java
@@ -16,12 +16,12 @@
package com.android.contacts.quickcontact;
-import com.android.contacts.Collapser;
-
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import com.android.contacts.Collapser;
+
/**
* Abstract definition of an action that could be performed, along with
* string description and icon.
diff --git a/src/com/android/contacts/quickcontact/DataAction.java b/src/com/android/contacts/quickcontact/DataAction.java
index ddec799..c10c338 100644
--- a/src/com/android/contacts/quickcontact/DataAction.java
+++ b/src/com/android/contacts/quickcontact/DataAction.java
@@ -16,32 +16,33 @@
package com.android.contacts.quickcontact;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountType.EditType;
-import com.android.contacts.model.DataKind;
-import com.android.contacts.util.Constants;
-import com.android.contacts.util.PhoneCapabilityTester;
-import com.android.contacts.util.StructuredPostalUtils;
-
import android.content.ContentUris;
-import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.net.WebAddress;
-import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Im;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.SipAddress;
-import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
-import android.provider.ContactsContract.CommonDataKinds.Website;
import android.provider.ContactsContract.Data;
import android.text.TextUtils;
import android.util.Log;
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.R;
+import com.android.contacts.model.account.AccountType.EditType;
+import com.android.contacts.model.dataitem.DataItem;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.contacts.model.dataitem.EmailDataItem;
+import com.android.contacts.model.dataitem.ImDataItem;
+import com.android.contacts.model.dataitem.PhoneDataItem;
+import com.android.contacts.model.dataitem.SipAddressDataItem;
+import com.android.contacts.model.dataitem.StructuredPostalDataItem;
+import com.android.contacts.model.dataitem.WebsiteDataItem;
+import com.android.contacts.util.Constants;
+import com.android.contacts.util.PhoneCapabilityTester;
+import com.android.contacts.util.StructuredPostalUtils;
+
/**
* Description of a specific {@link Data#_ID} item, with style information
* defined by a {@link DataKind}.
@@ -68,51 +69,45 @@
/**
* Create an action from common {@link Data} elements.
*/
- public DataAction(Context context, String mimeType, DataKind kind, long dataId,
- ContentValues entryValues) {
+ public DataAction(Context context, DataItem item) {
mContext = context;
- mKind = kind;
- mMimeType = mimeType;
+ mKind = item.getDataKind();
+ mMimeType = item.getMimeType();
// Determine type for subtitle
mSubtitle = "";
- if (kind.typeColumn != null) {
- if (entryValues.containsKey(kind.typeColumn)) {
- final int typeValue = entryValues.getAsInteger(kind.typeColumn);
+ if (item.hasKindTypeColumn()) {
+ final int typeValue = item.getKindTypeColumn();
- // get type string
- for (EditType type : kind.typeList) {
- if (type.rawValue == typeValue) {
- if (type.customColumn == null) {
- // Non-custom type. Get its description from the resource
- mSubtitle = context.getString(type.labelRes);
- } else {
- // Custom type. Read it from the database
- mSubtitle = entryValues.getAsString(type.customColumn);
- }
- break;
+ // get type string
+ for (EditType type : item.getDataKind().typeList) {
+ if (type.rawValue == typeValue) {
+ if (type.customColumn == null) {
+ // Non-custom type. Get its description from the resource
+ mSubtitle = context.getString(type.labelRes);
+ } else {
+ // Custom type. Read it from the database
+ mSubtitle = item.getContentValues().getAsString(type.customColumn);
}
+ break;
}
}
}
- final Integer superPrimary = entryValues.getAsInteger(Data.IS_SUPER_PRIMARY);
- mIsPrimary = superPrimary != null && superPrimary != 0;
+ mIsPrimary = item.isSuperPrimary();
+ mBody = item.buildDataString();
- if (mKind.actionBody != null) {
- mBody = mKind.actionBody.inflateUsing(context, entryValues);
- }
-
- mDataId = dataId;
- mDataUri = ContentUris.withAppendedId(Data.CONTENT_URI, dataId);
+ mDataId = item.getId();
+ mDataUri = ContentUris.withAppendedId(Data.CONTENT_URI, mDataId);
final boolean hasPhone = PhoneCapabilityTester.isPhone(mContext);
final boolean hasSms = PhoneCapabilityTester.isSmsIntentRegistered(mContext);
// Handle well-known MIME-types with special care
- if (Phone.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ if (item instanceof PhoneDataItem) {
if (PhoneCapabilityTester.isPhone(mContext)) {
- final String number = entryValues.getAsString(Phone.NUMBER);
+ PhoneDataItem phone = (PhoneDataItem) item;
+ final String number = phone.getNumber();
if (!TextUtils.isEmpty(number)) {
final Intent phoneIntent = hasPhone ? ContactsUtils.getCallIntent(number)
@@ -124,8 +119,8 @@
if (hasPhone && hasSms) {
mIntent = phoneIntent;
mAlternateIntent = smsIntent;
- mAlternateIconRes = kind.iconAltRes;
- mAlternateIconDescriptionRes = kind.iconAltDescriptionRes;
+ mAlternateIconRes = phone.getDataKind().iconAltRes;
+ mAlternateIconDescriptionRes = phone.getDataKind().iconAltDescriptionRes;
} else if (hasPhone) {
mIntent = phoneIntent;
} else if (hasSms) {
@@ -133,9 +128,10 @@
}
}
}
- } else if (SipAddress.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ } else if (item instanceof SipAddressDataItem) {
if (PhoneCapabilityTester.isSipPhone(mContext)) {
- final String address = entryValues.getAsString(SipAddress.SIP_ADDRESS);
+ final SipAddressDataItem sip = (SipAddressDataItem) item;
+ final String address = sip.getSipAddress();
if (!TextUtils.isEmpty(address)) {
final Uri callUri = Uri.fromParts(Constants.SCHEME_SIP, address, null);
mIntent = ContactsUtils.getCallIntent(callUri);
@@ -147,26 +143,27 @@
// for the SIP-related intent-filters in its manifest.
}
}
- } else if (Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
- final String address = entryValues.getAsString(Email.DATA);
+ } else if (item instanceof EmailDataItem) {
+ final EmailDataItem email = (EmailDataItem) item;
+ final String address = email.getData();
if (!TextUtils.isEmpty(address)) {
final Uri mailUri = Uri.fromParts(Constants.SCHEME_MAILTO, address, null);
mIntent = new Intent(Intent.ACTION_SENDTO, mailUri);
}
- } else if (Website.CONTENT_ITEM_TYPE.equals(mimeType)) {
- final String url = entryValues.getAsString(Website.URL);
+ } else if (item instanceof WebsiteDataItem) {
+ final WebsiteDataItem website = (WebsiteDataItem) item;
+ final String url = website.getUrl();
if (!TextUtils.isEmpty(url)) {
WebAddress webAddress = new WebAddress(url);
mIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(webAddress.toString()));
}
- } else if (Im.CONTENT_ITEM_TYPE.equals(mimeType)) {
- final boolean isEmail = Email.CONTENT_ITEM_TYPE.equals(
- entryValues.getAsString(Data.MIMETYPE));
- if (isEmail || isProtocolValid(entryValues)) {
- final int protocol = isEmail ? Im.PROTOCOL_GOOGLE_TALK :
- entryValues.getAsInteger(Im.PROTOCOL);
+ } else if (item instanceof ImDataItem) {
+ ImDataItem im = (ImDataItem) item;
+ final boolean isEmail = im.isCreatedFromEmail();
+ if (isEmail || im.isProtocolValid()) {
+ final int protocol = isEmail ? Im.PROTOCOL_GOOGLE_TALK : im.getProtocol();
if (isEmail) {
// Use Google Talk string when using Email, and clear data
@@ -176,8 +173,8 @@
mDataUri = null;
}
- String host = entryValues.getAsString(Im.CUSTOM_PROTOCOL);
- String data = entryValues.getAsString(isEmail ? Email.DATA : Im.DATA);
+ String host = im.getCustomProtocol();
+ String data = im.getData();
if (protocol != Im.PROTOCOL_CUSTOM) {
// Try bringing in a well-known host for specific protocols
host = ContactsUtils.lookupProviderNameFromId(protocol);
@@ -191,8 +188,7 @@
// If the address is also available for a video chat, we'll show the capability
// as a secondary action.
- final Integer chatCapabilityObj = entryValues.getAsInteger(Im.CHAT_CAPABILITY);
- final int chatCapability = chatCapabilityObj == null ? 0 : chatCapabilityObj;
+ final int chatCapability = im.getChatCapability();
final boolean isVideoChatCapable =
(chatCapability & Im.CAPABILITY_HAS_CAMERA) != 0;
final boolean isAudioChatCapable =
@@ -210,9 +206,9 @@
}
}
}
- } else if (StructuredPostal.CONTENT_ITEM_TYPE.equals(mimeType)) {
- final String postalAddress =
- entryValues.getAsString(StructuredPostal.FORMATTED_ADDRESS);
+ } else if (item instanceof StructuredPostalDataItem) {
+ StructuredPostalDataItem postal = (StructuredPostalDataItem) item;
+ final String postalAddress = postal.getFormattedAddress();
if (!TextUtils.isEmpty(postalAddress)) {
mIntent = StructuredPostalUtils.getViewPostalAddressIntent(postalAddress);
}
@@ -221,7 +217,7 @@
if (mIntent == null) {
// Otherwise fall back to default VIEW action
mIntent = new Intent(Intent.ACTION_VIEW);
- mIntent.setDataAndType(mDataUri, mimeType);
+ mIntent.setDataAndType(mDataUri, item.getMimeType());
}
mIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
@@ -236,19 +232,6 @@
mPresence = presence;
}
- private boolean isProtocolValid(ContentValues entryValues) {
- final String protocol = entryValues.getAsString(Im.PROTOCOL);
- if (protocol == null) {
- return false;
- }
- try {
- Integer.valueOf(protocol);
- } catch (NumberFormatException e) {
- return false;
- }
- return true;
- }
-
@Override
public CharSequence getSubtitle() {
return mSubtitle;
diff --git a/src/com/android/contacts/quickcontact/FloatingChildLayout.java b/src/com/android/contacts/quickcontact/FloatingChildLayout.java
index 20a3c1e..555f948 100644
--- a/src/com/android/contacts/quickcontact/FloatingChildLayout.java
+++ b/src/com/android/contacts/quickcontact/FloatingChildLayout.java
@@ -16,10 +16,6 @@
package com.android.contacts.quickcontact;
-import com.android.contacts.R;
-import com.android.contacts.test.NeededForReflection;
-import com.android.contacts.util.SchedulingUtils;
-
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
@@ -36,6 +32,10 @@
import android.widget.FrameLayout;
import android.widget.PopupWindow;
+import com.android.contacts.R;
+import com.android.contacts.test.NeededForReflection;
+import com.android.contacts.util.SchedulingUtils;
+
/**
* Layout containing single child {@link View} which it attempts to center
* around {@link #setChildTargetScreen(Rect)}.
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index 7c93a26..25fb3f4 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -16,29 +16,13 @@
package com.android.contacts.quickcontact;
-import com.android.contacts.Collapser;
-import com.android.contacts.ContactLoader;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.DataKind;
-import com.android.contacts.util.Constants;
-import com.android.contacts.util.DataStatus;
-import com.android.contacts.util.ImageViewDrawableSetter;
-import com.android.contacts.util.SchedulingUtils;
-import com.android.contacts.util.StopWatch;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.ActivityNotFoundException;
import android.content.ContentUris;
-import android.content.ContentValues;
import android.content.Context;
-import android.content.Entity;
-import android.content.Entity.NamedContentValues;
import android.content.Intent;
import android.content.Loader;
import android.content.pm.PackageManager;
@@ -48,13 +32,11 @@
import android.os.Bundle;
import android.os.Handler;
import android.provider.ContactsContract.CommonDataKinds.Email;
-import android.provider.ContactsContract.CommonDataKinds.Im;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.SipAddress;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.CommonDataKinds.Website;
import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.QuickContact;
import android.provider.ContactsContract.RawContacts;
import android.support.v13.app.FragmentPagerAdapter;
@@ -74,6 +56,23 @@
import android.widget.TextView;
import android.widget.Toast;
+import com.android.contacts.Collapser;
+import com.android.contacts.R;
+import com.android.contacts.model.Contact;
+import com.android.contacts.model.ContactLoader;
+import com.android.contacts.model.RawContact;
+import com.android.contacts.model.dataitem.DataItem;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.contacts.model.dataitem.EmailDataItem;
+import com.android.contacts.model.dataitem.ImDataItem;
+import com.android.contacts.util.Constants;
+import com.android.contacts.util.DataStatus;
+import com.android.contacts.util.ImageViewDrawableSetter;
+import com.android.contacts.util.SchedulingUtils;
+import com.android.contacts.util.StopWatch;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -330,7 +329,7 @@
/**
* Handle the result from the ContactLoader
*/
- private void bindData(ContactLoader.Result data) {
+ private void bindData(Contact data) {
final ResolveCache cache = ResolveCache.getInstance(this);
final Context context = this;
@@ -339,42 +338,29 @@
mDefaultsMap.clear();
- mStopWatch.lap("atm"); // AccountTypeManager initialization start
- final AccountTypeManager accountTypes = AccountTypeManager.getInstance(
- context.getApplicationContext());
- mStopWatch.lap("fatm"); // AccountTypeManager initialization finished
+ mStopWatch.lap("sph"); // Start photo setting
final ImageView photoView = (ImageView) mPhotoContainer.findViewById(R.id.photo);
mPhotoSetter.setupContactPhoto(data, photoView);
mStopWatch.lap("ph"); // Photo set
- for (Entity entity : data.getEntities()) {
- final ContentValues entityValues = entity.getEntityValues();
- final String accountType = entityValues.getAsString(RawContacts.ACCOUNT_TYPE);
- final String dataSet = entityValues.getAsString(RawContacts.DATA_SET);
- for (NamedContentValues subValue : entity.getSubValues()) {
- final ContentValues entryValues = subValue.values;
- final String mimeType = entryValues.getAsString(Data.MIMETYPE);
+ for (RawContact rawContact : data.getRawContacts()) {
+ for (DataItem dataItem : rawContact.getDataItems()) {
+ final String mimeType = dataItem.getMimeType();
// Skip this data item if MIME-type excluded
if (isMimeExcluded(mimeType)) continue;
- final long dataId = entryValues.getAsLong(Data._ID);
- final Integer primary = entryValues.getAsInteger(Data.IS_PRIMARY);
- final boolean isPrimary = primary != null && primary != 0;
- final Integer superPrimary = entryValues.getAsInteger(Data.IS_SUPER_PRIMARY);
- final boolean isSuperPrimary = superPrimary != null && superPrimary != 0;
+ final long dataId = dataItem.getId();
+ final boolean isPrimary = dataItem.isPrimary();
+ final boolean isSuperPrimary = dataItem.isSuperPrimary();
- final DataKind kind =
- accountTypes.getKindOrFallback(accountType, dataSet, mimeType);
-
- if (kind != null) {
+ if (dataItem.getDataKind() != null) {
// Build an action for this data entry, find a mapping to a UI
// element, build its summary from the cursor, and collect it
// along with all others of this MIME-type.
- final Action action = new DataAction(context, mimeType, kind, dataId,
- entryValues);
+ final Action action = new DataAction(context, dataItem);
final boolean wasAdded = considerAdd(action, cache, isSuperPrimary);
if (wasAdded) {
// Remember the default
@@ -386,12 +372,11 @@
// Handle Email rows with presence data as Im entry
final DataStatus status = data.getStatuses().get(dataId);
- if (status != null && Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
- final DataKind imKind = accountTypes.getKindOrFallback(accountType, dataSet,
- Im.CONTENT_ITEM_TYPE);
- if (imKind != null) {
- final DataAction action = new DataAction(context, Im.CONTENT_ITEM_TYPE,
- imKind, dataId, entryValues);
+ if (status != null && dataItem instanceof EmailDataItem) {
+ final EmailDataItem email = (EmailDataItem) dataItem;
+ final ImDataItem im = ImDataItem.createFromEmail(email);
+ if (im.getDataKind() != null) {
+ final DataAction action = new DataAction(context, im);
action.setPresence(status.getPresence());
considerAdd(action, cache, isSuperPrimary);
}
@@ -505,14 +490,14 @@
listFragment.setListener(mListFragmentListener);
}
- private LoaderCallbacks<ContactLoader.Result> mLoaderCallbacks =
- new LoaderCallbacks<ContactLoader.Result>() {
+ private LoaderCallbacks<Contact> mLoaderCallbacks =
+ new LoaderCallbacks<Contact>() {
@Override
- public void onLoaderReset(Loader<ContactLoader.Result> loader) {
+ public void onLoaderReset(Loader<Contact> loader) {
}
@Override
- public void onLoadFinished(Loader<ContactLoader.Result> loader, ContactLoader.Result data) {
+ public void onLoadFinished(Loader<Contact> loader, Contact data) {
mStopWatch.lap("lf"); // onLoadFinished
if (isFinishing()) {
close(false);
@@ -558,7 +543,7 @@
}
@Override
- public Loader<ContactLoader.Result> onCreateLoader(int id, Bundle args) {
+ public Loader<Contact> onCreateLoader(int id, Bundle args) {
if (mLookupUri == null) {
Log.wtf(TAG, "Lookup uri wasn't initialized. Loader was started too early");
}
diff --git a/src/com/android/contacts/quickcontact/QuickContactListFragment.java b/src/com/android/contacts/quickcontact/QuickContactListFragment.java
index 117480a..6fed31d 100644
--- a/src/com/android/contacts/quickcontact/QuickContactListFragment.java
+++ b/src/com/android/contacts/quickcontact/QuickContactListFragment.java
@@ -16,9 +16,6 @@
package com.android.contacts.quickcontact;
-import com.android.contacts.ContactPresenceIconUtil;
-import com.android.contacts.R;
-
import android.app.Fragment;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
@@ -31,10 +28,13 @@
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
-import android.widget.RelativeLayout;
import android.widget.ListView;
+import android.widget.RelativeLayout;
import android.widget.TextView;
+import com.android.contacts.ContactPresenceIconUtil;
+import com.android.contacts.R;
+
import java.util.List;
/** A fragment that shows the list of resolve items below a tab */
diff --git a/src/com/android/contacts/quickcontact/ResolveCache.java b/src/com/android/contacts/quickcontact/ResolveCache.java
index 026e0f4..ec59b94 100644
--- a/src/com/android/contacts/quickcontact/ResolveCache.java
+++ b/src/com/android/contacts/quickcontact/ResolveCache.java
@@ -16,9 +16,6 @@
package com.android.contacts.quickcontact;
-import com.android.contacts.util.PhoneCapabilityTester;
-import com.google.android.collect.Sets;
-
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -30,6 +27,9 @@
import android.provider.ContactsContract.CommonDataKinds.SipAddress;
import android.text.TextUtils;
+import com.android.contacts.util.PhoneCapabilityTester;
+import com.google.common.collect.Sets;
+
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.HashSet;
diff --git a/src/com/android/contacts/socialwidget/SocialWidgetProvider.java b/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
index 3283efd..03517d4 100644
--- a/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
+++ b/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
@@ -16,20 +16,9 @@
package com.android.contacts.socialwidget;
-import com.android.contacts.ContactLoader;
-import com.android.contacts.R;
-import com.android.contacts.list.ShortcutIntentBuilder;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.quickcontact.QuickContactBroadcastReceiver;
-import com.android.contacts.util.ContactBadgeUtil;
-import com.android.contacts.util.HtmlUtils;
-import com.android.contacts.util.StreamItemEntry;
-
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
-import android.content.ComponentName;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
@@ -38,7 +27,6 @@
import android.graphics.BitmapFactory;
import android.graphics.Typeface;
import android.net.Uri;
-import android.provider.ContactsContract.QuickContact;
import android.provider.ContactsContract.StreamItems;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
@@ -49,6 +37,16 @@
import android.view.View;
import android.widget.RemoteViews;
+import com.android.contacts.R;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.Contact;
+import com.android.contacts.model.ContactLoader;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.quickcontact.QuickContactBroadcastReceiver;
+import com.android.contacts.util.ContactBadgeUtil;
+import com.android.contacts.util.HtmlUtils;
+import com.android.contacts.util.StreamItemEntry;
+
import java.util.List;
public class SocialWidgetProvider extends AppWidgetProvider {
@@ -118,10 +116,10 @@
final ContactLoader contactLoader = new ContactLoader(context, contactUri, false, true,
false, true);
contactLoader.registerListener(0,
- new ContactLoader.OnLoadCompleteListener<ContactLoader.Result>() {
+ new ContactLoader.OnLoadCompleteListener<Contact>() {
@Override
- public void onLoadComplete(Loader<ContactLoader.Result> loader,
- ContactLoader.Result contactData) {
+ public void onLoadComplete(Loader<Contact> loader,
+ Contact contactData) {
bindRemoteViews(context, widgetId, appWidgetManager, contactData);
}
});
@@ -130,7 +128,7 @@
}
private static void bindRemoteViews(final Context context, final int widgetId,
- final AppWidgetManager widgetManager, ContactLoader.Result contactData) {
+ final AppWidgetManager widgetManager, Contact contactData) {
Log.d(TAG, "Loaded " + contactData.getLookupKey()
+ " for widget with id=" + widgetId);
final RemoteViews views = new RemoteViews(context.getPackageName(),
diff --git a/src/com/android/contacts/test/FragmentTestActivity.java b/src/com/android/contacts/test/FragmentTestActivity.java
index 161ed74..80c6731 100644
--- a/src/com/android/contacts/test/FragmentTestActivity.java
+++ b/src/com/android/contacts/test/FragmentTestActivity.java
@@ -16,11 +16,13 @@
package com.android.contacts.test;
+import android.os.Bundle;
+import android.view.Window;
+import android.view.WindowManager;
+
import com.android.contacts.ContactsActivity;
import com.android.contacts.R;
-import android.os.Bundle;
-
/**
* An activity that is used for testing fragments. A unit test starts this
* activity, adds a fragment and then tests the fragment.
@@ -30,6 +32,13 @@
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+
+ // Normally fragment/activity onStart() methods will not be called when screen is locked.
+ // Use the following flags to ensure that activities can be show for testing.
+ Window window = getWindow();
+ window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON |
+ WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
+
setContentView(R.layout.fragment_test);
}
}
diff --git a/src/com/android/contacts/test/InjectedServices.java b/src/com/android/contacts/test/InjectedServices.java
index 49b88be..4dd955f 100644
--- a/src/com/android/contacts/test/InjectedServices.java
+++ b/src/com/android/contacts/test/InjectedServices.java
@@ -16,12 +16,12 @@
package com.android.contacts.test;
-import com.google.android.collect.Maps;
-import com.google.common.annotations.VisibleForTesting;
-
import android.content.ContentResolver;
import android.content.SharedPreferences;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Maps;
+
import java.util.HashMap;
/**
diff --git a/src/com/android/contacts/util/AccountFilterUtil.java b/src/com/android/contacts/util/AccountFilterUtil.java
index 3f055d0..b95972c 100644
--- a/src/com/android/contacts/util/AccountFilterUtil.java
+++ b/src/com/android/contacts/util/AccountFilterUtil.java
@@ -16,11 +16,6 @@
package com.android.contacts.util;
-import com.android.contacts.R;
-import com.android.contacts.list.AccountFilterActivity;
-import com.android.contacts.list.ContactListFilter;
-import com.android.contacts.list.ContactListFilterController;
-
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
@@ -29,6 +24,11 @@
import android.view.View;
import android.widget.TextView;
+import com.android.contacts.R;
+import com.android.contacts.list.AccountFilterActivity;
+import com.android.contacts.list.ContactListFilter;
+import com.android.contacts.list.ContactListFilterController;
+
/**
* Utility class for account filter manipulation.
*/
@@ -163,4 +163,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/contacts/util/AccountPromptUtils.java b/src/com/android/contacts/util/AccountPromptUtils.java
index 111c52e..cdefda0 100644
--- a/src/com/android/contacts/util/AccountPromptUtils.java
+++ b/src/com/android/contacts/util/AccountPromptUtils.java
@@ -16,9 +16,6 @@
package com.android.contacts.util;
-import com.android.contacts.R;
-import com.android.contacts.model.GoogleAccountType;
-
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
@@ -32,6 +29,9 @@
import android.preference.PreferenceManager;
import android.util.Log;
+import com.android.contacts.R;
+import com.android.contacts.model.account.GoogleAccountType;
+
import java.io.IOException;
/**
diff --git a/src/com/android/contacts/util/AccountSelectionUtil.java b/src/com/android/contacts/util/AccountSelectionUtil.java
index 7317d21..d83cb41 100644
--- a/src/com/android/contacts/util/AccountSelectionUtil.java
+++ b/src/com/android/contacts/util/AccountSelectionUtil.java
@@ -16,11 +16,6 @@
package com.android.contacts.util;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountWithDataSet;
-
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
@@ -35,6 +30,11 @@
import android.widget.ArrayAdapter;
import android.widget.TextView;
+import com.android.contacts.R;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountWithDataSet;
+
import java.util.List;
/**
diff --git a/src/com/android/contacts/util/AccountsListAdapter.java b/src/com/android/contacts/util/AccountsListAdapter.java
index 058cf84..4355cba 100644
--- a/src/com/android/contacts/util/AccountsListAdapter.java
+++ b/src/com/android/contacts/util/AccountsListAdapter.java
@@ -16,11 +16,6 @@
package com.android.contacts.util;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountWithDataSet;
-
import android.content.Context;
import android.text.TextUtils.TruncateAt;
import android.view.LayoutInflater;
@@ -30,6 +25,11 @@
import android.widget.ImageView;
import android.widget.TextView;
+import com.android.contacts.R;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountWithDataSet;
+
import java.util.ArrayList;
import java.util.List;
diff --git a/src/com/android/contacts/util/AsyncTaskExecutors.java b/src/com/android/contacts/util/AsyncTaskExecutors.java
index 539dee7..36b05c7 100644
--- a/src/com/android/contacts/util/AsyncTaskExecutors.java
+++ b/src/com/android/contacts/util/AsyncTaskExecutors.java
@@ -16,12 +16,12 @@
package com.android.contacts.util;
-import com.android.contacts.test.NeededForTesting;
-import com.google.common.base.Preconditions;
-
import android.os.AsyncTask;
import android.os.Looper;
+import com.android.contacts.test.NeededForTesting;
+import com.google.common.base.Preconditions;
+
import java.util.concurrent.Executor;
/**
diff --git a/src/com/android/contacts/util/ClipboardUtils.java b/src/com/android/contacts/util/ClipboardUtils.java
index a160668..1d0a3c1 100644
--- a/src/com/android/contacts/util/ClipboardUtils.java
+++ b/src/com/android/contacts/util/ClipboardUtils.java
@@ -16,14 +16,14 @@
package com.android.contacts.util;
-import com.android.contacts.R;
-
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.text.TextUtils;
import android.widget.Toast;
+import com.android.contacts.R;
+
public class ClipboardUtils {
private static final String TAG = "ClipboardUtils";
diff --git a/src/com/android/contacts/util/ContactBadgeUtil.java b/src/com/android/contacts/util/ContactBadgeUtil.java
index de90c40..5c2cc65 100644
--- a/src/com/android/contacts/util/ContactBadgeUtil.java
+++ b/src/com/android/contacts/util/ContactBadgeUtil.java
@@ -16,9 +16,6 @@
package com.android.contacts.util;
-import com.android.contacts.ContactPhotoManager;
-import com.android.contacts.R;
-
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -29,6 +26,9 @@
import android.text.format.DateUtils;
import android.util.Log;
+import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.R;
+
/**
* Provides static functions to extract summary information for aggregate contacts
*/
diff --git a/src/com/android/contacts/util/DateUtils.java b/src/com/android/contacts/util/DateUtils.java
index d0bb68f..89127c9 100644
--- a/src/com/android/contacts/util/DateUtils.java
+++ b/src/com/android/contacts/util/DateUtils.java
@@ -21,6 +21,7 @@
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
+import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
@@ -34,6 +35,11 @@
// All the SimpleDateFormats in this class use the UTC timezone
public static final SimpleDateFormat NO_YEAR_DATE_FORMAT =
new SimpleDateFormat("--MM-dd", Locale.US);
+ /**
+ * When parsing a date without a year, the system assumes 1970, which wasn't a leap-year.
+ * Let's add a one-off hack for that day of the year
+ */
+ public static final String NO_YEAR_DATE_FEB29TH = "--02-29";
public static final SimpleDateFormat FULL_DATE_FORMAT =
new SimpleDateFormat("yyyy-MM-dd", Locale.US);
public static final SimpleDateFormat DATE_AND_TIME_FORMAT =
@@ -88,6 +94,14 @@
return null;
}
+ private static final Date getUtcDate(int year, int month, int dayOfMonth) {
+ final Calendar calendar = Calendar.getInstance(UTC_TIMEZONE, Locale.US);
+ calendar.set(Calendar.YEAR, year);
+ calendar.set(Calendar.MONTH, month);
+ calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
+ return calendar.getTime();
+ }
+
/**
* Parses the supplied string to see if it looks like a date. If so,
* returns the same date in a cleaned-up format for the user. Otherwise, returns
@@ -105,13 +119,21 @@
ParsePosition parsePosition = new ParsePosition(0);
+ final boolean noYearParsed;
Date date;
- synchronized (NO_YEAR_DATE_FORMAT) {
- date = NO_YEAR_DATE_FORMAT.parse(string, parsePosition);
+ // Unfortunately, we can't parse Feb 29th correctly, so let's handle this day seperately
+ if (NO_YEAR_DATE_FEB29TH.equals(string)) {
+ date = getUtcDate(0, Calendar.FEBRUARY, 29);
+ noYearParsed = true;
+ } else {
+ synchronized (NO_YEAR_DATE_FORMAT) {
+ date = NO_YEAR_DATE_FORMAT.parse(string, parsePosition);
+ }
+ noYearParsed = parsePosition.getIndex() == string.length();
}
- if (parsePosition.getIndex() == string.length()) {
+ if (noYearParsed) {
java.text.DateFormat outFormat = isMonthBeforeDay(context)
? FORMAT_WITHOUT_YEAR_MONTH_FIRST
: FORMAT_WITHOUT_YEAR_DAY_FIRST;
diff --git a/src/com/android/contacts/util/DialogManager.java b/src/com/android/contacts/util/DialogManager.java
index 661c5d3..49796db 100644
--- a/src/com/android/contacts/util/DialogManager.java
+++ b/src/com/android/contacts/util/DialogManager.java
@@ -16,8 +16,6 @@
package com.android.contacts.util;
-import com.android.contacts.R;
-
import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
@@ -25,6 +23,8 @@
import android.os.Bundle;
import android.view.View;
+import com.android.contacts.R;
+
/**
* Manages creation and destruction of Dialogs that are to be shown by Views. Unlike how Dialogs
* are regularly used, the Dialogs are not recycled but immediately destroyed after dismissal.
diff --git a/src/com/android/contacts/util/ExpirableCache.java b/src/com/android/contacts/util/ExpirableCache.java
index 196b03a..3f19a26 100644
--- a/src/com/android/contacts/util/ExpirableCache.java
+++ b/src/com/android/contacts/util/ExpirableCache.java
@@ -16,10 +16,10 @@
package com.android.contacts.util;
-import com.android.contacts.test.NeededForTesting;
-
import android.util.LruCache;
+import com.android.contacts.test.NeededForTesting;
+
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.concurrent.Immutable;
diff --git a/src/com/android/contacts/util/HtmlUtils.java b/src/com/android/contacts/util/HtmlUtils.java
index a3c9c64..cea300e 100644
--- a/src/com/android/contacts/util/HtmlUtils.java
+++ b/src/com/android/contacts/util/HtmlUtils.java
@@ -16,9 +16,6 @@
package com.android.contacts.util;
-import com.android.contacts.R;
-import com.google.common.annotations.VisibleForTesting;
-
import android.content.Context;
import android.content.res.Resources;
import android.text.Html;
@@ -30,6 +27,9 @@
import android.text.style.ImageSpan;
import android.text.style.QuoteSpan;
+import com.android.contacts.R;
+import com.google.common.annotations.VisibleForTesting;
+
/**
* Provides static functions to perform custom HTML to text conversions.
* Specifically, it adjusts the color and padding of the vertical
diff --git a/src/com/android/contacts/util/ImageViewDrawableSetter.java b/src/com/android/contacts/util/ImageViewDrawableSetter.java
index 1d23dd0..b231572 100644
--- a/src/com/android/contacts/util/ImageViewDrawableSetter.java
+++ b/src/com/android/contacts/util/ImageViewDrawableSetter.java
@@ -16,9 +16,6 @@
package com.android.contacts.util;
-import com.android.contacts.ContactLoader.Result;
-import com.android.contacts.ContactPhotoManager;
-
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.graphics.Bitmap;
@@ -29,6 +26,9 @@
import android.util.Log;
import android.widget.ImageView;
+import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.model.Contact;
+
import java.util.Arrays;
/**
@@ -49,7 +49,7 @@
mTarget = target;
}
- public void setupContactPhoto(Result contactData, ImageView photoView) {
+ public void setupContactPhoto(Contact contactData, ImageView photoView) {
setTarget(photoView);
setCompressedImage(contactData.getPhotoBinaryData());
}
diff --git a/src/com/android/contacts/util/LocalizedNameResolver.java b/src/com/android/contacts/util/LocalizedNameResolver.java
index c2ee90a..ec0b812 100644
--- a/src/com/android/contacts/util/LocalizedNameResolver.java
+++ b/src/com/android/contacts/util/LocalizedNameResolver.java
@@ -16,24 +16,24 @@
package com.android.contacts.util;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
import android.accounts.AccountManager;
import android.accounts.AuthenticatorDescription;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.content.pm.ServiceInfo;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ServiceInfo;
import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
-import android.content.res.Resources.NotFoundException;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
import java.io.IOException;
/**
diff --git a/src/com/android/contacts/util/PhoneCapabilityTester.java b/src/com/android/contacts/util/PhoneCapabilityTester.java
index ce248bb..421341c 100644
--- a/src/com/android/contacts/util/PhoneCapabilityTester.java
+++ b/src/com/android/contacts/util/PhoneCapabilityTester.java
@@ -16,8 +16,6 @@
package com.android.contacts.util;
-import com.android.contacts.R;
-
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -26,6 +24,8 @@
import android.net.sip.SipManager;
import android.telephony.TelephonyManager;
+import com.android.contacts.R;
+
import java.util.List;
/**
diff --git a/src/com/android/contacts/util/PhoneNumberFormatter.java b/src/com/android/contacts/util/PhoneNumberFormatter.java
index 204ac69..7ae28db 100644
--- a/src/com/android/contacts/util/PhoneNumberFormatter.java
+++ b/src/com/android/contacts/util/PhoneNumberFormatter.java
@@ -16,13 +16,13 @@
package com.android.contacts.util;
-import com.android.contacts.ContactsUtils;
-
import android.content.Context;
import android.os.AsyncTask;
import android.telephony.PhoneNumberFormattingTextWatcher;
import android.widget.TextView;
+import com.android.contacts.ContactsUtils;
+
public final class PhoneNumberFormatter {
private PhoneNumberFormatter() {}
diff --git a/src/com/android/contacts/util/SchedulingUtils.java b/src/com/android/contacts/util/SchedulingUtils.java
index c55bc16..94294fa 100644
--- a/src/com/android/contacts/util/SchedulingUtils.java
+++ b/src/com/android/contacts/util/SchedulingUtils.java
@@ -17,8 +17,8 @@
package com.android.contacts.util;
import android.view.View;
-import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.ViewTreeObserver.OnDrawListener;
+import android.view.ViewTreeObserver.OnGlobalLayoutListener;
/** Static methods that are useful for scheduling actions to occur at a later time. */
public class SchedulingUtils {
diff --git a/src/com/android/contacts/util/StopWatch.java b/src/com/android/contacts/util/StopWatch.java
index 1accfe2..c53f346 100644
--- a/src/com/android/contacts/util/StopWatch.java
+++ b/src/com/android/contacts/util/StopWatch.java
@@ -16,10 +16,10 @@
package com.android.contacts.util;
-import com.google.android.collect.Lists;
-
import android.util.Log;
+import com.google.common.collect.Lists;
+
import java.util.ArrayList;
/**
diff --git a/src/com/android/contacts/util/StreamItemEntry.java b/src/com/android/contacts/util/StreamItemEntry.java
index f9c8700..b15bae9 100644
--- a/src/com/android/contacts/util/StreamItemEntry.java
+++ b/src/com/android/contacts/util/StreamItemEntry.java
@@ -16,14 +16,14 @@
package com.android.contacts.util;
-import com.android.contacts.detail.ContactDetailDisplayUtils;
-import com.android.contacts.test.NeededForTesting;
-
import android.content.Context;
import android.database.Cursor;
import android.provider.ContactsContract.StreamItems;
import android.text.Html;
+import com.android.contacts.detail.ContactDetailDisplayUtils;
+import com.android.contacts.test.NeededForTesting;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
diff --git a/src/com/android/contacts/vcard/CancelActivity.java b/src/com/android/contacts/vcard/CancelActivity.java
index 5dafa53..ff8512b 100644
--- a/src/com/android/contacts/vcard/CancelActivity.java
+++ b/src/com/android/contacts/vcard/CancelActivity.java
@@ -15,8 +15,6 @@
*/
package com.android.contacts.vcard;
-import com.android.contacts.R;
-
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -28,11 +26,10 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
import android.util.Log;
+import com.android.contacts.R;
+
/**
* The Activity for canceling vCard import/export.
*/
diff --git a/src/com/android/contacts/vcard/ExportProcessor.java b/src/com/android/contacts/vcard/ExportProcessor.java
index b52839b..12f9e24 100644
--- a/src/com/android/contacts/vcard/ExportProcessor.java
+++ b/src/com/android/contacts/vcard/ExportProcessor.java
@@ -15,11 +15,6 @@
*/
package com.android.contacts.vcard;
-import com.android.contacts.R;
-import com.android.contacts.activities.PeopleActivity;
-import com.android.vcard.VCardComposer;
-import com.android.vcard.VCardConfig;
-
import android.app.Notification;
import android.app.NotificationManager;
import android.content.ContentResolver;
@@ -32,6 +27,11 @@
import android.text.TextUtils;
import android.util.Log;
+import com.android.contacts.R;
+import com.android.contacts.activities.PeopleActivity;
+import com.android.vcard.VCardComposer;
+import com.android.vcard.VCardConfig;
+
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
diff --git a/src/com/android/contacts/vcard/ExportVCardActivity.java b/src/com/android/contacts/vcard/ExportVCardActivity.java
index f38c9df..ac0850f 100644
--- a/src/com/android/contacts/vcard/ExportVCardActivity.java
+++ b/src/com/android/contacts/vcard/ExportVCardActivity.java
@@ -15,9 +15,6 @@
*/
package com.android.contacts.vcard;
-import com.android.contacts.R;
-import com.android.vcard.VCardComposer;
-
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -32,10 +29,11 @@
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
-import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
+import com.android.contacts.R;
+
import java.io.File;
/**
@@ -290,4 +288,4 @@
}
finish();
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/contacts/vcard/ImportProcessor.java b/src/com/android/contacts/vcard/ImportProcessor.java
index e8a9193..a2e8a48 100644
--- a/src/com/android/contacts/vcard/ImportProcessor.java
+++ b/src/com/android/contacts/vcard/ImportProcessor.java
@@ -15,6 +15,11 @@
*/
package com.android.contacts.vcard;
+import android.accounts.Account;
+import android.content.ContentResolver;
+import android.net.Uri;
+import android.util.Log;
+
import com.android.vcard.VCardEntry;
import com.android.vcard.VCardEntryCommitter;
import com.android.vcard.VCardEntryConstructor;
@@ -28,11 +33,6 @@
import com.android.vcard.exception.VCardNotSupportedException;
import com.android.vcard.exception.VCardVersionException;
-import android.accounts.Account;
-import android.content.ContentResolver;
-import android.net.Uri;
-import android.util.Log;
-
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
diff --git a/src/com/android/contacts/vcard/ImportVCardActivity.java b/src/com/android/contacts/vcard/ImportVCardActivity.java
index 2dc92af..a9566ef 100644
--- a/src/com/android/contacts/vcard/ImportVCardActivity.java
+++ b/src/com/android/contacts/vcard/ImportVCardActivity.java
@@ -16,20 +16,6 @@
package com.android.contacts.vcard;
-import com.android.contacts.ContactsActivity;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountWithDataSet;
-import com.android.contacts.util.AccountSelectionUtil;
-import com.android.vcard.VCardEntryCounter;
-import com.android.vcard.VCardParser;
-import com.android.vcard.VCardParser_V21;
-import com.android.vcard.VCardParser_V30;
-import com.android.vcard.VCardSourceDetector;
-import com.android.vcard.exception.VCardException;
-import com.android.vcard.exception.VCardNestedException;
-import com.android.vcard.exception.VCardVersionException;
-
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -60,6 +46,20 @@
import android.util.Log;
import android.widget.Toast;
+import com.android.contacts.ContactsActivity;
+import com.android.contacts.R;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.util.AccountSelectionUtil;
+import com.android.vcard.VCardEntryCounter;
+import com.android.vcard.VCardParser;
+import com.android.vcard.VCardParser_V21;
+import com.android.vcard.VCardParser_V30;
+import com.android.vcard.VCardSourceDetector;
+import com.android.vcard.exception.VCardException;
+import com.android.vcard.exception.VCardNestedException;
+import com.android.vcard.exception.VCardVersionException;
+
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
diff --git a/src/com/android/contacts/vcard/NfcImportVCardActivity.java b/src/com/android/contacts/vcard/NfcImportVCardActivity.java
index c3a55d2..035be60 100644
--- a/src/com/android/contacts/vcard/NfcImportVCardActivity.java
+++ b/src/com/android/contacts/vcard/NfcImportVCardActivity.java
@@ -16,19 +16,6 @@
package com.android.contacts.vcard;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountWithDataSet;
-import com.android.vcard.VCardEntry;
-import com.android.vcard.VCardEntryCounter;
-import com.android.vcard.VCardParser;
-import com.android.vcard.VCardParser_V21;
-import com.android.vcard.VCardParser_V30;
-import com.android.vcard.VCardSourceDetector;
-import com.android.vcard.exception.VCardException;
-import com.android.vcard.exception.VCardNestedException;
-import com.android.vcard.exception.VCardVersionException;
-
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
@@ -44,9 +31,21 @@
import android.provider.ContactsContract.RawContacts;
import android.util.Log;
+import com.android.contacts.R;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.vcard.VCardEntry;
+import com.android.vcard.VCardEntryCounter;
+import com.android.vcard.VCardParser;
+import com.android.vcard.VCardParser_V21;
+import com.android.vcard.VCardParser_V30;
+import com.android.vcard.VCardSourceDetector;
+import com.android.vcard.exception.VCardException;
+import com.android.vcard.exception.VCardNestedException;
+import com.android.vcard.exception.VCardVersionException;
+
import java.io.ByteArrayInputStream;
import java.io.IOException;
-import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
diff --git a/src/com/android/contacts/vcard/NotificationImportExportListener.java b/src/com/android/contacts/vcard/NotificationImportExportListener.java
index 06cf73f..855f680 100644
--- a/src/com/android/contacts/vcard/NotificationImportExportListener.java
+++ b/src/com/android/contacts/vcard/NotificationImportExportListener.java
@@ -16,9 +16,6 @@
package com.android.contacts.vcard;
-import com.android.contacts.R;
-import com.android.vcard.VCardEntry;
-
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
@@ -30,9 +27,11 @@
import android.os.Handler;
import android.os.Message;
import android.provider.ContactsContract.RawContacts;
-import android.widget.RemoteViews;
import android.widget.Toast;
+import com.android.contacts.R;
+import com.android.vcard.VCardEntry;
+
public class NotificationImportExportListener implements VCardImportExportListener,
Handler.Callback {
/** The tag used by vCard-related notifications. */
diff --git a/src/com/android/contacts/vcard/SelectAccountActivity.java b/src/com/android/contacts/vcard/SelectAccountActivity.java
index f27331e..0e9c5a8 100644
--- a/src/com/android/contacts/vcard/SelectAccountActivity.java
+++ b/src/com/android/contacts/vcard/SelectAccountActivity.java
@@ -15,18 +15,18 @@
*/
package com.android.contacts.vcard;
-import com.android.contacts.ContactsActivity;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountWithDataSet;
-import com.android.contacts.util.AccountSelectionUtil;
-
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
+import com.android.contacts.ContactsActivity;
+import com.android.contacts.R;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.util.AccountSelectionUtil;
+
import java.util.List;
public class SelectAccountActivity extends ContactsActivity {
diff --git a/src/com/android/contacts/vcard/VCardImportExportListener.java b/src/com/android/contacts/vcard/VCardImportExportListener.java
index d3ef198..82d7c21 100644
--- a/src/com/android/contacts/vcard/VCardImportExportListener.java
+++ b/src/com/android/contacts/vcard/VCardImportExportListener.java
@@ -16,10 +16,10 @@
package com.android.contacts.vcard;
-import com.android.vcard.VCardEntry;
-
import android.net.Uri;
+import com.android.vcard.VCardEntry;
+
interface VCardImportExportListener {
void onImportProcessed(ImportRequest request, int jobId, int sequence);
void onImportParsed(ImportRequest request, int jobId, VCardEntry entry, int currentCount,
diff --git a/src/com/android/contacts/vcard/VCardService.java b/src/com/android/contacts/vcard/VCardService.java
index 34c4acb..4ef1bcb 100644
--- a/src/com/android/contacts/vcard/VCardService.java
+++ b/src/com/android/contacts/vcard/VCardService.java
@@ -36,7 +36,6 @@
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
diff --git a/src/com/android/contacts/voicemail/VoicemailPlaybackFragment.java b/src/com/android/contacts/voicemail/VoicemailPlaybackFragment.java
index 8912a74..5973387 100644
--- a/src/com/android/contacts/voicemail/VoicemailPlaybackFragment.java
+++ b/src/com/android/contacts/voicemail/VoicemailPlaybackFragment.java
@@ -19,14 +19,6 @@
import static com.android.contacts.CallDetailActivity.EXTRA_VOICEMAIL_START_PLAYBACK;
import static com.android.contacts.CallDetailActivity.EXTRA_VOICEMAIL_URI;
-import com.android.common.io.MoreCloseables;
-import com.android.contacts.ProximitySensorAware;
-import com.android.contacts.R;
-import com.android.contacts.util.AsyncTaskExecutors;
-import com.android.ex.variablespeed.MediaPlayerProxy;
-import com.android.ex.variablespeed.VariableSpeed;
-import com.google.common.base.Preconditions;
-
import android.app.Activity;
import android.app.Fragment;
import android.content.ContentResolver;
@@ -47,6 +39,14 @@
import android.widget.SeekBar;
import android.widget.TextView;
+import com.android.common.io.MoreCloseables;
+import com.android.contacts.ProximitySensorAware;
+import com.android.contacts.R;
+import com.android.contacts.util.AsyncTaskExecutors;
+import com.android.ex.variablespeed.MediaPlayerProxy;
+import com.android.ex.variablespeed.VariableSpeed;
+import com.google.common.base.Preconditions;
+
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
diff --git a/src/com/android/contacts/voicemail/VoicemailPlaybackPresenter.java b/src/com/android/contacts/voicemail/VoicemailPlaybackPresenter.java
index 7aecf08..2c7ba52 100644
--- a/src/com/android/contacts/voicemail/VoicemailPlaybackPresenter.java
+++ b/src/com/android/contacts/voicemail/VoicemailPlaybackPresenter.java
@@ -18,13 +18,6 @@
import static android.util.MathUtils.constrain;
-import com.android.contacts.R;
-import com.android.contacts.util.AsyncTaskExecutor;
-import com.android.ex.variablespeed.MediaPlayerProxy;
-import com.android.ex.variablespeed.SingleThreadedMediaPlayerProxy;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-
import android.content.Context;
import android.database.ContentObserver;
import android.media.AudioManager;
@@ -37,6 +30,13 @@
import android.view.View;
import android.widget.SeekBar;
+import com.android.contacts.R;
+import com.android.contacts.util.AsyncTaskExecutor;
+import com.android.ex.variablespeed.MediaPlayerProxy;
+import com.android.ex.variablespeed.SingleThreadedMediaPlayerProxy;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
diff --git a/src/com/android/contacts/voicemail/VoicemailStatusHelperImpl.java b/src/com/android/contacts/voicemail/VoicemailStatusHelperImpl.java
index d88b5d3..c7f9c8f 100644
--- a/src/com/android/contacts/voicemail/VoicemailStatusHelperImpl.java
+++ b/src/com/android/contacts/voicemail/VoicemailStatusHelperImpl.java
@@ -24,13 +24,13 @@
import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION;
import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_OK;
-import com.android.contacts.R;
-import com.android.contacts.util.UriUtils;
-
import android.database.Cursor;
import android.net.Uri;
import android.provider.VoicemailContract.Status;
+import com.android.contacts.R;
+import com.android.contacts.util.UriUtils;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
diff --git a/src/com/android/contacts/widget/AlphaTouchInterceptorOverlay.java b/src/com/android/contacts/widget/AlphaTouchInterceptorOverlay.java
index a7d219c..8779a95 100644
--- a/src/com/android/contacts/widget/AlphaTouchInterceptorOverlay.java
+++ b/src/com/android/contacts/widget/AlphaTouchInterceptorOverlay.java
@@ -16,13 +16,13 @@
package com.android.contacts.widget;
-import com.android.contacts.detail.ContactDetailDisplayUtils;
-import com.android.contacts.util.ThemeUtils;
-
import android.content.Context;
import android.view.View;
import android.widget.FrameLayout;
+import com.android.contacts.detail.ContactDetailDisplayUtils;
+import com.android.contacts.util.ThemeUtils;
+
/**
* A View that other Views can use to create a touch-interceptor layer above
* their other sub-views. This layer can be enabled and disabled; when enabled,
diff --git a/src/com/android/contacts/widget/CompositeListAdapter.java b/src/com/android/contacts/widget/CompositeListAdapter.java
index 610b97f..34c8fa0 100644
--- a/src/com/android/contacts/widget/CompositeListAdapter.java
+++ b/src/com/android/contacts/widget/CompositeListAdapter.java
@@ -15,15 +15,15 @@
*/
package com.android.contacts.widget;
-import com.android.contacts.test.NeededForTesting;
-import com.google.common.annotations.VisibleForTesting;
-
import android.database.DataSetObserver;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListAdapter;
+import com.android.contacts.test.NeededForTesting;
+import com.google.common.annotations.VisibleForTesting;
+
/**
* A general purpose adapter that is composed of multiple sub-adapters. It just
* appends them in the order they are added. It listens to changes from all
diff --git a/src/com/android/contacts/widget/InterpolatingLayout.java b/src/com/android/contacts/widget/InterpolatingLayout.java
index 78785b9..fc3177c 100644
--- a/src/com/android/contacts/widget/InterpolatingLayout.java
+++ b/src/com/android/contacts/widget/InterpolatingLayout.java
@@ -16,8 +16,6 @@
package com.android.contacts.widget;
-import com.android.contacts.R;
-
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
@@ -27,6 +25,8 @@
import android.view.ViewGroup;
import android.widget.LinearLayout;
+import com.android.contacts.R;
+
/**
* Layout similar to LinearLayout that allows a child to specify examples of
* desired size depending on the parent size. For example if the widget wants to
diff --git a/src/com/android/contacts/widget/PinnedHeaderListAdapter.java b/src/com/android/contacts/widget/PinnedHeaderListAdapter.java
index a39cfcc..c01e331 100644
--- a/src/com/android/contacts/widget/PinnedHeaderListAdapter.java
+++ b/src/com/android/contacts/widget/PinnedHeaderListAdapter.java
@@ -15,12 +15,12 @@
*/
package com.android.contacts.widget;
-import com.android.common.widget.CompositeCursorAdapter;
-
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
+import com.android.common.widget.CompositeCursorAdapter;
+
/**
* A subclass of {@link CompositeCursorAdapter} that manages pinned partition headers.
*/
diff --git a/src/com/android/contacts/widget/PinnedHeaderListDemoActivity.java b/src/com/android/contacts/widget/PinnedHeaderListDemoActivity.java
index b553e3f..4276791 100644
--- a/src/com/android/contacts/widget/PinnedHeaderListDemoActivity.java
+++ b/src/com/android/contacts/widget/PinnedHeaderListDemoActivity.java
@@ -16,8 +16,6 @@
package com.android.contacts.widget;
-import com.android.contacts.R;
-
import android.app.ListActivity;
import android.content.Context;
import android.database.Cursor;
@@ -29,6 +27,8 @@
import android.view.ViewGroup;
import android.widget.TextView;
+import com.android.contacts.R;
+
/**
* An activity that demonstrates various use cases for the {@link PinnedHeaderListView}.
* If we decide to move PinnedHeaderListView to the framework, this class could go
diff --git a/src/com/android/contacts/widget/ProportionalLayout.java b/src/com/android/contacts/widget/ProportionalLayout.java
index 52a67d4..d069eb7 100644
--- a/src/com/android/contacts/widget/ProportionalLayout.java
+++ b/src/com/android/contacts/widget/ProportionalLayout.java
@@ -16,14 +16,14 @@
package com.android.contacts.widget;
-import com.android.contacts.R;
-
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
+import com.android.contacts.R;
+
/**
* Layout that calculates its height based on its width, or vice versa (depending on the set
* {@link #setDirection(Direction)}. The factor is specified in {@link #setRatio(float)}.
diff --git a/src/com/android/contacts/widget/TextHighlightingAnimation.java b/src/com/android/contacts/widget/TextHighlightingAnimation.java
index 882dd48..2924e4e 100644
--- a/src/com/android/contacts/widget/TextHighlightingAnimation.java
+++ b/src/com/android/contacts/widget/TextHighlightingAnimation.java
@@ -15,9 +15,6 @@
*/
package com.android.contacts.widget;
-import com.android.contacts.format.FormatUtils;
-import com.android.internal.R;
-
import android.database.CharArrayBuffer;
import android.graphics.Color;
import android.os.Handler;
@@ -26,6 +23,9 @@
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
+import com.android.contacts.format.FormatUtils;
+import com.android.internal.R;
+
/**
* An animation that alternately dims and brightens the non-highlighted portion of text.
*/
diff --git a/tests/res/values/donottranslate_strings.xml b/tests/res/values/donottranslate_strings.xml
index be6b5a7..dc8bf2f 100644
--- a/tests/res/values/donottranslate_strings.xml
+++ b/tests/res/values/donottranslate_strings.xml
@@ -52,10 +52,7 @@
<item>ACTION_SEARCH: contact</item>
<item>ACTION_SEARCH: email</item>
<item>ACTION_SEARCH: phone</item>
- <item>SEARCH_SUGGESTION_CLICKED (call button)</item>
<item>SEARCH_SUGGESTION_CLICKED: contact</item>
- <item>SEARCH_SUGGESTION_DIAL_NUMBER_CLICKED</item>
- <item>SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED</item>
<item>TODO: JOIN_CONTACT</item>
<!-- Edit Contact -->
diff --git a/tests/src/com/android/contacts/CallDetailActivityTest.java b/tests/src/com/android/contacts/CallDetailActivityTest.java
index 689f946..ae28929 100644
--- a/tests/src/com/android/contacts/CallDetailActivityTest.java
+++ b/tests/src/com/android/contacts/CallDetailActivityTest.java
@@ -20,13 +20,6 @@
import static com.android.contacts.voicemail.VoicemailPlaybackPresenter.Tasks.CHECK_FOR_CONTENT;
import static com.android.contacts.voicemail.VoicemailPlaybackPresenter.Tasks.PREPARE_MEDIA_PLAYER;
-import com.android.contacts.util.AsyncTaskExecutors;
-import com.android.contacts.util.FakeAsyncTaskExecutor;
-import com.android.contacts.util.IntegrationTestUtils;
-import com.android.contacts.util.LocaleTestUtils;
-import com.android.internal.view.menu.ContextMenuBuilder;
-import com.google.common.io.Closeables;
-
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
@@ -41,6 +34,13 @@
import android.view.Menu;
import android.widget.TextView;
+import com.android.contacts.util.AsyncTaskExecutors;
+import com.android.contacts.util.FakeAsyncTaskExecutor;
+import com.android.contacts.util.IntegrationTestUtils;
+import com.android.contacts.util.LocaleTestUtils;
+import com.android.internal.view.menu.ContextMenuBuilder;
+import com.google.common.io.Closeables;
+
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
diff --git a/tests/src/com/android/contacts/ContactDetailTest.java b/tests/src/com/android/contacts/ContactDetailTest.java
index b2c19f4..8d91d9e 100644
--- a/tests/src/com/android/contacts/ContactDetailTest.java
+++ b/tests/src/com/android/contacts/ContactDetailTest.java
@@ -16,13 +16,13 @@
package com.android.contacts;
+import android.test.ActivityUnitTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
import com.android.contacts.activities.ContactDetailActivity;
import com.android.contacts.tests.mocks.ContactsMockContext;
import com.android.contacts.tests.mocks.MockContentProvider;
-import android.test.ActivityUnitTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
@SmallTest
public class ContactDetailTest extends ActivityUnitTestCase<ContactDetailActivity> {
private ContactsMockContext mContext;
diff --git a/tests/src/com/android/contacts/ContactsLaunchPerformance.java b/tests/src/com/android/contacts/ContactsLaunchPerformance.java
index 9177457..5f0336b 100644
--- a/tests/src/com/android/contacts/ContactsLaunchPerformance.java
+++ b/tests/src/com/android/contacts/ContactsLaunchPerformance.java
@@ -19,8 +19,8 @@
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
-import android.test.LaunchPerformanceBase;
import android.os.Bundle;
+import android.test.LaunchPerformanceBase;
/**
* Instrumentation class for Address Book launch performance testing.
diff --git a/tests/src/com/android/contacts/PhoneCallDetailsHelperTest.java b/tests/src/com/android/contacts/PhoneCallDetailsHelperTest.java
index c1c3e08..b852b58 100644
--- a/tests/src/com/android/contacts/PhoneCallDetailsHelperTest.java
+++ b/tests/src/com/android/contacts/PhoneCallDetailsHelperTest.java
@@ -16,12 +16,6 @@
package com.android.contacts;
-import com.android.contacts.calllog.CallTypeHelper;
-import com.android.contacts.calllog.PhoneNumberHelper;
-import com.android.contacts.calllog.TestPhoneNumberHelper;
-import com.android.contacts.util.LocaleTestUtils;
-import com.android.internal.telephony.CallerInfo;
-
import android.content.Context;
import android.content.res.Resources;
import android.provider.CallLog.Calls;
@@ -31,6 +25,12 @@
import android.view.View;
import android.widget.TextView;
+import com.android.contacts.calllog.CallTypeHelper;
+import com.android.contacts.calllog.PhoneNumberHelper;
+import com.android.contacts.calllog.TestPhoneNumberHelper;
+import com.android.contacts.util.LocaleTestUtils;
+import com.android.internal.telephony.CallerInfo;
+
import java.util.GregorianCalendar;
import java.util.Locale;
diff --git a/tests/src/com/android/contacts/EntityDeltaListTests.java b/tests/src/com/android/contacts/RawContactDeltaListTests.java
similarity index 70%
rename from tests/src/com/android/contacts/EntityDeltaListTests.java
rename to tests/src/com/android/contacts/RawContactDeltaListTests.java
index ee27dd9..165e689 100644
--- a/tests/src/com/android/contacts/EntityDeltaListTests.java
+++ b/tests/src/com/android/contacts/RawContactDeltaListTests.java
@@ -21,37 +21,38 @@
import static android.content.ContentProviderOperation.TYPE_INSERT;
import static android.content.ContentProviderOperation.TYPE_UPDATE;
-import com.android.contacts.EntityModifierTests.MockContactsSource;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityModifier;
-import com.android.contacts.model.EntityDeltaList;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.google.android.collect.Lists;
-
import android.content.ContentProviderOperation;
import android.content.ContentValues;
-import android.content.Entity;
+import android.content.Context;
import android.net.Uri;
import android.provider.BaseColumns;
import android.provider.ContactsContract.AggregationExceptions;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.RawContacts;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
+import com.android.contacts.RawContactModifierTests.MockContactsSource;
+import com.android.contacts.model.RawContact;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.RawContactDeltaList;
+import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.model.account.AccountType;
+import com.google.common.collect.Lists;
+
import java.lang.reflect.Field;
import java.util.ArrayList;
/**
- * Tests for {@link EntityDeltaList} which focus on "diff" operations that should
+ * Tests for {@link RawContactDeltaList} which focus on "diff" operations that should
* create {@link AggregationExceptions} in certain cases.
*/
@LargeTest
-public class EntityDeltaListTests extends AndroidTestCase {
- public static final String TAG = "EntityDeltaListTests";
+public class RawContactDeltaListTests extends AndroidTestCase {
+ public static final String TAG = RawContactDeltaListTests.class.getSimpleName();
private static final long CONTACT_FIRST = 1;
private static final long CONTACT_SECOND = 2;
@@ -71,7 +72,7 @@
public static final String TEST_PHONE = "555-1212";
public static final String TEST_ACCOUNT = "org.example.test";
- public EntityDeltaListTests() {
+ public RawContactDeltaListTests() {
super();
}
@@ -95,47 +96,47 @@
return (ContentValues) field.get(operation);
}
- static EntityDelta getUpdate(long rawContactId) {
- final Entity before = EntityDeltaTests.getEntity(rawContactId,
- EntityDeltaTests.TEST_PHONE_ID);
- return EntityDelta.fromBefore(before);
+ static RawContactDelta getUpdate(Context context, long rawContactId) {
+ final RawContact before = RawContactDeltaTests.getRawContact(context, rawContactId,
+ RawContactDeltaTests.TEST_PHONE_ID);
+ return RawContactDelta.fromBefore(before);
}
- static EntityDelta getInsert() {
+ static RawContactDelta getInsert() {
final ContentValues after = new ContentValues();
- after.put(RawContacts.ACCOUNT_NAME, EntityDeltaTests.TEST_ACCOUNT_NAME);
+ after.put(RawContacts.ACCOUNT_NAME, RawContactDeltaTests.TEST_ACCOUNT_NAME);
after.put(RawContacts.SEND_TO_VOICEMAIL, 1);
final ValuesDelta values = ValuesDelta.fromAfter(after);
- return new EntityDelta(values);
+ return new RawContactDelta(values);
}
- static EntityDeltaList buildSet(EntityDelta... deltas) {
- final EntityDeltaList set = EntityDeltaList.fromSingle(deltas[0]);
+ static RawContactDeltaList buildSet(RawContactDelta... deltas) {
+ final RawContactDeltaList set = RawContactDeltaList.fromSingle(deltas[0]);
for (int i = 1; i < deltas.length; i++) {
set.add(deltas[i]);
}
return set;
}
- static EntityDelta buildBeforeEntity(long rawContactId, long version,
+ static RawContactDelta buildBeforeEntity(Context context, long rawContactId, long version,
ContentValues... entries) {
// Build an existing contact read from database
final ContentValues contact = new ContentValues();
contact.put(RawContacts.VERSION, version);
contact.put(RawContacts._ID, rawContactId);
- final Entity before = new Entity(contact);
+ final RawContact before = new RawContact(context, contact);
for (ContentValues entry : entries) {
- before.addSubValue(Data.CONTENT_URI, entry);
+ before.addDataItemValues(entry);
}
- return EntityDelta.fromBefore(before);
+ return RawContactDelta.fromBefore(before);
}
- static EntityDelta buildAfterEntity(ContentValues... entries) {
+ static RawContactDelta buildAfterEntity(ContentValues... entries) {
// Build an existing contact read from database
final ContentValues contact = new ContentValues();
contact.put(RawContacts.ACCOUNT_TYPE, TEST_ACCOUNT);
- final EntityDelta after = new EntityDelta(ValuesDelta.fromAfter(contact));
+ final RawContactDelta after = new RawContactDelta(ValuesDelta.fromAfter(contact));
for (ContentValues entry : entries) {
after.addEntry(ValuesDelta.fromAfter(entry));
}
@@ -164,24 +165,24 @@
return values;
}
- static void insertPhone(EntityDeltaList set, long rawContactId, ContentValues values) {
- final EntityDelta match = set.getByRawContactId(rawContactId);
+ static void insertPhone(RawContactDeltaList set, long rawContactId, ContentValues values) {
+ final RawContactDelta match = set.getByRawContactId(rawContactId);
match.addEntry(ValuesDelta.fromAfter(values));
}
- static ValuesDelta getPhone(EntityDeltaList set, long rawContactId, long dataId) {
- final EntityDelta match = set.getByRawContactId(rawContactId);
+ static ValuesDelta getPhone(RawContactDeltaList set, long rawContactId, long dataId) {
+ final RawContactDelta match = set.getByRawContactId(rawContactId);
return match.getEntry(dataId);
}
- static void assertDiffPattern(EntityDelta delta, ContentProviderOperation... pattern) {
+ static void assertDiffPattern(RawContactDelta delta, ContentProviderOperation... pattern) {
final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
delta.buildAssert(diff);
delta.buildDiff(diff);
assertDiffPattern(diff, pattern);
}
- static void assertDiffPattern(EntityDeltaList set, ContentProviderOperation... pattern) {
+ static void assertDiffPattern(RawContactDeltaList set, ContentProviderOperation... pattern) {
assertDiffPattern(set.buildDiff(), pattern);
}
@@ -281,7 +282,7 @@
return null;
}
- static Long getVersion(EntityDeltaList set, Long rawContactId) {
+ static Long getVersion(RawContactDeltaList set, Long rawContactId) {
return set.getByRawContactId(rawContactId).getValues().getAsLong(RawContacts.VERSION);
}
@@ -301,8 +302,8 @@
}
public void testInsert() {
- final EntityDelta insert = getInsert();
- final EntityDeltaList set = buildSet(insert);
+ final RawContactDelta insert = getInsert();
+ final RawContactDeltaList set = buildSet(insert);
// Inserting single shouldn't create rules
final ArrayList<ContentProviderOperation> diff = set.buildDiff();
@@ -311,9 +312,9 @@
}
public void testUpdateUpdate() {
- final EntityDelta updateFirst = getUpdate(CONTACT_FIRST);
- final EntityDelta updateSecond = getUpdate(CONTACT_SECOND);
- final EntityDeltaList set = buildSet(updateFirst, updateSecond);
+ final RawContactDelta updateFirst = getUpdate(mContext, CONTACT_FIRST);
+ final RawContactDelta updateSecond = getUpdate(mContext, CONTACT_SECOND);
+ final RawContactDeltaList set = buildSet(updateFirst, updateSecond);
// Updating two existing shouldn't create rules
final ArrayList<ContentProviderOperation> diff = set.buildDiff();
@@ -322,9 +323,9 @@
}
public void testUpdateInsert() {
- final EntityDelta update = getUpdate(CONTACT_FIRST);
- final EntityDelta insert = getInsert();
- final EntityDeltaList set = buildSet(update, insert);
+ final RawContactDelta update = getUpdate(mContext, CONTACT_FIRST);
+ final RawContactDelta insert = getInsert();
+ final RawContactDeltaList set = buildSet(update, insert);
// New insert should only create one rule
final ArrayList<ContentProviderOperation> diff = set.buildDiff();
@@ -333,10 +334,10 @@
}
public void testInsertUpdateInsert() {
- final EntityDelta insertFirst = getInsert();
- final EntityDelta update = getUpdate(CONTACT_FIRST);
- final EntityDelta insertSecond = getInsert();
- final EntityDeltaList set = buildSet(insertFirst, update, insertSecond);
+ final RawContactDelta insertFirst = getInsert();
+ final RawContactDelta update = getUpdate(mContext, CONTACT_FIRST);
+ final RawContactDelta insertSecond = getInsert();
+ final RawContactDeltaList set = buildSet(insertFirst, update, insertSecond);
// Two inserts should create two rules to bind against single existing
final ArrayList<ContentProviderOperation> diff = set.buildDiff();
@@ -345,10 +346,10 @@
}
public void testInsertInsertInsert() {
- final EntityDelta insertFirst = getInsert();
- final EntityDelta insertSecond = getInsert();
- final EntityDelta insertThird = getInsert();
- final EntityDeltaList set = buildSet(insertFirst, insertSecond, insertThird);
+ final RawContactDelta insertFirst = getInsert();
+ final RawContactDelta insertSecond = getInsert();
+ final RawContactDelta insertThird = getInsert();
+ final RawContactDeltaList set = buildSet(insertFirst, insertSecond, insertThird);
// Three new inserts should create only two binding rules
final ArrayList<ContentProviderOperation> diff = set.buildDiff();
@@ -357,21 +358,21 @@
}
public void testMergeDataRemoteInsert() {
- final EntityDeltaList first = buildSet(buildBeforeEntity(CONTACT_BOB, VER_FIRST,
- buildPhone(PHONE_RED)));
- final EntityDeltaList second = buildSet(buildBeforeEntity(CONTACT_BOB, VER_SECOND,
- buildPhone(PHONE_RED), buildPhone(PHONE_GREEN)));
+ final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
+ VER_FIRST, buildPhone(PHONE_RED)));
+ final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
+ VER_SECOND, buildPhone(PHONE_RED), buildPhone(PHONE_GREEN)));
// Merge in second version, verify they match
- final EntityDeltaList merged = EntityDeltaList.mergeAfter(second, first);
+ final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
assertEquals("Unexpected change when merging", second, merged);
}
public void testMergeDataLocalUpdateRemoteInsert() {
- final EntityDeltaList first = buildSet(buildBeforeEntity(CONTACT_BOB, VER_FIRST,
- buildPhone(PHONE_RED)));
- final EntityDeltaList second = buildSet(buildBeforeEntity(CONTACT_BOB, VER_SECOND,
- buildPhone(PHONE_RED), buildPhone(PHONE_GREEN)));
+ final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
+ VER_FIRST, buildPhone(PHONE_RED)));
+ final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
+ VER_SECOND, buildPhone(PHONE_RED), buildPhone(PHONE_GREEN)));
// Change the local number to trigger update
final ValuesDelta phone = getPhone(first, CONTACT_BOB, PHONE_RED);
@@ -384,7 +385,7 @@
buildUpdateAggregationDefault());
// Merge in the second version, verify diff matches
- final EntityDeltaList merged = EntityDeltaList.mergeAfter(second, first);
+ final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
assertDiffPattern(merged,
buildAssertVersion(VER_SECOND),
buildUpdateAggregationSuspended(),
@@ -393,10 +394,10 @@
}
public void testMergeDataLocalUpdateRemoteDelete() {
- final EntityDeltaList first = buildSet(buildBeforeEntity(CONTACT_BOB, VER_FIRST,
- buildPhone(PHONE_RED)));
- final EntityDeltaList second = buildSet(buildBeforeEntity(CONTACT_BOB, VER_SECOND,
- buildPhone(PHONE_GREEN)));
+ final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
+ VER_FIRST, buildPhone(PHONE_RED)));
+ final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
+ VER_SECOND, buildPhone(PHONE_GREEN)));
// Change the local number to trigger update
final ValuesDelta phone = getPhone(first, CONTACT_BOB, PHONE_RED);
@@ -410,7 +411,7 @@
// Merge in the second version, verify that our update changed to
// insert, since RED was deleted on remote side
- final EntityDeltaList merged = EntityDeltaList.mergeAfter(second, first);
+ final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
assertDiffPattern(merged,
buildAssertVersion(VER_SECOND),
buildUpdateAggregationSuspended(),
@@ -419,10 +420,10 @@
}
public void testMergeDataLocalDeleteRemoteUpdate() {
- final EntityDeltaList first = buildSet(buildBeforeEntity(CONTACT_BOB, VER_FIRST,
- buildPhone(PHONE_RED)));
- final EntityDeltaList second = buildSet(buildBeforeEntity(CONTACT_BOB, VER_SECOND,
- buildPhone(PHONE_RED, TEST_PHONE)));
+ final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
+ VER_FIRST, buildPhone(PHONE_RED)));
+ final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
+ VER_SECOND, buildPhone(PHONE_RED, TEST_PHONE)));
// Delete phone locally
final ValuesDelta phone = getPhone(first, CONTACT_BOB, PHONE_RED);
@@ -435,7 +436,7 @@
buildUpdateAggregationDefault());
// Merge in the second version, verify that our delete remains
- final EntityDeltaList merged = EntityDeltaList.mergeAfter(second, first);
+ final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
assertDiffPattern(merged,
buildAssertVersion(VER_SECOND),
buildUpdateAggregationSuspended(),
@@ -444,10 +445,10 @@
}
public void testMergeDataLocalInsertRemoteInsert() {
- final EntityDeltaList first = buildSet(buildBeforeEntity(CONTACT_BOB, VER_FIRST,
- buildPhone(PHONE_RED)));
- final EntityDeltaList second = buildSet(buildBeforeEntity(CONTACT_BOB, VER_SECOND,
- buildPhone(PHONE_RED), buildPhone(PHONE_GREEN)));
+ final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
+ VER_FIRST, buildPhone(PHONE_RED)));
+ final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
+ VER_SECOND, buildPhone(PHONE_RED), buildPhone(PHONE_GREEN)));
// Insert new phone locally
final ValuesDelta bluePhone = ValuesDelta.fromAfter(buildPhone(PHONE_BLUE));
@@ -459,7 +460,7 @@
buildUpdateAggregationDefault());
// Merge in the second version, verify that our insert remains
- final EntityDeltaList merged = EntityDeltaList.mergeAfter(second, first);
+ final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
assertDiffPattern(merged,
buildAssertVersion(VER_SECOND),
buildUpdateAggregationSuspended(),
@@ -468,15 +469,15 @@
}
public void testMergeRawContactLocalInsertRemoteInsert() {
- final EntityDeltaList first = buildSet(buildBeforeEntity(CONTACT_BOB, VER_FIRST,
- buildPhone(PHONE_RED)));
- final EntityDeltaList second = buildSet(buildBeforeEntity(CONTACT_BOB, VER_SECOND,
- buildPhone(PHONE_RED)), buildBeforeEntity(CONTACT_MARY, VER_SECOND,
- buildPhone(PHONE_RED)));
+ final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
+ VER_FIRST, buildPhone(PHONE_RED)));
+ final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
+ VER_SECOND, buildPhone(PHONE_RED)), buildBeforeEntity(mContext, CONTACT_MARY,
+ VER_SECOND, buildPhone(PHONE_RED)));
// Add new contact locally, should remain insert
final ContentValues joePhoneInsert = buildPhone(PHONE_BLUE);
- final EntityDelta joeContact = buildAfterEntity(joePhoneInsert);
+ final RawContactDelta joeContact = buildAfterEntity(joePhoneInsert);
final ContentValues joeContactInsert = joeContact.getValues().getCompleteValues();
joeContactInsert.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_SUSPENDED);
first.add(joeContact);
@@ -488,7 +489,7 @@
buildUpdateAggregationKeepTogether(CONTACT_BOB));
// Merge in the second version, verify that our insert remains
- final EntityDeltaList merged = EntityDeltaList.mergeAfter(second, first);
+ final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
assertDiffPattern(merged,
buildAssertVersion(VER_SECOND),
buildAssertVersion(VER_SECOND),
@@ -499,11 +500,11 @@
}
public void testMergeRawContactLocalDeleteRemoteDelete() {
- final EntityDeltaList first = buildSet(
- buildBeforeEntity(CONTACT_BOB, VER_FIRST, buildPhone(PHONE_RED)),
- buildBeforeEntity(CONTACT_MARY, VER_FIRST, buildPhone(PHONE_RED)));
- final EntityDeltaList second = buildSet(
- buildBeforeEntity(CONTACT_BOB, VER_SECOND, buildPhone(PHONE_RED)));
+ final RawContactDeltaList first = buildSet(
+ buildBeforeEntity(mContext, CONTACT_BOB, VER_FIRST, buildPhone(PHONE_RED)),
+ buildBeforeEntity(mContext, CONTACT_MARY, VER_FIRST, buildPhone(PHONE_RED)));
+ final RawContactDeltaList second = buildSet(
+ buildBeforeEntity(mContext, CONTACT_BOB, VER_SECOND, buildPhone(PHONE_RED)));
// Remove contact locally
first.getByRawContactId(CONTACT_MARY).markDeleted();
@@ -513,16 +514,16 @@
buildDelete(RawContacts.CONTENT_URI));
// Merge in the second version, verify that our delete isn't needed
- final EntityDeltaList merged = EntityDeltaList.mergeAfter(second, first);
+ final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
assertDiffPattern(merged);
}
public void testMergeRawContactLocalUpdateRemoteDelete() {
- final EntityDeltaList first = buildSet(
- buildBeforeEntity(CONTACT_BOB, VER_FIRST, buildPhone(PHONE_RED)),
- buildBeforeEntity(CONTACT_MARY, VER_FIRST, buildPhone(PHONE_RED)));
- final EntityDeltaList second = buildSet(
- buildBeforeEntity(CONTACT_BOB, VER_SECOND, buildPhone(PHONE_RED)));
+ final RawContactDeltaList first = buildSet(
+ buildBeforeEntity(mContext, CONTACT_BOB, VER_FIRST, buildPhone(PHONE_RED)),
+ buildBeforeEntity(mContext, CONTACT_MARY, VER_FIRST, buildPhone(PHONE_RED)));
+ final RawContactDeltaList second = buildSet(
+ buildBeforeEntity(mContext, CONTACT_BOB, VER_SECOND, buildPhone(PHONE_RED)));
// Perform local update
final ValuesDelta phone = getPhone(first, CONTACT_MARY, PHONE_RED);
@@ -540,7 +541,7 @@
contactInsert.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_SUSPENDED);
// Merge and verify that update turned into insert
- final EntityDeltaList merged = EntityDeltaList.mergeAfter(second, first);
+ final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
assertDiffPattern(merged,
buildAssertVersion(VER_SECOND),
buildOper(RawContacts.CONTENT_URI, TYPE_INSERT, contactInsert),
@@ -550,28 +551,28 @@
}
public void testMergeUsesNewVersion() {
- final EntityDeltaList first = buildSet(buildBeforeEntity(CONTACT_BOB, VER_FIRST,
- buildPhone(PHONE_RED)));
- final EntityDeltaList second = buildSet(buildBeforeEntity(CONTACT_BOB, VER_SECOND,
- buildPhone(PHONE_RED)));
+ final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
+ VER_FIRST, buildPhone(PHONE_RED)));
+ final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
+ VER_SECOND, buildPhone(PHONE_RED)));
assertEquals((Long)VER_FIRST, getVersion(first, CONTACT_BOB));
assertEquals((Long)VER_SECOND, getVersion(second, CONTACT_BOB));
- final EntityDeltaList merged = EntityDeltaList.mergeAfter(second, first);
+ final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
assertEquals((Long)VER_SECOND, getVersion(merged, CONTACT_BOB));
}
public void testMergeAfterEnsureAndTrim() {
- final EntityDeltaList first = buildSet(buildBeforeEntity(CONTACT_BOB, VER_FIRST,
- buildEmail(EMAIL_YELLOW)));
- final EntityDeltaList second = buildSet(buildBeforeEntity(CONTACT_BOB, VER_SECOND,
- buildEmail(EMAIL_YELLOW)));
+ final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
+ VER_FIRST, buildEmail(EMAIL_YELLOW)));
+ final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
+ VER_SECOND, buildEmail(EMAIL_YELLOW)));
// Ensure we have at least one phone
final AccountType source = getAccountType();
- final EntityDelta bobContact = first.getByRawContactId(CONTACT_BOB);
- EntityModifier.ensureKindExists(bobContact, source, Phone.CONTENT_ITEM_TYPE);
+ final RawContactDelta bobContact = first.getByRawContactId(CONTACT_BOB);
+ RawContactModifier.ensureKindExists(bobContact, source, Phone.CONTENT_ITEM_TYPE);
final ValuesDelta bobPhone = bobContact.getSuperPrimaryEntry(Phone.CONTENT_ITEM_TYPE, true);
// Make sure the update would insert a row
@@ -582,11 +583,11 @@
buildUpdateAggregationDefault());
// Trim values and ensure that we don't insert things
- EntityModifier.trimEmpty(bobContact, source);
+ RawContactModifier.trimEmpty(bobContact, source);
assertDiffPattern(first);
// Now re-parent the change, which should remain no-op
- final EntityDeltaList merged = EntityDeltaList.mergeAfter(second, first);
+ final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
assertDiffPattern(merged);
}
}
diff --git a/tests/src/com/android/contacts/EntityDeltaTests.java b/tests/src/com/android/contacts/RawContactDeltaTests.java
similarity index 82%
rename from tests/src/com/android/contacts/EntityDeltaTests.java
rename to tests/src/com/android/contacts/RawContactDeltaTests.java
index fa716c7..80e4c20 100644
--- a/tests/src/com/android/contacts/EntityDeltaTests.java
+++ b/tests/src/com/android/contacts/RawContactDeltaTests.java
@@ -16,35 +16,36 @@
package com.android.contacts;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.google.android.collect.Lists;
-
+import static android.content.ContentProviderOperation.TYPE_ASSERT;
+import static android.content.ContentProviderOperation.TYPE_DELETE;
import static android.content.ContentProviderOperation.TYPE_INSERT;
import static android.content.ContentProviderOperation.TYPE_UPDATE;
-import static android.content.ContentProviderOperation.TYPE_DELETE;
-import static android.content.ContentProviderOperation.TYPE_ASSERT;
import android.content.ContentProviderOperation;
-import android.content.ContentValues;
-import android.content.Entity;
import android.content.ContentProviderOperation.Builder;
+import android.content.ContentValues;
+import android.content.Context;
import android.os.Parcel;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
+import com.android.contacts.model.RawContact;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.google.common.collect.Lists;
+
import java.util.ArrayList;
/**
- * Tests for {@link EntityDelta} and {@link ValuesDelta}. These tests
+ * Tests for {@link RawContactDelta} and {@link ValuesDelta}. These tests
* focus on passing changes across {@link Parcel}, and verifying that they
* correctly build expected "diff" operations.
*/
@LargeTest
-public class EntityDeltaTests extends AndroidTestCase {
+public class RawContactDeltaTests extends AndroidTestCase {
public static final String TAG = "EntityDeltaTests";
public static final long TEST_CONTACT_ID = 12;
@@ -55,7 +56,7 @@
public static final String TEST_ACCOUNT_NAME = "TEST";
- public EntityDeltaTests() {
+ public RawContactDeltaTests() {
super();
}
@@ -64,7 +65,7 @@
mContext = getContext();
}
- public static Entity getEntity(long contactId, long phoneId) {
+ public static RawContact getRawContact(Context context, long contactId, long phoneId) {
// Build an existing contact read from database
final ContentValues contact = new ContentValues();
contact.put(RawContacts.VERSION, 43);
@@ -76,31 +77,31 @@
phone.put(Phone.NUMBER, TEST_PHONE_NUMBER_1);
phone.put(Phone.TYPE, Phone.TYPE_HOME);
- final Entity before = new Entity(contact);
- before.addSubValue(Data.CONTENT_URI, phone);
+ final RawContact before = new RawContact(context, contact);
+ before.addDataItemValues(phone);
return before;
}
/**
- * Test that {@link EntityDelta#mergeAfter(EntityDelta)} correctly passes
+ * Test that {@link RawContactDelta#mergeAfter(RawContactDelta)} correctly passes
* any changes through the {@link Parcel} object. This enforces that
- * {@link EntityDelta} should be identical when serialized against the same
- * "before" {@link Entity}.
+ * {@link RawContactDelta} should be identical when serialized against the same
+ * "before" {@link RawContact}.
*/
public void testParcelChangesNone() {
- final Entity before = getEntity(TEST_CONTACT_ID, TEST_PHONE_ID);
- final EntityDelta source = EntityDelta.fromBefore(before);
- final EntityDelta dest = EntityDelta.fromBefore(before);
+ final RawContact before = getRawContact(mContext, TEST_CONTACT_ID, TEST_PHONE_ID);
+ final RawContactDelta source = RawContactDelta.fromBefore(before);
+ final RawContactDelta dest = RawContactDelta.fromBefore(before);
// Merge modified values and assert they match
- final EntityDelta merged = EntityDelta.mergeAfter(dest, source);
+ final RawContactDelta merged = RawContactDelta.mergeAfter(dest, source);
assertEquals("Unexpected change when merging", source, merged);
}
public void testParcelChangesInsert() {
- final Entity before = getEntity(TEST_CONTACT_ID, TEST_PHONE_ID);
- final EntityDelta source = EntityDelta.fromBefore(before);
- final EntityDelta dest = EntityDelta.fromBefore(before);
+ final RawContact before = getRawContact(mContext, TEST_CONTACT_ID, TEST_PHONE_ID);
+ final RawContactDelta source = RawContactDelta.fromBefore(before);
+ final RawContactDelta dest = RawContactDelta.fromBefore(before);
// Add a new row and pass across parcel, should be same
final ContentValues phone = new ContentValues();
@@ -110,35 +111,35 @@
source.addEntry(ValuesDelta.fromAfter(phone));
// Merge modified values and assert they match
- final EntityDelta merged = EntityDelta.mergeAfter(dest, source);
+ final RawContactDelta merged = RawContactDelta.mergeAfter(dest, source);
assertEquals("Unexpected change when merging", source, merged);
}
public void testParcelChangesUpdate() {
// Update existing row and pass across parcel, should be same
- final Entity before = getEntity(TEST_CONTACT_ID, TEST_PHONE_ID);
- final EntityDelta source = EntityDelta.fromBefore(before);
- final EntityDelta dest = EntityDelta.fromBefore(before);
+ final RawContact before = getRawContact(mContext, TEST_CONTACT_ID, TEST_PHONE_ID);
+ final RawContactDelta source = RawContactDelta.fromBefore(before);
+ final RawContactDelta dest = RawContactDelta.fromBefore(before);
final ValuesDelta child = source.getEntry(TEST_PHONE_ID);
child.put(Phone.NUMBER, TEST_PHONE_NUMBER_2);
// Merge modified values and assert they match
- final EntityDelta merged = EntityDelta.mergeAfter(dest, source);
+ final RawContactDelta merged = RawContactDelta.mergeAfter(dest, source);
assertEquals("Unexpected change when merging", source, merged);
}
public void testParcelChangesDelete() {
// Delete a row and pass across parcel, should be same
- final Entity before = getEntity(TEST_CONTACT_ID, TEST_PHONE_ID);
- final EntityDelta source = EntityDelta.fromBefore(before);
- final EntityDelta dest = EntityDelta.fromBefore(before);
+ final RawContact before = getRawContact(mContext, TEST_CONTACT_ID, TEST_PHONE_ID);
+ final RawContactDelta source = RawContactDelta.fromBefore(before);
+ final RawContactDelta dest = RawContactDelta.fromBefore(before);
final ValuesDelta child = source.getEntry(TEST_PHONE_ID);
child.markDeleted();
// Merge modified values and assert they match
- final EntityDelta merged = EntityDelta.mergeAfter(dest, source);
+ final RawContactDelta merged = RawContactDelta.mergeAfter(dest, source);
assertEquals("Unexpected change when merging", source, merged);
}
@@ -200,13 +201,13 @@
}
/**
- * Test that {@link EntityDelta#buildDiff(ArrayList)} is correctly built for
+ * Test that {@link RawContactDelta#buildDiff(ArrayList)} is correctly built for
* insert, update, and delete cases. This only tests a subset of possible
* {@link Data} row changes.
*/
public void testEntityDiffNone() {
- final Entity before = getEntity(TEST_CONTACT_ID, TEST_PHONE_ID);
- final EntityDelta source = EntityDelta.fromBefore(before);
+ final RawContact before = getRawContact(mContext, TEST_CONTACT_ID, TEST_PHONE_ID);
+ final RawContactDelta source = RawContactDelta.fromBefore(before);
// Assert that writing unchanged produces few operations
final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
@@ -216,8 +217,8 @@
}
public void testEntityDiffNoneInsert() {
- final Entity before = getEntity(TEST_CONTACT_ID, TEST_PHONE_ID);
- final EntityDelta source = EntityDelta.fromBefore(before);
+ final RawContact before = getRawContact(mContext, TEST_CONTACT_ID, TEST_PHONE_ID);
+ final RawContactDelta source = RawContactDelta.fromBefore(before);
// Insert a new phone number
final ContentValues phone = new ContentValues();
@@ -253,8 +254,8 @@
}
public void testEntityDiffUpdateInsert() {
- final Entity before = getEntity(TEST_CONTACT_ID, TEST_PHONE_ID);
- final EntityDelta source = EntityDelta.fromBefore(before);
+ final RawContact before = getRawContact(mContext, TEST_CONTACT_ID, TEST_PHONE_ID);
+ final RawContactDelta source = RawContactDelta.fromBefore(before);
// Update parent contact values
source.getValues().put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DISABLED);
@@ -298,8 +299,8 @@
}
public void testEntityDiffNoneUpdate() {
- final Entity before = getEntity(TEST_CONTACT_ID, TEST_PHONE_ID);
- final EntityDelta source = EntityDelta.fromBefore(before);
+ final RawContact before = getRawContact(mContext, TEST_CONTACT_ID, TEST_PHONE_ID);
+ final RawContactDelta source = RawContactDelta.fromBefore(before);
// Update existing phone number
final ValuesDelta child = source.getEntry(TEST_PHONE_ID);
@@ -332,8 +333,8 @@
}
public void testEntityDiffDelete() {
- final Entity before = getEntity(TEST_CONTACT_ID, TEST_PHONE_ID);
- final EntityDelta source = EntityDelta.fromBefore(before);
+ final RawContact before = getRawContact(mContext, TEST_CONTACT_ID, TEST_PHONE_ID);
+ final RawContactDelta source = RawContactDelta.fromBefore(before);
// Delete entire entity
source.getValues().markDeleted();
@@ -361,7 +362,7 @@
after.put(RawContacts.SEND_TO_VOICEMAIL, 1);
final ValuesDelta values = ValuesDelta.fromAfter(after);
- final EntityDelta source = new EntityDelta(values);
+ final RawContactDelta source = new RawContactDelta(values);
// Assert two operations: delete Contact and enforce version
final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
@@ -382,7 +383,7 @@
after.put(RawContacts.SEND_TO_VOICEMAIL, 1);
final ValuesDelta values = ValuesDelta.fromAfter(after);
- final EntityDelta source = new EntityDelta(values);
+ final RawContactDelta source = new RawContactDelta(values);
// Insert a new phone number
final ContentValues phone = new ContentValues();
diff --git a/tests/src/com/android/contacts/EntityModifierTests.java b/tests/src/com/android/contacts/RawContactModifierTests.java
similarity index 80%
rename from tests/src/com/android/contacts/EntityModifierTests.java
rename to tests/src/com/android/contacts/RawContactModifierTests.java
index df4934a..9254a7e 100644
--- a/tests/src/com/android/contacts/EntityModifierTests.java
+++ b/tests/src/com/android/contacts/RawContactModifierTests.java
@@ -20,24 +20,8 @@
import static android.content.ContentProviderOperation.TYPE_INSERT;
import static android.content.ContentProviderOperation.TYPE_UPDATE;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountType.EditType;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.DataKind;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.model.EntityDeltaList;
-import com.android.contacts.model.EntityModifier;
-import com.android.contacts.model.ExchangeAccountType;
-import com.android.contacts.model.GoogleAccountType;
-import com.android.contacts.tests.mocks.ContactsMockContext;
-import com.android.contacts.tests.mocks.MockAccountTypeManager;
-import com.android.contacts.tests.mocks.MockContentProvider;
-import com.google.android.collect.Lists;
-
import android.content.ContentProviderOperation;
import android.content.ContentValues;
-import android.content.Entity;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
@@ -54,15 +38,31 @@
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.RawContact;
+import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.model.RawContactDelta.ValuesDelta;
+import com.android.contacts.model.RawContactDeltaList;
+import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountType.EditType;
+import com.android.contacts.model.account.ExchangeAccountType;
+import com.android.contacts.model.account.GoogleAccountType;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.contacts.tests.mocks.ContactsMockContext;
+import com.android.contacts.tests.mocks.MockAccountTypeManager;
+import com.android.contacts.tests.mocks.MockContentProvider;
+import com.google.common.collect.Lists;
+
import java.util.ArrayList;
import java.util.List;
/**
- * Tests for {@link EntityModifier} to verify that {@link AccountType}
+ * Tests for {@link RawContactModifier} to verify that {@link AccountType}
* constraints are being enforced correctly.
*/
@LargeTest
-public class EntityModifierTests extends AndroidTestCase {
+public class RawContactModifierTests extends AndroidTestCase {
public static final String TAG = "EntityModifierTests";
public static final long VER_FIRST = 100;
@@ -168,9 +168,9 @@
}
/**
- * Build an {@link Entity} with the requested set of phone numbers.
+ * Build an {@link RawContact} with the requested set of phone numbers.
*/
- protected EntityDelta getEntity(Long existingId, ContentValues... entries) {
+ protected RawContactDelta getRawContact(Long existingId, ContentValues... entries) {
final ContentValues contact = new ContentValues();
if (existingId != null) {
contact.put(RawContacts._ID, existingId);
@@ -178,11 +178,11 @@
contact.put(RawContacts.ACCOUNT_NAME, TEST_ACCOUNT_NAME);
contact.put(RawContacts.ACCOUNT_TYPE, TEST_ACCOUNT_TYPE);
- final Entity before = new Entity(contact);
+ final RawContact before = new RawContact(mContext, contact);
for (ContentValues values : entries) {
- before.addSubValue(Data.CONTENT_URI, values);
+ before.addDataItemValues(values);
}
- return EntityDelta.fromBefore(before);
+ return RawContactDelta.fromBefore(before);
}
/**
@@ -201,116 +201,116 @@
/**
* Insert various rows to test
- * {@link EntityModifier#getValidTypes(EntityDelta, DataKind, EditType)}
+ * {@link RawContactModifier#getValidTypes(RawContactDelta, DataKind, EditType)}
*/
public void testValidTypes() {
// Build a source and pull specific types
final AccountType source = getAccountType();
final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
- final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
- final EditType typeWork = EntityModifier.getType(kindPhone, Phone.TYPE_WORK);
- final EditType typeOther = EntityModifier.getType(kindPhone, Phone.TYPE_OTHER);
+ final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
+ final EditType typeWork = RawContactModifier.getType(kindPhone, Phone.TYPE_WORK);
+ final EditType typeOther = RawContactModifier.getType(kindPhone, Phone.TYPE_OTHER);
List<EditType> validTypes;
// Add first home, first work
- final EntityDelta state = getEntity(TEST_ID);
- EntityModifier.insertChild(state, kindPhone, typeHome);
- EntityModifier.insertChild(state, kindPhone, typeWork);
+ final RawContactDelta state = getRawContact(TEST_ID);
+ RawContactModifier.insertChild(state, kindPhone, typeHome);
+ RawContactModifier.insertChild(state, kindPhone, typeWork);
// Expecting home, other
- validTypes = EntityModifier.getValidTypes(state, kindPhone, null);
+ validTypes = RawContactModifier.getValidTypes(state, kindPhone, null);
assertContains(validTypes, typeHome);
assertNotContains(validTypes, typeWork);
assertContains(validTypes, typeOther);
// Add second home
- EntityModifier.insertChild(state, kindPhone, typeHome);
+ RawContactModifier.insertChild(state, kindPhone, typeHome);
// Expecting other
- validTypes = EntityModifier.getValidTypes(state, kindPhone, null);
+ validTypes = RawContactModifier.getValidTypes(state, kindPhone, null);
assertNotContains(validTypes, typeHome);
assertNotContains(validTypes, typeWork);
assertContains(validTypes, typeOther);
// Add third and fourth home (invalid, but possible)
- EntityModifier.insertChild(state, kindPhone, typeHome);
- EntityModifier.insertChild(state, kindPhone, typeHome);
+ RawContactModifier.insertChild(state, kindPhone, typeHome);
+ RawContactModifier.insertChild(state, kindPhone, typeHome);
// Expecting none
- validTypes = EntityModifier.getValidTypes(state, kindPhone, null);
+ validTypes = RawContactModifier.getValidTypes(state, kindPhone, null);
assertNotContains(validTypes, typeHome);
assertNotContains(validTypes, typeWork);
assertNotContains(validTypes, typeOther);
}
/**
- * Test {@link EntityModifier#canInsert(EntityDelta, DataKind)} by
+ * Test {@link RawContactModifier#canInsert(RawContactDelta, DataKind)} by
* inserting various rows.
*/
public void testCanInsert() {
// Build a source and pull specific types
final AccountType source = getAccountType();
final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
- final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
- final EditType typeWork = EntityModifier.getType(kindPhone, Phone.TYPE_WORK);
- final EditType typeOther = EntityModifier.getType(kindPhone, Phone.TYPE_OTHER);
+ final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
+ final EditType typeWork = RawContactModifier.getType(kindPhone, Phone.TYPE_WORK);
+ final EditType typeOther = RawContactModifier.getType(kindPhone, Phone.TYPE_OTHER);
// Add first home, first work
- final EntityDelta state = getEntity(TEST_ID);
- EntityModifier.insertChild(state, kindPhone, typeHome);
- EntityModifier.insertChild(state, kindPhone, typeWork);
- assertTrue("Unable to insert", EntityModifier.canInsert(state, kindPhone));
+ final RawContactDelta state = getRawContact(TEST_ID);
+ RawContactModifier.insertChild(state, kindPhone, typeHome);
+ RawContactModifier.insertChild(state, kindPhone, typeWork);
+ assertTrue("Unable to insert", RawContactModifier.canInsert(state, kindPhone));
// Add two other, which puts us just under "5" overall limit
- EntityModifier.insertChild(state, kindPhone, typeOther);
- EntityModifier.insertChild(state, kindPhone, typeOther);
- assertTrue("Unable to insert", EntityModifier.canInsert(state, kindPhone));
+ RawContactModifier.insertChild(state, kindPhone, typeOther);
+ RawContactModifier.insertChild(state, kindPhone, typeOther);
+ assertTrue("Unable to insert", RawContactModifier.canInsert(state, kindPhone));
// Add second home, which should push to snug limit
- EntityModifier.insertChild(state, kindPhone, typeHome);
- assertFalse("Able to insert", EntityModifier.canInsert(state, kindPhone));
+ RawContactModifier.insertChild(state, kindPhone, typeHome);
+ assertFalse("Able to insert", RawContactModifier.canInsert(state, kindPhone));
}
/**
* Test
- * {@link EntityModifier#getBestValidType(EntityDelta, DataKind, boolean, int)}
+ * {@link RawContactModifier#getBestValidType(RawContactDelta, DataKind, boolean, int)}
* by asserting expected best options in various states.
*/
public void testBestValidType() {
// Build a source and pull specific types
final AccountType source = getAccountType();
final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
- final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
- final EditType typeWork = EntityModifier.getType(kindPhone, Phone.TYPE_WORK);
- final EditType typeFaxWork = EntityModifier.getType(kindPhone, Phone.TYPE_FAX_WORK);
- final EditType typeOther = EntityModifier.getType(kindPhone, Phone.TYPE_OTHER);
+ final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
+ final EditType typeWork = RawContactModifier.getType(kindPhone, Phone.TYPE_WORK);
+ final EditType typeFaxWork = RawContactModifier.getType(kindPhone, Phone.TYPE_FAX_WORK);
+ final EditType typeOther = RawContactModifier.getType(kindPhone, Phone.TYPE_OTHER);
EditType suggested;
// Default suggestion should be home
- final EntityDelta state = getEntity(TEST_ID);
- suggested = EntityModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE);
+ final RawContactDelta state = getRawContact(TEST_ID);
+ suggested = RawContactModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE);
assertEquals("Unexpected suggestion", typeHome, suggested);
// Add first home, should now suggest work
- EntityModifier.insertChild(state, kindPhone, typeHome);
- suggested = EntityModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE);
+ RawContactModifier.insertChild(state, kindPhone, typeHome);
+ suggested = RawContactModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE);
assertEquals("Unexpected suggestion", typeWork, suggested);
// Add work fax, should still suggest work
- EntityModifier.insertChild(state, kindPhone, typeFaxWork);
- suggested = EntityModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE);
+ RawContactModifier.insertChild(state, kindPhone, typeFaxWork);
+ suggested = RawContactModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE);
assertEquals("Unexpected suggestion", typeWork, suggested);
// Add other, should still suggest work
- EntityModifier.insertChild(state, kindPhone, typeOther);
- suggested = EntityModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE);
+ RawContactModifier.insertChild(state, kindPhone, typeOther);
+ suggested = RawContactModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE);
assertEquals("Unexpected suggestion", typeWork, suggested);
// Add work, now should suggest other
- EntityModifier.insertChild(state, kindPhone, typeWork);
- suggested = EntityModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE);
+ RawContactModifier.insertChild(state, kindPhone, typeWork);
+ suggested = RawContactModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE);
assertEquals("Unexpected suggestion", typeOther, suggested);
}
@@ -322,34 +322,34 @@
final ContentValues after = new ContentValues();
final ValuesDelta values = ValuesDelta.fromAfter(after);
- assertTrue("Expected empty", EntityModifier.isEmpty(values, kindPhone));
+ assertTrue("Expected empty", RawContactModifier.isEmpty(values, kindPhone));
}
public void testIsEmptyDirectFields() {
final AccountType source = getAccountType();
final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
- final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
+ final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
// Test row that has type values, but core fields are empty
- final EntityDelta state = getEntity(TEST_ID);
- final ValuesDelta values = EntityModifier.insertChild(state, kindPhone, typeHome);
+ final RawContactDelta state = getRawContact(TEST_ID);
+ final ValuesDelta values = RawContactModifier.insertChild(state, kindPhone, typeHome);
- assertTrue("Expected empty", EntityModifier.isEmpty(values, kindPhone));
+ assertTrue("Expected empty", RawContactModifier.isEmpty(values, kindPhone));
// Insert some data to trigger non-empty state
values.put(Phone.NUMBER, TEST_PHONE);
- assertFalse("Expected non-empty", EntityModifier.isEmpty(values, kindPhone));
+ assertFalse("Expected non-empty", RawContactModifier.isEmpty(values, kindPhone));
}
public void testTrimEmptySingle() {
final AccountType source = getAccountType();
final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
- final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
+ final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
// Test row that has type values, but core fields are empty
- final EntityDelta state = getEntity(TEST_ID);
- EntityModifier.insertChild(state, kindPhone, typeHome);
+ final RawContactDelta state = getRawContact(TEST_ID);
+ RawContactModifier.insertChild(state, kindPhone, typeHome);
// Build diff, expecting insert for data row and update enforcement
final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
@@ -372,7 +372,7 @@
}
// Trim empty rows and try again, expecting delete of overall contact
- EntityModifier.trimEmpty(state, source);
+ RawContactModifier.trimEmpty(state, source);
diff.clear();
state.buildDiff(diff);
assertEquals("Unexpected operations", 1, diff.size());
@@ -386,63 +386,65 @@
public void testTrimEmptySpaces() {
final AccountType source = getAccountType();
final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
- final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
+ final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
// Test row that has type values, but values are spaces
- final EntityDelta state = EntityDeltaListTests.buildBeforeEntity(TEST_ID, VER_FIRST);
- final ValuesDelta values = EntityModifier.insertChild(state, kindPhone, typeHome);
+ final RawContactDelta state = RawContactDeltaListTests.buildBeforeEntity(mContext, TEST_ID,
+ VER_FIRST);
+ final ValuesDelta values = RawContactModifier.insertChild(state, kindPhone, typeHome);
values.put(Phone.NUMBER, " ");
// Build diff, expecting insert for data row and update enforcement
- EntityDeltaListTests.assertDiffPattern(state,
- EntityDeltaListTests.buildAssertVersion(VER_FIRST),
- EntityDeltaListTests.buildUpdateAggregationSuspended(),
- EntityDeltaListTests.buildOper(Data.CONTENT_URI, TYPE_INSERT,
- EntityDeltaListTests.buildDataInsert(values, TEST_ID)),
- EntityDeltaListTests.buildUpdateAggregationDefault());
+ RawContactDeltaListTests.assertDiffPattern(state,
+ RawContactDeltaListTests.buildAssertVersion(VER_FIRST),
+ RawContactDeltaListTests.buildUpdateAggregationSuspended(),
+ RawContactDeltaListTests.buildOper(Data.CONTENT_URI, TYPE_INSERT,
+ RawContactDeltaListTests.buildDataInsert(values, TEST_ID)),
+ RawContactDeltaListTests.buildUpdateAggregationDefault());
// Trim empty rows and try again, expecting delete of overall contact
- EntityModifier.trimEmpty(state, source);
- EntityDeltaListTests.assertDiffPattern(state,
- EntityDeltaListTests.buildAssertVersion(VER_FIRST),
- EntityDeltaListTests.buildDelete(RawContacts.CONTENT_URI));
+ RawContactModifier.trimEmpty(state, source);
+ RawContactDeltaListTests.assertDiffPattern(state,
+ RawContactDeltaListTests.buildAssertVersion(VER_FIRST),
+ RawContactDeltaListTests.buildDelete(RawContacts.CONTENT_URI));
}
public void testTrimLeaveValid() {
final AccountType source = getAccountType();
final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
- final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
+ final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
// Test row that has type values with valid number
- final EntityDelta state = EntityDeltaListTests.buildBeforeEntity(TEST_ID, VER_FIRST);
- final ValuesDelta values = EntityModifier.insertChild(state, kindPhone, typeHome);
+ final RawContactDelta state = RawContactDeltaListTests.buildBeforeEntity(mContext, TEST_ID,
+ VER_FIRST);
+ final ValuesDelta values = RawContactModifier.insertChild(state, kindPhone, typeHome);
values.put(Phone.NUMBER, TEST_PHONE);
// Build diff, expecting insert for data row and update enforcement
- EntityDeltaListTests.assertDiffPattern(state,
- EntityDeltaListTests.buildAssertVersion(VER_FIRST),
- EntityDeltaListTests.buildUpdateAggregationSuspended(),
- EntityDeltaListTests.buildOper(Data.CONTENT_URI, TYPE_INSERT,
- EntityDeltaListTests.buildDataInsert(values, TEST_ID)),
- EntityDeltaListTests.buildUpdateAggregationDefault());
+ RawContactDeltaListTests.assertDiffPattern(state,
+ RawContactDeltaListTests.buildAssertVersion(VER_FIRST),
+ RawContactDeltaListTests.buildUpdateAggregationSuspended(),
+ RawContactDeltaListTests.buildOper(Data.CONTENT_URI, TYPE_INSERT,
+ RawContactDeltaListTests.buildDataInsert(values, TEST_ID)),
+ RawContactDeltaListTests.buildUpdateAggregationDefault());
// Trim empty rows and try again, expecting no differences
- EntityModifier.trimEmpty(state, source);
- EntityDeltaListTests.assertDiffPattern(state,
- EntityDeltaListTests.buildAssertVersion(VER_FIRST),
- EntityDeltaListTests.buildUpdateAggregationSuspended(),
- EntityDeltaListTests.buildOper(Data.CONTENT_URI, TYPE_INSERT,
- EntityDeltaListTests.buildDataInsert(values, TEST_ID)),
- EntityDeltaListTests.buildUpdateAggregationDefault());
+ RawContactModifier.trimEmpty(state, source);
+ RawContactDeltaListTests.assertDiffPattern(state,
+ RawContactDeltaListTests.buildAssertVersion(VER_FIRST),
+ RawContactDeltaListTests.buildUpdateAggregationSuspended(),
+ RawContactDeltaListTests.buildOper(Data.CONTENT_URI, TYPE_INSERT,
+ RawContactDeltaListTests.buildDataInsert(values, TEST_ID)),
+ RawContactDeltaListTests.buildUpdateAggregationDefault());
}
public void testTrimEmptyUntouched() {
final AccountType source = getAccountType();
final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
- EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
+ RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
// Build "before" that has empty row
- final EntityDelta state = getEntity(TEST_ID);
+ final RawContactDelta state = getRawContact(TEST_ID);
final ContentValues before = new ContentValues();
before.put(Data._ID, TEST_ID);
before.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
@@ -454,7 +456,7 @@
assertEquals("Unexpected operations", 0, diff.size());
// Try trimming existing empty, which we shouldn't touch
- EntityModifier.trimEmpty(state, source);
+ RawContactModifier.trimEmpty(state, source);
diff.clear();
state.buildDiff(diff);
assertEquals("Unexpected operations", 0, diff.size());
@@ -463,7 +465,7 @@
public void testTrimEmptyAfterUpdate() {
final AccountType source = getAccountType();
final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
- final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
+ final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
// Build "before" that has row with some phone number
final ContentValues before = new ContentValues();
@@ -471,7 +473,7 @@
before.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
before.put(kindPhone.typeColumn, typeHome.rawValue);
before.put(Phone.NUMBER, TEST_PHONE);
- final EntityDelta state = getEntity(TEST_ID, before);
+ final RawContactDelta state = getRawContact(TEST_ID, before);
// Build diff, expecting no changes
final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
@@ -501,7 +503,7 @@
}
// Now run trim, which should turn that update into delete
- EntityModifier.trimEmpty(state, source);
+ RawContactModifier.trimEmpty(state, source);
diff.clear();
state.buildDiff(diff);
assertEquals("Unexpected operations", 1, diff.size());
@@ -516,11 +518,11 @@
final AccountType accountType = getAccountType();
final AccountTypeManager accountTypes = getAccountTypes(accountType);
final DataKind kindPhone = accountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
- EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
+ RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
// Try creating a contact without any child entries
- final EntityDelta state = getEntity(null);
- final EntityDeltaList set = EntityDeltaList.fromSingle(state);
+ final RawContactDelta state = getRawContact(null);
+ final RawContactDeltaList set = RawContactDeltaList.fromSingle(state);
// Build diff, expecting single insert
final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
@@ -533,7 +535,7 @@
}
// Trim empty rows and try again, expecting no insert
- EntityModifier.trimEmpty(set, accountTypes);
+ RawContactModifier.trimEmpty(set, accountTypes);
diff.clear();
state.buildDiff(diff);
assertEquals("Unexpected operations", 0, diff.size());
@@ -543,12 +545,12 @@
final AccountType accountType = getAccountType();
final AccountTypeManager accountTypes = getAccountTypes(accountType);
final DataKind kindPhone = accountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
- final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
+ final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
// Try creating a contact with single empty entry
- final EntityDelta state = getEntity(null);
- EntityModifier.insertChild(state, kindPhone, typeHome);
- final EntityDeltaList set = EntityDeltaList.fromSingle(state);
+ final RawContactDelta state = getRawContact(null);
+ RawContactModifier.insertChild(state, kindPhone, typeHome);
+ final RawContactDeltaList set = RawContactDeltaList.fromSingle(state);
// Build diff, expecting two insert operations
final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
@@ -566,7 +568,7 @@
}
// Trim empty rows and try again, expecting silence
- EntityModifier.trimEmpty(set, accountTypes);
+ RawContactModifier.trimEmpty(set, accountTypes);
diff.clear();
state.buildDiff(diff);
assertEquals("Unexpected operations", 0, diff.size());
@@ -576,7 +578,7 @@
final AccountType accountType = getAccountType();
final AccountTypeManager accountTypes = getAccountTypes(accountType);
final DataKind kindPhone = accountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
- final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
+ final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
// Build "before" with two phone numbers
final ContentValues first = new ContentValues();
@@ -591,8 +593,8 @@
second.put(kindPhone.typeColumn, typeHome.rawValue);
second.put(Phone.NUMBER, TEST_PHONE);
- final EntityDelta state = getEntity(TEST_ID, first, second);
- final EntityDeltaList set = EntityDeltaList.fromSingle(state);
+ final RawContactDelta state = getRawContact(TEST_ID, first, second);
+ final RawContactDeltaList set = RawContactDeltaList.fromSingle(state);
// Build diff, expecting no changes
final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
@@ -622,7 +624,7 @@
}
// Now run trim, which should turn that update into delete
- EntityModifier.trimEmpty(set, accountTypes);
+ RawContactModifier.trimEmpty(set, accountTypes);
diff.clear();
state.buildDiff(diff);
assertEquals("Unexpected operations", 3, diff.size());
@@ -647,7 +649,7 @@
final AccountType accountType = getAccountType();
final AccountTypeManager accountTypes = getAccountTypes(accountType);
final DataKind kindPhone = accountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
- final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
+ final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
// Build "before" with two phone numbers
final ContentValues first = new ContentValues();
@@ -656,8 +658,8 @@
first.put(kindPhone.typeColumn, typeHome.rawValue);
first.put(Phone.NUMBER, TEST_PHONE);
- final EntityDelta state = getEntity(TEST_ID, first);
- final EntityDeltaList set = EntityDeltaList.fromSingle(state);
+ final RawContactDelta state = getRawContact(TEST_ID, first);
+ final RawContactDeltaList set = RawContactDeltaList.fromSingle(state);
// Build diff, expecting no changes
final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
@@ -687,7 +689,7 @@
}
// Now run trim, which should turn into deleting the whole contact
- EntityModifier.trimEmpty(set, accountTypes);
+ RawContactModifier.trimEmpty(set, accountTypes);
diff.clear();
state.buildDiff(diff);
assertEquals("Unexpected operations", 1, diff.size());
@@ -708,10 +710,10 @@
first.put(StructuredName.GIVEN_NAME, TEST_NAME);
// Parse extras, making sure we keep single name
- final EntityDelta state = getEntity(TEST_ID, first);
+ final RawContactDelta state = getRawContact(TEST_ID, first);
final Bundle extras = new Bundle();
extras.putString(Insert.NAME, TEST_NAME2);
- EntityModifier.parseExtras(mContext, accountType, state, extras);
+ RawContactModifier.parseExtras(mContext, accountType, state, extras);
final int nameCount = state.getMimeEntriesCount(StructuredName.CONTENT_ITEM_TYPE, true);
assertEquals("Unexpected names", 1, nameCount);
@@ -726,7 +728,7 @@
first.put(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
first.put(Im.DATA, TEST_IM);
- final EntityDelta state = getEntity(TEST_ID, first);
+ final RawContactDelta state = getRawContact(TEST_ID, first);
final int beforeCount = state.getMimeEntries(Im.CONTENT_ITEM_TYPE).size();
// We should ignore data that doesn't fit account type rules, since account type
@@ -734,7 +736,7 @@
final Bundle extras = new Bundle();
extras.putInt(Insert.IM_PROTOCOL, Im.PROTOCOL_GOOGLE_TALK);
extras.putString(Insert.IM_HANDLE, TEST_IM);
- EntityModifier.parseExtras(mContext, accountType, state, extras);
+ RawContactModifier.parseExtras(mContext, accountType, state, extras);
final int afterCount = state.getMimeEntries(Im.CONTENT_ITEM_TYPE).size();
assertEquals("Broke account type rules", beforeCount, afterCount);
@@ -742,12 +744,12 @@
public void testParseExtrasIgnoreUnhandled() {
final AccountType accountType = getAccountType();
- final EntityDelta state = getEntity(TEST_ID);
+ final RawContactDelta state = getRawContact(TEST_ID);
// We should silently ignore types unsupported by account type
final Bundle extras = new Bundle();
extras.putString(Insert.POSTAL, TEST_POSTAL);
- EntityModifier.parseExtras(mContext, accountType, state, extras);
+ RawContactModifier.parseExtras(mContext, accountType, state, extras);
assertNull("Broke accoun type rules",
state.getMimeEntries(StructuredPostal.CONTENT_ITEM_TYPE));
@@ -755,12 +757,12 @@
public void testParseExtrasJobTitle() {
final AccountType accountType = getAccountType();
- final EntityDelta state = getEntity(TEST_ID);
+ final RawContactDelta state = getRawContact(TEST_ID);
// Make sure that we create partial Organizations
final Bundle extras = new Bundle();
extras.putString(Insert.JOB_TITLE, TEST_NAME);
- EntityModifier.parseExtras(mContext, accountType, state, extras);
+ RawContactModifier.parseExtras(mContext, accountType, state, extras);
final int count = state.getMimeEntries(Organization.CONTENT_ITEM_TYPE).size();
assertEquals("Expected to create organization", 1, count);
@@ -773,7 +775,7 @@
ContactsMockContext context = new ContactsMockContext(getContext());
- EntityDelta oldState = new EntityDelta();
+ RawContactDelta oldState = new RawContactDelta();
ContentValues mockNameValues = new ContentValues();
mockNameValues.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
mockNameValues.put(StructuredName.PREFIX, "prefix");
@@ -786,8 +788,8 @@
mockNameValues.put(StructuredName.PHONETIC_GIVEN_NAME, "PHONETIC_GIVEN");
oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
- EntityDelta newState = new EntityDelta();
- EntityModifier.migrateStructuredName(context, oldState, newState, kind);
+ RawContactDelta newState = new RawContactDelta();
+ RawContactModifier.migrateStructuredName(context, oldState, newState, kind);
List<ValuesDelta> list = newState.getMimeEntries(StructuredName.CONTENT_ITEM_TYPE);
assertEquals(1, list.size());
@@ -824,14 +826,14 @@
StructuredName.MIDDLE_NAME, StructuredName.FAMILY_NAME,
StructuredName.SUFFIX);
- EntityDelta oldState = new EntityDelta();
+ RawContactDelta oldState = new RawContactDelta();
ContentValues mockNameValues = new ContentValues();
mockNameValues.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
mockNameValues.put(StructuredName.DISPLAY_NAME, inputDisplayName);
oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
- EntityDelta newState = new EntityDelta();
- EntityModifier.migrateStructuredName(context, oldState, newState, kind);
+ RawContactDelta newState = new RawContactDelta();
+ RawContactModifier.migrateStructuredName(context, oldState, newState, kind);
List<ValuesDelta> list = newState.getMimeEntries(StructuredName.CONTENT_ITEM_TYPE);
assertEquals(1, list.size());
@@ -866,7 +868,7 @@
.returnRow("prefix given middle family suffix")
.withProjection(StructuredName.DISPLAY_NAME);
- EntityDelta oldState = new EntityDelta();
+ RawContactDelta oldState = new RawContactDelta();
ContentValues mockNameValues = new ContentValues();
mockNameValues.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
mockNameValues.put(StructuredName.PREFIX, "prefix");
@@ -876,8 +878,8 @@
mockNameValues.put(StructuredName.SUFFIX, "suffix");
oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
- EntityDelta newState = new EntityDelta();
- EntityModifier.migrateStructuredName(context, oldState, newState, kind);
+ RawContactDelta newState = new RawContactDelta();
+ RawContactModifier.migrateStructuredName(context, oldState, newState, kind);
List<ValuesDelta> list = newState.getMimeEntries(StructuredName.CONTENT_ITEM_TYPE);
assertNotNull(list);
@@ -892,14 +894,14 @@
AccountType newAccountType = new ExchangeAccountType(getContext(), "");
DataKind kind = newAccountType.getKindForMimetype(StructuredPostal.CONTENT_ITEM_TYPE);
- EntityDelta oldState = new EntityDelta();
+ RawContactDelta oldState = new RawContactDelta();
ContentValues mockNameValues = new ContentValues();
mockNameValues.put(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE);
mockNameValues.put(StructuredPostal.FORMATTED_ADDRESS, "formatted_address");
oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
- EntityDelta newState = new EntityDelta();
- EntityModifier.migratePostal(oldState, newState, kind);
+ RawContactDelta newState = new RawContactDelta();
+ RawContactModifier.migratePostal(oldState, newState, kind);
List<ValuesDelta> list = newState.getMimeEntries(StructuredPostal.CONTENT_ITEM_TYPE);
assertNotNull(list);
@@ -915,7 +917,7 @@
AccountType newAccountType = new GoogleAccountType(getContext(), "");
DataKind kind = newAccountType.getKindForMimetype(StructuredPostal.CONTENT_ITEM_TYPE);
- EntityDelta oldState = new EntityDelta();
+ RawContactDelta oldState = new RawContactDelta();
ContentValues mockNameValues = new ContentValues();
mockNameValues.put(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE);
mockNameValues.put(StructuredPostal.COUNTRY, "country");
@@ -925,8 +927,8 @@
mockNameValues.put(StructuredPostal.STREET, "street");
oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
- EntityDelta newState = new EntityDelta();
- EntityModifier.migratePostal(oldState, newState, kind);
+ RawContactDelta newState = new RawContactDelta();
+ RawContactModifier.migratePostal(oldState, newState, kind);
List<ValuesDelta> list = newState.getMimeEntries(StructuredPostal.CONTENT_ITEM_TYPE);
assertNotNull(list);
@@ -957,15 +959,15 @@
private void testMigrateEventCommon(AccountType oldAccountType, AccountType newAccountType) {
DataKind kind = newAccountType.getKindForMimetype(Event.CONTENT_ITEM_TYPE);
- EntityDelta oldState = new EntityDelta();
+ RawContactDelta oldState = new RawContactDelta();
ContentValues mockNameValues = new ContentValues();
mockNameValues.put(Data.MIMETYPE, Event.CONTENT_ITEM_TYPE);
mockNameValues.put(Event.START_DATE, "1972-02-08");
mockNameValues.put(Event.TYPE, Event.TYPE_BIRTHDAY);
oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
- EntityDelta newState = new EntityDelta();
- EntityModifier.migrateEvent(oldState, newState, kind, 1990);
+ RawContactDelta newState = new RawContactDelta();
+ RawContactModifier.migrateEvent(oldState, newState, kind, 1990);
List<ValuesDelta> list = newState.getMimeEntries(Event.CONTENT_ITEM_TYPE);
assertNotNull(list);
@@ -981,7 +983,7 @@
AccountType newAccountType = new ExchangeAccountType(getContext(), "");
DataKind kind = newAccountType.getKindForMimetype(Event.CONTENT_ITEM_TYPE);
- EntityDelta oldState = new EntityDelta();
+ RawContactDelta oldState = new RawContactDelta();
ContentValues mockNameValues = new ContentValues();
mockNameValues.put(Data.MIMETYPE, Event.CONTENT_ITEM_TYPE);
// No year format is not supported by Exchange.
@@ -995,8 +997,8 @@
mockNameValues.put(Event.TYPE, Event.TYPE_ANNIVERSARY);
oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
- EntityDelta newState = new EntityDelta();
- EntityModifier.migrateEvent(oldState, newState, kind, 1990);
+ RawContactDelta newState = new RawContactDelta();
+ RawContactModifier.migrateEvent(oldState, newState, kind, 1990);
List<ValuesDelta> list = newState.getMimeEntries(Event.CONTENT_ITEM_TYPE);
assertNotNull(list);
@@ -1013,7 +1015,7 @@
AccountType newAccountType = new ExchangeAccountType(getContext(), "");
DataKind kind = newAccountType.getKindForMimetype(Email.CONTENT_ITEM_TYPE);
- EntityDelta oldState = new EntityDelta();
+ RawContactDelta oldState = new RawContactDelta();
ContentValues mockNameValues = new ContentValues();
mockNameValues.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
mockNameValues.put(Email.TYPE, Email.TYPE_CUSTOM);
@@ -1037,8 +1039,8 @@
mockNameValues.put(Email.ADDRESS, "address4");
oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
- EntityDelta newState = new EntityDelta();
- EntityModifier.migrateGenericWithTypeColumn(oldState, newState, kind);
+ RawContactDelta newState = new RawContactDelta();
+ RawContactModifier.migrateGenericWithTypeColumn(oldState, newState, kind);
List<ValuesDelta> list = newState.getMimeEntries(Email.CONTENT_ITEM_TYPE);
assertNotNull(list);
@@ -1063,7 +1065,7 @@
AccountType newAccountType = new ExchangeAccountType(getContext(), "");
DataKind kind = newAccountType.getKindForMimetype(Im.CONTENT_ITEM_TYPE);
- EntityDelta oldState = new EntityDelta();
+ RawContactDelta oldState = new RawContactDelta();
ContentValues mockNameValues = new ContentValues();
mockNameValues.put(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
// Exchange doesn't support TYPE_HOME
@@ -1096,8 +1098,8 @@
mockNameValues.put(Im.DATA, "im4");
oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
- EntityDelta newState = new EntityDelta();
- EntityModifier.migrateGenericWithTypeColumn(oldState, newState, kind);
+ RawContactDelta newState = new RawContactDelta();
+ RawContactModifier.migrateGenericWithTypeColumn(oldState, newState, kind);
List<ValuesDelta> list = newState.getMimeEntries(Im.CONTENT_ITEM_TYPE);
assertNotNull(list);
@@ -1149,7 +1151,7 @@
// - "3" -- MOBILE
// - "4" -- WORK
- EntityDelta oldState = new EntityDelta();
+ RawContactDelta oldState = new RawContactDelta();
ContentValues mockNameValues = new ContentValues();
mockNameValues.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
mockNameValues.put(Phone.TYPE, Phone.TYPE_HOME);
@@ -1179,8 +1181,8 @@
mockNameValues.put(Phone.NUMBER, "5");
oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
- EntityDelta newState = new EntityDelta();
- EntityModifier.migrateGenericWithTypeColumn(oldState, newState, kind);
+ RawContactDelta newState = new RawContactDelta();
+ RawContactModifier.migrateGenericWithTypeColumn(oldState, newState, kind);
List<ValuesDelta> list = newState.getMimeEntries(Phone.CONTENT_ITEM_TYPE);
assertNotNull(list);
@@ -1208,15 +1210,15 @@
AccountType newAccountType = new ExchangeAccountType(getContext(), "");
DataKind kind = newAccountType.getKindForMimetype(Organization.CONTENT_ITEM_TYPE);
- EntityDelta oldState = new EntityDelta();
+ RawContactDelta oldState = new RawContactDelta();
ContentValues mockNameValues = new ContentValues();
mockNameValues.put(Data.MIMETYPE, Organization.CONTENT_ITEM_TYPE);
mockNameValues.put(Organization.COMPANY, "company1");
mockNameValues.put(Organization.DEPARTMENT, "department1");
oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
- EntityDelta newState = new EntityDelta();
- EntityModifier.migrateGenericWithoutTypeColumn(oldState, newState, kind);
+ RawContactDelta newState = new RawContactDelta();
+ RawContactModifier.migrateGenericWithoutTypeColumn(oldState, newState, kind);
List<ValuesDelta> list = newState.getMimeEntries(Organization.CONTENT_ITEM_TYPE);
assertNotNull(list);
diff --git a/tests/src/com/android/contacts/activities/PeopleActivityTest.java b/tests/src/com/android/contacts/activities/PeopleActivityTest.java
index ea7c3dc..11fccd1 100644
--- a/tests/src/com/android/contacts/activities/PeopleActivityTest.java
+++ b/tests/src/com/android/contacts/activities/PeopleActivityTest.java
@@ -16,25 +16,6 @@
package com.android.contacts.activities;
-import com.android.contacts.ContactPhotoManager;
-import com.android.contacts.ContactsApplication;
-import com.android.contacts.R;
-import com.android.contacts.detail.ContactDetailFragment;
-import com.android.contacts.interactions.TestLoaderManager;
-import com.android.contacts.list.ContactBrowseListFragment;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountWithDataSet;
-import com.android.contacts.model.BaseAccountType;
-import com.android.contacts.test.InjectedServices;
-import com.android.contacts.tests.mocks.ContactsMockContext;
-import com.android.contacts.tests.mocks.MockAccountTypeManager;
-import com.android.contacts.tests.mocks.MockContactPhotoManager;
-import com.android.contacts.tests.mocks.MockContentProvider;
-import com.android.contacts.tests.mocks.MockContentProvider.Query;
-import com.android.contacts.tests.mocks.MockSharedPreferences;
-import com.android.contacts.util.PhoneCapabilityTester;
-
import android.content.ContentValues;
import android.content.Intent;
import android.content.Loader;
@@ -51,6 +32,25 @@
import android.test.suitebuilder.annotation.SmallTest;
import android.widget.TextView;
+import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.ContactsApplication;
+import com.android.contacts.R;
+import com.android.contacts.detail.ContactDetailFragment;
+import com.android.contacts.interactions.TestLoaderManager;
+import com.android.contacts.list.ContactBrowseListFragment;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.model.account.BaseAccountType;
+import com.android.contacts.test.InjectedServices;
+import com.android.contacts.tests.mocks.ContactsMockContext;
+import com.android.contacts.tests.mocks.MockAccountTypeManager;
+import com.android.contacts.tests.mocks.MockContactPhotoManager;
+import com.android.contacts.tests.mocks.MockContentProvider;
+import com.android.contacts.tests.mocks.MockContentProvider.Query;
+import com.android.contacts.tests.mocks.MockSharedPreferences;
+import com.android.contacts.util.PhoneCapabilityTester;
+
/**
* This test is so outdated that it's disabled temporarily. TODO Update the test and re-enable it.
*
diff --git a/tests/src/com/android/contacts/calllog/CallLogAdapterTest.java b/tests/src/com/android/contacts/calllog/CallLogAdapterTest.java
index 8a98018..5bc31f9 100644
--- a/tests/src/com/android/contacts/calllog/CallLogAdapterTest.java
+++ b/tests/src/com/android/contacts/calllog/CallLogAdapterTest.java
@@ -16,14 +16,14 @@
package com.android.contacts.calllog;
-import com.google.common.collect.Lists;
-
import android.content.Context;
import android.database.MatrixCursor;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.view.View;
+import com.google.common.collect.Lists;
+
import java.util.List;
/**
diff --git a/tests/src/com/android/contacts/calllog/CallLogFragmentTest.java b/tests/src/com/android/contacts/calllog/CallLogFragmentTest.java
index 89c0a99..0eaca60 100644
--- a/tests/src/com/android/contacts/calllog/CallLogFragmentTest.java
+++ b/tests/src/com/android/contacts/calllog/CallLogFragmentTest.java
@@ -16,11 +16,6 @@
package com.android.contacts.calllog;
-import com.android.contacts.CallDetailActivity;
-import com.android.contacts.R;
-import com.android.contacts.test.FragmentTestActivity;
-import com.android.internal.telephony.CallerInfo;
-
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.ComponentName;
@@ -42,6 +37,11 @@
import android.view.View;
import android.widget.FrameLayout;
+import com.android.contacts.CallDetailActivity;
+import com.android.contacts.R;
+import com.android.contacts.test.FragmentTestActivity;
+import com.android.internal.telephony.CallerInfo;
+
import java.util.Date;
import java.util.Formatter;
import java.util.HashMap;
diff --git a/tests/src/com/android/contacts/calllog/CallLogGroupBuilderTest.java b/tests/src/com/android/contacts/calllog/CallLogGroupBuilderTest.java
index 24aa428..1fced0b 100644
--- a/tests/src/com/android/contacts/calllog/CallLogGroupBuilderTest.java
+++ b/tests/src/com/android/contacts/calllog/CallLogGroupBuilderTest.java
@@ -16,17 +16,19 @@
package com.android.contacts.calllog;
-import static com.google.android.collect.Lists.newArrayList;
+import static com.google.common.collect.Lists.newArrayList;
import android.database.MatrixCursor;
import android.provider.CallLog.Calls;
import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
import java.util.List;
/**
* Unit tests for {@link CallLogGroupBuilder}
*/
+@SmallTest
public class CallLogGroupBuilderTest extends AndroidTestCase {
/** A phone number for testing. */
private static final String TEST_NUMBER1 = "14125551234";
@@ -106,10 +108,9 @@
}
public void testAddGroups_Voicemail() {
- // Groups with one or more missed calls.
- assertCallsAreGrouped(Calls.VOICEMAIL_TYPE, Calls.MISSED_TYPE);
- assertCallsAreGrouped(Calls.VOICEMAIL_TYPE, Calls.MISSED_TYPE, Calls.MISSED_TYPE);
// Does not group with other types of calls, include voicemail themselves.
+ assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.MISSED_TYPE);
+ //assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.MISSED_TYPE, Calls.MISSED_TYPE);
assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.VOICEMAIL_TYPE);
assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.INCOMING_TYPE);
assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.OUTGOING_TYPE);
@@ -121,8 +122,8 @@
assertCallsAreGrouped(Calls.MISSED_TYPE, Calls.MISSED_TYPE, Calls.MISSED_TYPE);
// Does not group with other types of calls.
assertCallsAreNotGrouped(Calls.MISSED_TYPE, Calls.VOICEMAIL_TYPE);
- assertCallsAreNotGrouped(Calls.MISSED_TYPE, Calls.INCOMING_TYPE);
- assertCallsAreNotGrouped(Calls.MISSED_TYPE, Calls.OUTGOING_TYPE);
+ assertCallsAreGrouped(Calls.MISSED_TYPE, Calls.INCOMING_TYPE);
+ assertCallsAreGrouped(Calls.MISSED_TYPE, Calls.OUTGOING_TYPE);
}
public void testAddGroups_Incoming() {
@@ -131,9 +132,9 @@
assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE);
assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE);
assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE, Calls.INCOMING_TYPE);
+ assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.MISSED_TYPE);
// Does not group with voicemail and missed calls.
assertCallsAreNotGrouped(Calls.INCOMING_TYPE, Calls.VOICEMAIL_TYPE);
- assertCallsAreNotGrouped(Calls.INCOMING_TYPE, Calls.MISSED_TYPE);
}
public void testAddGroups_Outgoing() {
@@ -142,29 +143,28 @@
assertCallsAreGrouped(Calls.OUTGOING_TYPE, Calls.OUTGOING_TYPE);
assertCallsAreGrouped(Calls.OUTGOING_TYPE, Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE);
assertCallsAreGrouped(Calls.OUTGOING_TYPE, Calls.OUTGOING_TYPE, Calls.INCOMING_TYPE);
+ assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.MISSED_TYPE);
// Does not group with voicemail and missed calls.
assertCallsAreNotGrouped(Calls.INCOMING_TYPE, Calls.VOICEMAIL_TYPE);
- assertCallsAreNotGrouped(Calls.INCOMING_TYPE, Calls.MISSED_TYPE);
}
public void testAddGroups_Mixed() {
addMultipleOldCallLogEntries(TEST_NUMBER1,
Calls.VOICEMAIL_TYPE, // Stand-alone
- Calls.INCOMING_TYPE, // Group 1: 1-2
+ Calls.INCOMING_TYPE, // Group 1: 1-4
Calls.OUTGOING_TYPE,
- Calls.MISSED_TYPE, // Group 2: 3-4
+ Calls.MISSED_TYPE,
Calls.MISSED_TYPE,
Calls.VOICEMAIL_TYPE, // Stand-alone
Calls.INCOMING_TYPE, // Stand-alone
- Calls.VOICEMAIL_TYPE, // Group 3: 7-9
+ Calls.VOICEMAIL_TYPE, // Stand-alone
+ Calls.MISSED_TYPE, // Group 2: 8-10
Calls.MISSED_TYPE,
- Calls.MISSED_TYPE,
- Calls.OUTGOING_TYPE); // Stand-alone
+ Calls.OUTGOING_TYPE);
mBuilder.addGroups(mCursor);
- assertEquals(3, mFakeGroupCreator.groups.size());
- assertGroupIs(1, 2, false, mFakeGroupCreator.groups.get(0));
- assertGroupIs(3, 2, false, mFakeGroupCreator.groups.get(1));
- assertGroupIs(7, 3, false, mFakeGroupCreator.groups.get(2));
+ assertEquals(2, mFakeGroupCreator.groups.size());
+ assertGroupIs(1, 4, false, mFakeGroupCreator.groups.get(0));
+ assertGroupIs(8, 3, false, mFakeGroupCreator.groups.get(1));
}
public void testEqualPhoneNumbers() {
diff --git a/tests/src/com/android/contacts/calllog/CallLogListItemHelperTest.java b/tests/src/com/android/contacts/calllog/CallLogListItemHelperTest.java
index 0488044..a184f75 100644
--- a/tests/src/com/android/contacts/calllog/CallLogListItemHelperTest.java
+++ b/tests/src/com/android/contacts/calllog/CallLogListItemHelperTest.java
@@ -16,16 +16,16 @@
package com.android.contacts.calllog;
-import com.android.contacts.PhoneCallDetails;
-import com.android.contacts.PhoneCallDetailsHelper;
-import com.android.internal.telephony.CallerInfo;
-
import android.content.Context;
import android.content.res.Resources;
import android.provider.CallLog.Calls;
import android.test.AndroidTestCase;
import android.view.View;
+import com.android.contacts.PhoneCallDetails;
+import com.android.contacts.PhoneCallDetailsHelper;
+import com.android.internal.telephony.CallerInfo;
+
/**
* Unit tests for {@link CallLogListItemHelper}.
*/
diff --git a/tests/src/com/android/contacts/detail/ContactDetailDisplayUtilsTest.java b/tests/src/com/android/contacts/detail/ContactDetailDisplayUtilsTest.java
index 419cac8..07b3691 100644
--- a/tests/src/com/android/contacts/detail/ContactDetailDisplayUtilsTest.java
+++ b/tests/src/com/android/contacts/detail/ContactDetailDisplayUtilsTest.java
@@ -16,10 +16,6 @@
package com.android.contacts.detail;
-import com.android.contacts.R;
-import com.android.contacts.util.StreamItemEntry;
-import com.android.contacts.util.StreamItemEntryBuilder;
-
import android.content.Context;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
@@ -29,6 +25,10 @@
import android.view.View;
import android.widget.TextView;
+import com.android.contacts.R;
+import com.android.contacts.util.StreamItemEntry;
+import com.android.contacts.util.StreamItemEntryBuilder;
+
/**
* Unit tests for {@link ContactDetailDisplayUtils}.
*/
diff --git a/tests/src/com/android/contacts/detail/ContactDetailFragmentTests.java b/tests/src/com/android/contacts/detail/ContactDetailFragmentTests.java
index 02faa24..b1d1daa 100644
--- a/tests/src/com/android/contacts/detail/ContactDetailFragmentTests.java
+++ b/tests/src/com/android/contacts/detail/ContactDetailFragmentTests.java
@@ -16,8 +16,6 @@
package com.android.contacts.detail;
-import com.android.contacts.detail.ContactDetailFragment.DetailViewEntry;
-
import android.content.ContentValues;
import android.content.Intent;
import android.net.Uri;
@@ -26,6 +24,11 @@
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.contacts.detail.ContactDetailFragment.DetailViewEntry;
+import com.android.contacts.model.dataitem.DataItem;
+import com.android.contacts.model.dataitem.EmailDataItem;
+import com.android.contacts.model.dataitem.ImDataItem;
+
/**
* Tests for {@link ContactDetailFragment}.
*/
@@ -41,9 +44,10 @@
values.put(Im.TYPE, Im.TYPE_HOME);
values.put(Im.PROTOCOL, Im.PROTOCOL_GOOGLE_TALK);
values.put(Im.DATA, TEST_ADDRESS);
+ ImDataItem im = (ImDataItem) DataItem.createFrom(null, values);
DetailViewEntry entry = new ContactDetailFragment.DetailViewEntry();
- ContactDetailFragment.buildImActions(mContext, entry, values);
+ ContactDetailFragment.buildImActions(mContext, entry, im);
assertEquals(Intent.ACTION_SENDTO, entry.intent.getAction());
assertEquals("xmpp:" + TEST_ADDRESS + "?message", entry.intent.getData().toString());
@@ -58,9 +62,10 @@
values.put(Im.PROTOCOL, Im.PROTOCOL_GOOGLE_TALK);
values.put(Im.DATA, TEST_ADDRESS);
values.put(Im.CHAT_CAPABILITY, Im.CAPABILITY_HAS_VOICE | Im.CAPABILITY_HAS_VIDEO);
+ ImDataItem im = (ImDataItem) DataItem.createFrom(null, values);
DetailViewEntry entry = new ContactDetailFragment.DetailViewEntry();
- ContactDetailFragment.buildImActions(mContext, entry, values);
+ ContactDetailFragment.buildImActions(mContext, entry, im);
assertEquals(Intent.ACTION_SENDTO, entry.intent.getAction());
assertEquals("xmpp:" + TEST_ADDRESS + "?message", entry.intent.getData().toString());
@@ -77,9 +82,10 @@
values.put(Im.DATA, TEST_ADDRESS);
values.put(Im.CHAT_CAPABILITY, Im.CAPABILITY_HAS_VOICE | Im.CAPABILITY_HAS_VIDEO |
Im.CAPABILITY_HAS_VOICE);
+ ImDataItem im = (ImDataItem) DataItem.createFrom(null, values);
DetailViewEntry entry = new ContactDetailFragment.DetailViewEntry();
- ContactDetailFragment.buildImActions(mContext, entry, values);
+ ContactDetailFragment.buildImActions(mContext, entry, im);
assertEquals(Intent.ACTION_SENDTO, entry.intent.getAction());
assertEquals("xmpp:" + TEST_ADDRESS + "?message", entry.intent.getData().toString());
@@ -96,9 +102,10 @@
values.put(Im.PROTOCOL, Im.PROTOCOL_CUSTOM);
values.put(Im.CUSTOM_PROTOCOL, TEST_PROTOCOL);
values.put(Im.DATA, TEST_ADDRESS);
+ ImDataItem im = (ImDataItem) DataItem.createFrom(null, values);
DetailViewEntry entry = new ContactDetailFragment.DetailViewEntry();
- ContactDetailFragment.buildImActions(mContext, entry, values);
+ ContactDetailFragment.buildImActions(mContext, entry, im);
assertEquals(Intent.ACTION_SENDTO, entry.intent.getAction());
final Uri data = entry.intent.getData();
@@ -119,9 +126,11 @@
values.put(Email.DATA, TEST_ADDRESS);
values.put(Email.CHAT_CAPABILITY, Im.CAPABILITY_HAS_VOICE | Im.CAPABILITY_HAS_VIDEO |
Im.CAPABILITY_HAS_VOICE);
+ ImDataItem im = ImDataItem.createFromEmail(
+ (EmailDataItem) DataItem.createFrom(null, values));
DetailViewEntry entry = new ContactDetailFragment.DetailViewEntry();
- ContactDetailFragment.buildImActions(mContext, entry, values);
+ ContactDetailFragment.buildImActions(mContext, entry, im);
assertEquals(Intent.ACTION_SENDTO, entry.intent.getAction());
assertEquals("xmpp:" + TEST_ADDRESS + "?message", entry.intent.getData().toString());
diff --git a/tests/src/com/android/contacts/detail/StreamItemAdapterTest.java b/tests/src/com/android/contacts/detail/StreamItemAdapterTest.java
index cd2d6bf..7f1ee02 100644
--- a/tests/src/com/android/contacts/detail/StreamItemAdapterTest.java
+++ b/tests/src/com/android/contacts/detail/StreamItemAdapterTest.java
@@ -16,14 +16,14 @@
package com.android.contacts.detail;
-import com.android.contacts.util.StreamItemEntry;
-import com.android.contacts.util.StreamItemEntryBuilder;
-import com.google.common.collect.Lists;
-
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.view.View;
+import com.android.contacts.util.StreamItemEntry;
+import com.android.contacts.util.StreamItemEntryBuilder;
+import com.google.common.collect.Lists;
+
import java.util.ArrayList;
// TODO: We should have tests for action, but that requires a mock sync-adapter that specifies
diff --git a/tests/src/com/android/contacts/editor/ContactEditorUtilsTest.java b/tests/src/com/android/contacts/editor/ContactEditorUtilsTest.java
index 8007aee..9f2d49b 100644
--- a/tests/src/com/android/contacts/editor/ContactEditorUtilsTest.java
+++ b/tests/src/com/android/contacts/editor/ContactEditorUtilsTest.java
@@ -16,17 +16,15 @@
package com.android.contacts.editor;
-import com.android.contacts.editor.ContactEditorUtils;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountWithDataSet;
-import com.android.contacts.tests.mocks.MockAccountTypeManager;
-import com.google.android.collect.Sets;
-
-import android.content.Context;
import android.test.AndroidTestCase;
import android.test.MoreAsserts;
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.tests.mocks.MockAccountTypeManager;
+import com.google.common.collect.Sets;
+
import java.util.Collection;
import java.util.Set;
diff --git a/tests/src/com/android/contacts/format/TestTextWithHighlightingFactory.java b/tests/src/com/android/contacts/format/TestTextWithHighlightingFactory.java
index 2deaef3..9dbd364 100644
--- a/tests/src/com/android/contacts/format/TestTextWithHighlightingFactory.java
+++ b/tests/src/com/android/contacts/format/TestTextWithHighlightingFactory.java
@@ -16,15 +16,15 @@
package com.android.contacts.format;
-import com.android.contacts.widget.TextWithHighlighting;
-import com.android.contacts.widget.TextWithHighlightingFactory;
-
import android.database.CharArrayBuffer;
import android.graphics.Typeface;
import android.test.suitebuilder.annotation.SmallTest;
import android.text.SpannableStringBuilder;
import android.text.style.StyleSpan;
+import com.android.contacts.widget.TextWithHighlighting;
+import com.android.contacts.widget.TextWithHighlightingFactory;
+
/** A factory for {@link TextWithHighlighting} that wraps its parts in italics. */
@SmallTest
public final class TestTextWithHighlightingFactory implements TextWithHighlightingFactory {
@@ -46,4 +46,4 @@
public TextWithHighlighting createTextWithHighlighting() {
return new TestTextWithHighlighting();
}
-}
\ No newline at end of file
+}
diff --git a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
index b37d24f..fcbd83d 100644
--- a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
+++ b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
@@ -16,19 +16,6 @@
package com.android.contacts.interactions;
-import com.android.contacts.ContactsApplication;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.BaseAccountType;
-import com.android.contacts.test.FragmentTestActivity;
-import com.android.contacts.test.InjectedServices;
-import com.android.contacts.tests.mocks.ContactsMockContext;
-import com.android.contacts.tests.mocks.MockAccountTypeManager;
-import com.android.contacts.tests.mocks.MockContentProvider;
-import com.android.contacts.tests.mocks.MockContentProvider.Query;
-import com.android.contacts.util.IntegrationTestUtils;
-
import android.content.ContentUris;
import android.net.Uri;
import android.os.AsyncTask;
@@ -37,6 +24,19 @@
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.contacts.ContactsApplication;
+import com.android.contacts.R;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.BaseAccountType;
+import com.android.contacts.test.FragmentTestActivity;
+import com.android.contacts.test.InjectedServices;
+import com.android.contacts.tests.mocks.ContactsMockContext;
+import com.android.contacts.tests.mocks.MockAccountTypeManager;
+import com.android.contacts.tests.mocks.MockContentProvider;
+import com.android.contacts.tests.mocks.MockContentProvider.Query;
+import com.android.contacts.util.IntegrationTestUtils;
+
/**
* Tests for {@link ContactDeletionInteraction}.
*
diff --git a/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java b/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java
index 2da8859..a82e0f6 100644
--- a/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java
+++ b/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java
@@ -16,12 +16,6 @@
package com.android.contacts.interactions;
-import com.android.contacts.interactions.PhoneNumberInteraction.InteractionType;
-import com.android.contacts.interactions.PhoneNumberInteraction.PhoneItem;
-import com.android.contacts.tests.mocks.ContactsMockContext;
-import com.android.contacts.tests.mocks.MockContentProvider;
-import com.android.contacts.tests.mocks.MockContentProvider.Query;
-
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface.OnDismissListener;
@@ -36,6 +30,12 @@
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.contacts.interactions.PhoneNumberInteraction.InteractionType;
+import com.android.contacts.interactions.PhoneNumberInteraction.PhoneItem;
+import com.android.contacts.tests.mocks.ContactsMockContext;
+import com.android.contacts.tests.mocks.MockContentProvider;
+import com.android.contacts.tests.mocks.MockContentProvider.Query;
+
import java.util.ArrayList;
import java.util.List;
diff --git a/tests/src/com/android/contacts/list/ContactListItemViewTest.java b/tests/src/com/android/contacts/list/ContactListItemViewTest.java
index 82305d5..748876f 100644
--- a/tests/src/com/android/contacts/list/ContactListItemViewTest.java
+++ b/tests/src/com/android/contacts/list/ContactListItemViewTest.java
@@ -16,10 +16,6 @@
package com.android.contacts.list;
-import com.android.contacts.activities.PeopleActivity;
-import com.android.contacts.format.SpannedTestUtils;
-import com.android.contacts.util.IntegrationTestUtils;
-
import android.database.Cursor;
import android.database.MatrixCursor;
import android.provider.ContactsContract;
@@ -27,6 +23,10 @@
import android.test.suitebuilder.annotation.LargeTest;
import android.widget.TextView;
+import com.android.contacts.activities.PeopleActivity;
+import com.android.contacts.format.SpannedTestUtils;
+import com.android.contacts.util.IntegrationTestUtils;
+
/**
* Unit tests for {@link ContactListItemView}.
*
@@ -36,7 +36,7 @@
@LargeTest
public class ContactListItemViewTest extends ActivityInstrumentationTestCase2<PeopleActivity> {
/** The HTML code used to mark the start of the highlighted part. */
- private static final String START = "<font color =\"#99cc00\">";
+ private static final String START = "<font color =\"#33b5e5\">";
/** The HTML code used to mark the end of the highlighted part. */
private static final String END = "</font>";
diff --git a/tests/src/com/android/contacts/model/AccountTypeManagerTest.java b/tests/src/com/android/contacts/model/AccountTypeManagerTest.java
index 6f5bbf2..c8db85e 100644
--- a/tests/src/com/android/contacts/model/AccountTypeManagerTest.java
+++ b/tests/src/com/android/contacts/model/AccountTypeManagerTest.java
@@ -16,13 +16,16 @@
package com.android.contacts.model;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Maps;
-
import android.content.Context;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountTypeWithDataSet;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
diff --git a/tests/src/com/android/contacts/model/AccountWithDataSetTest.java b/tests/src/com/android/contacts/model/AccountWithDataSetTest.java
index 27c106e..1818c38 100644
--- a/tests/src/com/android/contacts/model/AccountWithDataSetTest.java
+++ b/tests/src/com/android/contacts/model/AccountWithDataSetTest.java
@@ -16,13 +16,14 @@
package com.android.contacts.model;
-import com.google.common.collect.Lists;
-
import android.os.Bundle;
import android.test.AndroidTestCase;
import android.test.MoreAsserts;
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.google.common.collect.Lists;
+
import java.util.List;
/**
diff --git a/tests/src/com/android/contacts/ContactLoaderTest.java b/tests/src/com/android/contacts/model/ContactLoaderTest.java
similarity index 92%
rename from tests/src/com/android/contacts/ContactLoaderTest.java
rename to tests/src/com/android/contacts/model/ContactLoaderTest.java
index 5c215f9..54d220f 100644
--- a/tests/src/com/android/contacts/ContactLoaderTest.java
+++ b/tests/src/com/android/contacts/model/ContactLoaderTest.java
@@ -14,15 +14,7 @@
* limitations under the License.
*/
-package com.android.contacts;
-
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountWithDataSet;
-import com.android.contacts.model.BaseAccountType;
-import com.android.contacts.test.InjectedServices;
-import com.android.contacts.tests.mocks.ContactsMockContext;
-import com.android.contacts.tests.mocks.MockAccountTypeManager;
-import com.android.contacts.tests.mocks.MockContentProvider;
+package com.android.contacts.model;
import android.content.ContentUris;
import android.net.Uri;
@@ -36,6 +28,15 @@
import android.test.LoaderTestCase;
import android.test.suitebuilder.annotation.LargeTest;
+import com.android.contacts.model.Contact;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.model.account.BaseAccountType;
+import com.android.contacts.test.InjectedServices;
+import com.android.contacts.tests.mocks.ContactsMockContext;
+import com.android.contacts.tests.mocks.MockAccountTypeManager;
+import com.android.contacts.tests.mocks.MockContentProvider;
+
/**
* Runs ContactLoader tests for the the contact-detail and editor view.
*/
@@ -74,23 +75,23 @@
super.tearDown();
}
- private ContactLoader.Result assertLoadContact(Uri uri) {
+ private Contact assertLoadContact(Uri uri) {
final ContactLoader loader = new ContactLoader(mMockContext, uri, true);
return getLoaderResultSynchronously(loader);
}
public void testNullUri() {
- ContactLoader.Result result = assertLoadContact(null);
+ Contact result = assertLoadContact(null);
assertTrue(result.isError());
}
public void testEmptyUri() {
- ContactLoader.Result result = assertLoadContact(Uri.EMPTY);
+ Contact result = assertLoadContact(Uri.EMPTY);
assertTrue(result.isError());
}
public void testInvalidUri() {
- ContactLoader.Result result = assertLoadContact(Uri.parse("content://wtf"));
+ Contact result = assertLoadContact(Uri.parse("content://wtf"));
assertTrue(result.isError());
}
@@ -111,14 +112,14 @@
mContactsProvider.expectTypeQuery(baseUri, Contacts.CONTENT_ITEM_TYPE);
queries.fetchAllData(entityUri, contactId, rawContactId, dataId, lookupKey);
- ContactLoader.Result contact = assertLoadContact(baseUri);
+ Contact contact = assertLoadContact(baseUri);
assertEquals(contactId, contact.getId());
assertEquals(rawContactId, contact.getNameRawContactId());
assertEquals(DisplayNameSources.STRUCTURED_NAME, contact.getDisplayNameSource());
assertEquals(lookupKey, contact.getLookupKey());
assertEquals(lookupUri, contact.getLookupUri());
- assertEquals(1, contact.getEntities().size());
+ assertEquals(1, contact.getRawContacts().size());
assertEquals(1, contact.getStatuses().size());
mContactsProvider.verify();
}
@@ -143,14 +144,14 @@
queries.fetchContactIdAndLookupFromRawContactUri(rawContactUri, contactId, lookupKey);
queries.fetchAllData(entityUri, contactId, rawContactId, dataId, lookupKey);
- ContactLoader.Result contact = assertLoadContact(legacyUri);
+ Contact contact = assertLoadContact(legacyUri);
assertEquals(contactId, contact.getId());
assertEquals(rawContactId, contact.getNameRawContactId());
assertEquals(DisplayNameSources.STRUCTURED_NAME, contact.getDisplayNameSource());
assertEquals(lookupKey, contact.getLookupKey());
assertEquals(lookupUri, contact.getLookupUri());
- assertEquals(1, contact.getEntities().size());
+ assertEquals(1, contact.getRawContacts().size());
assertEquals(1, contact.getStatuses().size());
mContactsProvider.verify();
}
@@ -174,14 +175,14 @@
queries.fetchContactIdAndLookupFromRawContactUri(rawContactUri, contactId, lookupKey);
queries.fetchAllData(entityUri, contactId, rawContactId, dataId, lookupKey);
- ContactLoader.Result contact = assertLoadContact(rawContactUri);
+ Contact contact = assertLoadContact(rawContactUri);
assertEquals(contactId, contact.getId());
assertEquals(rawContactId, contact.getNameRawContactId());
assertEquals(DisplayNameSources.STRUCTURED_NAME, contact.getDisplayNameSource());
assertEquals(lookupKey, contact.getLookupKey());
assertEquals(lookupUri, contact.getLookupUri());
- assertEquals(1, contact.getEntities().size());
+ assertEquals(1, contact.getRawContacts().size());
assertEquals(1, contact.getStatuses().size());
mContactsProvider.verify();
}
@@ -203,14 +204,14 @@
mContactsProvider.expectTypeQuery(lookupNoIdUri, Contacts.CONTENT_ITEM_TYPE);
queries.fetchAllData(entityUri, contactId, rawContactId, dataId, lookupKey);
- ContactLoader.Result contact = assertLoadContact(lookupNoIdUri);
+ Contact contact = assertLoadContact(lookupNoIdUri);
assertEquals(contactId, contact.getId());
assertEquals(rawContactId, contact.getNameRawContactId());
assertEquals(DisplayNameSources.STRUCTURED_NAME, contact.getDisplayNameSource());
assertEquals(lookupKey, contact.getLookupKey());
assertEquals(lookupUri, contact.getLookupUri());
- assertEquals(1, contact.getEntities().size());
+ assertEquals(1, contact.getRawContacts().size());
assertEquals(1, contact.getStatuses().size());
mContactsProvider.verify();
}
@@ -232,14 +233,14 @@
mContactsProvider.expectTypeQuery(lookupUri, Contacts.CONTENT_ITEM_TYPE);
queries.fetchAllData(entityUri, contactId, rawContactId, dataId, lookupKey);
- ContactLoader.Result contact = assertLoadContact(lookupUri);
+ Contact contact = assertLoadContact(lookupUri);
assertEquals(contactId, contact.getId());
assertEquals(rawContactId, contact.getNameRawContactId());
assertEquals(DisplayNameSources.STRUCTURED_NAME, contact.getDisplayNameSource());
assertEquals(lookupKey, contact.getLookupKey());
assertEquals(lookupUri, contact.getLookupUri());
- assertEquals(1, contact.getEntities().size());
+ assertEquals(1, contact.getRawContacts().size());
assertEquals(1, contact.getStatuses().size());
mContactsProvider.verify();
}
@@ -271,14 +272,14 @@
mContactsProvider.expectTypeQuery(lookupWithWrongIdUri, Contacts.CONTENT_ITEM_TYPE);
queries.fetchAllData(entityUri, contactId, rawContactId, dataId, lookupKey);
- ContactLoader.Result contact = assertLoadContact(lookupWithWrongIdUri);
+ Contact contact = assertLoadContact(lookupWithWrongIdUri);
assertEquals(contactId, contact.getId());
assertEquals(rawContactId, contact.getNameRawContactId());
assertEquals(DisplayNameSources.STRUCTURED_NAME, contact.getDisplayNameSource());
assertEquals(lookupKey, contact.getLookupKey());
assertEquals(lookupUri, contact.getLookupUri());
- assertEquals(1, contact.getEntities().size());
+ assertEquals(1, contact.getRawContacts().size());
assertEquals(1, contact.getStatuses().size());
mContactsProvider.verify();
diff --git a/tests/src/com/android/contacts/model/AccountTypeTest.java b/tests/src/com/android/contacts/model/account/AccountTypeTest.java
similarity index 97%
rename from tests/src/com/android/contacts/model/AccountTypeTest.java
rename to tests/src/com/android/contacts/model/account/AccountTypeTest.java
index 6d4d6b0..ad111d9 100644
--- a/tests/src/com/android/contacts/model/AccountTypeTest.java
+++ b/tests/src/com/android/contacts/model/account/AccountTypeTest.java
@@ -14,14 +14,15 @@
* limitations under the License.
*/
-package com.android.contacts.model;
-
-import com.android.contacts.tests.R;
+package com.android.contacts.model.account;
import android.content.Context;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.tests.R;
+
/**
* Test case for {@link AccountType}.
*
diff --git a/tests/src/com/android/contacts/model/ExternalAccountTypeTest.java b/tests/src/com/android/contacts/model/account/ExternalAccountTypeTest.java
similarity index 98%
rename from tests/src/com/android/contacts/model/ExternalAccountTypeTest.java
rename to tests/src/com/android/contacts/model/account/ExternalAccountTypeTest.java
index 4c47d68..6eb3bd7 100644
--- a/tests/src/com/android/contacts/model/ExternalAccountTypeTest.java
+++ b/tests/src/com/android/contacts/model/account/ExternalAccountTypeTest.java
@@ -14,9 +14,7 @@
* limitations under the License.
*/
-package com.android.contacts.model;
-
-import com.android.contacts.tests.R;
+package com.android.contacts.model.account;
import android.content.Context;
import android.provider.ContactsContract.CommonDataKinds.Email;
@@ -33,9 +31,11 @@
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
-import java.util.List;
+import com.android.contacts.model.dataitem.DataKind;
+import com.android.contacts.tests.R;
+import com.google.common.base.Objects;
-import libcore.util.Objects;
+import java.util.List;
/**
* Test case for {@link ExternalAccountType}.
diff --git a/tests/src/com/android/contacts/tests/PhoneNumberTestService.java b/tests/src/com/android/contacts/tests/PhoneNumberTestService.java
index 894e66e..8178985 100644
--- a/tests/src/com/android/contacts/tests/PhoneNumberTestService.java
+++ b/tests/src/com/android/contacts/tests/PhoneNumberTestService.java
@@ -16,11 +16,6 @@
package com.android.contacts.tests;
-import com.android.i18n.phonenumbers.NumberParseException;
-import com.android.i18n.phonenumbers.PhoneNumberUtil;
-import com.android.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
-import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber;
-
import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
@@ -28,6 +23,11 @@
import android.telephony.PhoneNumberUtils;
import android.util.Log;
+import com.android.i18n.phonenumbers.NumberParseException;
+import com.android.i18n.phonenumbers.PhoneNumberUtil;
+import com.android.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
+import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber;
+
import java.util.LinkedHashSet;
import java.util.Set;
diff --git a/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java b/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
index c6577b8..519dc5c 100644
--- a/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
+++ b/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
@@ -16,9 +16,6 @@
package com.android.contacts.tests.allintents;
-import com.android.contacts.tests.R;
-import com.google.android.collect.Lists;
-
import android.accounts.Account;
import android.app.ListActivity;
import android.app.SearchManager;
@@ -48,6 +45,9 @@
import android.widget.ListView;
import android.widget.Toast;
+import com.android.contacts.tests.R;
+import com.google.common.collect.Lists;
+
/**
* An activity that provides access to various modes of the contacts application.
* Useful for manual and scripted tests.
@@ -96,10 +96,7 @@
ACTION_SEARCH_CONTACT,
ACTION_SEARCH_EMAIL,
ACTION_SEARCH_PHONE,
- SEARCH_SUGGESTION_CLICKED_CALL_BUTTON,
SEARCH_SUGGESTION_CLICKED_CONTACT,
- SEARCH_SUGGESTION_DIAL_NUMBER_CLICKED,
- SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED,
JOIN_CONTACT,
EDIT_CONTACT,
EDIT_CONTACT_LOOKUP,
@@ -317,17 +314,6 @@
startSearchResultActivity(intent);
break;
}
- case SEARCH_SUGGESTION_CLICKED_CALL_BUTTON: {
- long contactId = findArbitraryContactWithPhoneNumber();
- if (contactId != -1) {
- Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
- Intent intent = new Intent(Intents.SEARCH_SUGGESTION_CLICKED);
- intent.setData(contactUri);
- intent.putExtra(SearchManager.ACTION_MSG, "call");
- startContactListActivity(intent);
- }
- break;
- }
case SEARCH_SUGGESTION_CLICKED_CONTACT: {
long contactId = findArbitraryContactWithPhoneNumber();
if (contactId != -1) {
@@ -338,18 +324,6 @@
}
break;
}
- case SEARCH_SUGGESTION_DIAL_NUMBER_CLICKED: {
- Intent intent = new Intent(Intents.SEARCH_SUGGESTION_DIAL_NUMBER_CLICKED);
- intent.setData(Uri.parse("tel:800-4664411"));
- startContactListActivity(intent);
- break;
- }
- case SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED: {
- Intent intent = new Intent(Intents.SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED);
- intent.setData(Uri.parse("tel:800-4664411"));
- startContactListActivity(intent);
- break;
- }
case JOIN_CONTACT: {
// TODO
break;
diff --git a/tests/src/com/android/contacts/tests/allintents/ResultActivity.java b/tests/src/com/android/contacts/tests/allintents/ResultActivity.java
index 562f2ba..214e936 100644
--- a/tests/src/com/android/contacts/tests/allintents/ResultActivity.java
+++ b/tests/src/com/android/contacts/tests/allintents/ResultActivity.java
@@ -16,8 +16,6 @@
package com.android.contacts.tests.allintents;
-import com.android.contacts.tests.R;
-
import android.app.Activity;
import android.content.ContentUris;
import android.content.Intent;
@@ -28,16 +26,18 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
+import android.widget.ImageView.ScaleType;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
-import android.widget.ImageView.ScaleType;
+
+import com.android.contacts.tests.R;
import java.util.Arrays;
diff --git a/tests/src/com/android/contacts/tests/calllog/FillCallLogTestActivity.java b/tests/src/com/android/contacts/tests/calllog/FillCallLogTestActivity.java
index 3fc44cb..d04d978 100644
--- a/tests/src/com/android/contacts/tests/calllog/FillCallLogTestActivity.java
+++ b/tests/src/com/android/contacts/tests/calllog/FillCallLogTestActivity.java
@@ -16,8 +16,6 @@
package com.android.contacts.tests.calllog;
-import com.android.contacts.tests.R;
-
import android.app.Activity;
import android.app.LoaderManager;
import android.content.ContentProviderClient;
@@ -37,6 +35,8 @@
import android.widget.TextView;
import android.widget.Toast;
+import com.android.contacts.tests.R;
+
import java.util.Random;
/**
diff --git a/tests/src/com/android/contacts/tests/mocks/ContactsMockContext.java b/tests/src/com/android/contacts/tests/mocks/ContactsMockContext.java
index 2f959f4..a384dea 100644
--- a/tests/src/com/android/contacts/tests/mocks/ContactsMockContext.java
+++ b/tests/src/com/android/contacts/tests/mocks/ContactsMockContext.java
@@ -16,8 +16,6 @@
package com.android.contacts.tests.mocks;
-import com.android.contacts.model.AccountTypeManager;
-
import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
@@ -28,6 +26,8 @@
import android.provider.Settings;
import android.test.mock.MockContentResolver;
+import com.android.contacts.model.AccountTypeManager;
+
/**
* A mock context for contacts unit tests. Forwards everything to
* a supplied context, except content resolver operations, which are sent
diff --git a/tests/src/com/android/contacts/tests/mocks/MockAccountTypeManager.java b/tests/src/com/android/contacts/tests/mocks/MockAccountTypeManager.java
index 9084ef0..ce16743 100644
--- a/tests/src/com/android/contacts/tests/mocks/MockAccountTypeManager.java
+++ b/tests/src/com/android/contacts/tests/mocks/MockAccountTypeManager.java
@@ -15,20 +15,18 @@
*/
package com.android.contacts.tests.mocks;
-import com.android.contacts.model.AccountType;
import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.AccountTypeWithDataSet;
-import com.android.contacts.model.AccountWithDataSet;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Maps;
+import com.android.contacts.model.account.AccountType;
+import com.android.contacts.model.account.AccountTypeWithDataSet;
+import com.android.contacts.model.account.AccountWithDataSet;
+import com.google.common.base.Objects;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
import java.util.Arrays;
-import java.util.Collection;
import java.util.List;
import java.util.Map;
-import libcore.util.Objects;
-
/**
* A mock {@link AccountTypeManager} class.
*/
diff --git a/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java b/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java
index 10682c1..efd5ac2 100644
--- a/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java
+++ b/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java
@@ -16,12 +16,12 @@
package com.android.contacts.tests.mocks;
-import com.android.contacts.ContactPhotoManager;
-
import android.graphics.Bitmap;
import android.net.Uri;
import android.widget.ImageView;
+import com.android.contacts.ContactPhotoManager;
+
/**
* A photo preloader that always uses the "no contact" picture and never executes any real
* db queries
diff --git a/tests/src/com/android/contacts/tests/mocks/MockContentProvider.java b/tests/src/com/android/contacts/tests/mocks/MockContentProvider.java
index 40d5969..71b434d 100644
--- a/tests/src/com/android/contacts/tests/mocks/MockContentProvider.java
+++ b/tests/src/com/android/contacts/tests/mocks/MockContentProvider.java
@@ -16,9 +16,6 @@
package com.android.contacts.tests.mocks;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Maps;
-
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
@@ -26,13 +23,16 @@
import android.net.Uri;
import android.text.TextUtils;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+import junit.framework.Assert;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
-import junit.framework.Assert;
-
/**
* A programmable mock content provider.
*/
diff --git a/tests/src/com/android/contacts/tests/mocks/MockSharedPreferences.java b/tests/src/com/android/contacts/tests/mocks/MockSharedPreferences.java
index 40fd934..536ba7f 100644
--- a/tests/src/com/android/contacts/tests/mocks/MockSharedPreferences.java
+++ b/tests/src/com/android/contacts/tests/mocks/MockSharedPreferences.java
@@ -16,10 +16,10 @@
package com.android.contacts.tests.mocks;
-import com.google.android.collect.Maps;
-
import android.content.SharedPreferences;
+import com.google.common.collect.Maps;
+
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
diff --git a/tests/src/com/android/contacts/tests/quickcontact/QuickContactTestsActivity.java b/tests/src/com/android/contacts/tests/quickcontact/QuickContactTestsActivity.java
index 527d7a3..5092487 100644
--- a/tests/src/com/android/contacts/tests/quickcontact/QuickContactTestsActivity.java
+++ b/tests/src/com/android/contacts/tests/quickcontact/QuickContactTestsActivity.java
@@ -16,8 +16,6 @@
package com.android.contacts.tests.quickcontact;
-import com.android.contacts.tests.R;
-
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -32,6 +30,8 @@
import android.widget.QuickContactBadge;
import android.widget.TextView;
+import com.android.contacts.tests.R;
+
public class QuickContactTestsActivity extends Activity {
private static final int REQUEST_CODE_PICK = 1;
private static final String PREF_NAME = "quick_contact_prefs";
diff --git a/tests/src/com/android/contacts/tests/streamitems/StreamItemPopulatorActivity.java b/tests/src/com/android/contacts/tests/streamitems/StreamItemPopulatorActivity.java
index d6e95ef..20229d2 100644
--- a/tests/src/com/android/contacts/tests/streamitems/StreamItemPopulatorActivity.java
+++ b/tests/src/com/android/contacts/tests/streamitems/StreamItemPopulatorActivity.java
@@ -16,10 +16,6 @@
package com.android.contacts.tests.streamitems;
-import com.android.contacts.model.GoogleAccountType;
-import com.android.contacts.tests.R;
-import com.google.android.collect.Lists;
-
import android.app.Activity;
import android.content.ContentProviderOperation;
import android.content.ContentUris;
@@ -36,6 +32,10 @@
import android.widget.Button;
import android.widget.Toast;
+import com.android.contacts.model.account.GoogleAccountType;
+import com.android.contacts.tests.R;
+import com.google.common.collect.Lists;
+
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
diff --git a/tests/src/com/android/contacts/tests/widget/PinnedHeaderUseCaseActivity.java b/tests/src/com/android/contacts/tests/widget/PinnedHeaderUseCaseActivity.java
index b01963f..dd4ac5e 100644
--- a/tests/src/com/android/contacts/tests/widget/PinnedHeaderUseCaseActivity.java
+++ b/tests/src/com/android/contacts/tests/widget/PinnedHeaderUseCaseActivity.java
@@ -16,9 +16,6 @@
package com.android.contacts.tests.widget;
-import com.android.contacts.tests.R;
-import com.android.contacts.widget.PinnedHeaderListView;
-
import android.app.ListActivity;
import android.content.ComponentName;
import android.content.Intent;
@@ -27,6 +24,9 @@
import android.widget.ArrayAdapter;
import android.widget.ListView;
+import com.android.contacts.tests.R;
+import com.android.contacts.widget.PinnedHeaderListView;
+
/**
* An activity that demonstrates various use cases for the {@link PinnedHeaderListView}.
*/
diff --git a/tests/src/com/android/contacts/util/ExpirableCacheTest.java b/tests/src/com/android/contacts/util/ExpirableCacheTest.java
index 309cc0e..33e176e 100644
--- a/tests/src/com/android/contacts/util/ExpirableCacheTest.java
+++ b/tests/src/com/android/contacts/util/ExpirableCacheTest.java
@@ -16,12 +16,12 @@
package com.android.contacts.util;
-import com.android.contacts.util.ExpirableCache.CachedValue;
-
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.LruCache;
+import com.android.contacts.util.ExpirableCache.CachedValue;
+
/**
* Unit tests for {@link ExpirableCache}.
*/
diff --git a/tests/src/com/android/contacts/util/FakeAsyncTaskExecutor.java b/tests/src/com/android/contacts/util/FakeAsyncTaskExecutor.java
index e68c0ec..8c97f21 100644
--- a/tests/src/com/android/contacts/util/FakeAsyncTaskExecutor.java
+++ b/tests/src/com/android/contacts/util/FakeAsyncTaskExecutor.java
@@ -16,11 +16,11 @@
package com.android.contacts.util;
-import com.google.common.collect.Lists;
-
import android.app.Instrumentation;
import android.os.AsyncTask;
+import com.google.common.collect.Lists;
+
import junit.framework.Assert;
import java.util.Iterator;
diff --git a/tests/src/com/android/contacts/util/HtmlUtilsTest.java b/tests/src/com/android/contacts/util/HtmlUtilsTest.java
index 115f289..772e78f 100644
--- a/tests/src/com/android/contacts/util/HtmlUtilsTest.java
+++ b/tests/src/com/android/contacts/util/HtmlUtilsTest.java
@@ -16,8 +16,6 @@
package com.android.contacts.util;
-import com.android.contacts.util.HtmlUtils.StreamItemQuoteSpan;
-
import android.graphics.drawable.ColorDrawable;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
@@ -27,6 +25,8 @@
import android.text.style.ImageSpan;
import android.text.style.QuoteSpan;
+import com.android.contacts.util.HtmlUtils.StreamItemQuoteSpan;
+
/**
* Tests for {@link HtmlUtils}.
*
diff --git a/tests/src/com/android/contacts/util/IntegrationTestUtils.java b/tests/src/com/android/contacts/util/IntegrationTestUtils.java
index 66dd4ef..8c9dd6c 100644
--- a/tests/src/com/android/contacts/util/IntegrationTestUtils.java
+++ b/tests/src/com/android/contacts/util/IntegrationTestUtils.java
@@ -20,8 +20,6 @@
import static android.os.PowerManager.FULL_WAKE_LOCK;
import static android.os.PowerManager.ON_AFTER_RELEASE;
-import com.google.common.base.Preconditions;
-
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
@@ -30,6 +28,8 @@
import android.view.ViewGroup;
import android.widget.TextView;
+import com.google.common.base.Preconditions;
+
import junit.framework.Assert;
import java.util.ArrayList;
diff --git a/tests/src/com/android/contacts/util/StreamItemEntryBuilder.java b/tests/src/com/android/contacts/util/StreamItemEntryBuilder.java
index d8d8cf5..9eb550e 100644
--- a/tests/src/com/android/contacts/util/StreamItemEntryBuilder.java
+++ b/tests/src/com/android/contacts/util/StreamItemEntryBuilder.java
@@ -16,8 +16,6 @@
package com.android.contacts.util;
-import com.android.contacts.util.StreamItemEntry;
-
import android.content.Context;
/**
@@ -68,4 +66,4 @@
ret.decodeHtml(context);
return ret;
}
-}
\ No newline at end of file
+}
diff --git a/tests/src/com/android/contacts/voicemail/VoicemailStatusHelperImplTest.java b/tests/src/com/android/contacts/voicemail/VoicemailStatusHelperImplTest.java
index b1a0175..801c162 100644
--- a/tests/src/com/android/contacts/voicemail/VoicemailStatusHelperImplTest.java
+++ b/tests/src/com/android/contacts/voicemail/VoicemailStatusHelperImplTest.java
@@ -27,9 +27,6 @@
import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION;
import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_OK;
-import com.android.contacts.R;
-import com.android.contacts.voicemail.VoicemailStatusHelper.StatusMessage;
-
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
@@ -37,6 +34,9 @@
import android.provider.VoicemailContract.Status;
import android.test.AndroidTestCase;
+import com.android.contacts.R;
+import com.android.contacts.voicemail.VoicemailStatusHelper.StatusMessage;
+
import java.util.List;
/**
diff --git a/tests/src/com/android/contacts/widget/CompositeListAdapterTest.java b/tests/src/com/android/contacts/widget/CompositeListAdapterTest.java
index 87d268b..f7dc08e 100644
--- a/tests/src/com/android/contacts/widget/CompositeListAdapterTest.java
+++ b/tests/src/com/android/contacts/widget/CompositeListAdapterTest.java
@@ -15,8 +15,6 @@
*/
package com.android.contacts.widget;
-import com.google.android.collect.Lists;
-
import android.content.Context;
import android.database.DataSetObserver;
import android.test.AndroidTestCase;
@@ -24,6 +22,8 @@
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
+import com.google.common.collect.Lists;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;