am b4513a02: (-s ours) Reconcile with jb-mr1-factory-release jb-mr1-release - do not merge
* commit 'b4513a02eb6a2dfee3f384eea1d61f1989a7517c':
diff --git a/Android.mk b/Android.mk
index 67859bd..d04a68a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -3,11 +3,21 @@
LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+contacts_common_dir := ../ContactsCommon
+
+src_dirs := src $(contacts_common_dir)/src
+res_dirs := res $(contacts_common_dir)/res
+
+LOCAL_SRC_FILES := $(call all-java-files-under, $(src_dirs))
+LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, $(res_dirs))
+
+LOCAL_AAPT_FLAGS := \
+ --auto-add-overlay \
+ --extra-packages com.android.contacts.common
LOCAL_JAVA_LIBRARIES := telephony-common
LOCAL_STATIC_JAVA_LIBRARIES := \
- com.android.phone.common \
+ com.android.phone.shared \
com.android.vcard \
android-common \
guava \
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index dfa23cf..b791d94 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -60,126 +60,6 @@
android:hardwareAccelerated="true"
>
- <!-- Intercept Dialer Intents for devices without a phone.
- This activity should have the same intent filters as the DialtactsActivity,
- so that its capturing the same events. Omit android.intent.category.LAUNCHER, because we
- don't want this to show up in the Launcher. The priorities of the intent-filters
- are set lower, so that the user does not see a disambig dialog -->
- <activity
- android:name=".activities.NonPhoneActivity"
- android:theme="@style/NonPhoneActivityTheme"
- >
- <intent-filter android:priority="-1">
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:mimeType="vnd.android.cursor.item/phone" />
- <data android:mimeType="vnd.android.cursor.item/person" />
- </intent-filter>
- <intent-filter android:priority="-1">
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:scheme="voicemail" />
- </intent-filter>
- <intent-filter android:priority="-1">
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- <intent-filter android:priority="-1">
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- </intent-filter>
- <intent-filter android:priority="-1">
- <action android:name="android.intent.action.VIEW" />
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:scheme="tel" />
- </intent-filter>
- <intent-filter android:priority="-1">
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:mimeType="vnd.android.cursor.dir/calls" />
- </intent-filter>
- <intent-filter android:priority="-1">
- <action android:name="android.intent.action.CALL_BUTTON" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- </intent-filter>
- </activity>
-
- <!-- The entrance point for Phone UI.
- stateAlwaysHidden is set to suppress keyboard show up on
- dialpad screen. -->
- <activity android:name=".activities.DialtactsActivity"
- android:label="@string/launcherDialer"
- android:theme="@style/DialtactsTheme"
- android:uiOptions="splitActionBarWhenNarrow"
- android:launchMode="singleTask"
- android:clearTaskOnLaunch="true"
- android:icon="@mipmap/ic_launcher_phone"
- android:screenOrientation="nosensor"
- android:enabled="@*android:bool/config_voice_capable"
- android:taskAffinity="android.task.contacts.phone"
- android:windowSoftInputMode="stateAlwaysHidden|adjustNothing">
- <intent-filter>
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:mimeType="vnd.android.cursor.item/phone" />
- <data android:mimeType="vnd.android.cursor.item/person" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:scheme="voicemail" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
- <category android:name="android.intent.category.BROWSABLE" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.VIEW" />
- <action android:name="android.intent.action.DIAL" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:scheme="tel" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:mimeType="vnd.android.cursor.dir/calls" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.CALL_BUTTON" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- </intent-filter>
- <!-- This was never intended to be public, but is here for backward
- compatibility. Use Intent.ACTION_DIAL instead. -->
- <intent-filter>
- <action android:name="com.android.phone.action.TOUCH_DIALER" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.TAB" />
- </intent-filter>
- <intent-filter android:label="@string/recentCallsIconLabel">
- <action android:name="com.android.phone.action.RECENT_CALLS" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.TAB" />
- </intent-filter>
- </activity>
-
<!-- The main Contacts activity with the contact list, favorites, and groups. -->
<activity android:name=".activities.PeopleActivity"
android:label="@string/people"
@@ -321,24 +201,6 @@
android:exported="true"
/>
- <!-- Backwards compatibility: "Phone" from Gingerbread and earlier -->
- <activity-alias android:name="DialtactsActivity"
- android:targetActivity=".activities.DialtactsActivity"
- android:exported="true"
- />
-
- <!-- Backwards compatibility: "Call log" from Gingerbread and earlier -->
- <activity-alias android:name="RecentCallsListActivity"
- android:targetActivity=".activities.DialtactsActivity"
- android:exported="true"
- />
-
- <!-- Backwards compatibility: "Call log" from ICS -->
- <activity-alias android:name=".activities.CallLogActivity"
- android:targetActivity=".activities.DialtactsActivity"
- android:exported="true"
- />
-
<!-- An activity for joining contacts -->
<activity android:name=".activities.JoinContactActivity"
android:theme="@style/JoinContactActivityTheme"
@@ -461,20 +323,6 @@
</activity-alias>
- <activity android:name="CallDetailActivity"
- android:label="@string/callDetailTitle"
- android:theme="@style/CallDetailActivityTheme"
- android:screenOrientation="portrait"
- android:icon="@mipmap/ic_launcher_phone"
- android:taskAffinity="android.task.contacts.phone"
- >
- <intent-filter>
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:mimeType="vnd.android.cursor.item/calls" />
- </intent-filter>
- </activity>
-
<!-- Views the details of a single contact -->
<activity android:name=".activities.ContactDetailActivity"
android:label="@string/viewContactTitle"
@@ -527,7 +375,7 @@
</intent-filter>
</activity>
- <activity android:name=".test.FragmentTestActivity">
+ <activity android:name=".common.test.FragmentTestActivity">
<intent-filter>
<category android:name="android.intent.category.TEST" />
</intent-filter>
@@ -567,11 +415,6 @@
>
</activity>
- <!-- Interstitial activity that shows a phone disambig dialog -->
- <activity android:name="CallContactActivity"
- android:theme="@android:style/Theme.Translucent">
- </activity>
-
<!-- vCard related -->
<activity android:name=".vcard.ImportVCardActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
@@ -628,21 +471,6 @@
android:resource="@xml/social_widget_info" />
</receiver>
- <receiver android:name=".calllog.CallLogReceiver"
- android:enabled="@*android:bool/config_voice_capable">
- <intent-filter>
- <action android:name="android.intent.action.NEW_VOICEMAIL" />
- <data
- android:scheme="content"
- android:host="com.android.voicemail"
- android:mimeType="vnd.android.cursor.item/voicemail"
- />
- </intent-filter>
- <intent-filter android:priority="100">
- <action android:name="android.intent.action.BOOT_COMPLETED"/>
- </intent-filter>
- </receiver>
-
<activity
android:name=".socialwidget.SocialWidgetConfigureActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar" >
@@ -651,21 +479,73 @@
</intent-filter>
</activity>
- <service
- android:name=".calllog.CallLogNotificationsService"
- android:exported="false"
- />
+ <!-- Intercept Dialer Intents for devices without a phone.
+ This activity should have the same intent filters as the DialtactsActivity,
+ so that its capturing the same events. Omit android.intent.category.LAUNCHER, because
+ we don't want this to show up in the Launcher. The priorities of the intent-filters
+ are set lower, so that the user does not see a disambig dialog -->
+ <activity
+ android:name="com.android.contacts.NonPhoneActivity"
+ android:theme="@style/NonPhoneActivityTheme"
+ >
+ <intent-filter android:priority="-1">
+ <action android:name="android.intent.action.DIAL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ <data android:mimeType="vnd.android.cursor.item/phone"/>
+ <data android:mimeType="vnd.android.cursor.item/person"/>
+ </intent-filter>
+ <intent-filter android:priority="-1">
+ <action android:name="android.intent.action.DIAL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ <data android:scheme="voicemail"/>
+ </intent-filter>
+ <intent-filter android:priority="-1">
+ <action android:name="android.intent.action.DIAL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ </intent-filter>
+ <intent-filter android:priority="-1">
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ </intent-filter>
+ <intent-filter android:priority="-1">
+ <action android:name="android.intent.action.VIEW"/>
+ <action android:name="android.intent.action.DIAL"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ <data android:scheme="tel"/>
+ </intent-filter>
+ <intent-filter android:priority="-1">
+ <action android:name="android.intent.action.VIEW"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ <data android:mimeType="vnd.android.cursor.dir/calls"/>
+ </intent-filter>
+ <intent-filter android:priority="-1">
+ <action android:name="android.intent.action.CALL_BUTTON"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ <category android:name="android.intent.category.BROWSABLE"/>
+ </intent-filter>
+ </activity>
<!-- Service that is exclusively for the Phone application that sends out a view
- notification. This service might be removed in future versions of the app -->
+ notification. This service might be removed in future versions of the app.
+
+ This is called explicitly by the phone app via package name and class.
+ (PhoneUtils.sendViewNotificationAsync()). If this service moves, then phone
+ needs to be changed as well.
+ -->
<service android:name=".ViewNotificationService"
- android:permission="android.permission.WRITE_CONTACTS"
- android:exported="true">
+ android:permission="android.permission.WRITE_CONTACTS"
+ android:exported="true">
<intent-filter>
- <action android:name="com.android.contacts.VIEW_NOTIFICATION" />
- <data android:mimeType="vnd.android.cursor.item/contact" />
+ <action android:name="com.android.contacts.VIEW_NOTIFICATION"/>
+ <data android:mimeType="vnd.android.cursor.item/contact"/>
</intent-filter>
</service>
+
<meta-data android:name="android.nfc.disable_beam_default" android:value="true" />
</application>
</manifest>
diff --git a/res/drawable-hdpi/ab_stacked_opaque_dark_holo.9.png b/res/drawable-hdpi/ab_stacked_opaque_dark_holo.9.png
deleted file mode 100644
index 23320ea..0000000
--- a/res/drawable-hdpi/ab_stacked_opaque_dark_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_call_pressed.png b/res/drawable-hdpi/btn_call_pressed.png
deleted file mode 100644
index 6b497a2..0000000
--- a/res/drawable-hdpi/btn_call_pressed.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_background_texture.png b/res/drawable-hdpi/dial_background_texture.png
deleted file mode 100644
index 95bec9f..0000000
--- a/res/drawable-hdpi/dial_background_texture.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_0_wht.png b/res/drawable-hdpi/dial_num_0_wht.png
deleted file mode 100644
index c42bf4c..0000000
--- a/res/drawable-hdpi/dial_num_0_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_1_wht.png b/res/drawable-hdpi/dial_num_1_wht.png
deleted file mode 100644
index 434fd33..0000000
--- a/res/drawable-hdpi/dial_num_1_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_2_wht.png b/res/drawable-hdpi/dial_num_2_wht.png
deleted file mode 100644
index 2ae20ab..0000000
--- a/res/drawable-hdpi/dial_num_2_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_3_wht.png b/res/drawable-hdpi/dial_num_3_wht.png
deleted file mode 100644
index 991d5f3..0000000
--- a/res/drawable-hdpi/dial_num_3_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_4_wht.png b/res/drawable-hdpi/dial_num_4_wht.png
deleted file mode 100644
index 7aad3ef..0000000
--- a/res/drawable-hdpi/dial_num_4_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_5_wht.png b/res/drawable-hdpi/dial_num_5_wht.png
deleted file mode 100644
index 42a1d0b..0000000
--- a/res/drawable-hdpi/dial_num_5_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_6_wht.png b/res/drawable-hdpi/dial_num_6_wht.png
deleted file mode 100644
index b03e019..0000000
--- a/res/drawable-hdpi/dial_num_6_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_7_wht.png b/res/drawable-hdpi/dial_num_7_wht.png
deleted file mode 100644
index 8b72fff..0000000
--- a/res/drawable-hdpi/dial_num_7_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_8_wht.png b/res/drawable-hdpi/dial_num_8_wht.png
deleted file mode 100644
index 822f21a..0000000
--- a/res/drawable-hdpi/dial_num_8_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_9_wht.png b/res/drawable-hdpi/dial_num_9_wht.png
deleted file mode 100644
index 2ee944b..0000000
--- a/res/drawable-hdpi/dial_num_9_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_pound_wht.png b/res/drawable-hdpi/dial_num_pound_wht.png
deleted file mode 100644
index e10e57d..0000000
--- a/res/drawable-hdpi/dial_num_pound_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_star_wht.png b/res/drawable-hdpi/dial_num_star_wht.png
deleted file mode 100644
index 1dfc111..0000000
--- a/res/drawable-hdpi/dial_num_star_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_ab_dialer_holo_dark.png b/res/drawable-hdpi/ic_ab_dialer_holo_dark.png
deleted file mode 100644
index 5fea91f..0000000
--- a/res/drawable-hdpi/ic_ab_dialer_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_call_incoming_holo_dark.png b/res/drawable-hdpi/ic_call_incoming_holo_dark.png
deleted file mode 100644
index 8351f48..0000000
--- a/res/drawable-hdpi/ic_call_incoming_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_call_missed_holo_dark.png b/res/drawable-hdpi/ic_call_missed_holo_dark.png
deleted file mode 100644
index 7c17c30..0000000
--- a/res/drawable-hdpi/ic_call_missed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_call_outgoing_holo_dark.png b/res/drawable-hdpi/ic_call_outgoing_holo_dark.png
deleted file mode 100644
index 3b9e0f8..0000000
--- a/res/drawable-hdpi/ic_call_outgoing_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_call_voicemail_holo_dark.png b/res/drawable-hdpi/ic_call_voicemail_holo_dark.png
deleted file mode 100644
index 6d64a36..0000000
--- a/res/drawable-hdpi/ic_call_voicemail_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_contact_picture_180_holo_dark.png b/res/drawable-hdpi/ic_contact_picture_180_holo_dark.png
deleted file mode 100644
index a17da61..0000000
--- a/res/drawable-hdpi/ic_contact_picture_180_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_contact_picture_180_holo_light.png b/res/drawable-hdpi/ic_contact_picture_180_holo_light.png
deleted file mode 100644
index 38e4c30..0000000
--- a/res/drawable-hdpi/ic_contact_picture_180_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_contact_picture_holo_dark.png b/res/drawable-hdpi/ic_contact_picture_holo_dark.png
deleted file mode 100644
index 314fa00..0000000
--- a/res/drawable-hdpi/ic_contact_picture_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_contact_picture_holo_light.png b/res/drawable-hdpi/ic_contact_picture_holo_light.png
deleted file mode 100644
index 4c0e35e..0000000
--- a/res/drawable-hdpi/ic_contact_picture_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_dial_action_call.png b/res/drawable-hdpi/ic_dial_action_call.png
deleted file mode 100644
index ed08eb8..0000000
--- a/res/drawable-hdpi/ic_dial_action_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_dial_action_delete.png b/res/drawable-hdpi/ic_dial_action_delete.png
deleted file mode 100644
index 0bf8563..0000000
--- a/res/drawable-hdpi/ic_dial_action_delete.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_dialer_fork_add_call.png b/res/drawable-hdpi/ic_dialer_fork_add_call.png
deleted file mode 100755
index e046996..0000000
--- a/res/drawable-hdpi/ic_dialer_fork_add_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_dialer_fork_current_call.png b/res/drawable-hdpi/ic_dialer_fork_current_call.png
deleted file mode 100755
index 6e1a395..0000000
--- a/res/drawable-hdpi/ic_dialer_fork_current_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_dialer_fork_tt_keypad.png b/res/drawable-hdpi/ic_dialer_fork_tt_keypad.png
deleted file mode 100755
index 6b50da1..0000000
--- a/res/drawable-hdpi/ic_dialer_fork_tt_keypad.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_hold_pause_disabled_holo_dark.png b/res/drawable-hdpi/ic_hold_pause_disabled_holo_dark.png
deleted file mode 100644
index d21cc10..0000000
--- a/res/drawable-hdpi/ic_hold_pause_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_hold_pause_holo_dark.png b/res/drawable-hdpi/ic_hold_pause_holo_dark.png
deleted file mode 100644
index ac58ec8..0000000
--- a/res/drawable-hdpi/ic_hold_pause_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_play_active_holo_dark.png b/res/drawable-hdpi/ic_play_active_holo_dark.png
deleted file mode 100644
index 179b5a1..0000000
--- a/res/drawable-hdpi/ic_play_active_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_play_disabled_holo_dark.png b/res/drawable-hdpi/ic_play_disabled_holo_dark.png
deleted file mode 100644
index e3a3853..0000000
--- a/res/drawable-hdpi/ic_play_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_play_holo_dark.png b/res/drawable-hdpi/ic_play_holo_dark.png
deleted file mode 100644
index d5fd235..0000000
--- a/res/drawable-hdpi/ic_play_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_sound_off_speakerphone_disabled_holo_dark.png b/res/drawable-hdpi/ic_sound_off_speakerphone_disabled_holo_dark.png
deleted file mode 100644
index f1a9154..0000000
--- a/res/drawable-hdpi/ic_sound_off_speakerphone_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_sound_off_speakerphone_holo_dark.png b/res/drawable-hdpi/ic_sound_off_speakerphone_holo_dark.png
deleted file mode 100644
index 6f12d52..0000000
--- a/res/drawable-hdpi/ic_sound_off_speakerphone_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_sound_speakerphone_disabled_holo_dark.png b/res/drawable-hdpi/ic_sound_speakerphone_disabled_holo_dark.png
deleted file mode 100644
index 3e0f47e..0000000
--- a/res/drawable-hdpi/ic_sound_speakerphone_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_sound_speakerphone_holo_dark.png b/res/drawable-hdpi/ic_sound_speakerphone_holo_dark.png
deleted file mode 100644
index eadd0cd..0000000
--- a/res/drawable-hdpi/ic_sound_speakerphone_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ab_stacked_opaque_dark_holo.9.png b/res/drawable-mdpi/ab_stacked_opaque_dark_holo.9.png
deleted file mode 100644
index 3e912f5..0000000
--- a/res/drawable-mdpi/ab_stacked_opaque_dark_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/btn_call_pressed.png b/res/drawable-mdpi/btn_call_pressed.png
deleted file mode 100644
index 637b06a..0000000
--- a/res/drawable-mdpi/btn_call_pressed.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_background_texture.png b/res/drawable-mdpi/dial_background_texture.png
deleted file mode 100644
index a6d666c..0000000
--- a/res/drawable-mdpi/dial_background_texture.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_0_wht.png b/res/drawable-mdpi/dial_num_0_wht.png
deleted file mode 100644
index e6e295a..0000000
--- a/res/drawable-mdpi/dial_num_0_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_1_wht.png b/res/drawable-mdpi/dial_num_1_wht.png
deleted file mode 100644
index a640e36..0000000
--- a/res/drawable-mdpi/dial_num_1_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_2_wht.png b/res/drawable-mdpi/dial_num_2_wht.png
deleted file mode 100644
index e311f4f..0000000
--- a/res/drawable-mdpi/dial_num_2_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_3_wht.png b/res/drawable-mdpi/dial_num_3_wht.png
deleted file mode 100644
index f07324a..0000000
--- a/res/drawable-mdpi/dial_num_3_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_4_wht.png b/res/drawable-mdpi/dial_num_4_wht.png
deleted file mode 100644
index cd8d33c..0000000
--- a/res/drawable-mdpi/dial_num_4_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_5_wht.png b/res/drawable-mdpi/dial_num_5_wht.png
deleted file mode 100644
index a9f27dc..0000000
--- a/res/drawable-mdpi/dial_num_5_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_6_wht.png b/res/drawable-mdpi/dial_num_6_wht.png
deleted file mode 100644
index 2bdf08e..0000000
--- a/res/drawable-mdpi/dial_num_6_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_7_wht.png b/res/drawable-mdpi/dial_num_7_wht.png
deleted file mode 100644
index 6c1c599..0000000
--- a/res/drawable-mdpi/dial_num_7_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_8_wht.png b/res/drawable-mdpi/dial_num_8_wht.png
deleted file mode 100644
index db0694c..0000000
--- a/res/drawable-mdpi/dial_num_8_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_9_wht.png b/res/drawable-mdpi/dial_num_9_wht.png
deleted file mode 100644
index 692fdb0..0000000
--- a/res/drawable-mdpi/dial_num_9_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_pound_wht.png b/res/drawable-mdpi/dial_num_pound_wht.png
deleted file mode 100644
index f216d05..0000000
--- a/res/drawable-mdpi/dial_num_pound_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_star_wht.png b/res/drawable-mdpi/dial_num_star_wht.png
deleted file mode 100644
index f7e8e9f..0000000
--- a/res/drawable-mdpi/dial_num_star_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_ab_dialer_holo_dark.png b/res/drawable-mdpi/ic_ab_dialer_holo_dark.png
deleted file mode 100644
index c4cf2a1..0000000
--- a/res/drawable-mdpi/ic_ab_dialer_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_call_incoming_holo_dark.png b/res/drawable-mdpi/ic_call_incoming_holo_dark.png
deleted file mode 100644
index 8dcb350..0000000
--- a/res/drawable-mdpi/ic_call_incoming_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_call_missed_holo_dark.png b/res/drawable-mdpi/ic_call_missed_holo_dark.png
deleted file mode 100644
index af030cf..0000000
--- a/res/drawable-mdpi/ic_call_missed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_call_outgoing_holo_dark.png b/res/drawable-mdpi/ic_call_outgoing_holo_dark.png
deleted file mode 100644
index 38a01b7..0000000
--- a/res/drawable-mdpi/ic_call_outgoing_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_call_voicemail_holo_dark.png b/res/drawable-mdpi/ic_call_voicemail_holo_dark.png
deleted file mode 100644
index bf6d006..0000000
--- a/res/drawable-mdpi/ic_call_voicemail_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_contact_picture_180_holo_dark.png b/res/drawable-mdpi/ic_contact_picture_180_holo_dark.png
deleted file mode 100644
index acba333..0000000
--- a/res/drawable-mdpi/ic_contact_picture_180_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_contact_picture_180_holo_light.png b/res/drawable-mdpi/ic_contact_picture_180_holo_light.png
deleted file mode 100644
index 0b52683..0000000
--- a/res/drawable-mdpi/ic_contact_picture_180_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_contact_picture_holo_dark.png b/res/drawable-mdpi/ic_contact_picture_holo_dark.png
deleted file mode 100644
index 6876777..0000000
--- a/res/drawable-mdpi/ic_contact_picture_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_contact_picture_holo_light.png b/res/drawable-mdpi/ic_contact_picture_holo_light.png
deleted file mode 100644
index ead9718..0000000
--- a/res/drawable-mdpi/ic_contact_picture_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_dial_action_call.png b/res/drawable-mdpi/ic_dial_action_call.png
deleted file mode 100644
index 59a68f2..0000000
--- a/res/drawable-mdpi/ic_dial_action_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_dial_action_delete.png b/res/drawable-mdpi/ic_dial_action_delete.png
deleted file mode 100644
index 98341e9..0000000
--- a/res/drawable-mdpi/ic_dial_action_delete.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_dialer_fork_add_call.png b/res/drawable-mdpi/ic_dialer_fork_add_call.png
deleted file mode 100644
index 5a1555b..0000000
--- a/res/drawable-mdpi/ic_dialer_fork_add_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_dialer_fork_current_call.png b/res/drawable-mdpi/ic_dialer_fork_current_call.png
deleted file mode 100644
index 1be783e..0000000
--- a/res/drawable-mdpi/ic_dialer_fork_current_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_dialer_fork_tt_keypad.png b/res/drawable-mdpi/ic_dialer_fork_tt_keypad.png
deleted file mode 100644
index 4e3dd82..0000000
--- a/res/drawable-mdpi/ic_dialer_fork_tt_keypad.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_hold_pause_disabled_holo_dark.png b/res/drawable-mdpi/ic_hold_pause_disabled_holo_dark.png
deleted file mode 100644
index d8cec25..0000000
--- a/res/drawable-mdpi/ic_hold_pause_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_hold_pause_holo_dark.png b/res/drawable-mdpi/ic_hold_pause_holo_dark.png
deleted file mode 100644
index 3efa827..0000000
--- a/res/drawable-mdpi/ic_hold_pause_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_play_active_holo_dark.png b/res/drawable-mdpi/ic_play_active_holo_dark.png
deleted file mode 100644
index 042d8c1..0000000
--- a/res/drawable-mdpi/ic_play_active_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_play_disabled_holo_dark.png b/res/drawable-mdpi/ic_play_disabled_holo_dark.png
deleted file mode 100644
index 64bed72..0000000
--- a/res/drawable-mdpi/ic_play_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_play_holo_dark.png b/res/drawable-mdpi/ic_play_holo_dark.png
deleted file mode 100644
index a31671d..0000000
--- a/res/drawable-mdpi/ic_play_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_sound_off_speakerphone_disabled_holo_dark.png b/res/drawable-mdpi/ic_sound_off_speakerphone_disabled_holo_dark.png
deleted file mode 100644
index 0a83d81..0000000
--- a/res/drawable-mdpi/ic_sound_off_speakerphone_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_sound_off_speakerphone_holo_dark.png b/res/drawable-mdpi/ic_sound_off_speakerphone_holo_dark.png
deleted file mode 100644
index adaff60..0000000
--- a/res/drawable-mdpi/ic_sound_off_speakerphone_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_sound_speakerphone_disabled_holo_dark.png b/res/drawable-mdpi/ic_sound_speakerphone_disabled_holo_dark.png
deleted file mode 100644
index d722707..0000000
--- a/res/drawable-mdpi/ic_sound_speakerphone_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_sound_speakerphone_holo_dark.png b/res/drawable-mdpi/ic_sound_speakerphone_holo_dark.png
deleted file mode 100644
index 2b9600b..0000000
--- a/res/drawable-mdpi/ic_sound_speakerphone_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-nodpi/background_dial_holo_dark.png b/res/drawable-nodpi/background_dial_holo_dark.png
deleted file mode 100644
index 3dba50c..0000000
--- a/res/drawable-nodpi/background_dial_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ab_stacked_opaque_dark_holo.9.png b/res/drawable-xhdpi/ab_stacked_opaque_dark_holo.9.png
deleted file mode 100644
index 71e4c23..0000000
--- a/res/drawable-xhdpi/ab_stacked_opaque_dark_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/btn_call_pressed.png b/res/drawable-xhdpi/btn_call_pressed.png
deleted file mode 100644
index cdf52f8..0000000
--- a/res/drawable-xhdpi/btn_call_pressed.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_background_texture.png b/res/drawable-xhdpi/dial_background_texture.png
deleted file mode 100644
index 184049f..0000000
--- a/res/drawable-xhdpi/dial_background_texture.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_0_wht.png b/res/drawable-xhdpi/dial_num_0_wht.png
deleted file mode 100644
index dca0aea..0000000
--- a/res/drawable-xhdpi/dial_num_0_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_1_wht.png b/res/drawable-xhdpi/dial_num_1_wht.png
deleted file mode 100644
index d1535c1..0000000
--- a/res/drawable-xhdpi/dial_num_1_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_2_wht.png b/res/drawable-xhdpi/dial_num_2_wht.png
deleted file mode 100644
index 12c4ab9..0000000
--- a/res/drawable-xhdpi/dial_num_2_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_3_wht.png b/res/drawable-xhdpi/dial_num_3_wht.png
deleted file mode 100644
index 4353e8a..0000000
--- a/res/drawable-xhdpi/dial_num_3_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_4_wht.png b/res/drawable-xhdpi/dial_num_4_wht.png
deleted file mode 100644
index ccee5cc..0000000
--- a/res/drawable-xhdpi/dial_num_4_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_5_wht.png b/res/drawable-xhdpi/dial_num_5_wht.png
deleted file mode 100644
index f27f153..0000000
--- a/res/drawable-xhdpi/dial_num_5_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_6_wht.png b/res/drawable-xhdpi/dial_num_6_wht.png
deleted file mode 100644
index 8966d13..0000000
--- a/res/drawable-xhdpi/dial_num_6_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_7_wht.png b/res/drawable-xhdpi/dial_num_7_wht.png
deleted file mode 100644
index b018810..0000000
--- a/res/drawable-xhdpi/dial_num_7_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_8_wht.png b/res/drawable-xhdpi/dial_num_8_wht.png
deleted file mode 100644
index 7c7b4f8..0000000
--- a/res/drawable-xhdpi/dial_num_8_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_9_wht.png b/res/drawable-xhdpi/dial_num_9_wht.png
deleted file mode 100644
index 23984f0..0000000
--- a/res/drawable-xhdpi/dial_num_9_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_pound_wht.png b/res/drawable-xhdpi/dial_num_pound_wht.png
deleted file mode 100644
index be21af8..0000000
--- a/res/drawable-xhdpi/dial_num_pound_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_star_wht.png b/res/drawable-xhdpi/dial_num_star_wht.png
deleted file mode 100644
index 061a494..0000000
--- a/res/drawable-xhdpi/dial_num_star_wht.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_ab_dialer_holo_dark.png b/res/drawable-xhdpi/ic_ab_dialer_holo_dark.png
deleted file mode 100644
index a997643..0000000
--- a/res/drawable-xhdpi/ic_ab_dialer_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_call_incoming_holo_dark.png b/res/drawable-xhdpi/ic_call_incoming_holo_dark.png
deleted file mode 100644
index 8eb5f3d..0000000
--- a/res/drawable-xhdpi/ic_call_incoming_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_call_missed_holo_dark.png b/res/drawable-xhdpi/ic_call_missed_holo_dark.png
deleted file mode 100644
index 6d09a4e..0000000
--- a/res/drawable-xhdpi/ic_call_missed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_call_outgoing_holo_dark.png b/res/drawable-xhdpi/ic_call_outgoing_holo_dark.png
deleted file mode 100644
index 6360504..0000000
--- a/res/drawable-xhdpi/ic_call_outgoing_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_call_voicemail_holo_dark.png b/res/drawable-xhdpi/ic_call_voicemail_holo_dark.png
deleted file mode 100644
index d9684d1..0000000
--- a/res/drawable-xhdpi/ic_call_voicemail_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_contact_picture_180_holo_dark.png b/res/drawable-xhdpi/ic_contact_picture_180_holo_dark.png
deleted file mode 100644
index c4c001e..0000000
--- a/res/drawable-xhdpi/ic_contact_picture_180_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_contact_picture_180_holo_light.png b/res/drawable-xhdpi/ic_contact_picture_180_holo_light.png
deleted file mode 100644
index f6fd172..0000000
--- a/res/drawable-xhdpi/ic_contact_picture_180_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_contact_picture_holo_dark.png b/res/drawable-xhdpi/ic_contact_picture_holo_dark.png
deleted file mode 100644
index ddf797f..0000000
--- a/res/drawable-xhdpi/ic_contact_picture_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_contact_picture_holo_light.png b/res/drawable-xhdpi/ic_contact_picture_holo_light.png
deleted file mode 100644
index 05a65f6..0000000
--- a/res/drawable-xhdpi/ic_contact_picture_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dial_action_call.png b/res/drawable-xhdpi/ic_dial_action_call.png
deleted file mode 100644
index 0bd9803..0000000
--- a/res/drawable-xhdpi/ic_dial_action_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dial_action_delete.png b/res/drawable-xhdpi/ic_dial_action_delete.png
deleted file mode 100644
index 989e8b1..0000000
--- a/res/drawable-xhdpi/ic_dial_action_delete.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dialer_fork_add_call.png b/res/drawable-xhdpi/ic_dialer_fork_add_call.png
deleted file mode 100644
index 2c1f817..0000000
--- a/res/drawable-xhdpi/ic_dialer_fork_add_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dialer_fork_current_call.png b/res/drawable-xhdpi/ic_dialer_fork_current_call.png
deleted file mode 100644
index b1c4008..0000000
--- a/res/drawable-xhdpi/ic_dialer_fork_current_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dialer_fork_tt_keypad.png b/res/drawable-xhdpi/ic_dialer_fork_tt_keypad.png
deleted file mode 100644
index ccd8f8a..0000000
--- a/res/drawable-xhdpi/ic_dialer_fork_tt_keypad.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_hold_pause_disabled_holo_dark.png b/res/drawable-xhdpi/ic_hold_pause_disabled_holo_dark.png
deleted file mode 100644
index 9e12338..0000000
--- a/res/drawable-xhdpi/ic_hold_pause_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_hold_pause_holo_dark.png b/res/drawable-xhdpi/ic_hold_pause_holo_dark.png
deleted file mode 100644
index c298ab9..0000000
--- a/res/drawable-xhdpi/ic_hold_pause_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_play_active_holo_dark.png b/res/drawable-xhdpi/ic_play_active_holo_dark.png
deleted file mode 100644
index 20d0583..0000000
--- a/res/drawable-xhdpi/ic_play_active_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_play_disabled_holo_dark.png b/res/drawable-xhdpi/ic_play_disabled_holo_dark.png
deleted file mode 100644
index 9537351..0000000
--- a/res/drawable-xhdpi/ic_play_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_play_holo_dark.png b/res/drawable-xhdpi/ic_play_holo_dark.png
deleted file mode 100644
index afa6bb0..0000000
--- a/res/drawable-xhdpi/ic_play_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_sound_off_speakerphone_disabled_holo_dark.png b/res/drawable-xhdpi/ic_sound_off_speakerphone_disabled_holo_dark.png
deleted file mode 100644
index 764ff65..0000000
--- a/res/drawable-xhdpi/ic_sound_off_speakerphone_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_sound_off_speakerphone_holo_dark.png b/res/drawable-xhdpi/ic_sound_off_speakerphone_holo_dark.png
deleted file mode 100644
index 98a449f..0000000
--- a/res/drawable-xhdpi/ic_sound_off_speakerphone_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_sound_speakerphone_disabled_holo_dark.png b/res/drawable-xhdpi/ic_sound_speakerphone_disabled_holo_dark.png
deleted file mode 100644
index b836d49..0000000
--- a/res/drawable-xhdpi/ic_sound_speakerphone_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_sound_speakerphone_holo_dark.png b/res/drawable-xhdpi/ic_sound_speakerphone_holo_dark.png
deleted file mode 100644
index 71aad97..0000000
--- a/res/drawable-xhdpi/ic_sound_speakerphone_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/btn_call.xml b/res/drawable/btn_call.xml
deleted file mode 100644
index abce983..0000000
--- a/res/drawable/btn_call.xml
+++ /dev/null
@@ -1,32 +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.
--->
-
-<!-- Background resource for call button in the various dialpads.
- Almost a copy from framework's item_background_holo_dark.xml, but has different pressed effect
- -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item android:state_window_focused="false" android:drawable="@android:color/transparent" />
-
- <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
- <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/list_selector_disabled_holo_dark" />
- <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/list_selector_disabled_holo_dark" />
- <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/btn_call_pressed" />
- <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/btn_call_pressed" />
- <item android:state_focused="true" android:drawable="@drawable/list_focused_holo" />
- <item android:drawable="@android:color/transparent" />
-</selector>
-
diff --git a/res/drawable/dialpad_background.xml b/res/drawable/dialpad_background.xml
deleted file mode 100644
index 0e31f5e..0000000
--- a/res/drawable/dialpad_background.xml
+++ /dev/null
@@ -1,19 +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.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/dial_background_texture"
- android:tileMode="repeat" />
diff --git a/res/drawable/ic_hold_pause.xml b/res/drawable/ic_hold_pause.xml
deleted file mode 100644
index 19902ae..0000000
--- a/res/drawable/ic_hold_pause.xml
+++ /dev/null
@@ -1,21 +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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_enabled="false"
- android:drawable="@drawable/ic_hold_pause_disabled_holo_dark" />
- <item android:drawable="@drawable/ic_hold_pause_holo_dark" />
-</selector>
diff --git a/res/drawable/ic_play.xml b/res/drawable/ic_play.xml
deleted file mode 100644
index 1c43a55..0000000
--- a/res/drawable/ic_play.xml
+++ /dev/null
@@ -1,21 +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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_enabled="false"
- android:drawable="@drawable/ic_play_disabled_holo_dark" />
- <item android:drawable="@drawable/ic_play_holo_dark" />
-</selector>
diff --git a/res/drawable/ic_speakerphone_off.xml b/res/drawable/ic_speakerphone_off.xml
deleted file mode 100644
index 6a8a0a1..0000000
--- a/res/drawable/ic_speakerphone_off.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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_enabled="false" android:drawable="@drawable/ic_sound_off_speakerphone_disabled_holo_dark" />
- <item android:drawable="@drawable/ic_sound_off_speakerphone_holo_dark" />
-</selector>
diff --git a/res/drawable/ic_speakerphone_on.xml b/res/drawable/ic_speakerphone_on.xml
deleted file mode 100644
index 4bcd5c6..0000000
--- a/res/drawable/ic_speakerphone_on.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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_enabled="false" android:drawable="@drawable/ic_sound_speakerphone_disabled_holo_dark" />
- <item android:drawable="@drawable/ic_sound_speakerphone_holo_dark" />
-</selector>
diff --git a/res/drawable/ic_tab_dialer.xml b/res/drawable/ic_tab_dialer.xml
deleted file mode 100644
index 593d091..0000000
--- a/res/drawable/ic_tab_dialer.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:drawable="@drawable/ic_ab_dialer_holo_dark" />
-</selector>
-
diff --git a/res/drawable/seek_bar_thumb.xml b/res/drawable/seek_bar_thumb.xml
deleted file mode 100644
index c0cffcc..0000000
--- a/res/drawable/seek_bar_thumb.xml
+++ /dev/null
@@ -1,55 +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.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_enabled="true">
- <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- First item is the outer transparent sphere. -->
- <item>
- <shape
- android:shape="oval"
- >
- <size
- android:width="16dip"
- android:height="16dip"
- />
- <solid
- android:color="@color/voicemail_playback_seek_bar_yet_to_play"
- />
- </shape>
- </item>
- <!-- Second item is the inner almost-opaque sphere.
- Seems to derive its size from the outer, a size element doesn't change anything.
- Looks like using left, right, top and bottom on the item is best to fix inner sphere. -->
- <item
- android:left="3dip"
- android:right="3dip"
- android:top="3dip"
- android:bottom="3dip"
- >
- <shape
- android:shape="oval"
- >
- <solid
- android:color="@color/voicemail_playback_seek_bar_already_played"
- />
- </shape>
- </item>
- </layer-list>
- </item>
-
- <!-- Do not show the thumb when disabled -->
- <item android:drawable="@android:color/transparent" />
-</selector>
\ No newline at end of file
diff --git a/res/drawable/seekbar_drawable.xml b/res/drawable/seekbar_drawable.xml
deleted file mode 100644
index 96bbee3..0000000
--- a/res/drawable/seekbar_drawable.xml
+++ /dev/null
@@ -1,63 +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.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_enabled="true">
- <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:id="@android:id/background">
- <shape android:shape="line">
- <stroke
- android:width="2dip"
- android:color="@color/voicemail_playback_seek_bar_yet_to_play"
- />
- </shape>
- </item>
- <!-- I am not defining a secondary progress colour - we don't use it. -->
- <item android:id="@android:id/progress">
- <clip>
- <shape android:shape="line">
- <stroke
- android:width="2dip"
- android:color="@color/voicemail_playback_seek_bar_already_played"
- />
- </shape>
- </clip>
- </item>
- </layer-list>
- </item>
- <item>
- <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:id="@android:id/background">
- <shape android:shape="line">
- <stroke
- android:width="2dip"
- android:color="@color/voicemail_playback_seek_bar_yet_to_play"
- />
- </shape>
- </item>
- <!-- I am not defining a secondary progress colour - we don't use it. -->
- <item android:id="@android:id/progress">
- <clip>
- <shape android:shape="line">
- <stroke
- android:width="2dip"
- android:color="@color/voicemail_playback_seek_bar_yet_to_play"
- />
- </shape>
- </clip>
- </item>
- </layer-list>
- </item>
-</selector>
diff --git a/res/layout-land/dialpad_fragment.xml b/res/layout-land/dialpad_fragment.xml
deleted file mode 100644
index 63dd369..0000000
--- a/res/layout-land/dialpad_fragment.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/top"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
-
- <LinearLayout
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="3"
- android:orientation="vertical" >
-
- <LinearLayout
- android:id="@+id/digits_container"
- android:layout_width="match_parent"
- android:layout_height="0px"
- android:layout_weight="@integer/dialpad_layout_weight_digits"
- android:layout_marginTop="@dimen/dialpad_vertical_margin"
- android:background="@drawable/dialpad_background"
- android:gravity="center">
-
- <com.android.contacts.dialpad.DigitsEditText
- android:id="@+id/digits"
- android:layout_width="0dip"
- android:layout_weight="1"
- android:layout_height="match_parent"
- android:gravity="center"
- android:textAppearance="@style/DialtactsDigitsTextAppearance"
- android:textColor="?android:attr/textColorPrimary"
- android:nextFocusRight="@+id/overflow_menu"
- android:background="@android:color/transparent" />
-
- <ImageButton
- android:id="@+id/deleteButton"
- android:layout_width="56dip"
- android:layout_height="match_parent"
- android:layout_gravity="center_vertical"
- android:gravity="center"
- android:state_enabled="false"
- android:background="?android:attr/selectableItemBackground"
- android:contentDescription="@string/description_delete_button"
- android:src="@drawable/ic_dial_action_delete" />
-
-
- </LinearLayout>
- <!-- "Dialpad chooser" UI, shown only when the user brings up the
- Dialer while a call is already in progress.
- When this UI is visible, the other Dialer elements
- (the textfield and button) are hidden. -->
- <ListView android:id="@+id/dialpadChooser"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:footerDividersEnabled="true" />
-
- <!-- Keypad section -->
- <include layout="@layout/dialpad" />
- </LinearLayout>
- <View
- android:layout_width="@dimen/dialpad_center_margin"
- android:layout_height="match_parent"
- android:background="#66000000"/>
- <RelativeLayout
- android:id="@+id/dialButtonContainer"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="2"
- android:background="@drawable/dialpad_background">
- <View
- android:layout_width="match_parent"
- android:layout_height="@dimen/dialpad_button_margin"
- android:layout_above="@id/dialButton"
- android:background="#33000000" />
- <ImageButton android:id="@+id/dialButton"
- android:layout_width="match_parent"
- android:layout_height="@dimen/call_button_height"
- android:layout_alignParentBottom="true"
- android:state_enabled="false"
- android:background="@drawable/btn_call"
- android:contentDescription="@string/description_dial_button"
- android:src="@drawable/ic_dial_action_call" />
- </RelativeLayout>
-</LinearLayout>
diff --git a/res/layout-land/dialtacts_activity.xml b/res/layout-land/dialtacts_activity.xml
deleted file mode 100644
index f43fe5f..0000000
--- a/res/layout-land/dialtacts_activity.xml
+++ /dev/null
@@ -1,27 +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:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginTop="?android:attr/actionBarSize"
- android:id="@+id/dialtacts_frame"
- >
- <android.support.v4.view.ViewPager
- android:id="@+id/pager"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
-</FrameLayout>
diff --git a/res/layout-land/quickcontact_activity.xml b/res/layout-land/quickcontact_activity.xml
index dbd5260..689ab9d 100644
--- a/res/layout-land/quickcontact_activity.xml
+++ b/res/layout-land/quickcontact_activity.xml
@@ -15,7 +15,7 @@
-->
<view
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
+ xmlns:ex="http://schemas.android.com/apk/res-auto"
class="com.android.contacts.quickcontact.FloatingChildLayout"
android:id="@+id/floating_layout"
android:layout_width="match_parent"
diff --git a/res/layout-sw580dp-land/people_activity.xml b/res/layout-sw580dp-land/people_activity.xml
index 3a86842..1026951 100644
--- a/res/layout-sw580dp-land/people_activity.xml
+++ b/res/layout-sw580dp-land/people_activity.xml
@@ -16,7 +16,7 @@
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
+ xmlns:ex="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
diff --git a/res/layout-sw580dp/contact_editor_fragment.xml b/res/layout-sw580dp/contact_editor_fragment.xml
index 572de4f..2c6e1f1 100644
--- a/res/layout-sw580dp/contact_editor_fragment.xml
+++ b/res/layout-sw580dp/contact_editor_fragment.xml
@@ -16,7 +16,7 @@
<com.android.contacts.widget.InterpolatingLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
+ xmlns:ex="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/panel_message">
@@ -34,4 +34,4 @@
ex:layout_narrowMarginLeft="50dip"
ex:layout_narrowMarginRight="50dip"/>
-</com.android.contacts.widget.InterpolatingLayout>
\ No newline at end of file
+</com.android.contacts.widget.InterpolatingLayout>
diff --git a/res/layout-sw580dp/detail_header_contact_with_updates.xml b/res/layout-sw580dp/detail_header_contact_with_updates.xml
index f732b23..c7fd25a 100644
--- a/res/layout-sw580dp/detail_header_contact_with_updates.xml
+++ b/res/layout-sw580dp/detail_header_contact_with_updates.xml
@@ -22,7 +22,7 @@
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
+ xmlns:ex="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
diff --git a/res/layout-sw580dp/detail_header_contact_without_updates.xml b/res/layout-sw580dp/detail_header_contact_without_updates.xml
index 3c01b16..bc5a8e1 100644
--- a/res/layout-sw580dp/detail_header_contact_without_updates.xml
+++ b/res/layout-sw580dp/detail_header_contact_without_updates.xml
@@ -20,7 +20,7 @@
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
+ xmlns:ex="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
diff --git a/res/layout-sw580dp/group_editor_activity.xml b/res/layout-sw580dp/group_editor_activity.xml
index d344487..f93d247 100644
--- a/res/layout-sw580dp/group_editor_activity.xml
+++ b/res/layout-sw580dp/group_editor_activity.xml
@@ -16,7 +16,7 @@
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
+ xmlns:ex="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.android.contacts.widget.InterpolatingLayout
diff --git a/res/layout-sw580dp/people_activity.xml b/res/layout-sw580dp/people_activity.xml
index 42c6afc..e29b6b0 100644
--- a/res/layout-sw580dp/people_activity.xml
+++ b/res/layout-sw580dp/people_activity.xml
@@ -16,7 +16,7 @@
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
+ xmlns:ex="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
diff --git a/res/layout-sw580dp/quickcontact_activity.xml b/res/layout-sw580dp/quickcontact_activity.xml
index a97d86c..b0291fc 100644
--- a/res/layout-sw580dp/quickcontact_activity.xml
+++ b/res/layout-sw580dp/quickcontact_activity.xml
@@ -15,7 +15,7 @@
-->
<view
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
+ xmlns:ex="http://schemas.android.com/apk/res-auto"
class="com.android.contacts.quickcontact.FloatingChildLayout"
android:id="@+id/floating_layout"
android:layout_width="match_parent"
diff --git a/res/layout-sw580dp/updates_header_contact.xml b/res/layout-sw580dp/updates_header_contact.xml
index b8b3278..6079499 100644
--- a/res/layout-sw580dp/updates_header_contact.xml
+++ b/res/layout-sw580dp/updates_header_contact.xml
@@ -19,7 +19,7 @@
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
+ xmlns:ex="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
@@ -53,4 +53,4 @@
android:singleLine="true"
android:ellipsize="end" />
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/res/layout-sw680dp-land/contact_detail_empty.xml b/res/layout-sw680dp-land/contact_detail_empty.xml
index e12dd39..0ff9960 100644
--- a/res/layout-sw680dp-land/contact_detail_empty.xml
+++ b/res/layout-sw680dp-land/contact_detail_empty.xml
@@ -18,7 +18,7 @@
<com.android.contacts.widget.InterpolatingLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
+ xmlns:ex="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/emptyText"
@@ -33,4 +33,4 @@
ex:layout_narrowMarginLeft="44dip"
android:paddingTop="10dip"
android:lineSpacingMultiplier="0.92"/>
-</com.android.contacts.widget.InterpolatingLayout>
\ No newline at end of file
+</com.android.contacts.widget.InterpolatingLayout>
diff --git a/res/layout-sw680dp-land/people_activity.xml b/res/layout-sw680dp-land/people_activity.xml
index 2dea4eb..ae7bc0d 100644
--- a/res/layout-sw680dp-land/people_activity.xml
+++ b/res/layout-sw680dp-land/people_activity.xml
@@ -16,7 +16,7 @@
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
+ xmlns:ex="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
diff --git a/res/layout-sw680dp/people_activity.xml b/res/layout-sw680dp/people_activity.xml
index f604f9b..59b4869 100644
--- a/res/layout-sw680dp/people_activity.xml
+++ b/res/layout-sw680dp/people_activity.xml
@@ -16,7 +16,7 @@
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
+ xmlns:ex="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
diff --git a/res/layout/call_detail.xml b/res/layout/call_detail.xml
deleted file mode 100644
index 1d0a285..0000000
--- a/res/layout/call_detail.xml
+++ /dev/null
@@ -1,218 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
- android:id="@+id/call_detail"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone"
- android:background="@android:color/black"
->
- <!--
- The list view is under everything.
- It contains a first header element which is hidden under the controls UI.
- When scrolling, the controls move up until the name bar hits the top.
- -->
- <ListView
- android:id="@+id/history"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_alignParentTop="true"
- />
-
- <!-- All the controls which are part of the pinned header are in this layout. -->
- <RelativeLayout
- android:id="@+id/controls"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_alignParentLeft="true"
- android:layout_alignParentTop="true"
- >
- <FrameLayout
- android:id="@+id/voicemail_status"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_alignParentTop="true"
- android:visibility="gone"
- >
- <include layout="@layout/call_log_voicemail_status"/>
- </FrameLayout>
-
- <view
- class="com.android.contacts.widget.ProportionalLayout"
- android:id="@+id/contact_background_sizer"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_below="@id/voicemail_status"
- ex:ratio="0.5"
- ex:direction="widthToHeight"
- >
- <ImageView
- android:id="@+id/contact_background"
- android:layout_width="match_parent"
- android:layout_height="0dip"
- android:adjustViewBounds="true"
- android:scaleType="centerCrop"
- />
- </view>
- <LinearLayout
- android:id="@+id/blue_separator"
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:background="@android:color/holo_blue_light"
- android:layout_below="@+id/contact_background_sizer"
- />
- <View
- android:id="@+id/photo_text_bar"
- android:layout_width="match_parent"
- android:layout_height="42dip"
- android:background="#7F000000"
- android:layout_alignParentLeft="true"
- android:layout_alignBottom="@id/contact_background_sizer"
- />
- <ImageView
- android:id="@+id/main_action"
- android:layout_width="wrap_content"
- android:layout_height="0dip"
- android:scaleType="center"
- android:layout_alignRight="@id/photo_text_bar"
- android:layout_alignBottom="@id/photo_text_bar"
- android:layout_alignTop="@id/photo_text_bar"
- android:layout_marginRight="@dimen/call_log_outer_margin"
- />
- <TextView
- android:id="@+id/header_text"
- android:layout_width="wrap_content"
- android:layout_height="0dip"
- android:layout_alignLeft="@id/photo_text_bar"
- android:layout_toLeftOf="@id/main_action"
- android:layout_alignTop="@id/photo_text_bar"
- android:layout_alignBottom="@id/photo_text_bar"
- android:layout_marginRight="@dimen/call_log_inner_margin"
- android:layout_marginLeft="@dimen/call_detail_contact_name_margin"
- android:gravity="center_vertical"
- android:textColor="?attr/call_log_primary_text_color"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:singleLine="true"
- />
- <ImageButton
- android:id="@+id/main_action_push_layer"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_alignLeft="@id/contact_background_sizer"
- android:layout_alignTop="@id/contact_background_sizer"
- android:layout_alignRight="@id/contact_background_sizer"
- android:layout_alignBottom="@id/contact_background_sizer"
- android:background="?android:attr/selectableItemBackground"
- />
- <LinearLayout
- android:id="@+id/voicemail_container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingBottom="@dimen/call_detail_button_spacing"
- android:layout_below="@id/blue_separator"
- >
- <!-- The voicemail fragment will be put here. -->
- </LinearLayout>
- <FrameLayout
- android:id="@+id/call_and_sms"
- android:layout_width="match_parent"
- android:layout_height="@dimen/call_log_list_item_height"
- android:layout_marginBottom="@dimen/call_detail_button_spacing"
- android:layout_below="@id/voicemail_container"
- android:gravity="center_vertical"
- android:background="@drawable/dialpad_background"
- >
- <LinearLayout
- android:id="@+id/call_and_sms_main_action"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal"
- android:focusable="true"
- android:background="?android:attr/selectableItemBackground"
- >
-
- <LinearLayout
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:paddingLeft="@dimen/call_log_indent_margin"
- android:orientation="vertical"
- android:gravity="center_vertical"
- >
-
- <TextView android:id="@+id/call_and_sms_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingRight="@dimen/call_log_icon_margin"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="?attr/call_log_primary_text_color"
- android:singleLine="true"
- android:ellipsize="end"
- />
-
- <TextView android:id="@+id/call_and_sms_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingRight="@dimen/call_log_icon_margin"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="?attr/call_log_primary_text_color"
- android:textAllCaps="true"
- android:singleLine="true"
- android:ellipsize="end"
- />
- </LinearLayout>
-
- <View android:id="@+id/call_and_sms_divider"
- android:layout_width="1px"
- android:layout_height="32dip"
- android:background="@drawable/ic_divider_dashed_holo_dark"
- android:layout_gravity="center_vertical"
- />
-
- <ImageView android:id="@+id/call_and_sms_icon"
- android:layout_width="@color/call_log_voicemail_highlight_color"
- android:layout_height="match_parent"
- android:paddingLeft="@dimen/call_log_inner_margin"
- android:paddingRight="@dimen/call_log_outer_margin"
- android:gravity="center"
- android:scaleType="centerInside"
- android:focusable="true"
- android:background="?android:attr/selectableItemBackground"
- />
- </LinearLayout>
- </FrameLayout>
- </RelativeLayout>
-
- <!--
- Used to hide the UI when playing a voicemail and the proximity sensor
- is detecting something near the screen.
- -->
- <View
- android:id="@+id/blank"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_alignParentLeft="true"
- android:layout_alignParentTop="true"
- android:background="@android:color/black"
- android:visibility="gone"
- android:clickable="true"
- />
-</RelativeLayout>
diff --git a/res/layout/call_detail_history_header.xml b/res/layout/call_detail_history_header.xml
deleted file mode 100644
index 63c8673..0000000
--- a/res/layout/call_detail_history_header.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<!-- This layout is supposed to match the content of the controls in call_detail.xml -->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <!-- Contact photo. -->
- <view
- class="com.android.contacts.widget.ProportionalLayout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_below="@id/voicemail_status"
- ex:ratio="0.5"
- ex:direction="widthToHeight"
- >
- <!-- Proportional layout requires a view in it. -->
- <View
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- />
- </view>
- <!-- Separator line -->
- <View
- android:layout_width="match_parent"
- android:layout_height="1dip"
- />
- <!-- Voicemail controls -->
- <!-- TODO: Make the height be based on a constant. -->
- <View
- android:id="@+id/header_voicemail_container"
- android:layout_width="match_parent"
- android:layout_height="140dip"
- android:layout_marginBottom="@dimen/call_detail_button_spacing"
- />
- <!-- Call and SMS -->
- <View
- android:id="@+id/header_call_and_sms_container"
- android:layout_width="match_parent"
- android:layout_height="@dimen/call_log_list_item_height"
- />
-
-</LinearLayout>
diff --git a/res/layout/call_detail_history_item.xml b/res/layout/call_detail_history_item.xml
deleted file mode 100644
index 28a7da0..0000000
--- a/res/layout/call_detail_history_item.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="@dimen/call_log_list_item_height"
- android:paddingTop="@dimen/call_log_inner_margin"
- android:paddingBottom="@dimen/call_log_inner_margin"
- android:paddingLeft="@dimen/call_log_indent_margin"
- android:paddingRight="@dimen/call_log_outer_margin"
- android:orientation="vertical"
->
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- >
- <view
- class="com.android.contacts.calllog.CallTypeIconsView"
- android:id="@+id/call_type_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- />
- <TextView
- android:id="@+id/call_type_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="@dimen/call_log_icon_margin"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="@color/secondary_text_color"
- />
- </LinearLayout>
- <TextView
- android:id="@+id/date"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="@color/secondary_text_color"
- />
- <TextView
- android:id="@+id/duration"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="@color/secondary_text_color"
- />
-</LinearLayout>
diff --git a/res/layout/call_log_fragment.xml b/res/layout/call_log_fragment.xml
deleted file mode 100644
index 687fa35..0000000
--- a/res/layout/call_log_fragment.xml
+++ /dev/null
@@ -1,82 +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.
--->
-
-<!-- Layout parameters are set programmatically. -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/FragmentActionBarPadding"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:divider="?android:attr/dividerHorizontal"
- android:showDividers="end">
-
- <FrameLayout
- android:id="@+id/voicemail_status"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:visibility="gone">
- <include layout="@layout/call_log_voicemail_status"
- />
- </FrameLayout>
-
- <FrameLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- >
- <TextView
- android:id="@+id/filter_status"
- style="@style/ContactListSeparatorTextViewStyle"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="@dimen/call_log_outer_margin"
- android:layout_marginRight="@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">
- <ListView android:id="@android:id/list"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:fadingEdge="none"
- android:scrollbarStyle="outsideOverlay"
- android:divider="@null"
- />
- <TextView android:id="@android:id/empty"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:text="@string/recentCalls_empty"
- android:gravity="center"
- android:layout_marginTop="@dimen/empty_message_top_margin"
- android:textColor="?android:attr/textColorSecondary"
- android:textAppearance="?android:attr/textAppearanceLarge"
- />
- </FrameLayout>
-</LinearLayout>
diff --git a/res/layout/call_log_list_item.xml b/res/layout/call_log_list_item.xml
deleted file mode 100644
index 4040c28..0000000
--- a/res/layout/call_log_list_item.xml
+++ /dev/null
@@ -1,167 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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"
- class="com.android.contacts.calllog.CallLogListItemView"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
->
- <!--
- This layout may represent either a call log item or one of the
- headers in the call log.
-
- The former will make the @id/call_log_item visible and the
- @id/call_log_header gone.
-
- The latter will make the @id/call_log_header visible and the
- @id/call_log_item gone
- -->
-
- <LinearLayout
- android:id="@+id/primary_action_view"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_marginLeft="@dimen/call_log_outer_margin"
- android:layout_marginRight="@dimen/call_log_outer_margin"
- android:orientation="horizontal"
- android:gravity="center_vertical"
- android:background="?android:attr/selectableItemBackground"
- android:focusable="true"
- android:nextFocusRight="@+id/secondary_action_icon"
- android:nextFocusLeft="@+id/quick_contact_photo"
- >
- <QuickContactBadge
- android:id="@+id/quick_contact_photo"
- android:layout_width="@dimen/call_log_list_contact_photo_size"
- android:layout_height="@dimen/call_log_list_contact_photo_size"
- android:nextFocusRight="@id/primary_action_view"
- android:layout_alignParentLeft="true"
- android:layout_centerVertical="true"
- android:focusable="true"
- />
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:paddingTop="@dimen/call_log_inner_margin"
- android:paddingBottom="@dimen/call_log_inner_margin"
- android:orientation="vertical"
- android:gravity="center_vertical"
- android:layout_marginLeft="@dimen/call_log_inner_margin"
- >
- <TextView
- android:id="@+id/name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginRight="@dimen/call_log_icon_margin"
- android:textColor="?attr/call_log_primary_text_color"
- android:textSize="18sp"
- android:singleLine="true"
- />
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- >
- <TextView
- android:id="@+id/number"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginRight="@dimen/call_log_icon_margin"
- android:textColor="?attr/call_log_secondary_text_color"
- android:textSize="14sp"
- android:singleLine="true"
- android:ellipsize="marquee"
- />
- <TextView
- android:id="@+id/label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginRight="@dimen/call_log_icon_margin"
- android:textColor="?attr/call_log_secondary_text_color"
- android:textStyle="bold"
- android:textSize="14sp"
- android:singleLine="true"
- android:ellipsize="marquee"
- />
- </LinearLayout>
- <LinearLayout
- android:id="@+id/call_type"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- >
- <view
- class="com.android.contacts.calllog.CallTypeIconsView"
- android:id="@+id/call_type_icons"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginRight="@dimen/call_log_icon_margin"
- android:layout_gravity="center_vertical"
- />
- <TextView
- android:id="@+id/call_count_and_date"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginRight="@dimen/call_log_icon_margin"
- android:layout_gravity="center_vertical"
- android:textColor="?attr/call_log_secondary_text_color"
- android:textSize="14sp"
- android:singleLine="true"
- />
- </LinearLayout>
- </LinearLayout>
- <View
- android:id="@+id/divider"
- android:layout_width="1px"
- android:layout_height="@dimen/call_log_call_action_size"
- android:background="@drawable/ic_divider_dashed_holo_dark"
- android:layout_gravity="center_vertical"
- />
- <ImageButton
- android:id="@+id/secondary_action_icon"
- android:layout_width="@dimen/call_log_call_action_width"
- android:layout_height="match_parent"
- android:paddingLeft="@dimen/call_log_inner_margin"
- android:paddingTop="@dimen/call_log_inner_margin"
- android:paddingBottom="@dimen/call_log_inner_margin"
- android:paddingRight="@dimen/call_log_inner_margin"
- android:scaleType="center"
- android:background="?android:attr/selectableItemBackground"
- android:nextFocusLeft="@id/primary_action_view"
- />
- </LinearLayout>
-
- <TextView
- android:id="@+id/call_log_header"
- style="@style/ContactListSeparatorTextViewStyle"
- android:layout_marginLeft="@dimen/call_log_outer_margin"
- android:layout_marginRight="@dimen/call_log_outer_margin"
- android:paddingTop="@dimen/call_log_inner_margin"
- android:paddingBottom="@dimen/call_log_inner_margin" />
-
- <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:background="#55ffffff"
- />
-</view>
diff --git a/res/layout/call_log_voicemail_status.xml b/res/layout/call_log_voicemail_status.xml
deleted file mode 100644
index 191c821..0000000
--- a/res/layout/call_log_voicemail_status.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="?attr/call_log_voicemail_status_height"
- android:background="?attr/call_log_voicemail_status_background_color"
- >
- <TextView
- android:id="@+id/voicemail_status_message"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_weight="1"
- android:paddingLeft="@dimen/call_log_outer_margin"
- android:paddingRight="@dimen/call_log_inner_margin"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="?attr/call_log_voicemail_status_text_color"
- />
- <TextView
- android:id="@+id/voicemail_status_action"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:gravity="center_vertical"
- android:paddingLeft="@dimen/call_log_inner_margin"
- android:paddingRight="@dimen/call_log_outer_margin"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="?attr/call_log_voicemail_status_action_text_color"
- android:background="?android:attr/selectableItemBackground"
- android:clickable="true"
- />
- </LinearLayout>
-</merge>
diff --git a/res/layout/detail_header_contact_with_updates.xml b/res/layout/detail_header_contact_with_updates.xml
index 39f0582..3391595 100644
--- a/res/layout/detail_header_contact_with_updates.xml
+++ b/res/layout/detail_header_contact_with_updates.xml
@@ -22,7 +22,7 @@
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
+ xmlns:ex="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<view
@@ -36,4 +36,4 @@
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</view>
-</FrameLayout>
\ No newline at end of file
+</FrameLayout>
diff --git a/res/layout/detail_header_contact_without_updates.xml b/res/layout/detail_header_contact_without_updates.xml
index 7e5037e..b261511 100644
--- a/res/layout/detail_header_contact_without_updates.xml
+++ b/res/layout/detail_header_contact_without_updates.xml
@@ -20,7 +20,7 @@
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
+ xmlns:ex="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
@@ -43,4 +43,4 @@
android:layout_height="@dimen/detail_contact_photo_shadow_height"
android:background="?android:attr/windowContentOverlay"/>
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/res/layout/dialpad.xml b/res/layout/dialpad.xml
deleted file mode 100644
index 54b7955..0000000
--- a/res/layout/dialpad.xml
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2006 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.
--->
-
-<!-- Dialpad in the Phone app. -->
-<TableLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/dialpad"
- android:layout_width="match_parent"
- android:layout_height="0px"
- android:layout_weight="@integer/dialpad_layout_weight_dialpad"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="@dimen/dialpad_vertical_margin"
- android:paddingLeft="5dip"
- android:paddingRight="5dip"
- android:paddingBottom="10dip"
- android:background="@drawable/dialpad_background">
-
- <TableRow
- android:layout_height="0px"
- android:layout_weight="1">
- <com.android.contacts.dialpad.DialpadImageButton
- android:id="@+id/one" style="@style/DialtactsDialpadButtonStyle"
- android:src="@drawable/dial_num_1_wht"
- android:contentDescription="@string/description_image_button_one" />
- <com.android.contacts.dialpad.DialpadImageButton
- android:id="@+id/two" style="@style/DialtactsDialpadButtonStyle"
- android:src="@drawable/dial_num_2_wht"
- android:contentDescription="@string/description_image_button_two" />
- <com.android.contacts.dialpad.DialpadImageButton
- android:id="@+id/three" style="@style/DialtactsDialpadButtonStyle"
- android:src="@drawable/dial_num_3_wht"
- android:contentDescription="@string/description_image_button_three" />
- </TableRow>
-
- <TableRow
- android:layout_height="0px"
- android:layout_weight="1">
- <com.android.contacts.dialpad.DialpadImageButton
- android:id="@+id/four" style="@style/DialtactsDialpadButtonStyle"
- android:src="@drawable/dial_num_4_wht"
- android:contentDescription="@string/description_image_button_four" />
- <com.android.contacts.dialpad.DialpadImageButton
- android:id="@+id/five" style="@style/DialtactsDialpadButtonStyle"
- android:src="@drawable/dial_num_5_wht"
- android:contentDescription="@string/description_image_button_five" />
- <com.android.contacts.dialpad.DialpadImageButton
- android:id="@+id/six" style="@style/DialtactsDialpadButtonStyle"
- android:src="@drawable/dial_num_6_wht"
- android:contentDescription="@string/description_image_button_six" />
- </TableRow>
-
- <TableRow
- android:layout_height="0px"
- android:layout_weight="1">
- <com.android.contacts.dialpad.DialpadImageButton
- android:id="@+id/seven" style="@style/DialtactsDialpadButtonStyle"
- android:src="@drawable/dial_num_7_wht"
- android:contentDescription="@string/description_image_button_seven" />
- <com.android.contacts.dialpad.DialpadImageButton
- android:id="@+id/eight" style="@style/DialtactsDialpadButtonStyle"
- android:src="@drawable/dial_num_8_wht"
- android:contentDescription="@string/description_image_button_eight" />
- <com.android.contacts.dialpad.DialpadImageButton
- android:id="@+id/nine" style="@style/DialtactsDialpadButtonStyle"
- android:src="@drawable/dial_num_9_wht"
- android:contentDescription="@string/description_image_button_nine" />
- </TableRow>
-
- <TableRow
- android:layout_height="0px"
- android:layout_weight="1">
- <com.android.contacts.dialpad.DialpadImageButton
- android:id="@+id/star" style="@style/DialtactsDialpadButtonStyle"
- android:src="@drawable/dial_num_star_wht"
- android:contentDescription="@string/description_image_button_star" />
- <com.android.contacts.dialpad.DialpadImageButton
- android:id="@+id/zero" style="@style/DialtactsDialpadButtonStyle"
- android:src="@drawable/dial_num_0_wht"
- android:contentDescription="@string/description_image_button_zero" />
- <com.android.contacts.dialpad.DialpadImageButton
- android:id="@+id/pound" style="@style/DialtactsDialpadButtonStyle"
- android:src="@drawable/dial_num_pound_wht"
- android:contentDescription="@string/description_image_button_pound" />
- </TableRow>
-</TableLayout>
diff --git a/res/layout/dialpad_chooser_list_item.xml b/res/layout/dialpad_chooser_list_item.xml
deleted file mode 100644
index 853ca47..0000000
--- a/res/layout/dialpad_chooser_list_item.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<!-- Layout of a single item in the Dialer's "Dialpad chooser" UI. -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <ImageView android:id="@+id/icon"
- android:layout_width="64dp"
- android:layout_height="64dp"
- android:scaleType="center" />
-
- <TextView android:id="@+id/text"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_gravity="center_vertical"
- android:layout_width="0dip"
- android:layout_weight="1"
- android:layout_height="wrap_content" />
-
-</LinearLayout>
diff --git a/res/layout/dialpad_fragment.xml b/res/layout/dialpad_fragment.xml
deleted file mode 100644
index 796eb28..0000000
--- a/res/layout/dialpad_fragment.xml
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/top"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:paddingLeft="@dimen/dialpad_horizontal_margin"
- android:paddingRight="@dimen/dialpad_horizontal_margin">
-
- <!-- Text field and possibly soft menu button above the keypad where
- the digits are displayed. -->
- <LinearLayout
- android:id="@+id/digits_container"
- android:layout_width="match_parent"
- android:layout_height="0px"
- android:layout_weight="@integer/dialpad_layout_weight_digits"
- android:layout_marginTop="@dimen/dialpad_vertical_margin"
- android:gravity="center"
- android:background="@drawable/dialpad_background" >
-
- <com.android.contacts.dialpad.DigitsEditText
- android:id="@+id/digits"
- android:layout_width="0dip"
- android:layout_weight="1"
- android:layout_height="match_parent"
- android:gravity="center"
- android:textAppearance="@style/DialtactsDigitsTextAppearance"
- android:textColor="?android:attr/textColorPrimary"
- android:nextFocusRight="@+id/overflow_menu"
- android:background="@android:color/transparent" />
-
- <ImageButton
- android:id="@+id/deleteButton"
- android:layout_width="56dip"
- android:layout_height="match_parent"
- android:layout_gravity="center_vertical"
- android:gravity="center"
- android:state_enabled="false"
- android:background="?android:attr/selectableItemBackground"
- android:contentDescription="@string/description_delete_button"
- android:src="@drawable/ic_dial_action_delete" />
- </LinearLayout>
-
- <!-- Keypad section -->
- <include layout="@layout/dialpad" />
-
- <View
- android:layout_width="match_parent"
- android:layout_height="@dimen/dialpad_vertical_margin"
- android:background="#66000000"/>
-
- <!-- left and right paddings will be modified by the code. See DialpadFragment. -->
- <FrameLayout
- android:id="@+id/dialButtonContainer"
- android:layout_width="match_parent"
- android:layout_height="0px"
- android:layout_weight="@integer/dialpad_layout_weight_additional_buttons"
- android:layout_gravity="center_horizontal"
- android:background="@drawable/dialpad_background">
-
- <ImageButton
- android:id="@+id/dialButton"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:state_enabled="false"
- android:background="@drawable/btn_call"
- android:contentDescription="@string/description_dial_button"
- android:src="@drawable/ic_dial_action_call" />
-
- </FrameLayout>
-
- <!-- "Dialpad chooser" UI, shown only when the user brings up the
- Dialer while a call is already in progress.
- When this UI is visible, the other Dialer elements
- (the textfield/button and the dialpad) are hidden. -->
- <ListView android:id="@+id/dialpadChooser"
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:layout_weight="1"
- />
-
-</LinearLayout>
diff --git a/res/layout/dialtacts_activity.xml b/res/layout/dialtacts_activity.xml
deleted file mode 100644
index 35fa00f..0000000
--- a/res/layout/dialtacts_activity.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2006 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginTop="?android:attr/actionBarSize"
- android:id="@+id/dialtacts_frame"
- >
- <android.support.v4.view.ViewPager
- android:id="@+id/pager"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
-
- <ImageButton
- android:id="@+id/searchButton"
- android:layout_width="wrap_content"
- android:layout_height="?android:attr/actionBarSize"
- android:layout_gravity="bottom|left"
- android:state_enabled="false"
- android:background="?android:attr/selectableItemBackground"
- android:contentDescription="@string/description_search_button"
- android:src="@drawable/ic_dial_action_search"/>
-
- <ImageButton
- android:id="@+id/overflow_menu"
- android:layout_width="wrap_content"
- android:layout_height="?android:attr/actionBarSize"
- android:layout_gravity="bottom|right"
- android:src="@drawable/ic_menu_overflow"
- android:contentDescription="@string/action_menu_overflow_description"
- android:nextFocusLeft="@id/digits"
- android:background="?android:attr/selectableItemBackground"/>
-</FrameLayout>
diff --git a/res/layout/dialtacts_custom_action_bar.xml b/res/layout/dialtacts_custom_action_bar.xml
deleted file mode 100644
index 0af8eaa..0000000
--- a/res/layout/dialtacts_custom_action_bar.xml
+++ /dev/null
@@ -1,43 +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.
--->
-
-<!-- Dimensions are set at runtime in ActionBarAdapter -->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="0dip"
- android:layout_height="0dip"
- android:orientation="horizontal">
-
- <SearchView
- android:id="@+id/search_view"
- android:layout_width="0px"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:iconifiedByDefault="false"
- android:inputType="textFilter" />
-
- <ImageButton
- android:id="@+id/search_option"
- android:layout_width="wrap_content"
- android:paddingLeft="4dip"
- android:paddingRight="4dip"
- android:layout_height="match_parent"
- android:layout_alignParentRight="true"
- android:src="@drawable/ic_menu_overflow"
- android:background="?android:attr/selectableItemBackground"
- android:visibility="gone" />
-
-</LinearLayout>
diff --git a/res/layout/playback_layout.xml b/res/layout/playback_layout.xml
deleted file mode 100644
index 2dfcb4d..0000000
--- a/res/layout/playback_layout.xml
+++ /dev/null
@@ -1,133 +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.
--->
-
-<RelativeLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@color/voicemail_playback_ui_background"
->
- <!-- Mute, playback, trash buttons. -->
- <LinearLayout
- android:id="@+id/buttons_linear_layout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layout_alignParentTop="true"
- >
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="58dip"
- android:layout_marginRight="@dimen/call_detail_button_spacing"
- android:background="@drawable/dialpad_background"
- android:layout_weight="1"
- >
- <ImageButton
- android:id="@+id/playback_start_stop"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="?android:attr/selectableItemBackground"
- android:src="@drawable/ic_hold_pause"
- />
- </LinearLayout>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="58dip"
- android:background="@drawable/dialpad_background"
- android:layout_weight="1"
- >
- <ImageButton
- android:id="@+id/playback_speakerphone"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="?android:attr/selectableItemBackground"
- android:src="@drawable/ic_speakerphone_on"
- />
- </LinearLayout>
- </LinearLayout>
- <RelativeLayout
- android:id="@+id/seek_container"
- android:layout_width="match_parent"
- android:layout_height="80dip"
- android:background="@drawable/dialpad_background"
- android:layout_below="@id/buttons_linear_layout"
- android:layout_marginTop="@dimen/call_detail_button_spacing"
- >
- <!-- SeekBar left-right margin decreased from redlines 72dip by 8dip to account for
- half thumb width (thumb is 16dip).
- Vertically, SeekBar and rate buttons should be below centre, position achieved by
- making them centred but giving a difference between top and bottom padding,
- difference is currently 10dip. -->
- <SeekBar
- android:id="@+id/playback_seek"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:progressDrawable="@drawable/seekbar_drawable"
- android:thumb="@drawable/seek_bar_thumb"
- android:thumbOffset="8dip"
- android:progress="0"
- android:paddingLeft="8dip"
- android:paddingRight="8dip"
- android:paddingTop="30dip"
- android:paddingBottom="20dip"
- android:layout_marginRight="64dip"
- android:layout_marginLeft="64dip"
- android:max="0"
- android:layout_centerVertical="true"
- />
- <TextView
- android:id="@+id/playback_position_text"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:textSize="14sp"
- android:layout_alignParentTop="true"
- android:layout_centerHorizontal="true"
- android:layout_marginTop="10dip"
- />
- <TextView
- android:id="@+id/playback_speed_text"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:textSize="14sp"
- android:layout_alignParentTop="true"
- android:layout_centerHorizontal="true"
- android:layout_marginTop="10dip"
- android:alpha="0"
- />
- <ImageButton
- android:id="@+id/rate_decrease_button"
- android:src="@drawable/ic_minus"
- android:layout_width="64dip"
- android:layout_height="wrap_content"
- android:background="?android:attr/selectableItemBackground"
- android:paddingBottom="19dip"
- android:paddingTop="29dip"
- android:layout_alignParentLeft="true"
- android:layout_centerVertical="true"
- />
- <ImageButton
- android:id="@+id/rate_increase_button"
- android:src="@drawable/ic_plus"
- android:layout_width="64dip"
- android:layout_height="wrap_content"
- android:background="?android:attr/selectableItemBackground"
- android:paddingBottom="19dip"
- android:paddingTop="29dip"
- android:layout_alignParentRight="true"
- android:layout_centerVertical="true"
- />
- </RelativeLayout>
-</RelativeLayout>
diff --git a/res/layout/quickcontact_activity.xml b/res/layout/quickcontact_activity.xml
index c1759bf..b3351ba 100644
--- a/res/layout/quickcontact_activity.xml
+++ b/res/layout/quickcontact_activity.xml
@@ -15,7 +15,7 @@
-->
<view
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
+ xmlns:ex="http://schemas.android.com/apk/res-auto"
class="com.android.contacts.quickcontact.FloatingChildLayout"
android:id="@+id/floating_layout"
android:layout_width="match_parent"
diff --git a/res/layout/stream_item_row_images.xml b/res/layout/stream_item_row_images.xml
index 46e1f4f..7e440ab 100644
--- a/res/layout/stream_item_row_images.xml
+++ b/res/layout/stream_item_row_images.xml
@@ -16,7 +16,7 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
+ xmlns:ex="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/detail_update_section_between_items_padding">
diff --git a/res/layout/updates_header_contact.xml b/res/layout/updates_header_contact.xml
index bfcd6e0..9b59c82 100644
--- a/res/layout/updates_header_contact.xml
+++ b/res/layout/updates_header_contact.xml
@@ -19,7 +19,7 @@
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:ex="http://schemas.android.com/apk/res/com.android.contacts"
+ xmlns:ex="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
@@ -61,4 +61,4 @@
</FrameLayout>
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/res/menu/call_details_cab.xml b/res/menu/call_details_cab.xml
deleted file mode 100644
index 7de675f..0000000
--- a/res/menu/call_details_cab.xml
+++ /dev/null
@@ -1,22 +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.
--->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:id="@+id/copy_phone_number"
- android:icon="?android:attr/actionModeCopyDrawable"
- android:title="@string/menu_copy"
- />
-</menu>
diff --git a/res/menu/call_details_options.xml b/res/menu/call_details_options.xml
deleted file mode 100644
index 63ce8f5..0000000
--- a/res/menu/call_details_options.xml
+++ /dev/null
@@ -1,34 +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.
--->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:id="@+id/menu_trash"
- android:icon="@drawable/ic_trash_holo_dark"
- android:showAsAction="ifRoom"
- android:title="@string/recentCalls_trashVoicemail"
- android:onClick="onMenuTrashVoicemail"
- />
- <item
- android:id="@+id/menu_remove_from_call_log"
- android:title="@string/recentCalls_removeFromRecentList"
- android:onClick="onMenuRemoveFromCallLog"
- />
- <item
- android:id="@+id/menu_edit_number_before_call"
- android:title="@string/recentCalls_editNumberBeforeCall"
- android:onClick="onMenuEditNumberBeforeCall"
- />
-</menu>
diff --git a/res/menu/call_log_options.xml b/res/menu/call_log_options.xml
deleted file mode 100644
index bf2973f..0000000
--- a/res/menu/call_log_options.xml
+++ /dev/null
@@ -1,54 +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.
--->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item
- android:id="@+id/show_all_calls"
- android:title="@string/menu_show_all_calls"
- 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="never"
- android:orderInCategory="1"/>
-</menu>
diff --git a/res/menu/dialpad_options.xml b/res/menu/dialpad_options.xml
deleted file mode 100644
index 6dda8fc..0000000
--- a/res/menu/dialpad_options.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:id="@+id/menu_add_contacts"
- android:title="@string/recentCalls_addToContact"
- android:showAsAction="withText"
- android:orderInCategory="1" />
- <item
- android:id="@+id/menu_2s_pause"
- android:title="@string/add_2sec_pause"
- android:showAsAction="withText"
- android:orderInCategory="1" />
-
- <item
- android:id="@+id/menu_add_wait"
- android:title="@string/add_wait"
- android:showAsAction="withText"
- android:orderInCategory="1" />
-
- <item
- android:id="@+id/menu_call_settings_dialpad"
- android:title="@string/call_settings"
- android:showAsAction="withText"
- android:orderInCategory="1" />
-</menu>
diff --git a/res/menu/dialtacts_options.xml b/res/menu/dialtacts_options.xml
deleted file mode 100644
index 8eaa915..0000000
--- a/res/menu/dialtacts_options.xml
+++ /dev/null
@@ -1,52 +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.
--->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:id="@+id/search_on_action_bar"
- android:title="@string/menu_search"
- android:icon="@drawable/ic_dial_action_search"
- android:showAsAction="ifRoom" />
-
- <!-- This should come after the other menus in CallLog and Dialpad -->
- <item
- android:id="@+id/menu_call_settings"
- android:title="@string/call_settings"
- android:showAsAction="withText"
- android:orderInCategory="2" />
-
- <item
- android:id="@+id/filter_option"
- android:title="@string/menu_contacts_filter"
- android:showAsAction="withText" />
-
- <item
- android:id="@+id/add_contact"
- android:icon="@drawable/ic_add_contact_holo_dark"
- android:title="@string/menu_newContact"
- android:showAsAction="ifRoom" />
-
- <!-- Ugly hack: empty item never clickable.
- This is for forcing search icon on left even when there's a single item
- in the bottom ActionBar.
- We intentionally don't use android:icon to avoid other issues around item with
- a null icon.
-
- TODO: look for better idea. -->
- <item
- android:id="@+id/empty_right_menu_item"
- android:actionLayout="@layout/empty2"
- android:showAsAction="ifRoom" />
-</menu>
diff --git a/res/menu/dialtacts_search_options.xml b/res/menu/dialtacts_search_options.xml
deleted file mode 100644
index 0979ebb..0000000
--- a/res/menu/dialtacts_search_options.xml
+++ /dev/null
@@ -1,26 +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.
--->
-<!-- Used with DialtactsActivity's search mode. -->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:id="@+id/filter_option"
- android:title="@string/menu_contacts_filter"
- android:showAsAction="withText" />
- <item
- android:id="@+id/add_contact"
- android:title="@string/menu_newContact"
- android:showAsAction="withText" />
-</menu>
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 3895029..db58550 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Foon"</string>
<string name="people" msgid="1048457247435785074">"Mense"</string>
<string name="contactsList" msgid="8661624236494819731">"Kontakte"</string>
<string name="shortcutContact" msgid="749243779392912958">"Kontak"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Alle kontakte"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Groepe"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Gunstelinge"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Foon"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Oproeprekord"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Stuur teksboodskap"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Bel <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Redigeer nommer voor oproep"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Voeg by kontakte"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Verwyder uit oproeprekord"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Maak oproeprekord skoon"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Vee stemboodskap uit"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Deel stemboodskap"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Oproeprekord is leeg."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Vee oproeprekord uit?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Al jou oproeprekords sal uitgevee word."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Vee tans oproeprekord uit..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Vee dikwels-gebruikte kontakte uit?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Jy gaan die lys van dikwels-gebruikte kontakte in die Mense- en Foonprogramme uitvee, en e-posprogramme dwing om jou adresvoorkeure van nuuts af te leer."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Vee tans dikwels-gebruikte kontakte uit..."</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Stel my profiel op"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Voer persoon se naam in"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Sien opdaterings"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Stemboodskap"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> stemboodskappe"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Speel"</string>
- <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">"Nuwe stemboodskap van <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Kon nie stemboodskap speel nie."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Buffering…"</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Haal stemboodskappe…"</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Kon nie stemboodskap haal nie."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Nuut"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Ouer"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Slegs oproepe met stemboodskappe"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Slegs inkomende oproepe"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Slegs uitgaande oproepe"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Slegs gemisde oproepe"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Kan nie aan stemboodskapsbediener koppel nie."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Kan nie aan stemboodskapbediener koppel nie. Nuwe stemboodskappe wag."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Stel jou stemboodskapdiens op."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Oudio nie beskikbaar nie."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Stel op"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Bel stemboodskap"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Stadigste spoed"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Stadige spoed"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Normale spoed"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Vinnige spoed"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Vinnigste spoed"</string>
- <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>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index d5b72cb..f6f3aef 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"ስልክ"</string>
<string name="people" msgid="1048457247435785074">"ሰዎች"</string>
<string name="contactsList" msgid="8661624236494819731">"እውቅያዎች"</string>
<string name="shortcutContact" msgid="749243779392912958">"እውቅያ"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"ሁሉም እውቂያዎች"</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>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"የፅሁፍ መልዕክት ላክ"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"ጥሪ <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"ከመደወል በፊት ቁጥር አርትዕ"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"ወደ ዕውቂያዎች አክል"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"ከጥሪ ማስታወሻ አስወግድ"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"የጥሪ ማስታወሻ አጥራ"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"የድምፅ መልዕክት ሰርዝ"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"የድምፅ መልዕክት አጋራ"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"ምዝግብ ማስታወሻባዶ ነው..."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"የጥሪ ማስታወሻ አጥራ"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"ሁሉም የጥሪ ማህደሮችህ ይሰረዛሉ፡፡"</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"የጥሪ ምዝግብ ማስታወሻ በማጥራት ላይ…"</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"በተደጋጋሚ ያገኘሃቸው ይጠረጉ?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"በሰዎች እና በስልክ መተግበሪያዎች ውስጥ በተደጋጋሚ ያገኘሃቸውን ዝርዝር ጠርገህ የኢሜይል መተግበሪያዎች ምርጫዎችህን ከባዶ ተነስተው እንያውቁ ታስገድዳለህ።"</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"በተደጋጋሚ ያገኘሃቸውን በመጥረግ ላይ…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"መገለጫዬን አዘጋጅ"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"የግለሰቡን ስም ተይብ"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"አዘምኖችን ዕይ"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"የድምፅ መልዕክት"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> የድምፅ መልዕክቶች"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"አጫውት"</string>
- <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_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="call_log_voicemail_header" msgid="3945407886667089173">"የድምጽ መልዕክት ያላቸው ጥሪዎች ብቻ"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"ገቢ ጥሪዎች ብቻ"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"ወጪ ጥሪዎች ብቻ"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"ያመለጡ ጥሪዎች ብቻ"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"ወደ ድምፅ መልዕክት አገልጋይ ለመገናኘት አልተቻለም።"</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>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"የድምፅመልዕክት ደውል"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"በጣም ቀርፋፋ ፍጥነት"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"ቀርፋፋ ፍጥነት"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"መደበኛ ፍጥነት"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"ፈጣን ፍጥነት"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"በጣም ፈጣን ፍጥነት"</string>
- <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>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 579ba2d..951c4c2 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"الهاتف"</string>
<string name="people" msgid="1048457247435785074">"أشخاص"</string>
<string name="contactsList" msgid="8661624236494819731">"جهات الاتصال"</string>
<string name="shortcutContact" msgid="749243779392912958">"الاتصال بـ"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"جميع جهات الاتصال"</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>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"إرسال رسالة نصية"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"الاتصال بـ <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"تعديل الرقم قبل الاتصال"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"إضافة إلى جهات الاتصال"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"إزالة من سجل المكالمات"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"محو سجل المكالمات"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"حذف بريد صوتي"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"مشاركة البريد الصوتي"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"سجل المكالمات فارغ."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"محو سجل المكالمات؟"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"سيتم حذف جميع سجلات المكالمات."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"جارٍ محو سجل المكالمات..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"هل تريد محو قائمة من يُتصل بهم كثيرًا؟"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"ستمحو قائمة من يتم الاتصال بهم كثيرًا في تطبيقي الأشخاص والهاتف، وستفرض على تطبيقات البريد الإلكتروني التعرف على تفضيلات توجيه الرسائل من البداية."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"جارٍ محو قائمة المُتصل بهم كثيرًا…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"إعداد الملف الشخصي"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"اكتب اسم الشخص"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"عرض التحديثات"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"البريد الصوتي"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> من رسائل البريد الصوتي"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"تشغيل"</string>
- <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_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="call_log_voicemail_header" msgid="3945407886667089173">"المكالمات التي تشتمل على بريد صوتي فقط"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"المكالمات الواردة فقط"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"المكالمات الصادرة فقط"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"المكالمات الفائتة فقط"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"لا يمكن الاتصال بخادم البريد الصوتي."</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>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"اتصال ببريد صوتي..."</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"أبطأ سرعة"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"سرعة بطيئة"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"سرعة عادية"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"سرعة عالية"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"أعلى سرعة"</string>
- <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>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index e88b5da..ad75c04 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Тэлефон"</string>
<string name="people" msgid="1048457247435785074">"Людзі"</string>
<string name="contactsList" msgid="8661624236494819731">"Кантакты"</string>
<string name="shortcutContact" msgid="749243779392912958">"Кантакт"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Усе кантакты"</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>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Адправiць тэкставае паведамленне"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Выклікаць карыстальнiка <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Рэдагаваць нумар перад выклікам"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Дадаць у кантакты"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Выдаліць са спісу выклікаў"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Ачысціць спіс выклікаў"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Выдаліць галасавое паведамленне"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Адправiць галасавое паведамленне"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Спіс выклікаў пусты."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Ачысціць спіс выклікаў?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Усе вашы запісы выклікаў будуць выдалены."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Выдаленне гiсторыi выклiкаў..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Выдалiць частыя кантакты?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Вы выдалiце найбольш частыя кантакты ў прыкладаннях \"Кантакты\" i \"Тэлефон\" i прымусiце прыкладаннi па працы з электроннай поштай вывучыць вашы налады адрасацыi з нуля."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Выдаленне частых кантактаў..."</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Наладзіць мой профіль"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Тып імя чалавека"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Прагл. абнаўленняў"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Галас. пошта"</item>
- <item quantity="other" msgid="5513481419205061254">"Галасавых паведамленняў: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Прайграць"</string>
- <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">"Запiс у буфер..."</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="call_log_voicemail_header" msgid="3945407886667089173">"Толькi выклiкі з галасавой поштай"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Толькi ўваходныя выклiкi"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Толькi выходныя выклiкi"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Толькі прапушчаныя выклiкi"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Немагчыма падлучыцца да сервера галасавой пошты."</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>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Выкл. гал. пошту"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Самая нiзкая хуткасць"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Нiзкая хуткасць"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Звычайная хуткасць"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Высокая хуткасць"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Максімальная хуткасць"</string>
- <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>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 73f5800..349d0f0 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Телефон"</string>
<string name="people" msgid="1048457247435785074">"Хора"</string>
<string name="contactsList" msgid="8661624236494819731">"Контакти"</string>
<string name="shortcutContact" msgid="749243779392912958">"Контакт"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Всички контакти"</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>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Изпращане на SMS"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Обаждане на <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Редактиране на номер преди обаждане"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Добавяне към контакти"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Премахване от списък с обаждания"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Изчистване на списъка с обажданията"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Изтриване на гласова поща"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Споделяне на гласова поща"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Списъкът на обажданията е празен."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Да се изчисти ли списъкът с обаждания?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Всичките ви записи на обажданията ще бъдат изтрити."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Списъкът с обаждания се изчиства..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Да се изчистят ли често търсените?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Ще изчистите списъка с често търсените в приложенията Хора и Телефон и ще принудите приложенията за имейл да научат предпочитанията ви за адресите, започвайки отначало."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Често търсените се изчистват…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Настройка на потребителския ми профил"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Въведете името на човека"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Актуализации"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Гласова поща"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> гл. съобщения"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Пускане"</string>
- <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_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="call_log_voicemail_header" msgid="3945407886667089173">"Само обаждания с гласова поща"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Само входящи обаждания"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Само изходящи обаждания"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Само пропуснати обаждания"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Не може да се осъществи връзка със сървъра за гласова поща."</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>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Чуйте гл. си поща"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Най-бавна скорост"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Бавна скорост"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Нормална скорост"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Бърза скорост"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Най-бърза скорост"</string>
- <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>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 71ec12b..486af20 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telèfon"</string>
<string name="people" msgid="1048457247435785074">"Persones"</string>
<string name="contactsList" msgid="8661624236494819731">"Contactes"</string>
<string name="shortcutContact" msgid="749243779392912958">"Contacte"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Tots els contactes"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Grups"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Preferits"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telèfon"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Registre de trucades"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Envia un missatge de text"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Truca a <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Edita el número abans de trucar"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Afegeix als contactes"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Elimina del registre de trucades"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Esborra el registre de trucades"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Suprimeix missatge de veu"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Comparteix la bústia de veu"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"El registre de trucades és buit."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Esborrament registre"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Se suprimiran tots els registres de trucades."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Esborrant registre de trucades..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Vols esborrar contac. més freqüents?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"S\'esborrarà la llista de contactes més freqüents a les aplicacions de contactes i del telèfon i es forçarà les aplicacions de correu electrònic a obtenir informació sobre les preferències de direccionament des de zero."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"S\'està esb. cont. més freqüents..."</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Configura el meu perfil"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Escriu el nom de la persona"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Mostra actualitzac."</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Missatge de veu"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> missatges de veu"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Reprodueix"</string>
- <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">"Nou missatge de veu de <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"No s\'ha pogut reproduir correu de veu."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"S\'està emmagatzemant a mem. intermèd.…"</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"S\'està obtenint el correu de veu…"</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"No s\'ha pogut obtenir el correu de veu."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Nous"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Anteriors"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Només trucades amb bústia de veu"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Només trucades entrants"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Només trucades sortints"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Només trucades perdudes"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"No es pot connectar amb el servidor de la bústia de veu."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"No es pot connectar a servidor bústia de veu. Hi ha miss. nous."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Configura la bústia de veu."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Àudio no disponible."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Configura"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Truca a bústia veu"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Velocitat mínima"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Velocitat baixa"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Velocitat normal"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Velocitat alta"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Velocitat màxima"</string>
- <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 trucades sortints"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index cb59a0c..afa4443 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telefon"</string>
<string name="people" msgid="1048457247435785074">"Lidé"</string>
<string name="contactsList" msgid="8661624236494819731">"Kontakty"</string>
<string name="shortcutContact" msgid="749243779392912958">"Kontakt"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Všechny kontakty"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Skupiny"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Oblíbené"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Hovory"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Odeslat textovou zprávu"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Volat kontakt <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Před voláním upravit číslo"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Přidat do kontaktů"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Odstranit z hovorů"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Vymazat hovory"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Smazat hlasovou zprávu"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Sdílet hlasovou schránku"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Záznam hovorů je prázdný."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Vymazat hovory?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Všechny záznamy hovorů budou smazány."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Vymazání hovorů..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Vymazat často kontaktované osoby?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Vymažete seznam často kontaktovaných osob v aplikacích Lidé a Telefon a e-mailové aplikace budou muset nastavení adresátů vytvořit znovu."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Mazání často kontaktovaných osob..."</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Nastavit profil"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Zadejte jméno osoby"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Zobrazit aktualizace"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Hlasová schránka"</item>
- <item quantity="other" msgid="5513481419205061254">"Hlasové zprávy: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Přehrát"</string>
- <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">"Nová hlasová zpráva – <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Hlasovou zprávu nelze přehrát."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Ukládání do vyrovnávací paměti…"</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Načítání hlasové schránky…"</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Nepodařilo se načíst hlasovou zprávu."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Nové"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Starší"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Jen hovory s hlasovou schránkou"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Jen příchozí hovory"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Jen odchozí hovory"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Jen zmeškané hovory"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Nelze se připojit k serveru hlasové schránky."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Nové zprávy v hlasové schránce. K serveru se nelze připojit."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Nastavte hlasovou schránku."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Zvuk není k dispozici."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Nastavit"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Volat hlas. schránku"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Nejnižší rychlost"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Nízká rychlost"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Běžná rychlost"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Vysoká rychlost"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Nejvyšší rychlost"</string>
- <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>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 91153e3..9fad07e 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telefon"</string>
<string name="people" msgid="1048457247435785074">"Personer"</string>
<string name="contactsList" msgid="8661624236494819731">"Kontakter"</string>
<string name="shortcutContact" msgid="749243779392912958">"Kontakt"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Alle kontaktpersoner"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupper"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favorit"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Opk.liste"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Send sms"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Ring til <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Rediger nummer inden opkald"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Føj til kontakter"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Fjern fra opkaldsliste"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Ryd opkaldsliste"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Slet telefonsvarerbesked"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Del telefonsvarerbesked"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Opkaldslisten er tom."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Ryd opkaldsliste?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Alle registrerede opkald slettes."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Rydder opkaldslisten..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Vil du rydde de ofte kontaktede?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Hvis du gør dette, rydder du listen over personer, som du ofte kontakter, i appene Personer og Telefon. Du vil samtidig tvinge e-mailapps til at lære dine adressepræferencer fra bunden."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Rydder ofte kontaktede personer…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Opret min profil"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Indtast personens navn"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Se opdateringer"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Telefonsvarer"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> telefonsvarerbeskeder"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Spil"</string>
- <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">"Nye besked fra <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Telefonbeskeden kunne ikke afspilles."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Gemmer i buffer..."</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Henter telefonsvarerbeskeden..."</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Telefonsvarerbeskeden kunne ikke hentes."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Nye"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Ældre"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Kun opkald med telefonsvarer"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Kun indgående opkald"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Kun udgående opkald"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Kun ubesvarede opkald"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Der kan ikke oprettes forbindelse til telefonsvarerserveren."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Der kan ikke oprettes forbindelse til telefonsvarerserveren. Du har nye beskeder."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Konfigurer din telefonsvarer."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Lyd ikke tilgængelig."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Konfigurer"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Ring til tlfsvarer"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Laveste hastighed"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Lav hastighed"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Normal hastighed"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Høj hastighed"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Højeste hastighed"</string>
- <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>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 138ea63..316cd99 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telefon"</string>
<string name="people" msgid="1048457247435785074">"Kontakte"</string>
<string name="contactsList" msgid="8661624236494819731">"Kontakte"</string>
<string name="shortcutContact" msgid="749243779392912958">"Kontakt"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Alle Kontakte"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Gruppen"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoriten"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Anrufe"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"SMS/MMS senden"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"<xliff:g id="NAME">%s</xliff:g> anrufen"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Nr. vor Anruf bearbeiten"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Zu Kontakten hinzufügen"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Aus Anrufliste entfernen"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Anrufliste löschen"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Mailbox-Nachricht löschen"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Mailbox-Nachricht teilen"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Anrufliste ist leer."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Anrufliste löschen?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Ihre gesamte Anrufliste wird gelöscht."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Anrufliste wird gelöscht..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Liste \"Häufig kontaktiert\" löschen?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Sie löschen die Liste \"Häufig kontaktiert\" in den Apps \"Kontakte\" und \"Telefon\" und geben Ihre Adresseinstellungen für E-Mail-Apps neu ein."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"\"Häufig kontaktiert\" wird gelöscht…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Mein Profil einrichten"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Name der Person eingeben"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Updates anzeigen"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Mailbox-Nachricht"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> Mailbox-Nachrichten"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Anhören"</string>
- <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">"Neue Mailbox-Nachricht von <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Abhören der Mailbox nicht möglich"</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Pufferung ..."</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Mailbox-Nachricht wird abgerufen ..."</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Abrufen der Nachricht nicht möglich"</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Neu"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Älter"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Nur Mailbox-Anrufe"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Nur eingehende Anrufe"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Nur ausgehende Anrufe"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Nur entgangene Anrufe"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Es kann keine Verbindung zum Mailbox-Server hergestellt werden."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Verbindung zu Server nicht möglich. Neue Mailbox-Nachrichten"</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Mailbox einrichten"</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Audio nicht verfügbar"</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Einrichten"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Mailbox anrufen"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Geringste Geschwindigkeit"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Geringe Geschwindigkeit"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Normale Geschwindigkeit"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Hohe Geschwindigkeit"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Höchste Geschwindigkeit"</string>
- <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>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index cea27a1..5ecb34c 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Τηλέφωνο"</string>
<string name="people" msgid="1048457247435785074">"Άτομα"</string>
<string name="contactsList" msgid="8661624236494819731">"Επαφές"</string>
<string name="shortcutContact" msgid="749243779392912958">"Επαφή"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Όλες οι επαφές"</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>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Αποστολή μηνύματος κειμένου"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Κλήση <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Επεξεργασία αριθμού πριν την κλήση"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Προσθήκη στις επαφές"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Κατάργηση από το αρχείο καταγραφής κλήσεων"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Εκκαθάριση αρχείου καταγραφής κλήσεων"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Διαγραφή αυτόματου τηλεφωνητή"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Κοινή χρήση αυτόμ. τηλεφωνητή"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Το αρχείο καταγραφής κλήσεων είναι κενό."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Εκκαθάριση αρχείου;"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Όλα τα αρχεία κλήσεων θα διαγραφούν."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Εκκαθάριση αρχ. καταγραφής κλήσεων…"</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Διαγραφή ατόμων με συχνή επικοινωνία;"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Θα διαγράψετε τη λίστα ατόμων με τα οποία είχατε συχνή επικοινωνία στις εφαρμογές \"Άτομα\" και \"Τηλέφωνο\" και θα κάνετε τις εφαρμογές ηλεκτρονικού ταχυδρομείου να μάθουν τις προτιμήσεις επικοινωνίας σας από την αρχή."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Διαγρ. ατόμων με συχνή επικοινωνία…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Ρύθμιση του προφίλ μου"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Πληκτρολογήστε το όνομα του ατόμου"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Προβολή ενημερώσεων"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Αυτόματος τηλεφωνητής"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> μηνύμ. αυτόμ. τηλεφωνητή"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Αναπαραγωγή"</string>
- <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_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="call_log_voicemail_header" msgid="3945407886667089173">"Μόνο κλήσεις με ηχητικά μηνύματα"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Μόνο εισερχόμενες κλήσεις"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Μόνο εξερχόμενες κλήσεις"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Μόνο αναπάντητες κλήσεις"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Αδυναμία σύνδεσης με τον διακομιστή αυτόματου τηλεφωνητή."</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>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Κλήση αυτόμ. τηλεφ."</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Μικρότερη δυνατή ταχύτητα"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Χαμηλή ταχύτητα"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Κανονική ταχύτητα"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Μεγάλη ταχύτητα"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Μεγαλύτερη δυνατή ταχύτητα"</string>
- <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>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 82d1dbc..5107a81 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Phone"</string>
<string name="people" msgid="1048457247435785074">"People"</string>
<string name="contactsList" msgid="8661624236494819731">"Contacts"</string>
<string name="shortcutContact" msgid="749243779392912958">"Contact"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"All contacts"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Groups"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favourites"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Phone"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Call log"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Send text message"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Call <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Edit number before call"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Add to contacts"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Remove from call log"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Clear call log"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Delete voicemail"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Share voicemail"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Call log is empty."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Clear call log?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"All your call records will be deleted."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Clearing call log…"</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Clear frequently contacted?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"You\'ll clear the frequently contacted list in the People and Phone apps and force email apps to learn your addressing preferences from scratch."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Clearing frequently contacted…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Set up my profile"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Type person\'s name"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"View updates"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Voicemail"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> Voicemails"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Play"</string>
- <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">"New voicemail from <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Couldn\'t play voicemail."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Buffering…"</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Fetching voicemail…"</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Couldn\'t fetch voicemail."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"New"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Older"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Calls with voicemail only"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Incoming calls only"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Outgoing calls only"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Missed calls only"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Cannot connect to voicemail server."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Can\'t connect to voicemail server. New voicemails are waiting."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Set up your voicemail."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Audio not available."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Set up"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Call voicemail"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Slowest speed"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Slow speed"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Normal speed"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Fast speed"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Fastest speed"</string>
- <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>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index b4ee9b9..4bc34b9 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Teléfono"</string>
<string name="people" msgid="1048457247435785074">"Personas"</string>
<string name="contactsList" msgid="8661624236494819731">"Contactos"</string>
<string name="shortcutContact" msgid="749243779392912958">"Contacto"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Todos los contactos"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupos"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoritos"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Teléfono"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Llamadas"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Enviar mensaje de texto"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Llamar a <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Editar número antes de llamar"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Agregar a contactos"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Eliminar del registro de llamadas"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Eliminar registro de llamadas"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Eliminar mensaje de voz"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Compartir mensaje de voz"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"El registro de llamadas está vacío."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"¿Eliminar registro?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Se eliminarán todos tus registros de llamadas."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Borrando registro de llamadas..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"¿Borrar los contactos frecuentes?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Estás a punto de borrar la lista de contactos frecuentes de las aplicaciones Personas y Teléfono y harás que las aplicaciones de correo deban aprender nuevamente tus preferencias."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Borrando contactos frecuentes…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Configurar mi perfil"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Escribe el nombre de la persona."</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Ver actualizaciones"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Mensaje de voz"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> mensajes de voz"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Reproducir"</string>
- <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">"Nuevo mensaje de voz de <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"No se pudo reproducir el mensaje de voz."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Almacenando en el búfer"</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Obteniendo el mensaje de voz"</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"No se pudo obtener el mensaje de voz."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Nuevo"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Más antigua"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Solo llamadas con buzón de voz"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Solo llamadas entrantes"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Solo llamadas salientes"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Solo llamadas perdidas"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"No se puede conectar al servidor del buzón de voz."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"No se puede conectar al buzón de voz. Nuevos mensajes en espera."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Configura tu buzón de voz."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Audio no disponible"</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Configurar"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Llamar buzón de voz"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Más lento"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Lento"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Normal"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Rápido"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Más rápido"</string>
- <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>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 4be783a..bdb15b2 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Teléfono"</string>
<string name="people" msgid="1048457247435785074">"Contactos"</string>
<string name="contactsList" msgid="8661624236494819731">"Contactos"</string>
<string name="shortcutContact" msgid="749243779392912958">"Contacto"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Todos los contactos"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupos"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoritos"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Teléfono"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Llamadas"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Enviar un mensaje de texto"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Llamar a <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Editar número antes de llamar"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Añadir a contactos"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Eliminar del registro de llamadas"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Borrar registro de llamadas"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Eliminar mensaje de voz"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Compartir mensaje de voz"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"El registro de llamadas está vacío."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"¿Borrar registro?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Se eliminarán todos los registros de llamadas."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Borrando registro de llamadas..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"¿Borrar contactos frecuentes?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Vas a borrar la lista de contactos frecuentes de las aplicaciones Contactos y Teléfono y obligarás a las aplicaciones de correo electrónico a que memoricen tus preferencias de nuevo."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Borrando contactos frecuentes…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Configurar mi perfil"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Escribe el nombre de la persona"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Ver actualizaciones"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Mensaje de voz"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> mensajes de voz"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Reproducir"</string>
- <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">"Nuevo mensaje de voz de <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"No se ha podido reproducir el mensaje."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Almacenando en búfer..."</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Recuperando mensaje de voz..."</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"No se ha podido recuperar el mensaje."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Nuevo"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Anteriores"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Solo llamadas con mensajes de voz"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Solo llamadas entrantes"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Solo llamadas salientes"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Solo llamadas perdidas"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"No se puede conectar con el servidor del buzón de voz."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"No se puede conectar al buzón de voz. Nuevos mensajes en espera"</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Configurar el buzón de voz"</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Audio no disponible"</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Configurar"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Llamar a buzón de voz"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Más lenta"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Lenta"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Normal"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Rápida"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Más rápida"</string>
- <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>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 8659234..bf8fb1b 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telefon"</string>
<string name="people" msgid="1048457247435785074">"Inimesed"</string>
<string name="contactsList" msgid="8661624236494819731">"Kontaktid"</string>
<string name="shortcutContact" msgid="749243779392912958">"Kontakt"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Kõik kontaktid"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupid"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Lemmikud"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Kõnelogi"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Tekstsõnumi saatmine"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Helista kasutajale <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Muuda enne helistamist numbrit"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Lisa kontaktidesse"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Eemalda kõnelogist"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Kustuta kõnelogi"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Kustuta kõnepost"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Jaga kõneposti"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Kõnelogi on tühi."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Kustutada kõnelogi?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Kõik teie kõnesalvestised kustutatakse."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Kõnelogi kustutamine ..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Kas kustutada sagedased kontaktid?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Kustutate jaotistes Inimesed ja Telefonirakendused loendi Sagedased kontaktid ning meilirakendused peavad teie adresseerimiseelistused uuesti omandama."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Saged. kontaktide kustutamine ..."</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Minu profiili seadistamine"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Sisestage isiku nimi"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Kuva värskendused"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Kõnepost"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> kõnepostisõnumit"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Esitamine"</string>
- <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">"Uus kõnepostisõnum kasutajalt <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Kõnepostisõnumi esitamine ebaõnnestus."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Puhverdamine ..."</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Kõneposti toomine ..."</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Kõneposti toomine ebaõnnestus."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Uued"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Vanemad"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Ainult kõnepostiga kõned"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Ainult sissetulevad kõned"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Ainult väljuvad kõned"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Ainult vastamata kõned"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Kõnepostiserveriga ei saa ühendust."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Kõnepostiserveriga ei saa ühendust. Uued kõnepostisõnumid ootel."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Seadistage oma kõnepost."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Heli pole saadaval."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Seadistamine"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Helista kõneposti"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Aeglaseim kiirus"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Aeglane kiirus"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Tavaline kiirus"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Kiire kiirus"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Kiireim kiirus"</string>
- <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>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 78c6399..e65f133 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"تلفن"</string>
<string name="people" msgid="1048457247435785074">"افراد"</string>
<string name="contactsList" msgid="8661624236494819731">"مخاطبین"</string>
<string name="shortcutContact" msgid="749243779392912958">"مخاطب"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"همه مخاطبین"</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>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"ارسال پیام متنی"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"تماس با <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"ویرایش شماره قبل از تماس"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"افزودن به مخاطبین"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"حذف از گزارش تماس"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"پاک کردن گزارش تماس"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"حذف پست صوتی"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"اشتراکگذاری پست صوتی"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"گزارش تماس خالی است."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"گزارش تماس پاک شود؟"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"تمام سابقه تماس شما حذف خواهد شد."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"در حال پاک کردن گزارش تماس..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"لیست تماس مکرر با مخاطب پاک شود؟"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"با این کار شما در برنامه «افراد» و «تلفن»، لیست افرادی را که با آنها بیشترین تماس را داشتهاید پاک خواهید کرد و برنامههای ایمیل مجبور میشوند تنظیمات برگزیده آدرسدهی شما را از اول یاد بگیرند."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"در حال پاک کردن لیست تماس مکرر..."</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"راهاندازی نمایه من"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"نام شخص را تایپ کنید"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"مشاهده بهروزرسانیها"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"پست صوتی"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> پست صوتی"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"پخش"</string>
- <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_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="call_log_voicemail_header" msgid="3945407886667089173">"فقط تماسهای دارای پست صوتی"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"فقط تماسهای دریافتی"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"فقط تماسهای خروجی"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"فقط تماسهای بیپاسخ"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"اتصال به سرور پست صوتی امکانپذیر نیست."</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>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"تماس با پست صوتی"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"کمترین سرعت"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"سرعت کم"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"سرعت عادی"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"سرعت زیاد"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"بیشترین سرعت"</string>
- <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>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 3a659e7..8c5021c 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Puhelin"</string>
<string name="people" msgid="1048457247435785074">"Henkilöt"</string>
<string name="contactsList" msgid="8661624236494819731">"Yhteystiedot"</string>
<string name="shortcutContact" msgid="749243779392912958">"Yhteystieto"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Kaikki kontaktit"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Ryhmät"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Suosikit"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Puhelin"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Puheluloki"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Lähetä tekstiviesti"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Soita: <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Muokkaa numeroa ennen puhelua"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Lisää yhteystietoihin"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Poista puhelulokista"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Tyhjennä puheluloki"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Poista vastaajaviesti"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Jaa vastaajaviesti"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Puheluloki on tyhjä."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Tyhjennä puheluloki?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Kaikki puhelutallenteet poistetaan."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Tyhjennetään puhelulokia..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Tyhjennetäänkö usein käytetyt?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Toiminto tyhjentää Henkilöt- ja Puhelin-sovellusten usein käytettyjen kontaktien luettelon. Lisäksi sähköpostisovellukset pakotetaan opettelemaan osoiteasetuksesi uudestaan."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Tyhjennetään usein käytetyt..."</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Luo profiili"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Kirjoita henkilön nimi"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Näytä päivitykset"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Vastaaja"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> vastaajaviestiä"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Toista"</string>
- <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">"Uusi vastaajaviesti: <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Vastaajaviestin toisto ei onnistu."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Puskuroidaan..."</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Haetaan vastaajaviestiä..."</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Vastaajaviestin nouto epäonnistui."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Uusi"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Vanhemmat"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Vain vastaajaan menneet puhelut"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Vain saapuvat puhelut"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Vain soitetut puhelut"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Vain vastaamattomat puhelut"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Ei voi yhdistää vastaajapalvelimeen."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Ei voi yhdist. vastaajapalvelimeen. Uusia viestejä vastaajassa."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Ota puhelinvastaaja käyttöön."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Ääntä ei ole saatavilla."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Asetusten määritys"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Soita vastaajaan"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Hitain"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Hidas"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Normaali nopeus"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Nopea"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Nopein"</string>
- <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>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index fc3cbf4..a7fc73f 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Téléphone"</string>
<string name="people" msgid="1048457247435785074">"Contacts"</string>
<string name="contactsList" msgid="8661624236494819731">"Contacts"</string>
<string name="shortcutContact" msgid="749243779392912958">"Contact"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Tous les contacts"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Groupes"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoris"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Tél."</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Appels"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Envoyer un SMS"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Appeler <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Modifier le numéro avant d\'effectuer l\'appel"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Ajouter aux contacts"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Supprimer du journal d\'appels"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Effacer tous les appels"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Supprimer le message vocal"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Partager le message vocal"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Aucun appel."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Effacer les appels ?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Votre journal d\'appels va être supprimé."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Effacement des appels…"</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Effacer les contacts fréquents ?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Cette opération efface la liste des personnes que vous contactez le plus souvent dans les applications Contacts et Téléphone, et oblige vos applications de messagerie électronique à apprendre à nouveau les adresses que vous utilisez le plus souvent."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Suppression des contacts fréquents"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Configurer mon profil"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Saisissez le nom de la personne"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Afficher mises à jour"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Messages vocaux"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> messages vocaux"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Lire"</string>
- <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">"Nouveau message vocal de <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Impossible d\'écouter le message vocal."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Mise en mémoire tampon..."</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Récupération des messages vocaux..."</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Impossible de récupérer messages vocaux."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Nouveau"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Précédent"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Seulement les appels avec message vocal"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Seulement les appels entrants"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Seulement les appels sortants"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Seulement les appels manqués"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Impossible de se connecter au serveur de messagerie vocale."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Connexion messagerie vocale impossible. Messages en attente."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Configurez votre messagerie vocale."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Contenu audio indisponible."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Configuration"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Appeler mess. vocale"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Vitesse minimale"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"vitesse lente"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Vitesse normale"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Vitesse rapide"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Vitesse maximale"</string>
- <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>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 88a216f..ca9a897 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"फ़ोन"</string>
<string name="people" msgid="1048457247435785074">"लोग"</string>
<string name="contactsList" msgid="8661624236494819731">"संपर्क"</string>
<string name="shortcutContact" msgid="749243779392912958">"संपर्क"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"सभी संपर्क"</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>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"पाठ संदेश भेजें"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"<xliff:g id="NAME">%s</xliff:g> को कॉल करें"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"कॉल करने से पहले नंबर संपादित करें"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"संपर्कों में जोड़ें"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"कॉल लॉग से निकालें"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"कॉल लॉग साफ़ करें"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"ध्वनि मेल हटाएं"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"ध्वनिमेल साझा करें"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"कॉल लॉग खाली है."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"कॉल लॉग साफ़ करें?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"आपके सभी कॉल रिकॉर्ड हटा दिए जाएंगे."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"कॉल लॉग साफ़ हो रहा है..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"अक्सर किए जाने वाले संपर्क साफ करें?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"आपको लोग और फ़ोन एप्लिकेशन में अक्सर संपर्क करने की सूची साफ़ करनी होगी, और अपने ईमेल एप्लिकेशन को आपकी प्राथमिकताओं को प्रारंभ से जानने के लिए बाध्य करना होगा."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"अक्सर किए जाने वाले संपर्क साफ़ कर रहा है…"</string>
@@ -218,7 +203,7 @@
<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">"एक vCard फ़ाइल आयात करें"</string>
<string name="import_multiple_vcard_string" msgid="3810226492811062392">"एकाधिक vCard फ़ाइलें आयात करें"</string>
<string name="import_all_vcard_string" msgid="5518136113853448474">"सभी vCard फ़ाइलें आयात करें"</string>
@@ -290,8 +275,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>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"मेरी प्रोफ़ाइल सेट करें"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"व्यक्ति का नाम लिखें"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"अपडेट देखें"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"ध्वनिमेल"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> ध्वनिमेल"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"चलाएं"</string>
- <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_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="call_log_voicemail_header" msgid="3945407886667089173">"केवल ध्वनिमेल वाले कॉल"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"केवल इनकमिंग कॉल"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"केवल आउटगोइंग कॉल"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"केवल छूटे कॉल"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"ध्वनिमेल सर्वर से कनेक्ट नहीं हो सकता."</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>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"ध्वनिमेल कॉल करें"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"सबसे धीमी गति"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"धीमी गति"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"सामान्य गति"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"तेज़ गति"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"सबसे तेज़ गति"</string>
- <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>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index c8d6bcb..2cbc577 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telefon"</string>
<string name="people" msgid="1048457247435785074">"Osobe"</string>
<string name="contactsList" msgid="8661624236494819731">"Kontakti"</string>
<string name="shortcutContact" msgid="749243779392912958">"Kontakt"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Svi kontakti"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupe"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoriti"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Zapisnik poziva"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Pošalji tekstnu poruku"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Nazovi <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Uredi broj prije pozivanja"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Dodaj u kontakte"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Ukloni iz zapisnika poziva"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Izbriši zapisnik poziva"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Brisanje govorne pošte"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Podijeli govornu poštu"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Zapisnik poziva je prazan"</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Izbrisati dnevnik poziva?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Svi vaši zapisi poziva bit će izbrisani."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Brisanje dnevnika poziva..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Brisati podatke o čestim kontaktima?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Obrisat ćete popis osoba s kojima često kontaktirate u aplikacijama Osobe i Telefoni tako da će aplikacije e-pošte morati naučiti vaše preference adresiranja od početka."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Brisanje često kontaktiranih..."</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Postavi moj profil"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Upišite ime osobe"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Prikaži ažuriranja"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Govorna pošta"</item>
- <item quantity="other" msgid="5513481419205061254">"Br. govornih pošta: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Reproduciraj"</string>
- <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">"Nova govorna pošta od kontakta <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Reprodukcija govorne pošte nije uspjela"</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Stavljanje u međuspremnik..."</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Dohvaćanje govorne pošte..."</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Dohvaćanje govorne pošte nije uspjelo."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Novo"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Starije"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Samo pozivi s govornom poštom"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Samo dolazni pozivi"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Samo odlazni pozivi"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Samo propušteni pozivi"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Povezivanje s poslužiteljem govorne pošte nije moguće."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Vezu s poslužiteljem govorne pošte nije moguće uspostaviti. Nova govorna pošta čeka."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Postavite svoju govornu poštu."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Zvuk nije dostupan."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Postavljanje"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Zovi govornu poštu"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Najsporije"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Sporo"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Normalna brzina"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Brzo"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Najbrže"</string>
- <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>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 80268af..e985263 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telefon"</string>
<string name="people" msgid="1048457247435785074">"Személyek"</string>
<string name="contactsList" msgid="8661624236494819731">"Címtár"</string>
<string name="shortcutContact" msgid="749243779392912958">"Névjegy"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Az összes névjegy"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Csoportok"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Kedvencek"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Híváslista"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"SMS küldése"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"<xliff:g id="NAME">%s</xliff:g> hívása"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Szám szerkesztése hívás előtt"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Hozzáadás a névjegyekhez"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Eltávolítás a híváslistából"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Híváslista törlése"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Hangposta törlése"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Hangposta megosztása"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"A híváslista üres."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Törli a híváslistát?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Minden telefonhívás törlésre kerül."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Híváslista törlése..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Törli a gyakran keresetteket?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Törölni fogja a gyakran keresett személyek listáját a Személyek és a Telefon alkalmazásokban, és arra kényszeríti az e-mail alkalmazásokat, hogy újra, elölről megtanulják az Ön címzési preferenciáit."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Gyakran keresettek törlése..."</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Saját profil beállítása"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Írja be a személy nevét"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Frissítések"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Hangposta"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> hangüzenet"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Lejátszás"</string>
- <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">"Új hangüzenet tőle: <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Nem lehet lejátszani a hangpostát."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Pufferelés…"</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Hangpostaüzenet lekérése…"</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"A hangposta nem hívható le."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Új"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Régebbi"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Csak hangpostahívások"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Csak bejövő hívások"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Csak kimenő hívások"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Csak nem fogadott hívások"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Nem lehet csatlakozni a hangpostaszerverhez."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"A hangposta nem érhető el. Új hangüzenetek várakoznak."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Állítsa be a hangpostát."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Nincs hang."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Beállítás"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Hangposta hívása"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Leglassabb"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Lassú"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Normál sebesség"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Gyors"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Leggyorsabb"</string>
- <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>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 662e92c..c1f142a 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telepon"</string>
<string name="people" msgid="1048457247435785074">"Orang"</string>
<string name="contactsList" msgid="8661624236494819731">"Kontak"</string>
<string name="shortcutContact" msgid="749243779392912958">"Kontak"</string>
@@ -26,7 +25,7 @@
<string name="callShortcutActivityTitle" msgid="6065749861423648991">"Pilih nomor untuk dipanggil"</string>
<string name="messageShortcutActivityTitle" msgid="3084542316620335911">"Pilih nomor untuk dikirimi pesan"</string>
<string name="contactPickerActivityTitle" msgid="4301062192337417640">"Pilih kontak"</string>
- <string name="starredList" msgid="4817256136413959463">"Yang berkilau bintangnya"</string>
+ <string name="starredList" msgid="4817256136413959463">"Yang berbintang"</string>
<string name="frequentList" msgid="7154768136473953056">"Sering"</string>
<string name="strequentList" msgid="5640192862059373511">"Favorit"</string>
<string name="viewContactTitle" msgid="7989394521836644384">"Detail kontak"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Semua kontak"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Grup"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favorit"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telepon"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Log panggilan"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Kirim SMS"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Panggil <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Edit nomor sebelum memanggil"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Tambahkan ke kontak"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Hapus dari log panggilan"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Hapus log panggilan"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Hapus pesan suara"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Bagikan kotak pesan"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Log panggilan kosong."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Hapus log panggilan?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Semua catatan panggilan Anda akan dihapus."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Menghapus log panggilan..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Hapus yang sering dihubungi?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Anda akan menghapus daftar yang sering dihubungi pada aplikasi Orang dan Ponsel, serta memaksa aplikasi email untuk mempelajari preferensi penanganan Anda dari awal."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Menghapus yang sering dihubungi..."</string>
@@ -201,7 +186,7 @@
<string name="description_image_button_seven" msgid="2450357020447676481">"tujuh"</string>
<string name="description_image_button_eight" msgid="6969435115163287801">"delapan"</string>
<string name="description_image_button_nine" msgid="7857248695662558323">"sembilan"</string>
- <string name="description_image_button_star" msgid="3365919907520767866">"kilaukan bintang"</string>
+ <string name="description_image_button_star" msgid="3365919907520767866">"bintangi"</string>
<string name="description_image_button_zero" msgid="4133108949401820710">"nol"</string>
<string name="description_image_button_pound" msgid="3039765597595889230">"pound"</string>
<string name="description_voicemail_button" msgid="3402506823655455591">"kotak pesan"</string>
@@ -447,7 +432,7 @@
<string name="local_search_label" msgid="2551177578246113614">"Semua kontak"</string>
<string name="toast_making_personal_copy" msgid="288549957278065542">"Membuat salinan pribadi..."</string>
<string name="list_filter_all_accounts" msgid="8908683398914322369">"Semua kontak"</string>
- <string name="list_filter_all_starred" msgid="5031734941601931356">"Yang berkilau bintangnya"</string>
+ <string name="list_filter_all_starred" msgid="5031734941601931356">"Yang berbintang"</string>
<string name="list_filter_custom" msgid="8910173055702057002">"Khusus"</string>
<string name="list_filter_customize" msgid="4789963356004169321">"Khusus"</string>
<string name="list_filter_phones" msgid="735313795643493365">"Semua kontak dengan nomor telepon"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Siapkan profil saya"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Ketik nama seseorang"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Lihat pembaruan"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Pesan suara"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> Pesan suara"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Putar"</string>
- <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">"Pesan suara baru dari <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Tidak dapat memutar pesan suara."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Menyangga…"</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Mengambil pesan suara…"</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Tidak dapat mengambil pesan suara."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Baru"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Lawas"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Hanya panggilan dengan pesan suara"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Hanya panggilan masuk"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Hanya panggilan keluar"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Hanya panggilan tak terjawab"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Tidak dapat tersambung ke server kotak pesan."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Tak dpt trsmbung ke srvr ktk pesan. Ktk pesan baru sdg menunggu."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Siapkan kotak pesan Anda."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Audio tidak tersedia."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Siapkan"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Panggil pesan suara"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Kecepatan paling rendah"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Kecepatan rendah"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Kecepatan normal"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Kecepatan tinggi"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Kecepatan tertinggi"</string>
- <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>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 44f8ddf..70d2e6d 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telefono"</string>
<string name="people" msgid="1048457247435785074">"Persone"</string>
<string name="contactsList" msgid="8661624236494819731">"Contatti"</string>
<string name="shortcutContact" msgid="749243779392912958">"Contatto"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Tutti i contatti"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Gruppi"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Preferiti"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telefono"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Chiamate"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Invia messaggio di testo"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Chiama <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Modifica prima di chiamare"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Aggiungi a contatti"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Rimuovi da registro"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Cancella registro chiamate"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Elimina messaggio vocale"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Condividi messaggio vocale"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Il registro chiamate è vuoto."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Cancellare registro?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Tutte le voci nel registro chiamate verranno eliminate."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Cancellazione registro chiamate..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Cancellare contattati di frequente?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Cancellerai l\'elenco degli utenti contattati di frequente nelle applicazioni Persone e Telefono e imposterai l\'acquisizione forzata delle tue preferenze di indirizzamento da zero nelle applicazioni email."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Cancellazione contattati di frequente…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Imposta il mio profilo"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Digita il nome della persona"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Visualizza aggiornamenti"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Segreteria"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> messaggi vocali"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Riproduci"</string>
- <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">"Nuovo messaggio vocale da <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Riproduzione messaggio vocale non riuscita."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Buffering..."</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Recupero messaggi segreteria..."</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Recupero messaggi segreteria non riuscito."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Nuovi"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Precedenti"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Solo chiamate con segreteria"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Solo chiamate in arrivo"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Solo chiamate in uscita"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Solo chiamate perse"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Impossibile collegarsi al server della segreteria."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Impossibile collegarsi al server. Nuovi mess. vocali in attesa."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Imposta la tua segreteria."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Audio non disponibile."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Imposta"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Chiama segreteria"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Velocità più bassa"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Bassa velocità"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Velocità normale"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Alta velocità"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Massima velocità"</string>
- <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>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index b138e88..d999394 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"טלפון"</string>
<string name="people" msgid="1048457247435785074">"אנשים"</string>
<string name="contactsList" msgid="8661624236494819731">"אנשי קשר"</string>
<string name="shortcutContact" msgid="749243779392912958">"איש קשר"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"כל אנשי הקשר"</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>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"שלח הודעת טקסט"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"התקשר אל <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"ערוך מספר לפני השיחה"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"הוסף לאנשי הקשר"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"הסר מיומן השיחות"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"נקה יומן שיחות"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"מחק דואר קולי"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"שתף דואר קולי"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"יומן השיחות ריק."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"לנקות את יומן השיחות?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"כל רשומות השיחה שלך יימחקו."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"מנקה את יומן השיחות..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"האם למחוק אנשי קשר קבועים?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"פעולה זו תמחק את רשימת האנשים שאתה יוצר איתם קשר בתדירות הגבוהה ביותר ביישומים \'אנשים\' ו\'טלפון\' ותאלץ יישומי דוא\"ל ללמוד מהתחלה את העדפות הכתובות שלך."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"מוחק אנשי קשר קבועים…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"הגדר את הפרופיל שלי"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"הקלד שם של אדם"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"הצג עדכונים"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"דואר קולי"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> הודעות קוליות"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"הפעל"</string>
- <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_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="call_log_voicemail_header" msgid="3945407886667089173">"שיחות עם דואר קולי בלבד"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"שיחות נכנסות בלבד"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"שיחות יוצאות בלבד"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"שיחות שלא נענו בלבד"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"לא ניתן להתחבר לשרת הדואר הקולי."</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>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"התקשר לדואר קולי"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"המהירות הנמוכה ביותר"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"מהירות נמוכה"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"מהירות רגילה"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"מהירות גבוהה"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"המהירות הגבוהה ביותר"</string>
- <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>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 45a2346..4a4d3a1 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"電話"</string>
<string name="people" msgid="1048457247435785074">"連絡帳"</string>
<string name="contactsList" msgid="8661624236494819731">"連絡先"</string>
<string name="shortcutContact" msgid="749243779392912958">"連絡先"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"すべての連絡先"</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>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"SMSを送信"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"<xliff:g id="NAME">%s</xliff:g>に発信"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"発信前に番号を編集"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"連絡先に追加"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"通話履歴から消去"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"通話履歴を全件消去"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"ボイスメールを削除"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"ボイスメールを共有"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"通話履歴なし"</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"通話履歴を消しますか?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"すべての通話記録は削除されます。"</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"通話履歴を消去しています..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"よく使う連絡先をクリアしますか?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"連絡帳アプリや電話アプリのよく使う連絡先リストをクリアし、メールアプリがアドレス設定を初めから保存していくようにします。"</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"よく使う連絡先をクリアしています…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"プロフィールを設定"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"名前を入力"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"更新情報を表示"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"ボイスメール"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g>件のボイスメール"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"再生"</string>
- <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_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="call_log_voicemail_header" msgid="3945407886667089173">"ボイスメールのある着信のみ"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"着信のみ"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"発信のみ"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"不在着信のみ"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"ボイスメールサーバーに接続できません。"</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>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"ボイスメール呼び出し"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"最も遅い"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"遅い"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"標準"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"速い"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"最も速い"</string>
- <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>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 0d32153..fbba169 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"휴대전화"</string>
<string name="people" msgid="1048457247435785074">"피플"</string>
<string name="contactsList" msgid="8661624236494819731">"주소록"</string>
<string name="shortcutContact" msgid="749243779392912958">"연락처"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"모든 연락처"</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>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"문자 메시지 보내기"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"전화걸기: <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"통화하기 전에 번호 수정"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"주소록에 추가"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"통화기록에서 삭제"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"통화기록 지우기"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"음성사서함 삭제"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"음성사서함 공유"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"통화기록이 없습니다."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"통화기록을 지우시겠습니까?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"모든 통화 기록을 삭제합니다."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"통화기록을 지우는 중..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"자주 연락하는 사람들 목록을 삭제하시겠습니까?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"피플 및 휴대전화 앱에서 자주 연락하는 사람들 목록을 삭제하고 이메일 앱이 주소록 환경설정을 처음부터 다시 반영하도록 합니다."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"자주 연락하는 사람들 목록을 삭제하는 중…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"내 프로필 설정"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"이름 입력"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"업데이트 보기"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"음성사서함"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g>개의 음성사서함"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"재생"</string>
- <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_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="call_log_voicemail_header" msgid="3945407886667089173">"음성사서함 메시지만"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"수신 전화만"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"발신 전화만"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"부재중 전화만"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"음성사서함 서버에 연결할 수 없습니다."</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>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"음성사서함 연결"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"가장 느린 속도"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"느린 속도"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"보통 속도"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"빠른 속도"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"가장 빠른 속도"</string>
- <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>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 61e78a5..322e26f 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telefonas"</string>
<string name="people" msgid="1048457247435785074">"Žmonės"</string>
<string name="contactsList" msgid="8661624236494819731">"Adresinė"</string>
<string name="shortcutContact" msgid="749243779392912958">"Adresatas"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Visi kontaktai"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupės"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Adresynas"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telefonas"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Skambučių žurnalas"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Siųsti teksto pranešimą"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Skambinti <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Redaguoti numerį prieš skambutį"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Pridėti prie adresatų"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Pašalinti iš skambučių žurnalo"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Išvalyti skambučių žurnalą"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Ištrinti balso pašto pran."</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Bendrinti balso paštą"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Skambučių žurnalas tuščias."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Išv. skamb. žurnalą?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Visi jūsų skambučių įrašai bus ištrinti."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Valomas skambučių žurnalas…"</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Išvalyti dažniaus. naud. kontaktus?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Išvalysite dažniausiai naudojamų kontaktų sąrašą Žmonių ir Telefono programose, o el. pašto programoms reikės iš naujo gauti adresavimo nuostatas."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Valomi dažniaus. naud. kontaktai…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Nustatyti mano profilį"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Įveskite asmens vardą ir (arba) pavardę"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Žiūrėti naujinius"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Balso paštas"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> balso pašto pranešim."</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Paleisti"</string>
- <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">"Nauji b. pašto pran. iš <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Nepavyko paleisti balso pašto praneš."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Rašoma į buferį…"</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Gaunamas balso paštas…"</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Nepavyko gauti balso pašto pranešimo."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Nauji"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Senesni"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Tik skambučiai su balso paštu"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Tik gaunami skambučiai"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Tik siunčiami skambučiai"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Tik praleisti skambučiai"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Neįmanoma prisijungti prie balso pašto serverio."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Neįm. prisij. prie bal. pšt. serv. Laukia nauji b. pšt. praneš."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Nustatyti balso paštą."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Garsas negalimas."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Nustatyti"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Skamb. į balso pšt."</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Mažiausias greitis"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Mažas greitis"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Normalus greitis"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Didelis greitis"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Didžiausias greitis"</string>
- <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>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 09ffc4c..20c0d94 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Tālrunis"</string>
<string name="people" msgid="1048457247435785074">"Kontakti"</string>
<string name="contactsList" msgid="8661624236494819731">"Kontaktpersonas"</string>
<string name="shortcutContact" msgid="749243779392912958">"Kontaktpersona"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Visas kontaktpersonas"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupas"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Izlase"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Zvanīt"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Zvanu žurnāls"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Sūtīt īsziņu"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Zvanīt: <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Rediģēt numuru pirms zvanīšanas"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Pievienot kontaktpersonām"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Noņemt no zvanu žurnāla"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Notīrīt zvanu žurnālu"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Dzēst balss pasta ziņojumu"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Kopīgot balss pastu"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Zvanu žurnāls ir tukšs."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Vai not. zv. žurn.?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Visi zvanu ieraksti tiks dzēsti."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Notiek zvanu žurnāla tīrīšana..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Vai dzēst bieži lietotos kontaktus?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Tiks dzēsts bieži lietoto kontaktpersonu saraksts lietotnēs Personas un Tālrunis, un e-pasta lietotnēs adrešu preferenču saglabāšana tiks sākta no sākuma."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Bieži lietoto kontaktu dzēšana..."</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Iestatīt savu profilu"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Rakstiet personas vārdu."</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Skatīt atjaunināj."</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Balss pasts"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> balss pasta ziņojums(-i)"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Atskaņot"</string>
- <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">"Jauns b. pasta ziņ. no: <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Nevarēja atskaņot balss pasta ziņojumu."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Notiek buferizācija..."</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Notiek balss pasta iegūšana..."</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Nevarēja iegūt balss pasta ziņojumu."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Jauns"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Vecāki"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Tikai balss pasta zvani"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Tikai ienākošie zvani"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Tikai izejošie zvani"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Tikai neatbildētie zvani"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Nevar izveidot savienojumu ar balss pasta serveri."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Nevar izv. sav. ar b. pasta serv. Ienākuši jauni b. pasta ziņ."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Iestatiet balss pastu."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Audio nav pieejams."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Iestatīt"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Zvanīt balss pastam"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Mazākais ātrums"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Mazs ātrums"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Parasts ātrums"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Liels ātrums"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Lielākais ātrums"</string>
- <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>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 375530f..d017eef 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telefon"</string>
<string name="people" msgid="1048457247435785074">"Orang"</string>
<string name="contactsList" msgid="8661624236494819731">"Kenalan"</string>
<string name="shortcutContact" msgid="749243779392912958">"Kenalan"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Semua kenalan"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Kumpulan"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Kegemaran"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Log panggilan"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Hantar mesej teks"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Panggil <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Edit nombor sebelum panggilan"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Tambah ke kenalan"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Alih keluar daripada log panggilan"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Padam bersih log panggilan"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Padamkan mel suara"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Kongsi mel suara"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Log panggilan kosong."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Padam bersih log panggilan?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Semua rekod panggilan anda akan dipadamkan."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Memadam bersih log panggilan..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Padam bersih senarai kerap dihubungi?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Anda akan mengosongkan senarai orang yang kerap dihubungi dalam apl Orang dan Telefon serta memaksa apl e-mel untuk mempelajari pilihan alamat anda dari awal."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Memadam bersih senarai kerap dihubungi..."</string>
@@ -499,35 +484,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Sediakan profil saya"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Taip nama orang"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Lihat kemas kini"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Mel suara"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> Mel suara"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Main"</string>
- <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">"Mel suara baru daripada <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Tidak dapat memainkan mel suara."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Menimbal…"</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Sedang mendapatkan mel suara…"</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Tidak dapat mengambil mel suara."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Baru"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Lebih lama"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Panggilan dengan mel suara sahaja"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Panggilan masuk sahaja"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Panggilan keluar sahaja"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Panggilan terlepas sahaja"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Tidak boleh bersambung kepada pelayan mel suara."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Tak boleh brsmbg kpd pelayan mel suara. Mel suara baru menunggu."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Sediakan mel suara anda."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Audio tidak tersedia."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Menyediakan"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Panggil mel suara"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"kelajuan paling perlahan"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Kelajuan perlahan"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Kelajuan biasa"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Kelajuan pantas"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Kelajuan paling pantas"</string>
- <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">"Tunjuk panggilan keluar shj"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 1389805..aa29277 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telefon"</string>
<string name="people" msgid="1048457247435785074">"Personer"</string>
<string name="contactsList" msgid="8661624236494819731">"Kontakter"</string>
<string name="shortcutContact" msgid="749243779392912958">"Kontakt"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Alle kontakter"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupper"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoritter"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Logg"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Send SMS-melding"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Ring <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Rediger nummer før anrop"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Legg til kontakter"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Fjern fra anropslogg"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Tøm anropslogg"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Slett talepost"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Del talepost"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Anropsloggen er tom."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Tømme samtaleloggen?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Alle samtalelogger kommer til å slettes."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Tømmer anropsloggen …"</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Fjerne ofte kontaktede personer?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Du fjerner listen over ofte kontaktede personer i Personer-appen og Telefon-appen, og tvinger e-postappene til å bli kjent med adresseinnstillingene fra grunnen av."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Fjerner ofte kontaktede personer"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Konfigurer profilen min"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Tast inn personens navn"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Se oppdateringer"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Talepostkasse"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> talemeldinger"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Spill av"</string>
- <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">"Nye talemeldinger fra <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Kunne ikke spille av talemelding."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Bufrer …"</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Henter talepost …"</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Kunne ikke hente talepost."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Nytt"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Eldre"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Bare anrop som gikk til talepostkasse"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Bare innkommende anrop"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Bare utgående anrop"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Bare ubesvarte anrop"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Kan ikke koble til taleposttjener."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Kan ikke koble til taleposttjener. Nye talemeldinger venter."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Konfigurer talepost."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Lyd er ikke tilgjengelig."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Konfigurer"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Ring talepostkasse"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Laveste hastighet"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Lav hastighet"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Normal hastighet"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Høy hastighet"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Høyeste hastighet"</string>
- <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>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 95f6907..bcff131 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telefoon"</string>
<string name="people" msgid="1048457247435785074">"Personen"</string>
<string name="contactsList" msgid="8661624236494819731">"Contacten"</string>
<string name="shortcutContact" msgid="749243779392912958">"Contacten"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Alle contacten"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Groepen"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoriet"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telefoon"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Gesprek"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Sms verzenden"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"<xliff:g id="NAME">%s</xliff:g> bellen"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Nummer bewerken voor bellen"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Toevoegen aan contacten"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Verwijderen uit Gesprekken"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Gesprekken wissen"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Voicemail verwijderen"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Voicemail delen"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Gesprekken is leeg"</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Oproeplog wissen?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Al uw oproepgegevens worden verwijderd."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Oproeplogboek wissen..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Lijst met regelmatige contacten wissen?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"U wist de lijst met contacten waarmee u regelmatig contact opneemt in de apps Personen en Telefoon, en e-mailapps moeten uw voorkeursadressen weer opnieuw leren."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Regelmatige contacten wissen..."</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Mijn profiel instellen"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Typ de naam van de persoon"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Updates bekijken"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Voicemail"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> voicemails"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Afspelen"</string>
- <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">"Nieuwe voicemail van <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Kan voicemail niet afspelen."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"In buffer opslaan…"</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Voicemail ophalen…"</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Kan voicemail niet ophalen."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Nieuw"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Ouder"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Alleen oproepen met voicemail"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Alleen inkomende oproepen"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Alleen uitgaande oproepen"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Alleen gemiste oproepen"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Kan geen verbinding maken met de voicemailserver."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Kan niet verbinden met voicemailservers. Er is nieuwe voicemail."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Stel uw voicemail in."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Audio niet beschikbaar."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Instellen"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Bellen met voicemail"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Laagste snelheid"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Lage snelheid"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Normale snelheid"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Hoge snelheid"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Hoogste snelheid"</string>
- <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>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 6a71556..618eb06 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telefon"</string>
<string name="people" msgid="1048457247435785074">"Osoby"</string>
<string name="contactsList" msgid="8661624236494819731">"Kontakty"</string>
<string name="shortcutContact" msgid="749243779392912958">"Kontakt"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Wszystkie kontakty"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupy"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Ulubione"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Rejestr"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Wyślij wiadomość tekstową"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Zadzwoń do: <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Edytuj numer przed nawiązaniem połączenia"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Dodaj do kontaktów"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Usuń z rejestru połączeń"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Wyczyść rejestr połączeń"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Usuń pocztę głosową"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Udostępnij pocztę głosową"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Rejestr połączeń jest pusty."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Usunąć rejestr połączeń?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Wszystkie dane połączeń zostaną usunięte."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Czyszczenie rejestru połączeń…"</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Wyczyścić częste kontakty?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Wyczyścisz listę częstych kontaktów w aplikacjach Osoby i Telefon. Aplikacje pocztowe będą musiały od nowa poznawać Twoje preferencje adresowe."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Czyszczę częste kontakty…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Konfiguruj profil"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Wpisz imię osoby"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Pokaż aktualizacje"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Poczta głosowa"</item>
- <item quantity="other" msgid="5513481419205061254">"Wiadomości głosowe: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Odtwórz"</string>
- <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">"Nowa poczta głosowa od: <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Nie można odtworzyć poczty głosowej."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Buforowanie..."</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Pobieranie poczty głosowej..."</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Nie można pobrać poczty głosowej."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Nowe"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Starsze"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Tylko połączenia z pocztą głosową"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Tylko połączenia przychodzące"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Tylko połączenia wychodzące"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Tylko połączenia nieodebrane"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Nie można połączyć z serwerem poczty głosowej."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Nie można połączyć z pocztą głosową. Masz nowe wiadomości."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Skonfiguruj pocztę głosową."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Dźwięk jest niedostępny."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Konfiguracja"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Połącz z pocztą"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Najwolniej"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Wolno"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Normalnie"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Szybko"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Najszybciej"</string>
- <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>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 148973e..e603b72 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telefone"</string>
<string name="people" msgid="1048457247435785074">"Pessoas"</string>
<string name="contactsList" msgid="8661624236494819731">"Contactos"</string>
<string name="shortcutContact" msgid="749243779392912958">"Contacto"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Todos os contactos"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupos"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoritos"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telefone"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Chamadas"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Enviar mensagem de texto"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Ligar a <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Editar número antes de efectuar a chamada"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Adicionar aos contactos"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Remover do registo de chamadas"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Limpar registo de chamadas"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Eliminar correio de voz"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Partilhar correio de voz"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"O registo de chamadas está vazio."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Limpar reg. de cham.?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Todos os registos de chamadas serão eliminados."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"A limpar registo de chamadas..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Limpar contactos frequentes?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Irá limpar a lista de contactos frequentes nas aplicações Pessoas e Telemóvel e forçar as aplicações de email a aprenderem as suas preferências de endereço de raiz."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"A limpar contactos frequentes..."</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Configurar o meu perfil"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Introduza o nome da pessoa"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Ver atualizações"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Correio de voz"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> Mensagens de correio de voz"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Reproduzir"</string>
- <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">"Nova msg de correio de voz de <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Não foi possível reprod. correio de voz."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"A colocar na memória intermédia..."</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"A obter correio de voz..."</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Não foi possível obter correio de voz."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Novo"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"+ antigo"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Apenas chamadas com correio de voz"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Apenas chamadas recebidas"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Apenas chamadas efetuadas"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Apenas chamadas não atendidas"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Não é possível ligar ao servidor de correio de voz."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Não é possível ligar ao serv. corr. voz. Novas msgs à espera."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Configure o seu correio de voz."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"O áudio não está disponível."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Configurar"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Chamar correio de voz"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Velocidade mais lenta"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Velocidade reduzida"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Velocidade normal"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Velocidade rápida"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Velocidade mais rápida"</string>
- <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>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 8d61af3..84dc7de 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telefone"</string>
<string name="people" msgid="1048457247435785074">"Pessoas"</string>
<string name="contactsList" msgid="8661624236494819731">"Contatos"</string>
<string name="shortcutContact" msgid="749243779392912958">"Contato"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Todos os contatos"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupos"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoritos"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telefone"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Chamadas"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Enviar SMS/MMS"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Chamar <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Editar número antes da chamada"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Adicionar aos contatos"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Remover do registro de chamadas"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Limpar registro de chamadas"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Excluir correio de voz"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Compartilhar correio de voz"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"O registro de chamadas está vazio."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Limpar registro de chamadas?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Todos os registros de chamada serão eliminados."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Limpando o registro de chamadas..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Apagar contatos frequentes?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Você apagará a lista de contatos frequentes nos aplicativos Pessoas e Telefone, fazendo com que os aplicativos de e-mail tenham que descobrir suas preferências de endereço."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Apagando contatos frequentes…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Configurar meu perfil"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Digite o nome da pessoa"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Ver atualizações"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Mensagem de voz"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> mensagens de voz"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Reproduzir"</string>
- <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">"Nova mensagem de voz de <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Não foi possível reprod. mens. de voz."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Armazenar em buffer…"</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Buscando o correio de voz…"</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Não foi possível obter o correio de voz."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Novas"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Antigas"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Somente chamadas com correio de voz"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Somente chamadas recebidas"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Somente chamadas de saída"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Somente chamadas perdidas"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Não é possível se conectar ao servidor de correio de voz."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Impossível conect. ao serv. correio voz. Novas mensagens de voz."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Configure seu correio de voz."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Áudio não disponível."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Configurar"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Chamar correio voz"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Velocidade mais lenta"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Baixa velocidade"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Velocidade normal"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Velocidade rápida"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Velocidade mais rápida"</string>
- <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>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index 507c96a..3fd3f6e 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telefon"</string>
<!-- no translation found for people (1048457247435785074) -->
<skip />
<string name="contactsList" msgid="8661624236494819731">"Contacts"</string>
@@ -183,25 +182,6 @@
<!-- no translation found for contactsGroupsLabel (2841971472518003524) -->
<skip />
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favurits"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Cloms"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Trametter in SMS"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Telefonar a(d) <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Modifitgar il numer avant che telefonar"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Agiuntar als contacts"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Allontanar da la glista da cloms"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Stizzar la glista da cloms"</string>
- <!-- no translation found for recentCalls_trashVoicemail (7604696960787435655) -->
- <skip />
- <!-- no translation found for recentCalls_shareVoicemail (1416112847592942840) -->
- <skip />
- <string name="recentCalls_empty" msgid="247053222448663107">"La glista da cloms e vida"</string>
- <!-- no translation found for clearCallLogConfirmation_title (6427524640461816332) -->
- <skip />
- <!-- no translation found for clearCallLogConfirmation (5043563133171583152) -->
- <skip />
- <!-- no translation found for clearCallLogProgress_title (8365943000154295771) -->
- <skip />
<!-- no translation found for clearFrequentsConfirmation_title (766292372438450432) -->
<skip />
<!-- no translation found for clearFrequentsConfirmation (3254215748990281318) -->
@@ -704,58 +684,6 @@
<skip />
<!-- no translation found for view_updates_from_group (1782685984905600034) -->
<skip />
- <!-- no translation found for notification_voicemail_title:one (1746619685488504230) -->
- <!-- no translation found for notification_voicemail_title:other (5513481419205061254) -->
- <!-- no translation found for notification_action_voicemail_play (6113133136977996863) -->
- <skip />
- <!-- no translation found for notification_voicemail_callers_list (1153954809339404149) -->
- <skip />
- <!-- no translation found for notification_new_voicemail_ticker (895342132049452081) -->
- <skip />
- <!-- no translation found for voicemail_playback_error (1811242131549854624) -->
- <skip />
- <!-- no translation found for voicemail_buffering (738287747618697097) -->
- <skip />
- <!-- no translation found for voicemail_fetching_content (877911315738258780) -->
- <skip />
- <!-- no translation found for voicemail_fetching_timout (6691792377574905201) -->
- <skip />
- <!-- no translation found for call_log_new_header (846546437517724715) -->
- <skip />
- <!-- no translation found for call_log_old_header (6262205894314263629) -->
- <skip />
- <!-- no translation found for call_log_voicemail_header (3945407886667089173) -->
- <skip />
- <!-- no translation found for call_log_incoming_header (2787722299753674684) -->
- <skip />
- <!-- no translation found for call_log_outgoing_header (761009180766735769) -->
- <skip />
- <!-- no translation found for call_log_missed_header (8017148056610855956) -->
- <skip />
- <!-- no translation found for voicemail_status_voicemail_not_available (3021980206152528883) -->
- <skip />
- <!-- no translation found for voicemail_status_messages_waiting (7113421459602803605) -->
- <skip />
- <!-- no translation found for voicemail_status_configure_voicemail (3738537770636895689) -->
- <skip />
- <!-- no translation found for voicemail_status_audio_not_available (3369618334553341626) -->
- <skip />
- <!-- no translation found for voicemail_status_action_configure (8671796489912239589) -->
- <skip />
- <!-- no translation found for voicemail_status_action_call_server (1824816252288551794) -->
- <skip />
- <!-- no translation found for voicemail_speed_slowest (1733460666177707312) -->
- <skip />
- <!-- no translation found for voicemail_speed_slower (1508601287347216244) -->
- <skip />
- <!-- no translation found for voicemail_speed_normal (9033988544627228892) -->
- <skip />
- <!-- no translation found for voicemail_speed_faster (2019965121475935488) -->
- <skip />
- <!-- no translation found for voicemail_speed_fastest (5758712343491183292) -->
- <skip />
- <!-- no translation found for call_log_item_count_and_date (7641933305703520787) -->
- <skip />
<!-- no translation found for group_name_hint (238359485263401293) -->
<skip />
<!-- no translation found for nfc_vcard_file_name (2823095213265993609) -->
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 2d41bf2..c010be0 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telefon"</string>
<string name="people" msgid="1048457247435785074">"Persoane"</string>
<string name="contactsList" msgid="8661624236494819731">"Agendă"</string>
<string name="shortcutContact" msgid="749243779392912958">"Persoană din Agendă"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Toată Agenda"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupuri"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favorite"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Jurnal de apeluri"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Trimiteţi un mesaj text"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Apelaţi <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Modificaţi numărul înainte de apelare"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Adăugaţi la persoane din agendă"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Eliminaţi din jurnalul de apeluri"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Ştergeţi jurnalul de apeluri"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Ştergeţi mesajul vocal"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Distribuiţi mesajul vocal"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Jurnalul de apeluri este gol."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Ştergeţi apelurile?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Toate înregistrările apelurilor dvs. vor fi şterse."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Se goleşte jurnalul de apeluri..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Ştergeţi persoane frecvent contactate?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Veţi şterge lista cu persoanele contactate cel mai frecvent din aplicaţiile Persoane şi Telefon şi veţi forţa aplicaţiile de e-mail să reţină preferinţele dvs. pentru adrese de la zero."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Ştergeți persoane frecv. contactate…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Configuraţi profilul"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Introduceţi numele persoanei"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Afişaţi actualizări"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Mesaj vocal"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> (de) mesaje vocale"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Redaţi"</string>
- <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">"Mesaj vocal nou de la <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Nu s-a putut reda mesajul vocal."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Se utilizează memoria tampon..."</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Se preia mesajul vocal..."</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Nu s-a putut prelua mesajul vocal."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Noi"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Mai vechi"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Numai apelurile cu mesaje vocale"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Numai apelurile primite"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Numai apelurile efectuate"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Numai apelurile nepreluate"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Nu se poate realiza conectarea la serverul de mesagerie vocală."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Nu se conectează server mesagerie vocală. Aşteaptă mesaje noi."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Configuraţi mesageria vocală."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Componenta audio nu este disponibilă."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Configuraţi"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Apel. mesag. vocală"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Viteză minimă"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Viteză redusă"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Viteză normală"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Viteză crescută"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Viteză maximă"</string>
- <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>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index cabde2f..330348a 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Телефон"</string>
<string name="people" msgid="1048457247435785074">"Контакты"</string>
<string name="contactsList" msgid="8661624236494819731">"Контакты"</string>
<string name="shortcutContact" msgid="749243779392912958">"Контакт"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Все контакты"</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>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Отправить SMS"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Вызов: <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Изменить номер и вызвать"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Добавить в контакты"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Удалить из списка вызовов"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Очистить список"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Удалить голосовое сообщение"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Поделиться"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Список вызовов пуст."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Удаление данных"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Журнал звонков будет очищен."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Очистка списка вызовов..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Очистить список популярных контактов?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Список популярных контактов в приложениях \"Контакты\" и \"Телефон\" будет очищен, и почтовые приложения начнут создавать этот список заново."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Подождите…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Настроить профиль"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Имя контакта"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Обновления"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Голосовая почта"</item>
- <item quantity="other" msgid="5513481419205061254">"Голосовые сообщения: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Прослушать"</string>
- <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_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="call_log_voicemail_header" msgid="3945407886667089173">"Только звонки с голосовой почтой"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Только входящие звонки"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Только исходящие звонки"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Только пропущенные звонки"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Не удалось подключиться к серверу голосовой почты."</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>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Получить почту"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Минимальная скорость"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Низкая скорость"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Средняя скорость"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Высокая скорость"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Максимальная скорость"</string>
- <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>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 6de2e27..b7b2da7 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telefón"</string>
<string name="people" msgid="1048457247435785074">"Ľudia"</string>
<string name="contactsList" msgid="8661624236494819731">"Kontakty"</string>
<string name="shortcutContact" msgid="749243779392912958">"Kontakt"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Všetky kontakty"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Skupiny"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Obľúbené"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telefón"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Denník hovorov"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Poslať textovú správu"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Zavolať kontakt <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Pred volaním upraviť číslo"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Pridať medzi kontakty"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Odstrániť zo záznamu hovorov"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Vymazať záznam hovorov"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Odstrániť hlasovú správu"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Zdieľať hlasovú správu"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Záznam hovorov je prázdny."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Vymazať záznam hov.?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Všetky záznamy o hovoroch budú odstránené."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Vymazávanie denníka hovorov..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Vymazať často kontaktované osoby?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Vymažete zoznam často kontaktovaných osôb v aplikáciách Ľudia a Telefón a použijete odznova predvoľby adresátov v e-mailových aplikáciách."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Mazanie často kontaktovaných osôb."</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Nastaviť môj profil"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Zadajte meno osoby"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Zobraziť aktualizácie"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Hlasová správa"</item>
- <item quantity="other" msgid="5513481419205061254">"Počet hlasových správ: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Prehrať"</string>
- <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">"Nová hlasová správa – <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Nepodarilo sa prehrať hlasovú správu."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Ukladanie do vyrovnávacej pamäte…"</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Načítavanie hlasovej správy…"</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Nepodarilo sa načítať hlasovú správu."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Nové"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Staršie"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Iba volania do hlasovej schránky"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Iba prichádzajúce hovory"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Iba odchádzajúce hovory"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Iba zmeškané hovory"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Nepodarilo sa pripojiť k serveru hlasovej schránky."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Nepodarilo sa prip. k serveru hl. schránky. Nové hlas. správy."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Nastavenie hlasovej schránky."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Zvuk nie je k dispozícii."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Nastavenie"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Volať hlas. schránku"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Najnižšia rýchlosť"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Nízka rýchlosť"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Normálna rýchlosť"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Vysoká rýchlosť"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Najvyššia rýchlosť"</string>
- <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>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 7b65a36..d8a0b0b 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telefon"</string>
<string name="people" msgid="1048457247435785074">"Ljudje"</string>
<string name="contactsList" msgid="8661624236494819731">"Stiki"</string>
<string name="shortcutContact" msgid="749243779392912958">"Vizitka"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Vsi stiki"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Skupine"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Priljubljeno"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Dnevnik klicev"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Pošlji besedilno sporočilo"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Pokliči <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Pred klicanjem uredi številko"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Dodaj med stike"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Odstrani iz dnevnika klicev"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Počisti dnevnik klicev"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Brisanje sporočil odzivnika"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Skupna raba odzivnika"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Dnevnik klicev je prazen."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Izbr. dnev. klicev?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Vsi vaši zapisi bodo izbrisani."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Brisanje dnevnika klicev ..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Želite izbrisati seznam pog. stikov?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Izbrisali boste seznam pogostih stikov v aplikacijah Ljudje in Telefon, zato bodo e-poštne aplikacije začele shranjevati vaše pogoste naslovnike od začetka."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Brisanje seznama pogostih stikov …"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Nastavi moj profil"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Vnesite ime osebe"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Prikaz posodobitev"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Sporočila glasovne pošte"</item>
- <item quantity="other" msgid="5513481419205061254">"Št. sporočil glasovne pošte: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Predvajaj"</string>
- <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">"Nova glasovna pošta od <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Sporočil odzivn. ni mogoče predvajati."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Medpomnjenje…"</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Prejemanje sporočil odzivnika…"</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Sporočil odzi. ni bilo mogoče prejeti."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Novo"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Starejši"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Samo klici z odzivnikom"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Samo dohodni klici"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Samo odhodni klici"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Samo neodgovorjeni klici"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"S strežnikom za odzivnik se ni mogoče povezati."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"S strež. odzivnika se ni mogoče povezati. Nova sporočila čakajo."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Nastavite odzivnik."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Zvok ni na voljo."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Nastavite odzivnik"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Klicanje glasovne pošte"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Najpočasnejše predvajanje"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Počasno predvajanje"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Običajna hitrost"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Hitro predvajanje"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Najhitrejše predvajanje"</string>
- <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>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 02d38a8..9997eb9 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Телефон"</string>
<string name="people" msgid="1048457247435785074">"Особе"</string>
<string name="contactsList" msgid="8661624236494819731">"Контакти"</string>
<string name="shortcutContact" msgid="749243779392912958">"Контакт"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Сви контакти"</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>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Пошаљи SMS"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Позови <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Измените број пре позива"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Додај у контакте"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Уклони из евиденције позива"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Обриши евиденцију позива"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Избриши говорну поруку"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Дели говорну поруку"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Евиденција позива је празна."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Обрисати евиденцију позива?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Све евиденције позива ће бити избрисане."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Брисање евиденције позива..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Брисање често контактираних?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Обрисаћете листу често контактираних у апликацијама Људи и Телефон, па ће апликације е-поште морати из почетка да сакупе информације о адресирању."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Брисање често контактираних..."</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Подеси мој профил"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Унесите име особе"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Прикажи ажурирања"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Говорна пошта"</item>
- <item quantity="other" msgid="5513481419205061254">"Говорних порука: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Пусти"</string>
- <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_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="call_log_voicemail_header" msgid="3945407886667089173">"Само позиви са говорном поштом"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Само долазни позиви"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Само одлазни позиви"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Само пропуштени позиви"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Није могуће повезати се са сервером говорне поште."</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>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Зови говорну пошту"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Најмања брзина"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Мала брзина"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Нормална брзина"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Велика брзина"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Највећа брзина"</string>
- <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>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 118a33b..684b375 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telefon"</string>
<string name="people" msgid="1048457247435785074">"Personer"</string>
<string name="contactsList" msgid="8661624236494819731">"Kontakter"</string>
<string name="shortcutContact" msgid="749243779392912958">"Kontakt"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Alla kontakter"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Grupper"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Favoriter"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Samtalshistorik"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Skicka SMS"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Ring <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Redigera nummer före samtal"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Lägg till i Kontakter"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Ta bort från samtalshistorik"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Rensa samtalshistorik"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Ta bort röstmeddelande"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Dela röstmeddelande"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Samtalshistoriken är tom."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Rensa samtalslista?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Alla samtalslistor kommer att tas bort."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Samtalshistoriken rensas …"</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Rensa listan?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Du rensar listan över personer som du kontaktar ofta i apparna Personer och Telefon, och e-postappar tvingas lära sig dina mottagarinställningar från början."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Listan rensas …"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Skapa min profil"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Ange personens namn"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Visa uppdateringar"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Röstmeddelanden"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> röstmeddelanden"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Spela upp"</string>
- <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">"Nytt röstmeddelande från <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Det gick inte att spela upp röstmeddelandet."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Buffrar…"</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Hämtar röstmedelande…"</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Det gick inte att hämta röstmeddelandet."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Nya"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Äldre"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Endast samtal med röstmeddelande"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Endast inkommande samtal"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Endast utgående samtal"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Endast missade samtal"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Det går inte att ansluta till röstbrevlådan."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Kan inte ansluta till röstbrevlådan. Nya meddelanden väntar."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Konfigurera röstbrevlådan."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Ljud saknas."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Konfigurera"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Ring röstbrevlådan"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Lägsta hastighet"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Låg hastighet"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Normal hastighet"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Hög hastighet"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Högsta hastigheten"</string>
- <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>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 8cd0a80..289661f 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Simu"</string>
<string name="people" msgid="1048457247435785074">"Watu"</string>
<string name="contactsList" msgid="8661624236494819731">"Anwani"</string>
<string name="shortcutContact" msgid="749243779392912958">"Anwani"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Anwani zote"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Vikundi"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Vipendwa"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Simu"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Logi ya orodha ya kupiga simu"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Tuma ujumbe wa maandishi"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Pigia <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Hariri nambari kabla ya kupiga"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Ongeza kwa anwani"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Toa kwa orodha ya simu zilizopigwa"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Futa rekodi ya simu"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Futa barua ya sauti"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Shiriki barua ya sauti"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Orodha ya kupiga simu ni tupu."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Futa rekodi ya simu?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Kumbukumbu zako zote za simu zitafutwa."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Inafuta rekodi ya simu ..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Futa uliowasiliana nao mara kwa mara?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Utafuta orodha ya unaowasiliana nao mara kwa mara katika programu ya Watu na Simu, na ulazimishe programu za barua pepe kujifunza mapendeleo yako ya anwani kutoka mwanzo."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Inafuta uliowasiliana nao mara kwa mara..."</string>
@@ -291,7 +276,7 @@
<string name="menu_contacts_filter" msgid="2165153460860262501">"Anwani za kuonyesha"</string>
<string name="menu_import_export" msgid="26217871113229507">"Leta/hamisha"</string>
<string name="dialog_import_export" msgid="4360648034889921624">"Leta/Hamisha wawasiliani"</string>
- <string name="dialog_import" msgid="2431698729761448759">"Ingiza wasiliani"</string>
+ <string name="dialog_import" msgid="2431698729761448759">"Ingiza anwani"</string>
<string name="menu_share" msgid="943789700636542260">"Shiriki"</string>
<string name="share_via" msgid="563121028023030093">"Shiriki anwani kupitia"</string>
<string name="share_error" msgid="948429331673358107">"Mwasiliani huyu hawezi kushirikishwa."</string>
@@ -452,7 +437,7 @@
<string name="list_filter_all_starred" msgid="5031734941601931356">"Zenye Nyota"</string>
<string name="list_filter_custom" msgid="8910173055702057002">"Maalum"</string>
<string name="list_filter_customize" msgid="4789963356004169321">"Geuza kukufaa"</string>
- <string name="list_filter_phones" msgid="735313795643493365">"Wasiliani wote walio na nambari ya simu"</string>
+ <string name="list_filter_phones" msgid="735313795643493365">"Anwani zote zilizo na nambari za simu"</string>
<string name="list_filter_single" msgid="5871400283515893087">"Anwani"</string>
<string name="custom_list_filter" msgid="7836035257402013957">"Bainisha mwonekano maalum"</string>
<string name="contact_list_loading" msgid="5488620820563977329">"Inapakia…"</string>
@@ -473,7 +458,7 @@
<string name="social_widget_loading" msgid="5327336597364074608">"Inapakia…"</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="contacts_unavailable_import_contacts" msgid="4957393255392437529">"Ingiza anwani"</string>
<string name="create_group_dialog_title" msgid="6874527142828424475">"Unda kikundi kipya"</string>
<string name="create_group_item_label" msgid="4411981763169654825">"Unda kikundi kipya"</string>
<plurals name="num_groups_in_account">
@@ -499,35 +484,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Unda wasifu wangu"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Charaza jina la mtu"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Tazama visasisho"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Barua ya sauti"</item>
- <item quantity="other" msgid="5513481419205061254">"Barua za sauti <xliff:g id="COUNT">%1$d</xliff:g>"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Cheza"</string>
- <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">"Barua mpya ya sauti kutoka <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Haikuweza kucheza barua ya sauti."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Inaakibisha…"</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Inaleta barua ya sauti…"</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Haikuweza kuleta barua ya sauti."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Mpya"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Nzee zaidi"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Simu zilizo na ujumbe wa sauti tu"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Simu zinazoingia tu"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Simu zinazotoka tu"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Simu zisizojibiwa tu"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Haiwezi kuunganisha kwa seva ya ujumbe wa sauti."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Haiwezi kuunganishwa kwenye seva ya ujumbe wa sauti. Jumbe mpya za sauti zinasubiri."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Sanidi ujumbe wako wa sauti."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Sauti haipatikani."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Sanidi"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Pigia barua sauti"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Kasi ya taratibu zaidi"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Kasi ya taratibu"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Kasi ya kawaida"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Kasi ya haraka"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Kasi ya haraka zaidi"</string>
- <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>
@@ -557,9 +513,9 @@
<string name="external_profile_title" msgid="8034998767621359438">"Wasifu wangu wa <xliff:g id="EXTERNAL_SOURCE">%1$s</xliff:g>"</string>
<string name="toast_displaying_all_contacts" msgid="2737388783898593875">"Inaonyesha anwani zote"</string>
<string name="no_account_prompt" msgid="7061052512446855192">"Watu wanafanya kazi vizuri wakiwa na Akaunti ya Google. "\n" "\n" • Iangalie kwa kutumia kivinjari chochote. "\n" • Tunza mawasiliano yako kwa usalama."</string>
- <string name="generic_no_account_prompt" msgid="7218827704367325460">"Weka wasiliani wako salama hata ukipoteza simu yako: landanisha na huduma ya tovuti."</string>
+ <string name="generic_no_account_prompt" msgid="7218827704367325460">"Weka anwani za unaowasiliana nao salama hata ukipoteza simu yako: sawazisha kwa huduma iliyo mtandaoni."</string>
<string name="generic_no_account_prompt_title" msgid="753783911899054860">"Ongeza akaunti"</string>
- <string name="contact_editor_prompt_zero_accounts" msgid="1785345895691886499">"Mwasiliani wako mpya hatahifadhiwa. Ongeza akaunti ambayo inahifadhi wasiliani katika mtandao?"</string>
+ <string name="contact_editor_prompt_zero_accounts" msgid="1785345895691886499">"Anwani yako mpya haitahifadhiwa. Je, ungetaka kuongeza akaunti ambayo inahifadhi nakala ya anwani katika mtandao?"</string>
<string name="contact_editor_prompt_one_account" msgid="8669032699767375976">"Mwasiliani wako mpya atalandanishwa na <xliff:g id="ACCOUNT_NAME">%1$s</xliff:g>."</string>
<string name="contact_editor_prompt_multiple_accounts" msgid="611828200100438242">"Unaweza kulandanisha mwasiliani mpya aliye na moja ya zifuatazo. Ni gani ambayo unataka kutumia?"</string>
<string name="keep_local" msgid="1258761699192993322">"Weka karibu"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 19cdcb7..fb4f005 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"โทรศัพท์"</string>
<string name="people" msgid="1048457247435785074">"บุคคล"</string>
<string name="contactsList" msgid="8661624236494819731">"รายชื่อในสมุดโทรศัพท์"</string>
<string name="shortcutContact" msgid="749243779392912958">"สมุดโทรศัพท์"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"ที่อยู่ติดต่อทั้งหมด"</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>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"ส่งข้อความตัวอักษร"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"โทรหา <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"แก้ไขหมายเลขก่อนโทร"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"เพิ่มในสมุดโทรศัพท์"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"ลบจากบันทึกการโทร"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"ล้างบันทึกการโทร"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"ลบข้อความเสียง"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"แบ่งปันข้อความเสียง"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"บันทึกการโทรว่างเปล่า"</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"ล้างบันทึกการโทร"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"บันทึกการโทรทั้งหมดของคุณจะถูกลบออก"</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"กำลังล้างบันทึกการโทร..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"ล้างผู้ที่คุณติดต่อด้วยบ่อยๆ หรือไม่"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"คุณจะล้างรายชื่อของผู้ที่ติดต่อด้วยบ่อยๆ ในแอป People and Phone และบังคับให้แอปอีเมลเรียนรู้การกำหนดที่อยู่ของคุณใหม่ตั้งแต่ต้น"</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"กำลังล้างผู้ที่คุณติดต่อด้วยบ่อยๆ…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"ตั้งค่าโปรไฟล์ของฉัน"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"พิมพ์ชื่อของบุคคล"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"ดูการอัปเดต"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"ข้อความเสียง"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> ข้อความเสียง"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"เล่น"</string>
- <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_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="call_log_voicemail_header" msgid="3945407886667089173">"เฉพาะสายที่มีข้อความเสียง"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"เฉพาะสายเรียกเข้า"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"เฉพาะสายโทรออก"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"เฉพาะสายที่ไม่ได้รับ"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ข้อความเสียง"</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>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"เรียกข้อความเสียง"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"ช้าที่สุด"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"ช้า"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"เร็วปกติ"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"เร็ว"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"เร็วที่สุด"</string>
- <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>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 46eb3ca..d4a59db 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telepono"</string>
<string name="people" msgid="1048457247435785074">"Mga Tao"</string>
<string name="contactsList" msgid="8661624236494819731">"Mga Contact"</string>
<string name="shortcutContact" msgid="749243779392912958">"Contact"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Lahat ng contact"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Mga Pangkat"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Mga Paborito"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telepono"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Log ng tawag"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Magpadala ng text message"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Tawagan si <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"I-edit ang numero bago tumawag"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Idagdag sa mga contact"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Alisin mula sa log ng tawag"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"I-clear ang log ng tawag"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Tanggalin ang voicemail"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Ibahagi ang voicemail"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Walang laman ang log ng tawag."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"I-clear ang log ng tawag?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Tatanggalin ang lahat ng iyong record ng tawag."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Kini-clear ang log ng tawag…"</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"I-clear ang mga madalas tinatawagan?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Iki-clear mo ang listahan ng mga madalas na tinatawagan sa Mga Tao at Telepono na mga app, at pilitin ang mga email app na matutunan ang iyong mga kagustuhan sa pag-address mula sa umpisa."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Kini-clear ang mga madalas tinatawagan…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"I-set up ang aking profile"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"I-type ang pangalan ng tao"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Tingnan ang mga update"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Voicemail"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> (na) Voicemail"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"I-play"</string>
- <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">"Bagong voicemail mula kay <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Hindi ma-play ang voicemail."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Nagba-buffer…"</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Kinukuha ang voicemail…"</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Hindi makuha ang voicemail."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Bago"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Mas Luma"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Mga tawag lang na may voicemail"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Mga papasok na tawag lang"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Mga papalabas na tawag lang"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Mga hindi nasagot na tawag lang"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Hindi makakonekta sa server ng voicemail."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Hindi makakonekta sa server ng voicemail. Naghihintay ang mga bagong voicemail."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"I-set up ang iyong voicemail."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Hindi available ang audio."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"I-set up"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Tawagan ang voicemail"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Pinakamabagal na takbo"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Mabagal na takbo"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Karaniwang takbo"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Mabilis na takbo"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Pinakamabilis na takbo"</string>
- <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>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 945d538..d42bec9 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Telefon"</string>
<string name="people" msgid="1048457247435785074">"Kişiler"</string>
<string name="contactsList" msgid="8661624236494819731">"Kişiler"</string>
<string name="shortcutContact" msgid="749243779392912958">"Kişi"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Tüm kişiler"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Gruplar"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Sık Kullanılanlar"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Telefon"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Çağrı kaydı"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Kısa mesaj gönder"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Ara: <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Önce numarayı düzenle"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Kişilere ekle"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Çağrı kaydından kaldır"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Çağrı kaydını temizle"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Sesli mesajı sil"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Sesli mesajı paylaş"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Çağrı kaydı boş."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Çağrı günlüğünü sil?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Tüm çağrı kayıtlarınız silinecek."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Çağrı günlüğü temizleniyor..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Sık iletişim kurulanlar silinsin mi?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Kişiler ve Telefon uygulamalarındaki sık iletişim kurulanlar listesini temizleyecek ve e-posta uygulamalarını adres tercihlerinizi en baştan öğrenmeye zorlayacaksınız."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Sık iletişim kurulanlar siliniyor…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Profilimi ayarla"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Kişinin adını yazın"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Gncellmlri görüntüle"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Sesli mesaj"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> Sesli mesaj"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Oynat"</string>
- <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">"Yeni sesli mesj gönderen: <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Sesli mesaj yürütülemedi."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Arabelleğe alınıyor..."</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Sesli mesaj getiriliyor..."</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Sesli mesaj getirilemedi."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Yeni"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Daha eski"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Yalnızca sesli mesaj içeren çağrılar"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Yalnızca gelen çağrılar"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Yalnızca giden çağrılar"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Yalnızca cevapsız çağrılar"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Sesli mesaj sunucusuna bağlanılamıyor."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Sesli msj suncsuna bağlanılamıyor. Yeni sesli mesajlar bekliyor."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Sesli mesajınızı yapılandırın."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Ses kullanılamıyor."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Yapılandır"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Sesli mesaj ara"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"En yavaş hız"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Düşük hız"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Normal hız"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Yüksek hız"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"En yüksek hız"</string>
- <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>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 3467b62..44bf3d0 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Телеф."</string>
<string name="people" msgid="1048457247435785074">"Люди"</string>
<string name="contactsList" msgid="8661624236494819731">"Контакти"</string>
<string name="shortcutContact" msgid="749243779392912958">"Контакт"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Усі контакти"</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>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Надісл. текст. повід."</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Набрати <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Редаг. номер перед викл."</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Дод. до контактів"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Видал. з журн. викликів"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Очист. журнал викл."</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Видалити голосову пошту"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Надіслати голос. повідомлення"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Журн. викл. порожній."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Очистити журнал викликів?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Усі записи викликів буде видалено."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Очищення журналу викликів..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Очистити список частих контактів?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Ви очистите список користувачів, з якими часто спілкувалися, у програмах \"Телефон\" і \"Люди\" та примусите програми електронної пошти заново запам’ятовувати нові адреси."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Очищення списку частих контактів…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Налаштувати профіль"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Введіть ім’я особи"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Переглян. оновлення"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Голосова пошта"</item>
- <item quantity="other" msgid="5513481419205061254">"Повідомлень голос. пошти: <xliff:g id="COUNT">%1$d</xliff:g>"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Відтворити"</string>
- <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_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="call_log_voicemail_header" msgid="3945407886667089173">"Лише виклики з голосовою поштою"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Лише вхідні виклики"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Лише вихідні виклики"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Лише пропущені виклики"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Неможливо під’єднатися до сервера голосової пошти."</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>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Дзвон.на голос.пошту"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Найнижча швидкість"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Низька швидкість"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Звичайна швидкість"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Висока швидкість"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Найвища швидкість"</string>
- <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>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 6fd53f8..958865e 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Điện thoại"</string>
<string name="people" msgid="1048457247435785074">"Mọi người"</string>
<string name="contactsList" msgid="8661624236494819731">"Danh bạ"</string>
<string name="shortcutContact" msgid="749243779392912958">"Liên hệ"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Tất cả liên hệ"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Nhóm"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Mục ưa thích"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Điện thoại"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Nhật ký cuộc gọi"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Gửi tin nhắn văn bản"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Gọi <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Chỉnh sửa số trước khi gọi"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Thêm vào danh bạ"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Xóa khỏi nhật ký cuộc gọi"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Xóa nhật ký cuộc gọi"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Xóa thư thoại"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Hiển thị thư thoại"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Nhật ký cuộc gọi trống."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Xóa nhật ký c.gọi?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Tất cả bản ghi cuộc gọi của bạn sẽ bị xóa."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Đang xóa nhật ký cuộc gọi…"</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Xóa danh sách liên hệ thường xuyên?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Bạn sẽ xóa danh sách liên hệ thường xuyên trong ứng dụng Liên hệ và điện thoại cũng như buộc các ứng dụng email phải tìm hiểu các tùy chọn gửi của bạn lại từ đầu."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Đang xóa DS liên hệ thường xuyên…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Thiết lập tiểu sử của tôi"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Nhập tên của người này"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Xem thông tin c.nhật"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Thư thoại"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> Thư thoại"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Phát"</string>
- <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">"Thư thoại mới từ <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Không thể phát thư thoại."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Đang lưu tạm vào bộ đệm…"</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"Đang tìm nạp thư thoại…"</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Không thể tìm nạp thư thoại."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Mới"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Cũ hơn"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Chỉ cuộc gọi có thư thoại"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Chỉ cuộc gọi đến"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Chỉ cuộc gọi đi"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Chỉ cuộc gọi nhỡ"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Không thể kết nối với máy chủ thư thoại."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Không thể kết nối với máy chủ thư thoại. Thư thoại mới đang chờ."</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Thiết lập thư thoại của bạn."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Âm thanh không khả dụng."</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Thiết lập"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Gọi thư thoại"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"Tốc độ chậm nhất"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"Tốc độ chậm"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"Tốc độ bình thường"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"Tốc độ nhanh"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Tốc độ nhanh nhất"</string>
- <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>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 48aff2f..75324b4 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"拨号"</string>
<string name="people" msgid="1048457247435785074">"联系人"</string>
<string name="contactsList" msgid="8661624236494819731">"联系人"</string>
<string name="shortcutContact" msgid="749243779392912958">"联系人"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"所有联系人"</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>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"发送短信"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"呼叫<xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"呼叫之前编辑号码"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"添加到“联系人”"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"从通话记录中删除"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"清除通话记录"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"删除语音邮件"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"分享语音邮件"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"通话记录为空。"</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"要清除通话记录吗?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"系统将删除您的所有通话记录。"</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"正在清除通话记录..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"是否清除常用联系人?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"此操作会清除“联系人”和“拨号”应用中的常用联系人列表,并强制电子邮件应用重新获取您最常使用的联系地址。"</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"正在清除常用联系人…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"设置我的个人资料"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"键入联系人的姓名"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"查看更新"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"语音邮件"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> 封语音邮件"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"播放"</string>
- <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_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="call_log_voicemail_header" msgid="3945407886667089173">"只显示语音信箱留言"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"只显示来电"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"只显示外拨电话"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"只显示未接来电"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"无法连接到语音信箱服务器。"</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>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"呼叫语音信箱"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"最慢"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"慢速"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"正常速度"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"快速"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"最快"</string>
- <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>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 8fce496..aba1827 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"電話"</string>
<string name="people" msgid="1048457247435785074">"使用者"</string>
<string name="contactsList" msgid="8661624236494819731">"聯絡人"</string>
<string name="shortcutContact" msgid="749243779392912958">"聯絡人"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"所有聯絡人"</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>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"傳送簡訊"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"撥電話給<xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"撥打電話前編輯號碼"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"新增至通訊錄"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"從通話記錄中移除"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"清除通話記錄"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"刪除語音留言"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"分享語音信箱"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"無通話記錄。"</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"確定要清除通話記錄?"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"即將刪除您所有的通話記錄。"</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"正在清除通話記錄…"</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"清除常用聯絡人?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"您將清除「使用者」應用程式和「電話」應用程式中的常用聯絡人清單,並強制電子郵件應用程式重新瞭解您的寄件偏好設定。"</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"正在清除常用聯絡人…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"設定我的個人資料"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"輸入聯絡人的名稱"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"查看更新"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"語音留言"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> 則語音留言"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"播放"</string>
- <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_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="call_log_voicemail_header" msgid="3945407886667089173">"僅顯示語音信箱留言"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"僅顯示來電"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"僅顯示已撥電話"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"僅顯示未接來電"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"無法連線至語音信箱伺服器。"</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>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"撥打語音信箱號碼"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"最慢速"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"慢速"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"正常速度"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"快速"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"最快速"</string>
- <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>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 0960606..f849c65 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -16,7 +16,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="launcherDialer" msgid="8636288196618486553">"Ifoni"</string>
<string name="people" msgid="1048457247435785074">"Abantu"</string>
<string name="contactsList" msgid="8661624236494819731">"Othi tana nabo"</string>
<string name="shortcutContact" msgid="749243779392912958">"Othintana naye"</string>
@@ -137,20 +136,6 @@
<string name="contactsAllLabel" msgid="6479708629170672169">"Bonke oxhumana nabo"</string>
<string name="contactsGroupsLabel" msgid="2841971472518003524">"Amaqembu"</string>
<string name="contactsFavoritesLabel" msgid="8417039765586853670">"Izintandokazi"</string>
- <string name="dialerIconLabel" msgid="6500826552823403796">"Ifoni"</string>
- <string name="recentCallsIconLabel" msgid="1419116422359067949">"Ifayela lokungena lekholi"</string>
- <string name="menu_sendTextMessage" msgid="6937343460284499306">"Thumela umyalezo wombhalo"</string>
- <string name="recentCalls_callNumber" msgid="1756372533999226126">"Shayela <xliff:g id="NAME">%s</xliff:g>"</string>
- <string name="recentCalls_editNumberBeforeCall" msgid="7756171675833267857">"Hlela inombolo ngaphambi kokushaya ucingo"</string>
- <string name="recentCalls_addToContact" msgid="1429899535546487008">"Engeza kothintana nabo"</string>
- <string name="recentCalls_removeFromRecentList" msgid="401662244636511330">"Susa kwifayela yokungena"</string>
- <string name="recentCalls_deleteAll" msgid="6352364392762163704">"Sula ifayela lokungena"</string>
- <string name="recentCalls_trashVoicemail" msgid="7604696960787435655">"Susa imeyili yezwi"</string>
- <string name="recentCalls_shareVoicemail" msgid="1416112847592942840">"Abelana nemeyili yezwi"</string>
- <string name="recentCalls_empty" msgid="247053222448663107">"Ifayela lokungena lekholi alinalutho."</string>
- <string name="clearCallLogConfirmation_title" msgid="6427524640461816332">"Sula ifayela lokungena"</string>
- <string name="clearCallLogConfirmation" msgid="5043563133171583152">"Yonke imininingwane eqoshiwe iyosuswa."</string>
- <string name="clearCallLogProgress_title" msgid="8365943000154295771">"Isula imininingwane yokushaya..."</string>
<string name="clearFrequentsConfirmation_title" msgid="766292372438450432">"Sula oxhumana nabo njalo?"</string>
<string name="clearFrequentsConfirmation" msgid="3254215748990281318">"Uzosula uhlu okuxhunyanwa nalo njalo kwizinhlelo zokusebenza zaBantu kanye Nefoni, futhi iphoqelela izinhlelo zokusebenza ze-imeyli ukufunda okukhethayo kokuthintana kusuka ekuqaleni."</string>
<string name="clearFrequentsProgress_title" msgid="5157001637482794212">"Isula oxhumana nabo njalo…"</string>
@@ -497,35 +482,6 @@
<string name="profile_display_name" msgid="4127389543625918771">"Misa iphrofayli yami"</string>
<string name="enter_contact_name" msgid="1738391320566349924">"Thayipha igama lomuntu"</string>
<string name="view_updates_from_group" msgid="1782685984905600034">"Buka Okwenziwe Kabusha"</string>
- <plurals name="notification_voicemail_title">
- <item quantity="one" msgid="1746619685488504230">"Ivoyisimeyili"</item>
- <item quantity="other" msgid="5513481419205061254">"<xliff:g id="COUNT">%1$d</xliff:g> ama-meyli ezwi"</item>
- </plurals>
- <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Dlala"</string>
- <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">"I-imeyli entsha esuka ku <xliff:g id="CALLER">%1$s</xliff:g>"</string>
- <string name="voicemail_playback_error" msgid="1811242131549854624">"Yehlulekile ukudlala i-voicemail."</string>
- <string name="voicemail_buffering" msgid="738287747618697097">"Ukugcina kumthamo"</string>
- <string name="voicemail_fetching_content" msgid="877911315738258780">"ilanda i-voicemail..."</string>
- <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Yehlulekile ukulanda i-voicemail."</string>
- <string name="call_log_new_header" msgid="846546437517724715">"Okusha"</string>
- <string name="call_log_old_header" msgid="6262205894314263629">"Okudadlana"</string>
- <string name="call_log_voicemail_header" msgid="3945407886667089173">"Amakholi anevoyisimeyili kuphela"</string>
- <string name="call_log_incoming_header" msgid="2787722299753674684">"Amakholi angenayo kuphela"</string>
- <string name="call_log_outgoing_header" msgid="761009180766735769">"Amakholi aphumayo kuphela"</string>
- <string name="call_log_missed_header" msgid="8017148056610855956">"Amakholi agejiwe kuphela"</string>
- <string name="voicemail_status_voicemail_not_available" msgid="3021980206152528883">"Ayikwazi ukuxhuma kusiphakeli se-imeyli yezwi."</string>
- <string name="voicemail_status_messages_waiting" msgid="7113421459602803605">"Ayikwazi ukuxhumana nesiphakeli semeyli yezwi. Ama-imeyli ezwi amasha alindile"</string>
- <string name="voicemail_status_configure_voicemail" msgid="3738537770636895689">"Setha umyalezo wakho wephimbo."</string>
- <string name="voicemail_status_audio_not_available" msgid="3369618334553341626">"Umsindo awutholakali"</string>
- <string name="voicemail_status_action_configure" msgid="8671796489912239589">"Setha"</string>
- <string name="voicemail_status_action_call_server" msgid="1824816252288551794">"Shayela ivoyisimeyili"</string>
- <string name="voicemail_speed_slowest" msgid="1733460666177707312">"ijubane elincane kakhulu"</string>
- <string name="voicemail_speed_slower" msgid="1508601287347216244">"ijubane elinensayo"</string>
- <string name="voicemail_speed_normal" msgid="9033988544627228892">"ijubane elijwayelekile"</string>
- <string name="voicemail_speed_faster" msgid="2019965121475935488">"ijubane elisheshayo"</string>
- <string name="voicemail_speed_fastest" msgid="5758712343491183292">"Ijubane eliphezulu kakhudlwane"</string>
- <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>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 5a5016e..c5f0ae2 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -92,21 +92,6 @@
<attr name="list_item_label_width_weight" format="integer" />
</declare-styleable>
- <declare-styleable name="CallLog">
- <attr name="call_log_primary_text_color" format="color" />
- <attr name="call_log_primary_background_color" format="color" />
- <attr name="call_log_secondary_text_color" format="color" />
- <attr name="call_log_secondary_background_color" format="color" />
- <attr name="call_log_header_color" format="color" />
- </declare-styleable>
-
- <declare-styleable name="VoicemailStatus">
- <attr name="call_log_voicemail_status_height" format="dimension" />
- <attr name="call_log_voicemail_status_background_color" format="color" />
- <attr name="call_log_voicemail_status_text_color" format="color" />
- <attr name="call_log_voicemail_status_action_text_color" format="color" />
- </declare-styleable>
-
<declare-styleable name="Favorites">
<attr name="favorites_padding_bottom" format="dimension" />
</declare-styleable>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index cb2b1ca..c767de4 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -73,9 +73,6 @@
<!-- Color of the vertical stripe that goes on the left of a block quote inside a stream item -->
<color name="stream_item_stripe_color">#CCCCCC</color>
- <!-- Color of image view placeholder. -->
- <color name="image_placeholder">#DDDDDD</color>
-
<!-- Standard color for selected items. -->
<color name="item_selected">#660099cc</color>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 94faf49..eae076f 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -160,19 +160,6 @@
<!-- Height of the quick contact photo container (for screens that are too large to use the screen width/height as a constraint)-->
<dimen name="quick_contact_photo_container_height">180dip</dimen>
- <!-- Height of edit text in dialpad fragment -->
- <dimen name="dialpad_horizontal_margin">0dip</dimen>
- <dimen name="dialpad_vertical_margin">2dip</dimen>
- <dimen name="dialpad_digits_text_size">35sp</dimen>
-
- <!-- Just used in landscape mode -->
- <dimen name="dialpad_digits_height">0px</dimen>
- <dimen name="dialpad_digits_margin_bottom">0px</dimen>
- <dimen name="dialpad_center_margin">3dp</dimen>
- <dimen name="dialpad_button_margin">2dp</dimen>
- <!-- Match call_button_height to Phone's dimens/in_call_end_button_height -->
- <dimen name="call_button_height">74dp</dimen>
-
<!-- Width of search view in action bar. Use 0dip for MATCH_PARENT -->
<dimen name="search_view_width">0dip</dimen>
@@ -202,18 +189,6 @@
<!-- Top padding of the ListView in the contact tile list -->
<dimen name="contact_tile_list_padding_top">0dip</dimen>
- <!-- Call Log -->
- <dimen name="call_log_call_action_size">32dip</dimen>
- <dimen name="call_log_call_action_width">48dip</dimen>
- <dimen name="call_log_icon_margin">4dip</dimen>
- <dimen name="call_log_inner_margin">8dip</dimen>
- <dimen name="call_log_outer_margin">16dip</dimen>
- <dimen name="call_log_indent_margin">24dip</dimen>
- <dimen name="call_log_list_item_height">56dip</dimen>
- <dimen name="call_log_list_contact_photo_size">64dip</dimen>
- <dimen name="call_detail_contact_name_margin">24dip</dimen>
- <dimen name="call_detail_button_spacing">2dip</dimen>
-
<!-- Empty message margins -->
<dimen name="empty_message_top_margin">48dip</dimen>
<dimen name="no_accounts_message_margin">20dip</dimen>
@@ -231,13 +206,6 @@
<!-- Width of the lead margin on the left of a block quote inside a stream item -->
<dimen name="stream_item_stripe_width">8dip</dimen>
- <!-- Layout weight values for dialpad screen. These layouts will be used in one
- LinearLayout (dialpad_fragment.xml), configuring dialpad screen's vertical
- ratio. -->
- <integer name="dialpad_layout_weight_digits">20</integer>
- <integer name="dialpad_layout_weight_dialpad">65</integer>
- <integer name="dialpad_layout_weight_additional_buttons">15</integer>
-
<!-- Minimum height used with @drawable/list_section_divider_holo_custom.
Right now the drawable has implicit 32dip minimal height, which is confusing.
This value is for making the hidden configuration explicit in xml. -->
@@ -251,6 +219,4 @@
wide screen devices). -->
<dimen name="contact_picker_contact_list_min_height">550dip</dimen>
- <!-- Min with of fake menu buttons, which should be same as ActionBar's one -->
- <dimen name="fake_menu_button_min_width">56dip</dimen>
</resources>
diff --git a/res/values/donottranslate_config.xml b/res/values/donottranslate_config.xml
index 2110a8b..aaff275 100644
--- a/res/values/donottranslate_config.xml
+++ b/res/values/donottranslate_config.xml
@@ -37,13 +37,6 @@
<!-- Flag indicating whether Contacts app is allowed to share contacts with devices outside -->
<bool name="config_allow_share_visible_contacts">true</bool>
- <!-- If true, enable vibration (haptic feedback) for dialer key presses.
- The pattern is set on a per-platform basis using config_virtualKeyVibePattern.
- TODO: If enough users are annoyed by this, we might eventually
- need to make it a user preference rather than a per-platform
- resource. -->
- <bool name="config_enable_dialer_key_vibration">true</bool>
-
<!-- Flag indicating whether to show images in browse list -->
<bool name="config_browse_list_show_images">true</bool>
@@ -76,12 +69,6 @@
Without this configuration, 00002.vcf becomes the candidate.-->
<string name="config_export_extensions_to_consider" translatable="false"></string>
- <!-- If true, show an onscreen "Dial" button in the dialer.
- In practice this is used on all platforms even the ones with hard SEND/END
- keys, but for maximum flexibility it's controlled by a flag here
- (which can be overridden on a per-product basis.) -->
- <bool name="config_show_onscreen_dial_button">true</bool>
-
<!-- If true, an option is shown in Display Options UI to choose a sort order -->
<bool name="config_sort_order_user_changeable">true</bool>
@@ -127,10 +114,6 @@
contact detail page -->
<item name="tab_height_screen_width_percentage" type="fraction">50%</item>
- <!-- Regular expression for prohibiting certain phone numbers in dialpad.
- Ignored if empty. -->
- <string name="config_prohibited_phone_number_regexp"></string>
-
<!-- If true, enable the "import contacts from SIM" feature if the device
has an appropriate SIM or ICC card.
Setting this flag to false in a resource overlay allows you to
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d90d0ef..0958dd8 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -14,9 +14,6 @@
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Title for the activity that dials the phone. This is the name
- used in the Launcher icon. -->
- <string name="launcherDialer">Phone</string>
<!-- Title for the activity that opens the People app. This is the name
used in the Launcher icon. -->
@@ -381,63 +378,14 @@
[CHAR LIMIT=NONE] -->
<string name="contactsFavoritesLabel">Favorites</string>
- <!-- The description text for the dialer tab.
-
- Note: AccessibilityServices use this attribute to announce what the view represents.
- This is especially valuable for views without textual representation like ImageView.
-
- [CHAR LIMIT=NONE] -->
- <string name="dialerIconLabel">Phone</string>
-
- <!-- The description text for the call log tab.
-
- Note: AccessibilityServices use this attribute to announce what the view represents.
- This is especially valuable for views without textual representation like ImageView.
-
- [CHAR LIMIT=NONE] -->
- <string name="recentCallsIconLabel">Call log</string>
-
- <!-- Menu item used to send an SMS or MMS message to a phone number -->
- <string name="menu_sendTextMessage">Send text message</string>
-
- <!-- Menu item used to call a contact from the call log -->
- <string name="recentCalls_callNumber">Call <xliff:g id="name">%s</xliff:g></string>
-
- <!-- Menu item used to copy a number from the call log to the dialer so it can be edited before calling it -->
- <string name="recentCalls_editNumberBeforeCall">Edit number before call</string>
-
- <!-- Menu item used to add a number from the call log to contacts -->
- <string name="recentCalls_addToContact">Add to contacts</string>
-
- <!-- Menu item used to remove a single call from the call log -->
- <string name="recentCalls_removeFromRecentList">Remove from call log</string>
-
- <!-- Menu item used to remove all calls from the call log -->
- <string name="recentCalls_deleteAll">Clear call log</string>
-
- <!-- Menu item used to delete a voicemail. [CHAR LIMIT=30] -->
- <string name="recentCalls_trashVoicemail">Delete voicemail</string>
-
- <!-- Menu item used to share a voicemail. [CHAR LIMIT=30] -->
- <string name="recentCalls_shareVoicemail">Share voicemail</string>
-
- <!-- Text displayed when the call log is empty -->
- <string name="recentCalls_empty">Call log is empty.</string>
-
- <!-- Title of the confirmation dialog for clearing the call log. [CHAR LIMIT=37] -->
- <string name="clearCallLogConfirmation_title">Clear call log?</string>
-
- <!-- Confirmation dialog for clearing the call log. [CHAR LIMIT=NONE] -->
- <string name="clearCallLogConfirmation">All your call records will be deleted.</string>
-
- <!-- Title of the "Clearing call log" progress-dialog [CHAR LIMIT=35] -->
- <string name="clearCallLogProgress_title">Clearing call log\u2026</string>
-
<!-- Title of the confirmation dialog for clearing frequents. [CHAR LIMIT=37] -->
<string name="clearFrequentsConfirmation_title">Clear frequently contacted?</string>
<!-- Confirmation dialog for clearing frequents. [CHAR LIMIT=NONE] -->
- <string name="clearFrequentsConfirmation">You\'ll clear the frequently contacted list in the People and Phone apps, and force email apps to learn your addressing preferences from scratch.</string>
+ <string name="clearFrequentsConfirmation">You\'ll clear the frequently contacted list in the
+ People and Phone apps, and force email apps to learn your addressing preferences from
+ scratch.
+ </string>
<!-- Title of the "Clearing frequently contacted" progress-dialog [CHAR LIMIT=35] -->
<string name="clearFrequentsProgress_title">Clearing frequently contacted\u2026</string>
@@ -1081,92 +1029,6 @@
and will not be synced. -->
<string name="account_phone" product="default">Phone-only, unsynced</string>
- <!-- Action string for calling a custom phone number -->
- <string name="call_custom">Call <xliff:g id="custom">%s</xliff:g></string>
- <!-- Action string for calling a home phone number -->
- <string name="call_home">Call home</string>
- <!-- Action string for calling a mobile phone number -->
- <string name="call_mobile">Call mobile</string>
- <!-- Action string for calling a work phone number -->
- <string name="call_work">Call work</string>
- <!-- Action string for calling a work fax phone number -->
- <string name="call_fax_work">Call work fax</string>
- <!-- Action string for calling a home fax phone number -->
- <string name="call_fax_home">Call home fax</string>
- <!-- Action string for calling a pager phone number -->
- <string name="call_pager">Call pager</string>
- <!-- Action string for calling an other phone number -->
- <string name="call_other">Call</string>
- <!-- Action string for calling a callback number -->
- <string name="call_callback">Call callback</string>
- <!-- Action string for calling a car phone number -->
- <string name="call_car">Call car</string>
- <!-- Action string for calling a company main phone number -->
- <string name="call_company_main">Call company main</string>
- <!-- Action string for calling a ISDN phone number -->
- <string name="call_isdn">Call ISDN</string>
- <!-- Action string for calling a main phone number -->
- <string name="call_main">Call main</string>
- <!-- Action string for calling an other fax phone number -->
- <string name="call_other_fax">Call fax</string>
- <!-- Action string for calling a radio phone number -->
- <string name="call_radio">Call radio</string>
- <!-- Action string for calling a Telex phone number -->
- <string name="call_telex">Call telex</string>
- <!-- Action string for calling a TTY/TDD phone number -->
- <string name="call_tty_tdd">Call TTY/TDD</string>
- <!-- Action string for calling a work mobile phone number -->
- <string name="call_work_mobile">Call work mobile</string>
- <!-- Action string for calling a work pager phone number -->
- <string name="call_work_pager">Call work pager</string>
- <!-- Action string for calling an assistant phone number -->
- <string name="call_assistant">Call <xliff:g id="assistant">%s</xliff:g></string>
- <!-- Action string for calling a MMS phone number -->
- <string name="call_mms">Call MMS</string>
-
- <!-- Action string for sending an SMS to a custom phone number -->
- <string name="sms_custom">Text <xliff:g id="custom">%s</xliff:g></string>
- <!-- Action string for sending an SMS to a home phone number -->
- <string name="sms_home">Text home</string>
- <!-- Action string for sending an SMS to a mobile phone number -->
- <string name="sms_mobile">Text mobile</string>
- <!-- Action string for sending an SMS to a work phone number -->
- <string name="sms_work">Text work</string>
- <!-- Action string for sending an SMS to a work fax phone number -->
- <string name="sms_fax_work">Text work fax</string>
- <!-- Action string for sending an SMS to a home fax phone number -->
- <string name="sms_fax_home">Text home fax</string>
- <!-- Action string for sending an SMS to a pager phone number -->
- <string name="sms_pager">Text pager</string>
- <!-- Action string for sending an SMS to an other phone number -->
- <string name="sms_other">Text</string>
- <!-- Action string for sending an SMS to a callback number -->
- <string name="sms_callback">Text callback</string>
- <!-- Action string for sending an SMS to a car phone number -->
- <string name="sms_car">Text car</string>
- <!-- Action string for sending an SMS to a company main phone number -->
- <string name="sms_company_main">Text company main</string>
- <!-- Action string for sending an SMS to a ISDN phone number -->
- <string name="sms_isdn">Text ISDN</string>
- <!-- Action string for sending an SMS to a main phone number -->
- <string name="sms_main">Text main</string>
- <!-- Action string for sending an SMS to an other fax phone number -->
- <string name="sms_other_fax">Text fax</string>
- <!-- Action string for sending an SMS to a radio phone number -->
- <string name="sms_radio">Text radio</string>
- <!-- Action string for sending an SMS to a Telex phone number -->
- <string name="sms_telex">Text telex</string>
- <!-- Action string for sending an SMS to a TTY/TDD phone number -->
- <string name="sms_tty_tdd">Text TTY/TDD</string>
- <!-- Action string for sending an SMS to a work mobile phone number -->
- <string name="sms_work_mobile">Text work mobile</string>
- <!-- Action string for sending an SMS to a work pager phone number -->
- <string name="sms_work_pager">Text work pager</string>
- <!-- Action string for sending an SMS to an assistant phone number -->
- <string name="sms_assistant">Text <xliff:g id="assistant">%s</xliff:g></string>
- <!-- Action string for sending an SMS to a MMS phone number -->
- <string name="sms_mms">Text MMS</string>
-
<!-- Generic action string for text messaging a contact. Used by AccessibilityService to announce the purpose of the view. [CHAR LIMIT=NONE] -->
<string name="sms">Text message</string>
@@ -1569,94 +1431,6 @@
<!-- Button to view the updates from the current group on the group detail page [CHAR LIMIT=25] -->
<string name="view_updates_from_group">View updates</string>
- <!-- Title of the notification of new voicemails. [CHAR LIMIT=30] -->
- <plurals name="notification_voicemail_title">
- <item quantity="one">Voicemail</item>
- <item quantity="other"><xliff:g id="count">%1$d</xliff:g> Voicemails</item>
- </plurals>
-
- <!-- Used in the notification of a new voicemail for the action to play the voicemail. -->
- <string name="notification_action_voicemail_play">Play</string>
-
- <!-- Used to build a list of names or phone numbers, to indicate the callers who left
- voicemails.
- The first argument may be one or more callers, the most recent ones.
- The second argument is an additional callers.
- This string is used to build a list of callers.
-
- [CHAR LIMIT=10]
- -->
- <string name="notification_voicemail_callers_list"><xliff:g id="newer_callers">%1$s</xliff:g>, <xliff:g id="older_caller">%2$s</xliff:g></string>
-
- <!-- Text used in the ticker to notify the user of the latest voicemail. [CHAR LIMIT=30] -->
- <string name="notification_new_voicemail_ticker">New voicemail from <xliff:g id="caller">%1$s</xliff:g></string>
-
- <!-- Message to show when there is an error playing back the voicemail. [CHAR LIMIT=40] -->
- <string name="voicemail_playback_error">Couldn\'t play voicemail.</string>
-
- <!-- Message to display before we have prepared the media player, i.e. before we know duration. [CHAR LIMIT=40] -->
- <string name="voicemail_buffering">Buffering\u2026</string>
-
- <!-- Message to display whilst we are waiting for the content to be fetched. [CHAR LIMIT=40] -->
- <string name="voicemail_fetching_content">Fetching voicemail\u2026</string>
-
- <!-- Message to display if we fail to get content within a suitable time period. [CHAR LIMIT=40] -->
- <string name="voicemail_fetching_timout">Couldn\'t fetch voicemail.</string>
-
- <!-- The header in the call log used to identify missed calls and voicemail that have not yet been consumed [CHAR LIMIT=10] -->
- <string name="call_log_new_header">New</string>
-
- <!-- 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 only</string>
-
- <!-- The header to show that call log is only showing incoming calls. [CHAR LIMIT=40] -->
- <string name="call_log_incoming_header">Incoming calls only</string>
-
- <!-- The header to show that call log is only showing outgoing calls. [CHAR LIMIT=40] -->
- <string name="call_log_outgoing_header">Outgoing calls only</string>
-
- <!-- The header to show that call log is only showing missed calls. [CHAR LIMIT=40] -->
- <string name="call_log_missed_header">Missed calls only</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] -->
- <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.
- [CHAR LIMIT=64] -->
- <string name="voicemail_status_messages_waiting">Can\'t connect to voicemail server. New voicemails are waiting.</string>
- <!-- Voicemail status message shown at the top of call log to invite the user to configure
- visual voicemail. [CHAR LIMIT=64] -->
- <string name="voicemail_status_configure_voicemail">Set up your voicemail.</string>
- <!-- Voicemail status message shown at the top of call details screen to notify the user that
- the audio of this voicemail is not available. [CHAR LIMIT=64] -->
- <string name="voicemail_status_audio_not_available">Audio not available.</string>
-
- <!-- User action prompt shown next to a voicemail status message to let the user configure
- visual voicemail. [CHAR LIMIT=20] -->
- <string name="voicemail_status_action_configure">Set up</string>
- <!-- User action prompt shown next to a voicemail status message to let the user call voicemail
- server directly to listen to the voicemails. [CHAR LIMIT=20] -->
- <string name="voicemail_status_action_call_server">Call voicemail</string>
-
- <!-- The slowest voicemail playback speed. [CHAR LIMIT=30] -->
- <string name="voicemail_speed_slowest">Slowest speed</string>
- <!-- Slower than normal voicemail playback speed. [CHAR LIMIT=30] -->
- <string name="voicemail_speed_slower">Slow speed</string>
- <!-- Normal voicemail playback speed. [CHAR LIMIT=30] -->
- <string name="voicemail_speed_normal">Normal speed</string>
- <!-- Faster than normal pvoicemail playback speed. [CHAR LIMIT=30] -->
- <string name="voicemail_speed_faster">Fast speed</string>
- <!-- Fastest voicemail playback speed. [CHAR LIMIT=30] -->
- <string name="voicemail_speed_fastest">Fastest speed</string>
-
- <!-- The counter for calls in a group and the date of the latest call as shown in the call log [CHAR LIMIT=15] -->
- <string name="call_log_item_count_and_date">(<xliff:g id="count">%1$d</xliff:g>) <xliff:g id="date">%2$s</xliff:g></string>
-
<!-- Hint text in the group name box in the edit group view. [CHAR LIMIT=20]-->
<string name="group_name_hint">Group\'s name</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index ad8d07b..07ecd7f 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -14,72 +14,6 @@
limitations under the License.
-->
<resources>
- <style name="DialtactsTheme"
- parent="android:Theme.Holo">
- <item name="android:textColorSecondary">@color/dialtacts_secondary_text_color</item>
- <item name="android:windowActionBarOverlay">true</item>
- <item name="android:actionBarStyle">@style/DialtactsActionBarStyle</item>
- <item name="android:windowContentOverlay">@null</item>
- <item name="android:windowBackground">@drawable/background_dial_holo_dark</item>
- <item name="android:listViewStyle">@style/ListViewStyle</item>
- <item name="activated_background">@drawable/list_item_activated_background</item>
- <item name="section_header_background">@drawable/list_title_holo</item>
- <item name="list_section_header_height">32dip</item>
- <item name="list_item_divider">?android:attr/listDivider</item>
- <item name="list_item_padding_top">0dip</item>
- <item name="list_item_padding_right">0dip</item>
- <item name="list_item_padding_bottom">0dip</item>
- <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_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>
- <item name="list_item_profile_photo_size">70dip</item>
- <item name="list_item_prefix_highlight_color">@color/people_app_theme_color</item>
- <item name="list_item_header_text_indent">8dip</item>
- <item name="list_item_header_text_color">@color/people_app_theme_color</item>
- <item name="list_item_header_text_size">14sp</item>
- <item name="list_item_header_height">24dip</item>
- <item name="list_item_header_underline_height">1dip</item>
- <item name="list_item_header_underline_color">@color/people_app_theme_color</item>
- <item name="list_item_data_width_weight">5</item>
- <item name="list_item_label_width_weight">3</item>
- <item name="contact_browser_list_padding_left">16dip</item>
- <item name="contact_browser_list_padding_right">0dip</item>
- <item name="contact_browser_background">@android:color/transparent</item>
- <item name="list_item_text_indent">@dimen/contact_browser_list_item_text_indent</item>
- <!-- CallLog -->
- <item name="call_log_primary_text_color">#FFFFFF</item>
- <item name="call_log_primary_background_color">#000000</item>
- <item name="call_log_secondary_text_color">#888888</item>
- <item name="call_log_secondary_background_color">#333333</item>
- <item name="call_log_header_color">#33b5e5</item>
- <!-- VoicemailStatus -->
- <item name="call_log_voicemail_status_height">48dip</item>
- <item name="call_log_voicemail_status_background_color">#262626</item>
- <item name="call_log_voicemail_status_text_color">#888888</item>
- <item name="call_log_voicemail_status_action_text_color">#33b5e5</item>
- <!-- Favorites -->
- <item name="favorites_padding_bottom">?android:attr/actionBarSize</item>
- </style>
-
- <style name="CallDetailActivityTheme" parent="android:Theme.Holo">
- <item name="android:windowBackground">@android:color/black</item>
- <item name="android:gravity">top</item>
- <item name="android:listViewStyle">@style/ListViewStyle</item>
- <!-- CallLog -->
- <item name="call_log_primary_text_color">#FFFFFF</item>
- <item name="call_log_primary_background_color">#000000</item>
- <item name="call_log_secondary_text_color">#FFFFFF</item>
- <item name="call_log_secondary_background_color">#333333</item>
- <item name="call_log_header_color">#33b5e5</item>
- <!-- VoicemailStatus -->
- <item name="call_log_voicemail_status_height">48dip</item>
- <item name="call_log_voicemail_status_background_color">#262626</item>
- <item name="call_log_voicemail_status_text_color">#888888</item>
- <item name="call_log_voicemail_status_action_text_color">#33b5e5</item>
- </style>
<style name="DetailActivityTheme" parent="@android:style/Theme.Holo.Light.DarkActionBar">
<item name="android:actionBarStyle">@style/ContactsActionBarStyle</item>
@@ -254,25 +188,6 @@
<item name="android:layout_gravity">center_vertical</item>
</style>
- <style name="DialtactsDigitsTextAppearance">
- <item name="android:maxLines">1</item>
- <item name="android:scrollHorizontally">true</item>
- <item name="android:textSize">@dimen/dialpad_digits_text_size</item>
- <item name="android:freezesText">true</item>
- <item name="android:focusableInTouchMode">true</item>
- <item name="android:editable">true</item>
- <item name="android:cursorVisible">false</item>
- <item name="android:layout_weight">0</item>
- </style>
-
- <style name="DialtactsDialpadButtonStyle">
- <item name="android:layout_width">0dip</item>
- <item name="android:layout_height">match_parent</item>
- <item name="android:layout_weight">1</item>
- <item name="android:background">?android:attr/selectableItemBackground</item>
- <item name="android:soundEffectsEnabled">false</item>
- </style>
-
<style name="ConfirmAddDetailViewStyle">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
@@ -283,12 +198,6 @@
<item name="android:layout_height">150dip</item>
</style>
- <style name="DialtactsActionBarStyle" parent="android:Widget.Holo.ActionBar">
- <item name="android:backgroundSplit">@null</item>
- <item name="android:backgroundStacked">@drawable/ab_stacked_opaque_dark_holo</item>
- <item name="android:displayOptions"></item>
- </style>
-
<style name="QuickContactListItemStyle">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
diff --git a/script/test.sh b/script/test.sh
new file mode 100755
index 0000000..306340a
--- /dev/null
+++ b/script/test.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+#
+# 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.
+#
+
+adb shell am instrument ${@} -w com.android.contacts.tests/android.test.InstrumentationTestRunner
diff --git a/src/com/android/contacts/BackScrollManager.java b/src/com/android/contacts/BackScrollManager.java
deleted file mode 100644
index 192b79e..0000000
--- a/src/com/android/contacts/BackScrollManager.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-import android.view.View;
-import android.widget.AbsListView;
-import android.widget.ListView;
-
-/**
- * Handles scrolling back of a list tied to a header.
- * <p>
- * This is used to implement a header that scrolls up with the content of a list to be partially
- * obscured.
- */
-public class BackScrollManager {
- /** Defines the header to be scrolled. */
- public interface ScrollableHeader {
- /** Sets the offset by which to scroll. */
- public void setOffset(int offset);
- /** Gets the maximum offset that should be applied to the header. */
- public int getMaximumScrollableHeaderOffset();
- }
-
- private final ScrollableHeader mHeader;
- private final ListView mListView;
-
- private final AbsListView.OnScrollListener mScrollListener =
- new AbsListView.OnScrollListener() {
- @Override
- public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
- int totalItemCount) {
- if (firstVisibleItem != 0) {
- // The first item is not shown, the header should be pinned at the top.
- mHeader.setOffset(mHeader.getMaximumScrollableHeaderOffset());
- return;
- }
-
- View firstVisibleItemView = view.getChildAt(firstVisibleItem);
- if (firstVisibleItemView == null) {
- return;
- }
- // We scroll the header up, but at most pin it to the top of the screen.
- int offset = Math.min(
- (int) -view.getChildAt(firstVisibleItem).getY(),
- mHeader.getMaximumScrollableHeaderOffset());
- mHeader.setOffset(offset);
- }
-
- @Override
- public void onScrollStateChanged(AbsListView view, int scrollState) {
- // Nothing to do here.
- }
- };
-
- /**
- * Creates a new instance of a {@link BackScrollManager} that connected the header and the list
- * view.
- */
- public static void bind(ScrollableHeader header, ListView listView) {
- BackScrollManager backScrollManager = new BackScrollManager(header, listView);
- backScrollManager.bind();
- }
-
- private BackScrollManager(ScrollableHeader header, ListView listView) {
- mHeader = header;
- mListView = listView;
- }
-
- private void bind() {
- mListView.setOnScrollListener(mScrollListener);
- // We disable the scroll bar because it would otherwise be incorrect because of the hidden
- // header.
- mListView.setVerticalScrollBarEnabled(false);
- }
-}
diff --git a/src/com/android/contacts/CallContactActivity.java b/src/com/android/contacts/CallContactActivity.java
deleted file mode 100644
index c4b4dc7..0000000
--- a/src/com/android/contacts/CallContactActivity.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-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.
- */
-public class CallContactActivity extends ContactsActivity implements OnDismissListener {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- Uri contactUri = getIntent().getData();
- if (contactUri == null) {
- finish();
- }
-
- // If this method is being invoked with a saved state, rely on Activity
- // to restore it
- if (savedInstanceState != null) {
- return;
- }
-
- if (Contacts.CONTENT_ITEM_TYPE.equals(getContentResolver().getType(contactUri))) {
- PhoneNumberInteraction.startInteractionForPhoneCall(this, contactUri);
- } else {
- startActivity(ContactsUtils.getCallIntent(contactUri));
- finish();
- }
- }
-
- @Override
- public void onDismiss(DialogInterface dialog) {
- if (!isChangingConfigurations()) {
- finish();
- }
- }
-}
diff --git a/src/com/android/contacts/CallDetailActivity.java b/src/com/android/contacts/CallDetailActivity.java
deleted file mode 100644
index 7bb2157..0000000
--- a/src/com/android/contacts/CallDetailActivity.java
+++ /dev/null
@@ -1,936 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-import android.app.ActionBar;
-import android.app.Activity;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.provider.CallLog;
-import android.provider.CallLog.Calls;
-import android.provider.Contacts.Intents.Insert;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.Contacts;
-import android.provider.VoicemailContract.Voicemails;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.ActionMode;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.ListView;
-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;
-
-/**
- * Displays the details of a specific call log entry.
- * <p>
- * This activity can be either started with the URI of a single call log entry, or with the
- * {@link #EXTRA_CALL_LOG_IDS} extra to specify a group of call log entries.
- */
-public class CallDetailActivity extends Activity implements ProximitySensorAware {
- private static final String TAG = "CallDetail";
-
- /** The time to wait before enabling the blank the screen due to the proximity sensor. */
- private static final long PROXIMITY_BLANK_DELAY_MILLIS = 100;
- /** The time to wait before disabling the blank the screen due to the proximity sensor. */
- private static final long PROXIMITY_UNBLANK_DELAY_MILLIS = 500;
-
- /** The enumeration of {@link AsyncTask} objects used in this class. */
- public enum Tasks {
- MARK_VOICEMAIL_READ,
- DELETE_VOICEMAIL_AND_FINISH,
- REMOVE_FROM_CALL_LOG_AND_FINISH,
- UPDATE_PHONE_CALL_DETAILS,
- }
-
- /** A long array extra containing ids of call log entries to display. */
- public static final String EXTRA_CALL_LOG_IDS = "EXTRA_CALL_LOG_IDS";
- /** If we are started with a voicemail, we'll find the uri to play with this extra. */
- public static final String EXTRA_VOICEMAIL_URI = "EXTRA_VOICEMAIL_URI";
- /** If we should immediately start playback of the voicemail, this extra will be set to true. */
- public static final String EXTRA_VOICEMAIL_START_PLAYBACK = "EXTRA_VOICEMAIL_START_PLAYBACK";
- /** If the activity was triggered from a notification. */
- public static final String EXTRA_FROM_NOTIFICATION = "EXTRA_FROM_NOTIFICATION";
-
- private CallTypeHelper mCallTypeHelper;
- private PhoneNumberHelper mPhoneNumberHelper;
- private PhoneCallDetailsHelper mPhoneCallDetailsHelper;
- private TextView mHeaderTextView;
- private View mHeaderOverlayView;
- private ImageView mMainActionView;
- private ImageButton mMainActionPushLayerView;
- private ImageView mContactBackgroundView;
- private AsyncTaskExecutor mAsyncTaskExecutor;
- private ContactInfoHelper mContactInfoHelper;
-
- private String mNumber = null;
- private String mDefaultCountryIso;
-
- /* package */ LayoutInflater mInflater;
- /* package */ Resources mResources;
- /** Helper to load contact photos. */
- private ContactPhotoManager mContactPhotoManager;
- /** Helper to make async queries to content resolver. */
- private CallDetailActivityQueryHandler mAsyncQueryHandler;
- /** Helper to get voicemail status messages. */
- private VoicemailStatusHelper mVoicemailStatusHelper;
- // Views related to voicemail status message.
- private View mStatusMessageView;
- private TextView mStatusMessageText;
- private TextView mStatusMessageAction;
-
- /** Whether we should show "edit number before call" in the options menu. */
- private boolean mHasEditNumberBeforeCallOption;
- /** Whether we should show "trash" in the options menu. */
- private boolean mHasTrashOption;
- /** Whether we should show "remove from call log" in the options menu. */
- private boolean mHasRemoveFromCallLogOption;
-
- private ProximitySensorManager mProximitySensorManager;
- private final ProximitySensorListener mProximitySensorListener = new ProximitySensorListener();
-
- /**
- * The action mode used when the phone number is selected. This will be non-null only when the
- * phone number is selected.
- */
- private ActionMode mPhoneNumberActionMode;
-
- private CharSequence mPhoneNumberLabelToCopy;
- private CharSequence mPhoneNumberToCopy;
-
- /** Listener to changes in the proximity sensor state. */
- private class ProximitySensorListener implements ProximitySensorManager.Listener {
- /** Used to show a blank view and hide the action bar. */
- private final Runnable mBlankRunnable = new Runnable() {
- @Override
- public void run() {
- View blankView = findViewById(R.id.blank);
- blankView.setVisibility(View.VISIBLE);
- getActionBar().hide();
- }
- };
- /** Used to remove the blank view and show the action bar. */
- private final Runnable mUnblankRunnable = new Runnable() {
- @Override
- public void run() {
- View blankView = findViewById(R.id.blank);
- blankView.setVisibility(View.GONE);
- getActionBar().show();
- }
- };
-
- @Override
- public synchronized void onNear() {
- clearPendingRequests();
- postDelayed(mBlankRunnable, PROXIMITY_BLANK_DELAY_MILLIS);
- }
-
- @Override
- public synchronized void onFar() {
- clearPendingRequests();
- postDelayed(mUnblankRunnable, PROXIMITY_UNBLANK_DELAY_MILLIS);
- }
-
- /** Removed any delayed requests that may be pending. */
- public synchronized void clearPendingRequests() {
- View blankView = findViewById(R.id.blank);
- blankView.removeCallbacks(mBlankRunnable);
- blankView.removeCallbacks(mUnblankRunnable);
- }
-
- /** Post a {@link Runnable} with a delay on the main thread. */
- private synchronized void postDelayed(Runnable runnable, long delayMillis) {
- // Post these instead of executing immediately so that:
- // - They are guaranteed to be executed on the main thread.
- // - If the sensor values changes rapidly for some time, the UI will not be
- // updated immediately.
- View blankView = findViewById(R.id.blank);
- blankView.postDelayed(runnable, delayMillis);
- }
- }
-
- static final String[] CALL_LOG_PROJECTION = new String[] {
- CallLog.Calls.DATE,
- CallLog.Calls.DURATION,
- CallLog.Calls.NUMBER,
- CallLog.Calls.TYPE,
- CallLog.Calls.COUNTRY_ISO,
- CallLog.Calls.GEOCODED_LOCATION,
- };
-
- static final int DATE_COLUMN_INDEX = 0;
- static final int DURATION_COLUMN_INDEX = 1;
- static final int NUMBER_COLUMN_INDEX = 2;
- static final int CALL_TYPE_COLUMN_INDEX = 3;
- static final int COUNTRY_ISO_COLUMN_INDEX = 4;
- static final int GEOCODED_LOCATION_COLUMN_INDEX = 5;
-
- private final View.OnClickListener mPrimaryActionListener = new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (finishPhoneNumerSelectedActionModeIfShown()) {
- return;
- }
- startActivity(((ViewEntry) view.getTag()).primaryIntent);
- }
- };
-
- private final View.OnClickListener mSecondaryActionListener = new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (finishPhoneNumerSelectedActionModeIfShown()) {
- return;
- }
- startActivity(((ViewEntry) view.getTag()).secondaryIntent);
- }
- };
-
- private final View.OnLongClickListener mPrimaryLongClickListener =
- new View.OnLongClickListener() {
- @Override
- public boolean onLongClick(View v) {
- if (finishPhoneNumerSelectedActionModeIfShown()) {
- return true;
- }
- startPhoneNumberSelectedActionMode(v);
- return true;
- }
- };
-
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- setContentView(R.layout.call_detail);
-
- mAsyncTaskExecutor = AsyncTaskExecutors.createThreadPoolExecutor();
- mInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
- mResources = getResources();
-
- mCallTypeHelper = new CallTypeHelper(getResources());
- mPhoneNumberHelper = new PhoneNumberHelper(mResources);
- mPhoneCallDetailsHelper = new PhoneCallDetailsHelper(mResources, mCallTypeHelper,
- mPhoneNumberHelper);
- mVoicemailStatusHelper = new VoicemailStatusHelperImpl();
- mAsyncQueryHandler = new CallDetailActivityQueryHandler(this);
- mHeaderTextView = (TextView) findViewById(R.id.header_text);
- mHeaderOverlayView = findViewById(R.id.photo_text_bar);
- mStatusMessageView = findViewById(R.id.voicemail_status);
- mStatusMessageText = (TextView) findViewById(R.id.voicemail_status_message);
- mStatusMessageAction = (TextView) findViewById(R.id.voicemail_status_action);
- mMainActionView = (ImageView) findViewById(R.id.main_action);
- mMainActionPushLayerView = (ImageButton) findViewById(R.id.main_action_push_layer);
- mContactBackgroundView = (ImageView) findViewById(R.id.contact_background);
- mDefaultCountryIso = ContactsUtils.getCurrentCountryIso(this);
- mContactPhotoManager = ContactPhotoManager.getInstance(this);
- mProximitySensorManager = new ProximitySensorManager(this, mProximitySensorListener);
- mContactInfoHelper = new ContactInfoHelper(this, ContactsUtils.getCurrentCountryIso(this));
- configureActionBar();
- optionallyHandleVoicemail();
- if (getIntent().getBooleanExtra(EXTRA_FROM_NOTIFICATION, false)) {
- closeSystemDialogs();
- }
- }
-
- @Override
- public void onResume() {
- super.onResume();
- updateData(getCallLogEntryUris());
- }
-
- /**
- * Handle voicemail playback or hide voicemail ui.
- * <p>
- * If the Intent used to start this Activity contains the suitable extras, then start voicemail
- * playback. If it doesn't, then hide the voicemail ui.
- */
- private void optionallyHandleVoicemail() {
- View voicemailContainer = findViewById(R.id.voicemail_container);
- if (hasVoicemail()) {
- // Has voicemail: add the voicemail fragment. Add suitable arguments to set the uri
- // to play and optionally start the playback.
- // Do a query to fetch the voicemail status messages.
- VoicemailPlaybackFragment playbackFragment = new VoicemailPlaybackFragment();
- Bundle fragmentArguments = new Bundle();
- fragmentArguments.putParcelable(EXTRA_VOICEMAIL_URI, getVoicemailUri());
- if (getIntent().getBooleanExtra(EXTRA_VOICEMAIL_START_PLAYBACK, false)) {
- fragmentArguments.putBoolean(EXTRA_VOICEMAIL_START_PLAYBACK, true);
- }
- playbackFragment.setArguments(fragmentArguments);
- voicemailContainer.setVisibility(View.VISIBLE);
- getFragmentManager().beginTransaction()
- .add(R.id.voicemail_container, playbackFragment).commitAllowingStateLoss();
- mAsyncQueryHandler.startVoicemailStatusQuery(getVoicemailUri());
- markVoicemailAsRead(getVoicemailUri());
- } else {
- // No voicemail uri: hide the status view.
- mStatusMessageView.setVisibility(View.GONE);
- voicemailContainer.setVisibility(View.GONE);
- }
- }
-
- private boolean hasVoicemail() {
- return getVoicemailUri() != null;
- }
-
- private Uri getVoicemailUri() {
- return getIntent().getParcelableExtra(EXTRA_VOICEMAIL_URI);
- }
-
- private void markVoicemailAsRead(final Uri voicemailUri) {
- mAsyncTaskExecutor.submit(Tasks.MARK_VOICEMAIL_READ, new AsyncTask<Void, Void, Void>() {
- @Override
- public Void doInBackground(Void... params) {
- ContentValues values = new ContentValues();
- values.put(Voicemails.IS_READ, true);
- getContentResolver().update(voicemailUri, values,
- Voicemails.IS_READ + " = 0", null);
- return null;
- }
- });
- }
-
- /**
- * Returns the list of URIs to show.
- * <p>
- * There are two ways the URIs can be provided to the activity: as the data on the intent, or as
- * a list of ids in the call log added as an extra on the URI.
- * <p>
- * If both are available, the data on the intent takes precedence.
- */
- private Uri[] getCallLogEntryUris() {
- Uri uri = getIntent().getData();
- if (uri != null) {
- // If there is a data on the intent, it takes precedence over the extra.
- return new Uri[]{ uri };
- }
- long[] ids = getIntent().getLongArrayExtra(EXTRA_CALL_LOG_IDS);
- Uri[] uris = new Uri[ids.length];
- for (int index = 0; index < ids.length; ++index) {
- uris[index] = ContentUris.withAppendedId(Calls.CONTENT_URI_WITH_VOICEMAIL, ids[index]);
- }
- return uris;
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_CALL: {
- // Make sure phone isn't already busy before starting direct call
- TelephonyManager tm = (TelephonyManager)
- getSystemService(Context.TELEPHONY_SERVICE);
- if (tm.getCallState() == TelephonyManager.CALL_STATE_IDLE) {
- startActivity(ContactsUtils.getCallIntent(
- Uri.fromParts(Constants.SCHEME_TEL, mNumber, null)));
- return true;
- }
- }
- }
-
- return super.onKeyDown(keyCode, event);
- }
-
- /**
- * Update user interface with details of given call.
- *
- * @param callUris URIs into {@link CallLog.Calls} of the calls to be displayed
- */
- private void updateData(final Uri... callUris) {
- class UpdateContactDetailsTask extends AsyncTask<Void, Void, PhoneCallDetails[]> {
- @Override
- public PhoneCallDetails[] doInBackground(Void... params) {
- // TODO: All phone calls correspond to the same person, so we can make a single
- // lookup.
- final int numCalls = callUris.length;
- PhoneCallDetails[] details = new PhoneCallDetails[numCalls];
- try {
- for (int index = 0; index < numCalls; ++index) {
- details[index] = getPhoneCallDetailsForUri(callUris[index]);
- }
- return details;
- } catch (IllegalArgumentException e) {
- // Something went wrong reading in our primary data.
- Log.w(TAG, "invalid URI starting call details", e);
- return null;
- }
- }
-
- @Override
- public void onPostExecute(PhoneCallDetails[] details) {
- if (details == null) {
- // Somewhere went wrong: we're going to bail out and show error to users.
- Toast.makeText(CallDetailActivity.this, R.string.toast_call_detail_error,
- Toast.LENGTH_SHORT).show();
- finish();
- return;
- }
-
- // We know that all calls are from the same number and the same contact, so pick the
- // first.
- PhoneCallDetails firstDetails = details[0];
- mNumber = firstDetails.number.toString();
- final Uri contactUri = firstDetails.contactUri;
- final Uri photoUri = firstDetails.photoUri;
-
- // Set the details header, based on the first phone call.
- mPhoneCallDetailsHelper.setCallDetailsHeader(mHeaderTextView, firstDetails);
-
- // Cache the details about the phone number.
- final boolean canPlaceCallsTo = mPhoneNumberHelper.canPlaceCallsTo(mNumber);
- final boolean isVoicemailNumber = mPhoneNumberHelper.isVoicemailNumber(mNumber);
- final boolean isSipNumber = mPhoneNumberHelper.isSipNumber(mNumber);
-
- // Let user view contact details if they exist, otherwise add option to create new
- // contact from this number.
- final Intent mainActionIntent;
- final int mainActionIcon;
- final String mainActionDescription;
-
- final CharSequence nameOrNumber;
- if (!TextUtils.isEmpty(firstDetails.name)) {
- nameOrNumber = firstDetails.name;
- } else {
- nameOrNumber = firstDetails.number;
- }
-
- if (contactUri != null) {
- mainActionIntent = new Intent(Intent.ACTION_VIEW, contactUri);
- // This will launch People's detail contact screen, so we probably want to
- // treat it as a separate People task.
- mainActionIntent.setFlags(
- Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- mainActionIcon = R.drawable.ic_contacts_holo_dark;
- mainActionDescription =
- getString(R.string.description_view_contact, nameOrNumber);
- } else if (isVoicemailNumber) {
- mainActionIntent = null;
- mainActionIcon = 0;
- mainActionDescription = null;
- } else if (isSipNumber) {
- // TODO: This item is currently disabled for SIP addresses, because
- // the Insert.PHONE extra only works correctly for PSTN numbers.
- //
- // To fix this for SIP addresses, we need to:
- // - define ContactsContract.Intents.Insert.SIP_ADDRESS, and use it here if
- // the current number is a SIP address
- // - update the contacts UI code to handle Insert.SIP_ADDRESS by
- // updating the SipAddress field
- // and then we can remove the "!isSipNumber" check above.
- mainActionIntent = null;
- mainActionIcon = 0;
- mainActionDescription = null;
- } else if (canPlaceCallsTo) {
- mainActionIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
- mainActionIntent.setType(Contacts.CONTENT_ITEM_TYPE);
- mainActionIntent.putExtra(Insert.PHONE, mNumber);
- mainActionIcon = R.drawable.ic_add_contact_holo_dark;
- mainActionDescription = getString(R.string.description_add_contact);
- } else {
- // If we cannot call the number, when we probably cannot add it as a contact either.
- // This is usually the case of private, unknown, or payphone numbers.
- mainActionIntent = null;
- mainActionIcon = 0;
- mainActionDescription = null;
- }
-
- if (mainActionIntent == null) {
- mMainActionView.setVisibility(View.INVISIBLE);
- mMainActionPushLayerView.setVisibility(View.GONE);
- mHeaderTextView.setVisibility(View.INVISIBLE);
- mHeaderOverlayView.setVisibility(View.INVISIBLE);
- } else {
- mMainActionView.setVisibility(View.VISIBLE);
- mMainActionView.setImageResource(mainActionIcon);
- mMainActionPushLayerView.setVisibility(View.VISIBLE);
- mMainActionPushLayerView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- startActivity(mainActionIntent);
- }
- });
- mMainActionPushLayerView.setContentDescription(mainActionDescription);
- mHeaderTextView.setVisibility(View.VISIBLE);
- mHeaderOverlayView.setVisibility(View.VISIBLE);
- }
-
- // This action allows to call the number that places the call.
- if (canPlaceCallsTo) {
- final CharSequence displayNumber =
- mPhoneNumberHelper.getDisplayNumber(
- firstDetails.number, firstDetails.formattedNumber);
-
- ViewEntry entry = new ViewEntry(
- getString(R.string.menu_callNumber,
- FormatUtils.forceLeftToRight(displayNumber)),
- ContactsUtils.getCallIntent(mNumber),
- getString(R.string.description_call, nameOrNumber));
-
- // Only show a label if the number is shown and it is not a SIP address.
- if (!TextUtils.isEmpty(firstDetails.name)
- && !TextUtils.isEmpty(firstDetails.number)
- && !PhoneNumberUtils.isUriNumber(firstDetails.number.toString())) {
- entry.label = Phone.getTypeLabel(mResources, firstDetails.numberType,
- firstDetails.numberLabel);
- }
-
- // The secondary action allows to send an SMS to the number that placed the
- // call.
- if (mPhoneNumberHelper.canSendSmsTo(mNumber)) {
- entry.setSecondaryAction(
- R.drawable.ic_text_holo_dark,
- new Intent(Intent.ACTION_SENDTO,
- Uri.fromParts("sms", mNumber, null)),
- getString(R.string.description_send_text_message, nameOrNumber));
- }
-
- configureCallButton(entry);
- mPhoneNumberToCopy = displayNumber;
- mPhoneNumberLabelToCopy = entry.label;
- } else {
- disableCallButton();
- mPhoneNumberToCopy = null;
- mPhoneNumberLabelToCopy = null;
- }
-
- mHasEditNumberBeforeCallOption =
- canPlaceCallsTo && !isSipNumber && !isVoicemailNumber;
- mHasTrashOption = hasVoicemail();
- mHasRemoveFromCallLogOption = !hasVoicemail();
- invalidateOptionsMenu();
-
- ListView historyList = (ListView) findViewById(R.id.history);
- historyList.setAdapter(
- new CallDetailHistoryAdapter(CallDetailActivity.this, mInflater,
- mCallTypeHelper, details, hasVoicemail(), canPlaceCallsTo,
- findViewById(R.id.controls)));
- BackScrollManager.bind(
- new ScrollableHeader() {
- private View mControls = findViewById(R.id.controls);
- private View mPhoto = findViewById(R.id.contact_background_sizer);
- private View mHeader = findViewById(R.id.photo_text_bar);
- private View mSeparator = findViewById(R.id.blue_separator);
-
- @Override
- public void setOffset(int offset) {
- mControls.setY(-offset);
- }
-
- @Override
- public int getMaximumScrollableHeaderOffset() {
- // We can scroll the photo out, but we should keep the header if
- // present.
- if (mHeader.getVisibility() == View.VISIBLE) {
- return mPhoto.getHeight() - mHeader.getHeight();
- } else {
- // If the header is not present, we should also scroll out the
- // separator line.
- return mPhoto.getHeight() + mSeparator.getHeight();
- }
- }
- },
- historyList);
- loadContactPhotos(photoUri);
- findViewById(R.id.call_detail).setVisibility(View.VISIBLE);
- }
- }
- mAsyncTaskExecutor.submit(Tasks.UPDATE_PHONE_CALL_DETAILS, new UpdateContactDetailsTask());
- }
-
- /** Return the phone call details for a given call log URI. */
- private PhoneCallDetails getPhoneCallDetailsForUri(Uri callUri) {
- ContentResolver resolver = getContentResolver();
- Cursor callCursor = resolver.query(callUri, CALL_LOG_PROJECTION, null, null, null);
- try {
- if (callCursor == null || !callCursor.moveToFirst()) {
- throw new IllegalArgumentException("Cannot find content: " + callUri);
- }
-
- // Read call log specifics.
- String number = callCursor.getString(NUMBER_COLUMN_INDEX);
- long date = callCursor.getLong(DATE_COLUMN_INDEX);
- long duration = callCursor.getLong(DURATION_COLUMN_INDEX);
- int callType = callCursor.getInt(CALL_TYPE_COLUMN_INDEX);
- String countryIso = callCursor.getString(COUNTRY_ISO_COLUMN_INDEX);
- final String geocode = callCursor.getString(GEOCODED_LOCATION_COLUMN_INDEX);
-
- if (TextUtils.isEmpty(countryIso)) {
- countryIso = mDefaultCountryIso;
- }
-
- // Formatted phone number.
- final CharSequence formattedNumber;
- // Read contact specifics.
- final CharSequence nameText;
- final int numberType;
- final CharSequence numberLabel;
- final Uri photoUri;
- final Uri lookupUri;
- // If this is not a regular number, there is no point in looking it up in the contacts.
- ContactInfo info =
- mPhoneNumberHelper.canPlaceCallsTo(number)
- && !mPhoneNumberHelper.isVoicemailNumber(number)
- ? mContactInfoHelper.lookupNumber(number, countryIso)
- : null;
- if (info == null) {
- formattedNumber = mPhoneNumberHelper.getDisplayNumber(number, null);
- nameText = "";
- numberType = 0;
- numberLabel = "";
- photoUri = null;
- lookupUri = null;
- } else {
- formattedNumber = info.formattedNumber;
- nameText = info.name;
- numberType = info.type;
- numberLabel = info.label;
- photoUri = info.photoUri;
- lookupUri = info.lookupUri;
- }
- return new PhoneCallDetails(number, formattedNumber, countryIso, geocode,
- new int[]{ callType }, date, duration,
- nameText, numberType, numberLabel, lookupUri, photoUri);
- } finally {
- if (callCursor != null) {
- callCursor.close();
- }
- }
- }
-
- /** Load the contact photos and places them in the corresponding views. */
- private void loadContactPhotos(Uri photoUri) {
- mContactPhotoManager.loadPhoto(mContactBackgroundView, photoUri,
- mContactBackgroundView.getWidth(), true);
- }
-
- static final class ViewEntry {
- public final String text;
- public final Intent primaryIntent;
- /** The description for accessibility of the primary action. */
- public final String primaryDescription;
-
- public CharSequence label = null;
- /** Icon for the secondary action. */
- public int secondaryIcon = 0;
- /** Intent for the secondary action. If not null, an icon must be defined. */
- public Intent secondaryIntent = null;
- /** The description for accessibility of the secondary action. */
- public String secondaryDescription = null;
-
- public ViewEntry(String text, Intent intent, String description) {
- this.text = text;
- primaryIntent = intent;
- primaryDescription = description;
- }
-
- public void setSecondaryAction(int icon, Intent intent, String description) {
- secondaryIcon = icon;
- secondaryIntent = intent;
- secondaryDescription = description;
- }
- }
-
- /** Disables the call button area, e.g., for private numbers. */
- private void disableCallButton() {
- findViewById(R.id.call_and_sms).setVisibility(View.GONE);
- }
-
- /** Configures the call button area using the given entry. */
- private void configureCallButton(ViewEntry entry) {
- View convertView = findViewById(R.id.call_and_sms);
- convertView.setVisibility(View.VISIBLE);
-
- ImageView icon = (ImageView) convertView.findViewById(R.id.call_and_sms_icon);
- View divider = convertView.findViewById(R.id.call_and_sms_divider);
- TextView text = (TextView) convertView.findViewById(R.id.call_and_sms_text);
-
- View mainAction = convertView.findViewById(R.id.call_and_sms_main_action);
- mainAction.setOnClickListener(mPrimaryActionListener);
- mainAction.setTag(entry);
- mainAction.setContentDescription(entry.primaryDescription);
- mainAction.setOnLongClickListener(mPrimaryLongClickListener);
-
- if (entry.secondaryIntent != null) {
- icon.setOnClickListener(mSecondaryActionListener);
- icon.setImageResource(entry.secondaryIcon);
- icon.setVisibility(View.VISIBLE);
- icon.setTag(entry);
- icon.setContentDescription(entry.secondaryDescription);
- divider.setVisibility(View.VISIBLE);
- } else {
- icon.setVisibility(View.GONE);
- divider.setVisibility(View.GONE);
- }
- text.setText(entry.text);
-
- TextView label = (TextView) convertView.findViewById(R.id.call_and_sms_label);
- if (TextUtils.isEmpty(entry.label)) {
- label.setVisibility(View.GONE);
- } else {
- label.setText(entry.label);
- label.setVisibility(View.VISIBLE);
- }
- }
-
- protected void updateVoicemailStatusMessage(Cursor statusCursor) {
- if (statusCursor == null) {
- mStatusMessageView.setVisibility(View.GONE);
- return;
- }
- final StatusMessage message = getStatusMessage(statusCursor);
- if (message == null || !message.showInCallDetails()) {
- mStatusMessageView.setVisibility(View.GONE);
- return;
- }
-
- mStatusMessageView.setVisibility(View.VISIBLE);
- mStatusMessageText.setText(message.callDetailsMessageId);
- if (message.actionMessageId != -1) {
- mStatusMessageAction.setText(message.actionMessageId);
- }
- if (message.actionUri != null) {
- mStatusMessageAction.setClickable(true);
- mStatusMessageAction.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- startActivity(new Intent(Intent.ACTION_VIEW, message.actionUri));
- }
- });
- } else {
- mStatusMessageAction.setClickable(false);
- }
- }
-
- private StatusMessage getStatusMessage(Cursor statusCursor) {
- List<StatusMessage> messages = mVoicemailStatusHelper.getStatusMessages(statusCursor);
- if (messages.size() == 0) {
- return null;
- }
- // There can only be a single status message per source package, so num of messages can
- // at most be 1.
- if (messages.size() > 1) {
- Log.w(TAG, String.format("Expected 1, found (%d) num of status messages." +
- " Will use the first one.", messages.size()));
- }
- return messages.get(0);
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.call_details_options, menu);
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- // This action deletes all elements in the group from the call log.
- // We don't have this action for voicemails, because you can just use the trash button.
- menu.findItem(R.id.menu_remove_from_call_log).setVisible(mHasRemoveFromCallLogOption);
- menu.findItem(R.id.menu_edit_number_before_call).setVisible(mHasEditNumberBeforeCallOption);
- menu.findItem(R.id.menu_trash).setVisible(mHasTrashOption);
- return super.onPrepareOptionsMenu(menu);
- }
-
- @Override
- public boolean onMenuItemSelected(int featureId, MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home: {
- onHomeSelected();
- return true;
- }
-
- // All the options menu items are handled by onMenu... methods.
- default:
- throw new IllegalArgumentException();
- }
- }
-
- public void onMenuRemoveFromCallLog(MenuItem menuItem) {
- final StringBuilder callIds = new StringBuilder();
- for (Uri callUri : getCallLogEntryUris()) {
- if (callIds.length() != 0) {
- callIds.append(",");
- }
- callIds.append(ContentUris.parseId(callUri));
- }
- mAsyncTaskExecutor.submit(Tasks.REMOVE_FROM_CALL_LOG_AND_FINISH,
- new AsyncTask<Void, Void, Void>() {
- @Override
- public Void doInBackground(Void... params) {
- getContentResolver().delete(Calls.CONTENT_URI_WITH_VOICEMAIL,
- Calls._ID + " IN (" + callIds + ")", null);
- return null;
- }
-
- @Override
- public void onPostExecute(Void result) {
- finish();
- }
- });
- }
-
- public void onMenuEditNumberBeforeCall(MenuItem menuItem) {
- startActivity(new Intent(Intent.ACTION_DIAL, ContactsUtils.getCallUri(mNumber)));
- }
-
- public void onMenuTrashVoicemail(MenuItem menuItem) {
- final Uri voicemailUri = getVoicemailUri();
- mAsyncTaskExecutor.submit(Tasks.DELETE_VOICEMAIL_AND_FINISH,
- new AsyncTask<Void, Void, Void>() {
- @Override
- public Void doInBackground(Void... params) {
- getContentResolver().delete(voicemailUri, null, null);
- return null;
- }
- @Override
- public void onPostExecute(Void result) {
- finish();
- }
- });
- }
-
- private void configureActionBar() {
- ActionBar actionBar = getActionBar();
- if (actionBar != null) {
- actionBar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME);
- }
- }
-
- /** Invoked when the user presses the home button in the action bar. */
- private void onHomeSelected() {
- Intent intent = new Intent(Intent.ACTION_VIEW, Calls.CONTENT_URI);
- // This will open the call log even if the detail view has been opened directly.
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(intent);
- finish();
- }
-
- @Override
- protected void onPause() {
- // Immediately stop the proximity sensor.
- disableProximitySensor(false);
- mProximitySensorListener.clearPendingRequests();
- super.onPause();
- }
-
- @Override
- public void enableProximitySensor() {
- mProximitySensorManager.enable();
- }
-
- @Override
- public void disableProximitySensor(boolean waitForFarState) {
- mProximitySensorManager.disable(waitForFarState);
- }
-
- /**
- * If the phone number is selected, unselect it and return {@code true}.
- * Otherwise, just {@code false}.
- */
- private boolean finishPhoneNumerSelectedActionModeIfShown() {
- if (mPhoneNumberActionMode == null) return false;
- mPhoneNumberActionMode.finish();
- return true;
- }
-
- private void startPhoneNumberSelectedActionMode(View targetView) {
- mPhoneNumberActionMode = startActionMode(new PhoneNumberActionModeCallback(targetView));
- }
-
- private void closeSystemDialogs() {
- sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
- }
-
- private class PhoneNumberActionModeCallback implements ActionMode.Callback {
- private final View mTargetView;
- private final Drawable mOriginalViewBackground;
-
- public PhoneNumberActionModeCallback(View targetView) {
- mTargetView = targetView;
-
- // Highlight the phone number view. Remember the old background, and put a new one.
- mOriginalViewBackground = mTargetView.getBackground();
- mTargetView.setBackgroundColor(getResources().getColor(R.color.item_selected));
- }
-
- @Override
- public boolean onCreateActionMode(ActionMode mode, Menu menu) {
- if (TextUtils.isEmpty(mPhoneNumberToCopy)) return false;
-
- getMenuInflater().inflate(R.menu.call_details_cab, menu);
- return true;
- }
-
- @Override
- public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
- return true;
- }
-
- @Override
- public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
- switch (item.getItemId()) {
- case R.id.copy_phone_number:
- ClipboardUtils.copyText(CallDetailActivity.this, mPhoneNumberLabelToCopy,
- mPhoneNumberToCopy, true);
- mode.finish(); // Close the CAB
- return true;
- }
- return false;
- }
-
- @Override
- public void onDestroyActionMode(ActionMode mode) {
- mPhoneNumberActionMode = null;
-
- // Restore the view background.
- mTargetView.setBackground(mOriginalViewBackground);
- }
- }
-}
diff --git a/src/com/android/contacts/CallDetailActivityQueryHandler.java b/src/com/android/contacts/CallDetailActivityQueryHandler.java
deleted file mode 100644
index 41cf937..0000000
--- a/src/com/android/contacts/CallDetailActivityQueryHandler.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-import android.content.AsyncQueryHandler;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.VoicemailContract.Status;
-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.
- */
-public class CallDetailActivityQueryHandler extends AsyncQueryHandler {
- private static final String TAG = "CallDetail";
- private static final int QUERY_VOICEMAIL_CONTENT_TOKEN = 101;
- private static final int QUERY_VOICEMAIL_STATUS_TOKEN = 102;
-
- private final String[] VOICEMAIL_CONTENT_PROJECTION = new String[] {
- Voicemails.SOURCE_PACKAGE,
- Voicemails.HAS_CONTENT
- };
- private static final int SOURCE_PACKAGE_COLUMN_INDEX = 0;
- private static final int HAS_CONTENT_COLUMN_INDEX = 1;
-
- private final CallDetailActivity mCallDetailActivity;
-
- public CallDetailActivityQueryHandler(CallDetailActivity callDetailActivity) {
- super(callDetailActivity.getContentResolver());
- mCallDetailActivity = callDetailActivity;
- }
-
- /**
- * Fires a query to update voicemail status for the given voicemail record. On completion of the
- * query a call to {@link CallDetailActivity#updateVoicemailStatusMessage(Cursor)} is made.
- * <p>
- * if this is a voicemail record then it makes up to two asynchronous content resolver queries.
- * The first one to fetch voicemail content details and check if the voicemail record has audio.
- * If the voicemail record does not have an audio yet then it fires the second query to get the
- * voicemail status of the associated source.
- */
- public void startVoicemailStatusQuery(Uri voicemailUri) {
- startQuery(QUERY_VOICEMAIL_CONTENT_TOKEN, null, voicemailUri, VOICEMAIL_CONTENT_PROJECTION,
- null, null, null);
- }
-
- @Override
- protected synchronized void onQueryComplete(int token, Object cookie, Cursor cursor) {
- try {
- if (token == QUERY_VOICEMAIL_CONTENT_TOKEN) {
- // Query voicemail status only if this voicemail record does not have audio.
- if (moveToFirst(cursor) && hasNoAudio(cursor)) {
- startQuery(QUERY_VOICEMAIL_STATUS_TOKEN, null,
- Status.buildSourceUri(getSourcePackage(cursor)),
- VoicemailStatusHelperImpl.PROJECTION, null, null, null);
- } else {
- // nothing to show in status
- mCallDetailActivity.updateVoicemailStatusMessage(null);
- }
- } else if (token == QUERY_VOICEMAIL_STATUS_TOKEN) {
- mCallDetailActivity.updateVoicemailStatusMessage(cursor);
- } else {
- Log.w(TAG, "Unknown query completed: ignoring: " + token);
- }
- } finally {
- MoreCloseables.closeQuietly(cursor);
- }
- }
-
- /** Check that the cursor is non-null and can be moved to first. */
- private boolean moveToFirst(Cursor cursor) {
- if (cursor == null || !cursor.moveToFirst()) {
- Log.e(TAG, "Cursor not valid, could not move to first");
- return false;
- }
- return true;
- }
-
- private boolean hasNoAudio(Cursor voicemailCursor) {
- return voicemailCursor.getInt(HAS_CONTENT_COLUMN_INDEX) == 0;
- }
-
- private String getSourcePackage(Cursor voicemailCursor) {
- return voicemailCursor.getString(SOURCE_PACKAGE_COLUMN_INDEX);
- }
-}
diff --git a/src/com/android/contacts/Collapser.java b/src/com/android/contacts/Collapser.java
deleted file mode 100644
index 3b2f2a9..0000000
--- a/src/com/android/contacts/Collapser.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Class used for collapsing data items into groups of similar items. The data items that should be
- * collapsible should implement the Collapsible interface. The class also contains a utility
- * function that takes an ArrayList of items and returns a list of the same items collapsed into
- * groups.
- */
-public final class Collapser {
-
- /*
- * This utility class cannot be instantiated.
- */
- private Collapser() {}
-
- /*
- * Interface implemented by data types that can be collapsed into groups of similar data. This
- * can be used for example to collapse similar contact data items into a single item.
- */
- public interface Collapsible<T> {
- public boolean collapseWith(T t);
- public boolean shouldCollapseWith(T t);
- }
-
- /**
- * Collapses a list of Collapsible items into a list of collapsed items. Items are collapsed
- * if {@link Collapsible#shouldCollapseWith(Object)} returns true, and are collapsed
- * through the {@Link Collapsible#collapseWith(Object)} function implemented by the data item.
- *
- * @param list List of Objects of type <T extends Collapsible<T>> to be collapsed.
- */
- public static <T extends Collapsible<T>> void collapseList(List<T> list) {
-
- int listSize = list.size();
-
- for (int i = 0; i < listSize; i++) {
- T iItem = list.get(i);
- if (iItem != null) {
- for (int j = i + 1; j < listSize; j++) {
- T jItem = list.get(j);
- if (jItem != null) {
- if (iItem.shouldCollapseWith(jItem)) {
- iItem.collapseWith(jItem);
- list.set(j, null);
- }
- }
- }
- }
- }
-
- // Remove the null items
- Iterator<T> itr = list.iterator();
- while (itr.hasNext()) {
- if (itr.next() == null) {
- itr.remove();
- }
- }
-
- }
-}
diff --git a/src/com/android/contacts/ContactPhotoManager.java b/src/com/android/contacts/ContactPhotoManager.java
deleted file mode 100644
index 5c866d0..0000000
--- a/src/com/android/contacts/ContactPhotoManager.java
+++ /dev/null
@@ -1,1223 +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 android.content.ComponentCallbacks2;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Paint.Style;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.TransitionDrawable;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Handler.Callback;
-import android.os.HandlerThread;
-import android.os.Message;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Contacts.Photo;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.Directory;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.LruCache;
-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;
-import java.lang.ref.SoftReference;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Asynchronously loads contact photos and maintains a cache of photos.
- */
-public abstract class ContactPhotoManager implements ComponentCallbacks2 {
- static final String TAG = "ContactPhotoManager";
- static final boolean DEBUG = false; // Don't submit with true
- static final boolean DEBUG_SIZES = false; // Don't submit with true
-
- /** Caches 180dip in pixel. This is used to detect whether to show the hires or lores version
- * of the default avatar */
- private static int s180DipInPixel = -1;
-
- public static final String CONTACT_PHOTO_SERVICE = "contactPhotos";
-
- /**
- * Returns the resource id of the default avatar. Tries to find a resource that is bigger
- * than the given extent (width or height). If extent=-1, a thumbnail avatar is returned
- */
- public static int getDefaultAvatarResId(Context context, int extent, boolean darkTheme) {
- // TODO: Is it worth finding a nicer way to do hires/lores here? In practice, the
- // default avatar doesn't look too different when stretched
- if (s180DipInPixel == -1) {
- Resources r = context.getResources();
- s180DipInPixel = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 180,
- r.getDisplayMetrics());
- }
-
- final boolean hires = (extent != -1) && (extent > s180DipInPixel);
- return getDefaultAvatarResId(hires, darkTheme);
- }
-
- public static int getDefaultAvatarResId(boolean hires, boolean darkTheme) {
- if (hires && darkTheme) return R.drawable.ic_contact_picture_180_holo_dark;
- if (hires) return R.drawable.ic_contact_picture_180_holo_light;
- if (darkTheme) return R.drawable.ic_contact_picture_holo_dark;
- return R.drawable.ic_contact_picture_holo_light;
- }
-
- public static abstract class DefaultImageProvider {
- /**
- * Applies the default avatar to the ImageView. Extent is an indicator for the size (width
- * or height). If darkTheme is set, the avatar is one that looks better on dark background
- */
- public abstract void applyDefaultImage(ImageView view, int extent, boolean darkTheme);
- }
-
- private static class AvatarDefaultImageProvider extends DefaultImageProvider {
- @Override
- public void applyDefaultImage(ImageView view, int extent, boolean darkTheme) {
- view.setImageResource(getDefaultAvatarResId(view.getContext(), extent, darkTheme));
- }
- }
-
- private static class BlankDefaultImageProvider extends DefaultImageProvider {
- private static Drawable sDrawable;
-
- @Override
- public void applyDefaultImage(ImageView view, int extent, boolean darkTheme) {
- if (sDrawable == null) {
- Context context = view.getContext();
- sDrawable = new ColorDrawable(context.getResources().getColor(
- R.color.image_placeholder));
- }
- view.setImageDrawable(sDrawable);
- }
- }
-
- public static final DefaultImageProvider DEFAULT_AVATAR = new AvatarDefaultImageProvider();
-
- public static final DefaultImageProvider DEFAULT_BLANK = new BlankDefaultImageProvider();
-
- /**
- * Requests the singleton instance of {@link AccountTypeManager} with data bound from
- * the available authenticators. This method can safely be called from the UI thread.
- */
- public static ContactPhotoManager getInstance(Context context) {
- Context applicationContext = context.getApplicationContext();
- ContactPhotoManager service =
- (ContactPhotoManager) applicationContext.getSystemService(CONTACT_PHOTO_SERVICE);
- if (service == null) {
- service = createContactPhotoManager(applicationContext);
- Log.e(TAG, "No contact photo service in context: " + applicationContext);
- }
- return service;
- }
-
- public static synchronized ContactPhotoManager createContactPhotoManager(Context context) {
- return new ContactPhotoManagerImpl(context);
- }
-
- /**
- * Load thumbnail image into the supplied image view. If the photo is already cached,
- * it is displayed immediately. Otherwise a request is sent to load the photo
- * from the database.
- */
- public abstract void loadThumbnail(ImageView view, long photoId, boolean darkTheme,
- DefaultImageProvider defaultProvider);
-
- /**
- * Calls {@link #loadThumbnail(ImageView, long, boolean, DefaultImageProvider)} with
- * {@link #DEFAULT_AVATAR}.
- */
- public final void loadThumbnail(ImageView view, long photoId, boolean darkTheme) {
- loadThumbnail(view, photoId, darkTheme, DEFAULT_AVATAR);
- }
-
- /**
- * Load photo into the supplied image view. If the photo is already cached,
- * it is displayed immediately. Otherwise a request is sent to load the photo
- * from the location specified by the URI.
- * @param view The target view
- * @param photoUri The uri of the photo to load
- * @param requestedExtent Specifies an approximate Max(width, height) of the targetView.
- * This is useful if the source image can be a lot bigger that the target, so that the decoding
- * is done using efficient sampling. If requestedExtent is specified, no sampling of the image
- * is performed
- * @param darkTheme Whether the background is dark. This is used for default avatars
- * @param defaultProvider The provider of default avatars (this is used if photoUri doesn't
- * refer to an existing image)
- */
- public abstract void loadPhoto(ImageView view, Uri photoUri, int requestedExtent,
- boolean darkTheme, DefaultImageProvider defaultProvider);
-
- /**
- * Calls {@link #loadPhoto(ImageView, Uri, boolean, boolean, DefaultImageProvider)} with
- * {@link #DEFAULT_AVATAR}.
- */
- public final void loadPhoto(ImageView view, Uri photoUri, int requestedExtent,
- boolean darkTheme) {
- loadPhoto(view, photoUri, requestedExtent, darkTheme, DEFAULT_AVATAR);
- }
-
- /**
- * Calls {@link #loadPhoto(ImageView, Uri, boolean, boolean, DefaultImageProvider)} with
- * {@link #DEFAULT_AVATAR} and with the assumption, that the image is a thumbnail
- */
- public final void loadDirectoryPhoto(ImageView view, Uri photoUri, boolean darkTheme) {
- loadPhoto(view, photoUri, -1, darkTheme, DEFAULT_AVATAR);
- }
-
- /**
- * Remove photo from the supplied image view. This also cancels current pending load request
- * inside this photo manager.
- */
- public abstract void removePhoto(ImageView view);
-
- /**
- * Temporarily stops loading photos from the database.
- */
- public abstract void pause();
-
- /**
- * Resumes loading photos from the database.
- */
- public abstract void resume();
-
- /**
- * Marks all cached photos for reloading. We can continue using cache but should
- * also make sure the photos haven't changed in the background and notify the views
- * if so.
- */
- public abstract void refreshCache();
-
- /**
- * Stores the given bitmap directly in the LRU bitmap cache.
- * @param photoUri The URI of the photo (for future requests).
- * @param bitmap The bitmap.
- * @param photoBytes The bytes that were parsed to create the bitmap.
- */
- public abstract void cacheBitmap(Uri photoUri, Bitmap bitmap, byte[] photoBytes);
-
- /**
- * Initiates a background process that over time will fill up cache with
- * preload photos.
- */
- public abstract void preloadPhotosInBackground();
-
- // ComponentCallbacks2
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- }
-
- // ComponentCallbacks2
- @Override
- public void onLowMemory() {
- }
-
- // ComponentCallbacks2
- @Override
- public void onTrimMemory(int level) {
- }
-}
-
-class ContactPhotoManagerImpl extends ContactPhotoManager implements Callback {
- private static final String LOADER_THREAD_NAME = "ContactPhotoLoader";
-
- private static final int FADE_TRANSITION_DURATION = 200;
-
- /**
- * Type of message sent by the UI thread to itself to indicate that some photos
- * need to be loaded.
- */
- private static final int MESSAGE_REQUEST_LOADING = 1;
-
- /**
- * Type of message sent by the loader thread to indicate that some photos have
- * been loaded.
- */
- private static final int MESSAGE_PHOTOS_LOADED = 2;
-
- private static final String[] EMPTY_STRING_ARRAY = new String[0];
-
- private static final String[] COLUMNS = new String[] { Photo._ID, Photo.PHOTO };
-
- /**
- * Maintains the state of a particular photo.
- */
- private static class BitmapHolder {
- final byte[] bytes;
- final int originalSmallerExtent;
-
- volatile boolean fresh;
- Bitmap bitmap;
- Reference<Bitmap> bitmapRef;
- int decodedSampleSize;
-
- public BitmapHolder(byte[] bytes, int originalSmallerExtent) {
- this.bytes = bytes;
- this.fresh = true;
- this.originalSmallerExtent = originalSmallerExtent;
- }
- }
-
- private final Context mContext;
-
- /**
- * An LRU cache for bitmap holders. The cache contains bytes for photos just
- * as they come from the database. Each holder has a soft reference to the
- * actual bitmap.
- */
- private final LruCache<Object, BitmapHolder> mBitmapHolderCache;
-
- /**
- * {@code true} if ALL entries in {@link #mBitmapHolderCache} are NOT fresh.
- */
- private volatile boolean mBitmapHolderCacheAllUnfresh = true;
-
- /**
- * Cache size threshold at which bitmaps will not be preloaded.
- */
- private final int mBitmapHolderCacheRedZoneBytes;
-
- /**
- * Level 2 LRU cache for bitmaps. This is a smaller cache that holds
- * the most recently used bitmaps to save time on decoding
- * them from bytes (the bytes are stored in {@link #mBitmapHolderCache}.
- */
- private final LruCache<Object, Bitmap> mBitmapCache;
-
- /**
- * A map from ImageView to the corresponding photo ID or uri, encapsulated in a request.
- * The request may swapped out before the photo loading request is started.
- */
- private final ConcurrentHashMap<ImageView, Request> mPendingRequests =
- new ConcurrentHashMap<ImageView, Request>();
-
- /**
- * Handler for messages sent to the UI thread.
- */
- private final Handler mMainThreadHandler = new Handler(this);
-
- /**
- * Thread responsible for loading photos from the database. Created upon
- * the first request.
- */
- private LoaderThread mLoaderThread;
-
- /**
- * A gate to make sure we only send one instance of MESSAGE_PHOTOS_NEEDED at a time.
- */
- private boolean mLoadingRequested;
-
- /**
- * Flag indicating if the image loading is paused.
- */
- private boolean mPaused;
-
- /** Cache size for {@link #mBitmapHolderCache} for devices with "large" RAM. */
- private static final int HOLDER_CACHE_SIZE = 2000000;
-
- /** Cache size for {@link #mBitmapCache} for devices with "large" RAM. */
- private static final int BITMAP_CACHE_SIZE = 36864 * 48; // 1728K
-
- private static final int LARGE_RAM_THRESHOLD = 640 * 1024 * 1024;
-
- /** For debug: How many times we had to reload cached photo for a stale entry */
- private final AtomicInteger mStaleCacheOverwrite = new AtomicInteger();
-
- /** For debug: How many times we had to reload cached photo for a fresh entry. Should be 0. */
- private final AtomicInteger mFreshCacheOverwrite = new AtomicInteger();
-
- public ContactPhotoManagerImpl(Context context) {
- mContext = context;
-
- final float cacheSizeAdjustment =
- (MemoryUtils.getTotalMemorySize() >= LARGE_RAM_THRESHOLD) ? 1.0f : 0.5f;
- final int bitmapCacheSize = (int) (cacheSizeAdjustment * BITMAP_CACHE_SIZE);
- mBitmapCache = new LruCache<Object, Bitmap>(bitmapCacheSize) {
- @Override protected int sizeOf(Object key, Bitmap value) {
- return value.getByteCount();
- }
-
- @Override protected void entryRemoved(
- boolean evicted, Object key, Bitmap oldValue, Bitmap newValue) {
- if (DEBUG) dumpStats();
- }
- };
- final int holderCacheSize = (int) (cacheSizeAdjustment * HOLDER_CACHE_SIZE);
- mBitmapHolderCache = new LruCache<Object, BitmapHolder>(holderCacheSize) {
- @Override protected int sizeOf(Object key, BitmapHolder value) {
- return value.bytes != null ? value.bytes.length : 0;
- }
-
- @Override protected void entryRemoved(
- boolean evicted, Object key, BitmapHolder oldValue, BitmapHolder newValue) {
- if (DEBUG) dumpStats();
- }
- };
- mBitmapHolderCacheRedZoneBytes = (int) (holderCacheSize * 0.75);
- Log.i(TAG, "Cache adj: " + cacheSizeAdjustment);
- if (DEBUG) {
- Log.d(TAG, "Cache size: " + btk(mBitmapHolderCache.maxSize())
- + " + " + btk(mBitmapCache.maxSize()));
- }
- }
-
- /** Converts bytes to K bytes, rounding up. Used only for debug log. */
- private static String btk(int bytes) {
- return ((bytes + 1023) / 1024) + "K";
- }
-
- private static final int safeDiv(int dividend, int divisor) {
- return (divisor == 0) ? 0 : (dividend / divisor);
- }
-
- /**
- * Dump cache stats on logcat.
- */
- private void dumpStats() {
- if (!DEBUG) return;
- {
- int numHolders = 0;
- int rawBytes = 0;
- int bitmapBytes = 0;
- int numBitmaps = 0;
- for (BitmapHolder h : mBitmapHolderCache.snapshot().values()) {
- numHolders++;
- if (h.bytes != null) {
- rawBytes += h.bytes.length;
- }
- Bitmap b = h.bitmapRef != null ? h.bitmapRef.get() : null;
- if (b != null) {
- numBitmaps++;
- bitmapBytes += b.getByteCount();
- }
- }
- Log.d(TAG, "L1: " + btk(rawBytes) + " + " + btk(bitmapBytes) + " = "
- + btk(rawBytes + bitmapBytes) + ", " + numHolders + " holders, "
- + numBitmaps + " bitmaps, avg: "
- + btk(safeDiv(rawBytes, numHolders))
- + "," + btk(safeDiv(bitmapBytes,numBitmaps)));
- Log.d(TAG, "L1 Stats: " + mBitmapHolderCache.toString()
- + ", overwrite: fresh=" + mFreshCacheOverwrite.get()
- + " stale=" + mStaleCacheOverwrite.get());
- }
-
- {
- int numBitmaps = 0;
- int bitmapBytes = 0;
- for (Bitmap b : mBitmapCache.snapshot().values()) {
- numBitmaps++;
- bitmapBytes += b.getByteCount();
- }
- Log.d(TAG, "L2: " + btk(bitmapBytes) + ", " + numBitmaps + " bitmaps"
- + ", avg: " + btk(safeDiv(bitmapBytes, numBitmaps)));
- // We don't get from L2 cache, so L2 stats is meaningless.
- }
- }
-
- @Override
- public void onTrimMemory(int level) {
- if (DEBUG) Log.d(TAG, "onTrimMemory: " + level);
- if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {
- // Clear the caches. Note all pending requests will be removed too.
- clear();
- }
- }
-
- @Override
- public void preloadPhotosInBackground() {
- ensureLoaderThread();
- mLoaderThread.requestPreloading();
- }
-
- @Override
- public void loadThumbnail(ImageView view, long photoId, boolean darkTheme,
- DefaultImageProvider defaultProvider) {
- if (photoId == 0) {
- // No photo is needed
- defaultProvider.applyDefaultImage(view, -1, darkTheme);
- mPendingRequests.remove(view);
- } else {
- if (DEBUG) Log.d(TAG, "loadPhoto request: " + photoId);
- loadPhotoByIdOrUri(view, Request.createFromThumbnailId(photoId, darkTheme,
- defaultProvider));
- }
- }
-
- @Override
- public void loadPhoto(ImageView view, Uri photoUri, int requestedExtent, boolean darkTheme,
- DefaultImageProvider defaultProvider) {
- if (photoUri == null) {
- // No photo is needed
- defaultProvider.applyDefaultImage(view, requestedExtent, darkTheme);
- mPendingRequests.remove(view);
- } else {
- if (DEBUG) Log.d(TAG, "loadPhoto request: " + photoUri);
- loadPhotoByIdOrUri(view, Request.createFromUri(photoUri, requestedExtent, darkTheme,
- defaultProvider));
- }
- }
-
- private void loadPhotoByIdOrUri(ImageView view, Request request) {
- boolean loaded = loadCachedPhoto(view, request, false);
- if (loaded) {
- mPendingRequests.remove(view);
- } else {
- mPendingRequests.put(view, request);
- if (!mPaused) {
- // Send a request to start loading photos
- requestLoading();
- }
- }
- }
-
- @Override
- public void removePhoto(ImageView view) {
- view.setImageDrawable(null);
- mPendingRequests.remove(view);
- }
-
- @Override
- public void refreshCache() {
- if (mBitmapHolderCacheAllUnfresh) {
- if (DEBUG) Log.d(TAG, "refreshCache -- no fresh entries.");
- return;
- }
- if (DEBUG) Log.d(TAG, "refreshCache");
- mBitmapHolderCacheAllUnfresh = true;
- for (BitmapHolder holder : mBitmapHolderCache.snapshot().values()) {
- holder.fresh = false;
- }
- }
-
- /**
- * Checks if the photo is present in cache. If so, sets the photo on the view.
- *
- * @return false if the photo needs to be (re)loaded from the provider.
- */
- private boolean loadCachedPhoto(ImageView view, Request request, boolean fadeIn) {
- BitmapHolder holder = mBitmapHolderCache.get(request.getKey());
- if (holder == null) {
- // The bitmap has not been loaded ==> show default avatar
- request.applyDefaultImage(view);
- return false;
- }
-
- if (holder.bytes == null) {
- request.applyDefaultImage(view);
- return holder.fresh;
- }
-
- Bitmap cachedBitmap = holder.bitmapRef == null ? null : holder.bitmapRef.get();
- if (cachedBitmap == null) {
- if (holder.bytes.length < 8 * 1024) {
- // Small thumbnails are usually quick to inflate. Let's do that on the UI thread
- inflateBitmap(holder, request.getRequestedExtent());
- cachedBitmap = holder.bitmap;
- if (cachedBitmap == null) return false;
- } else {
- // This is bigger data. Let's send that back to the Loader so that we can
- // inflate this in the background
- request.applyDefaultImage(view);
- return false;
- }
- }
-
- final Drawable previousDrawable = view.getDrawable();
- if (fadeIn && previousDrawable != null) {
- final Drawable[] layers = new Drawable[2];
- // Prevent cascade of TransitionDrawables.
- if (previousDrawable instanceof TransitionDrawable) {
- final TransitionDrawable previousTransitionDrawable =
- (TransitionDrawable) previousDrawable;
- layers[0] = previousTransitionDrawable.getDrawable(
- previousTransitionDrawable.getNumberOfLayers() - 1);
- } else {
- layers[0] = previousDrawable;
- }
- layers[1] = new BitmapDrawable(mContext.getResources(), cachedBitmap);
- TransitionDrawable drawable = new TransitionDrawable(layers);
- view.setImageDrawable(drawable);
- drawable.startTransition(FADE_TRANSITION_DURATION);
- } else {
- view.setImageBitmap(cachedBitmap);
- }
-
- // Put the bitmap in the LRU cache. But only do this for images that are small enough
- // (we require that at least six of those can be cached at the same time)
- if (cachedBitmap.getByteCount() < mBitmapCache.maxSize() / 6) {
- mBitmapCache.put(request.getKey(), cachedBitmap);
- }
-
- // Soften the reference
- holder.bitmap = null;
-
- return holder.fresh;
- }
-
- /**
- * If necessary, decodes bytes stored in the holder to Bitmap. As long as the
- * bitmap is held either by {@link #mBitmapCache} or by a soft reference in
- * the holder, it will not be necessary to decode the bitmap.
- */
- private static void inflateBitmap(BitmapHolder holder, int requestedExtent) {
- final int sampleSize =
- BitmapUtil.findOptimalSampleSize(holder.originalSmallerExtent, requestedExtent);
- byte[] bytes = holder.bytes;
- if (bytes == null || bytes.length == 0) {
- return;
- }
-
- if (sampleSize == holder.decodedSampleSize) {
- // Check the soft reference. If will be retained if the bitmap is also
- // in the LRU cache, so we don't need to check the LRU cache explicitly.
- if (holder.bitmapRef != null) {
- holder.bitmap = holder.bitmapRef.get();
- if (holder.bitmap != null) {
- return;
- }
- }
- }
-
- try {
- Bitmap bitmap = BitmapUtil.decodeBitmapFromBytes(bytes, sampleSize);
-
- // make bitmap mutable and draw size onto it
- if (DEBUG_SIZES) {
- Bitmap original = bitmap;
- bitmap = bitmap.copy(bitmap.getConfig(), true);
- original.recycle();
- Canvas canvas = new Canvas(bitmap);
- Paint paint = new Paint();
- paint.setTextSize(16);
- paint.setColor(Color.BLUE);
- paint.setStyle(Style.FILL);
- canvas.drawRect(0.0f, 0.0f, 50.0f, 20.0f, paint);
- paint.setColor(Color.WHITE);
- paint.setAntiAlias(true);
- canvas.drawText(bitmap.getWidth() + "/" + sampleSize, 0, 15, paint);
- }
-
- holder.decodedSampleSize = sampleSize;
- holder.bitmap = bitmap;
- holder.bitmapRef = new SoftReference<Bitmap>(bitmap);
- if (DEBUG) {
- Log.d(TAG, "inflateBitmap " + btk(bytes.length) + " -> "
- + bitmap.getWidth() + "x" + bitmap.getHeight()
- + ", " + btk(bitmap.getByteCount()));
- }
- } catch (OutOfMemoryError e) {
- // Do nothing - the photo will appear to be missing
- }
- }
-
- public void clear() {
- if (DEBUG) Log.d(TAG, "clear");
- mPendingRequests.clear();
- mBitmapHolderCache.evictAll();
- mBitmapCache.evictAll();
- }
-
- @Override
- public void pause() {
- mPaused = true;
- }
-
- @Override
- public void resume() {
- mPaused = false;
- if (DEBUG) dumpStats();
- if (!mPendingRequests.isEmpty()) {
- requestLoading();
- }
- }
-
- /**
- * Sends a message to this thread itself to start loading images. If the current
- * view contains multiple image views, all of those image views will get a chance
- * to request their respective photos before any of those requests are executed.
- * This allows us to load images in bulk.
- */
- private void requestLoading() {
- if (!mLoadingRequested) {
- mLoadingRequested = true;
- mMainThreadHandler.sendEmptyMessage(MESSAGE_REQUEST_LOADING);
- }
- }
-
- /**
- * Processes requests on the main thread.
- */
- @Override
- public boolean handleMessage(Message msg) {
- switch (msg.what) {
- case MESSAGE_REQUEST_LOADING: {
- mLoadingRequested = false;
- if (!mPaused) {
- ensureLoaderThread();
- mLoaderThread.requestLoading();
- }
- return true;
- }
-
- case MESSAGE_PHOTOS_LOADED: {
- if (!mPaused) {
- processLoadedImages();
- }
- if (DEBUG) dumpStats();
- return true;
- }
- }
- return false;
- }
-
- public void ensureLoaderThread() {
- if (mLoaderThread == null) {
- mLoaderThread = new LoaderThread(mContext.getContentResolver());
- mLoaderThread.start();
- }
- }
-
- /**
- * Goes over pending loading requests and displays loaded photos. If some of the
- * photos still haven't been loaded, sends another request for image loading.
- */
- private void processLoadedImages() {
- Iterator<ImageView> iterator = mPendingRequests.keySet().iterator();
- while (iterator.hasNext()) {
- ImageView view = iterator.next();
- Request key = mPendingRequests.get(view);
- boolean loaded = loadCachedPhoto(view, key, true);
- if (loaded) {
- iterator.remove();
- }
- }
-
- softenCache();
-
- if (!mPendingRequests.isEmpty()) {
- requestLoading();
- }
- }
-
- /**
- * Removes strong references to loaded bitmaps to allow them to be garbage collected
- * if needed. Some of the bitmaps will still be retained by {@link #mBitmapCache}.
- */
- private void softenCache() {
- for (BitmapHolder holder : mBitmapHolderCache.snapshot().values()) {
- holder.bitmap = null;
- }
- }
-
- /**
- * Stores the supplied bitmap in cache.
- */
- private void cacheBitmap(Object key, byte[] bytes, boolean preloading, int requestedExtent) {
- if (DEBUG) {
- BitmapHolder prev = mBitmapHolderCache.get(key);
- if (prev != null && prev.bytes != null) {
- Log.d(TAG, "Overwriting cache: key=" + key + (prev.fresh ? " FRESH" : " stale"));
- if (prev.fresh) {
- mFreshCacheOverwrite.incrementAndGet();
- } else {
- mStaleCacheOverwrite.incrementAndGet();
- }
- }
- Log.d(TAG, "Caching data: key=" + key + ", " +
- (bytes == null ? "<null>" : btk(bytes.length)));
- }
- BitmapHolder holder = new BitmapHolder(bytes,
- bytes == null ? -1 : BitmapUtil.getSmallerExtentFromBytes(bytes));
-
- // Unless this image is being preloaded, decode it right away while
- // we are still on the background thread.
- if (!preloading) {
- inflateBitmap(holder, requestedExtent);
- }
-
- mBitmapHolderCache.put(key, holder);
- mBitmapHolderCacheAllUnfresh = false;
- }
-
- @Override
- public void cacheBitmap(Uri photoUri, Bitmap bitmap, byte[] photoBytes) {
- final int smallerExtent = Math.min(bitmap.getWidth(), bitmap.getHeight());
- // We can pretend here that the extent of the photo was the size that we originally
- // requested
- Request request = Request.createFromUri(photoUri, smallerExtent, false, DEFAULT_AVATAR);
- BitmapHolder holder = new BitmapHolder(photoBytes, smallerExtent);
- holder.bitmapRef = new SoftReference<Bitmap>(bitmap);
- mBitmapHolderCache.put(request.getKey(), holder);
- mBitmapHolderCacheAllUnfresh = false;
- mBitmapCache.put(request.getKey(), bitmap);
- }
-
- /**
- * Populates an array of photo IDs that need to be loaded. Also decodes bitmaps that we have
- * already loaded
- */
- private void obtainPhotoIdsAndUrisToLoad(Set<Long> photoIds,
- Set<String> photoIdsAsStrings, Set<Request> uris) {
- photoIds.clear();
- photoIdsAsStrings.clear();
- uris.clear();
-
- boolean jpegsDecoded = false;
-
- /*
- * Since the call is made from the loader thread, the map could be
- * changing during the iteration. That's not really a problem:
- * ConcurrentHashMap will allow those changes to happen without throwing
- * exceptions. Since we may miss some requests in the situation of
- * concurrent change, we will need to check the map again once loading
- * is complete.
- */
- Iterator<Request> iterator = mPendingRequests.values().iterator();
- while (iterator.hasNext()) {
- Request request = iterator.next();
- final BitmapHolder holder = mBitmapHolderCache.get(request.getKey());
- if (holder != null && holder.bytes != null && holder.fresh &&
- (holder.bitmapRef == null || holder.bitmapRef.get() == null)) {
- // This was previously loaded but we don't currently have the inflated Bitmap
- inflateBitmap(holder, request.getRequestedExtent());
- jpegsDecoded = true;
- } else {
- if (holder == null || !holder.fresh) {
- if (request.isUriRequest()) {
- uris.add(request);
- } else {
- photoIds.add(request.getId());
- photoIdsAsStrings.add(String.valueOf(request.mId));
- }
- }
- }
- }
-
- if (jpegsDecoded) mMainThreadHandler.sendEmptyMessage(MESSAGE_PHOTOS_LOADED);
- }
-
- /**
- * The thread that performs loading of photos from the database.
- */
- private class LoaderThread extends HandlerThread implements Callback {
- private static final int BUFFER_SIZE = 1024*16;
- private static final int MESSAGE_PRELOAD_PHOTOS = 0;
- private static final int MESSAGE_LOAD_PHOTOS = 1;
-
- /**
- * A pause between preload batches that yields to the UI thread.
- */
- private static final int PHOTO_PRELOAD_DELAY = 1000;
-
- /**
- * Number of photos to preload per batch.
- */
- private static final int PRELOAD_BATCH = 25;
-
- /**
- * Maximum number of photos to preload. If the cache size is 2Mb and
- * the expected average size of a photo is 4kb, then this number should be 2Mb/4kb = 500.
- */
- private static final int MAX_PHOTOS_TO_PRELOAD = 100;
-
- private final ContentResolver mResolver;
- private final StringBuilder mStringBuilder = new StringBuilder();
- private final Set<Long> mPhotoIds = Sets.newHashSet();
- private final Set<String> mPhotoIdsAsStrings = Sets.newHashSet();
- private final Set<Request> mPhotoUris = Sets.newHashSet();
- private final List<Long> mPreloadPhotoIds = Lists.newArrayList();
-
- private Handler mLoaderThreadHandler;
- private byte mBuffer[];
-
- private static final int PRELOAD_STATUS_NOT_STARTED = 0;
- private static final int PRELOAD_STATUS_IN_PROGRESS = 1;
- private static final int PRELOAD_STATUS_DONE = 2;
-
- private int mPreloadStatus = PRELOAD_STATUS_NOT_STARTED;
-
- public LoaderThread(ContentResolver resolver) {
- super(LOADER_THREAD_NAME);
- mResolver = resolver;
- }
-
- public void ensureHandler() {
- if (mLoaderThreadHandler == null) {
- mLoaderThreadHandler = new Handler(getLooper(), this);
- }
- }
-
- /**
- * Kicks off preloading of the next batch of photos on the background thread.
- * Preloading will happen after a delay: we want to yield to the UI thread
- * as much as possible.
- * <p>
- * If preloading is already complete, does nothing.
- */
- public void requestPreloading() {
- if (mPreloadStatus == PRELOAD_STATUS_DONE) {
- return;
- }
-
- ensureHandler();
- if (mLoaderThreadHandler.hasMessages(MESSAGE_LOAD_PHOTOS)) {
- return;
- }
-
- mLoaderThreadHandler.sendEmptyMessageDelayed(
- MESSAGE_PRELOAD_PHOTOS, PHOTO_PRELOAD_DELAY);
- }
-
- /**
- * Sends a message to this thread to load requested photos. Cancels a preloading
- * request, if any: we don't want preloading to impede loading of the photos
- * we need to display now.
- */
- public void requestLoading() {
- ensureHandler();
- mLoaderThreadHandler.removeMessages(MESSAGE_PRELOAD_PHOTOS);
- mLoaderThreadHandler.sendEmptyMessage(MESSAGE_LOAD_PHOTOS);
- }
-
- /**
- * Receives the above message, loads photos and then sends a message
- * to the main thread to process them.
- */
- @Override
- public boolean handleMessage(Message msg) {
- switch (msg.what) {
- case MESSAGE_PRELOAD_PHOTOS:
- preloadPhotosInBackground();
- break;
- case MESSAGE_LOAD_PHOTOS:
- loadPhotosInBackground();
- break;
- }
- return true;
- }
-
- /**
- * The first time it is called, figures out which photos need to be preloaded.
- * Each subsequent call preloads the next batch of photos and requests
- * another cycle of preloading after a delay. The whole process ends when
- * we either run out of photos to preload or fill up cache.
- */
- private void preloadPhotosInBackground() {
- if (mPreloadStatus == PRELOAD_STATUS_DONE) {
- return;
- }
-
- if (mPreloadStatus == PRELOAD_STATUS_NOT_STARTED) {
- queryPhotosForPreload();
- if (mPreloadPhotoIds.isEmpty()) {
- mPreloadStatus = PRELOAD_STATUS_DONE;
- } else {
- mPreloadStatus = PRELOAD_STATUS_IN_PROGRESS;
- }
- requestPreloading();
- return;
- }
-
- if (mBitmapHolderCache.size() > mBitmapHolderCacheRedZoneBytes) {
- mPreloadStatus = PRELOAD_STATUS_DONE;
- return;
- }
-
- mPhotoIds.clear();
- mPhotoIdsAsStrings.clear();
-
- int count = 0;
- int preloadSize = mPreloadPhotoIds.size();
- while(preloadSize > 0 && mPhotoIds.size() < PRELOAD_BATCH) {
- preloadSize--;
- count++;
- Long photoId = mPreloadPhotoIds.get(preloadSize);
- mPhotoIds.add(photoId);
- mPhotoIdsAsStrings.add(photoId.toString());
- mPreloadPhotoIds.remove(preloadSize);
- }
-
- loadThumbnails(true);
-
- if (preloadSize == 0) {
- mPreloadStatus = PRELOAD_STATUS_DONE;
- }
-
- Log.v(TAG, "Preloaded " + count + " photos. Cached bytes: "
- + mBitmapHolderCache.size());
-
- requestPreloading();
- }
-
- private void queryPhotosForPreload() {
- Cursor cursor = null;
- try {
- Uri uri = Contacts.CONTENT_URI.buildUpon().appendQueryParameter(
- ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(Directory.DEFAULT))
- .appendQueryParameter(ContactsContract.LIMIT_PARAM_KEY,
- String.valueOf(MAX_PHOTOS_TO_PRELOAD))
- .build();
- cursor = mResolver.query(uri, new String[] { Contacts.PHOTO_ID },
- Contacts.PHOTO_ID + " NOT NULL AND " + Contacts.PHOTO_ID + "!=0",
- null,
- Contacts.STARRED + " DESC, " + Contacts.LAST_TIME_CONTACTED + " DESC");
-
- if (cursor != null) {
- while (cursor.moveToNext()) {
- // Insert them in reverse order, because we will be taking
- // them from the end of the list for loading.
- mPreloadPhotoIds.add(0, cursor.getLong(0));
- }
- }
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
- }
-
- private void loadPhotosInBackground() {
- obtainPhotoIdsAndUrisToLoad(mPhotoIds, mPhotoIdsAsStrings, mPhotoUris);
- loadThumbnails(false);
- loadUriBasedPhotos();
- requestPreloading();
- }
-
- /** Loads thumbnail photos with ids */
- private void loadThumbnails(boolean preloading) {
- if (mPhotoIds.isEmpty()) {
- return;
- }
-
- // Remove loaded photos from the preload queue: we don't want
- // the preloading process to load them again.
- if (!preloading && mPreloadStatus == PRELOAD_STATUS_IN_PROGRESS) {
- for (Long id : mPhotoIds) {
- mPreloadPhotoIds.remove(id);
- }
- if (mPreloadPhotoIds.isEmpty()) {
- mPreloadStatus = PRELOAD_STATUS_DONE;
- }
- }
-
- mStringBuilder.setLength(0);
- mStringBuilder.append(Photo._ID + " IN(");
- for (int i = 0; i < mPhotoIds.size(); i++) {
- if (i != 0) {
- mStringBuilder.append(',');
- }
- mStringBuilder.append('?');
- }
- mStringBuilder.append(')');
-
- Cursor cursor = null;
- try {
- if (DEBUG) Log.d(TAG, "Loading " + TextUtils.join(",", mPhotoIdsAsStrings));
- cursor = mResolver.query(Data.CONTENT_URI,
- COLUMNS,
- mStringBuilder.toString(),
- mPhotoIdsAsStrings.toArray(EMPTY_STRING_ARRAY),
- null);
-
- if (cursor != null) {
- while (cursor.moveToNext()) {
- Long id = cursor.getLong(0);
- byte[] bytes = cursor.getBlob(1);
- cacheBitmap(id, bytes, preloading, -1);
- mPhotoIds.remove(id);
- }
- }
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
-
- // Remaining photos were not found in the contacts database (but might be in profile).
- for (Long id : mPhotoIds) {
- if (ContactsContract.isProfileId(id)) {
- Cursor profileCursor = null;
- try {
- profileCursor = mResolver.query(
- ContentUris.withAppendedId(Data.CONTENT_URI, id),
- COLUMNS, null, null, null);
- if (profileCursor != null && profileCursor.moveToFirst()) {
- cacheBitmap(profileCursor.getLong(0), profileCursor.getBlob(1),
- preloading, -1);
- } else {
- // Couldn't load a photo this way either.
- cacheBitmap(id, null, preloading, -1);
- }
- } finally {
- if (profileCursor != null) {
- profileCursor.close();
- }
- }
- } else {
- // Not a profile photo and not found - mark the cache accordingly
- cacheBitmap(id, null, preloading, -1);
- }
- }
-
- mMainThreadHandler.sendEmptyMessage(MESSAGE_PHOTOS_LOADED);
- }
-
- /**
- * Loads photos referenced with Uris. Those can be remote thumbnails
- * (from directory searches), display photos etc
- */
- private void loadUriBasedPhotos() {
- for (Request uriRequest : mPhotoUris) {
- Uri uri = uriRequest.getUri();
- if (mBuffer == null) {
- mBuffer = new byte[BUFFER_SIZE];
- }
- try {
- if (DEBUG) Log.d(TAG, "Loading " + uri);
- InputStream is = mResolver.openInputStream(uri);
- if (is != null) {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- try {
- int size;
- while ((size = is.read(mBuffer)) != -1) {
- baos.write(mBuffer, 0, size);
- }
- } finally {
- is.close();
- }
- cacheBitmap(uri, baos.toByteArray(), false,
- uriRequest.getRequestedExtent());
- mMainThreadHandler.sendEmptyMessage(MESSAGE_PHOTOS_LOADED);
- } else {
- Log.v(TAG, "Cannot load photo " + uri);
- cacheBitmap(uri, null, false, uriRequest.getRequestedExtent());
- }
- } catch (Exception ex) {
- Log.v(TAG, "Cannot load photo " + uri, ex);
- cacheBitmap(uri, null, false, uriRequest.getRequestedExtent());
- }
- }
- }
- }
-
- /**
- * A holder for either a Uri or an id and a flag whether this was requested for the dark or
- * light theme
- */
- private static final class Request {
- private final long mId;
- private final Uri mUri;
- private final boolean mDarkTheme;
- private final int mRequestedExtent;
- private final DefaultImageProvider mDefaultProvider;
-
- private Request(long id, Uri uri, int requestedExtent, boolean darkTheme,
- DefaultImageProvider defaultProvider) {
- mId = id;
- mUri = uri;
- mDarkTheme = darkTheme;
- mRequestedExtent = requestedExtent;
- mDefaultProvider = defaultProvider;
- }
-
- public static Request createFromThumbnailId(long id, boolean darkTheme,
- DefaultImageProvider defaultProvider) {
- return new Request(id, null /* no URI */, -1, darkTheme, defaultProvider);
- }
-
- public static Request createFromUri(Uri uri, int requestedExtent, boolean darkTheme,
- DefaultImageProvider defaultProvider) {
- return new Request(0 /* no ID */, uri, requestedExtent, darkTheme, defaultProvider);
- }
-
- public boolean isUriRequest() {
- return mUri != null;
- }
-
- public Uri getUri() {
- return mUri;
- }
-
- public long getId() {
- return mId;
- }
-
- public int getRequestedExtent() {
- return mRequestedExtent;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + (int) (mId ^ (mId >>> 32));
- result = prime * result + mRequestedExtent;
- result = prime * result + ((mUri == null) ? 0 : mUri.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (obj == null) return false;
- if (getClass() != obj.getClass()) return false;
- final Request that = (Request) obj;
- if (mId != that.mId) return false;
- if (mRequestedExtent != that.mRequestedExtent) return false;
- if (!UriUtils.areEqual(mUri, that.mUri)) return false;
- // Don't compare equality of mDarkTheme because it is only used in the default contact
- // photo case. When the contact does have a photo, the contact photo is the same
- // regardless of mDarkTheme, so we shouldn't need to put the photo request on the queue
- // twice.
- return true;
- }
-
- public Object getKey() {
- return mUri == null ? mId : mUri;
- }
-
- public void applyDefaultImage(ImageView view) {
- mDefaultProvider.applyDefaultImage(view, mRequestedExtent, mDarkTheme);
- }
- }
-}
diff --git a/src/com/android/contacts/ContactSaveService.java b/src/com/android/contacts/ContactSaveService.java
index 4333aa4..f1a5a72 100644
--- a/src/com/android/contacts/ContactSaveService.java
+++ b/src/com/android/contacts/ContactSaveService.java
@@ -46,10 +46,11 @@
import android.util.Log;
import android.widget.Toast;
+import com.android.contacts.common.database.ContactUpdateUtils;
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.RawContactModifier;
import com.android.contacts.model.account.AccountWithDataSet;
import com.android.contacts.util.CallerInfoCacheUtils;
import com.google.common.collect.Lists;
@@ -903,13 +904,7 @@
return;
}
- // Update the primary values in the data record.
- ContentValues values = new ContentValues(1);
- values.put(Data.IS_SUPER_PRIMARY, 1);
- values.put(Data.IS_PRIMARY, 1);
-
- getContentResolver().update(ContentUris.withAppendedId(Data.CONTENT_URI, dataId),
- values, null, null);
+ ContactUpdateUtils.setSuperPrimary(this, dataId);
}
/**
diff --git a/src/com/android/contacts/ContactTileLoaderFactory.java b/src/com/android/contacts/ContactTileLoaderFactory.java
index 3a23400..f3ca47a 100644
--- a/src/com/android/contacts/ContactTileLoaderFactory.java
+++ b/src/com/android/contacts/ContactTileLoaderFactory.java
@@ -22,10 +22,9 @@
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
+ * Used to create {@link CursorLoader}s to load different groups of
+ * {@link com.android.contacts.list.ContactTileView}.
*/
public final class ContactTileLoaderFactory {
diff --git a/src/com/android/contacts/ContactsActivity.java b/src/com/android/contacts/ContactsActivity.java
index 90900ce..f3ac147 100644
--- a/src/com/android/contacts/ContactsActivity.java
+++ b/src/com/android/contacts/ContactsActivity.java
@@ -25,7 +25,7 @@
import android.os.Bundle;
import android.view.View;
-import com.android.contacts.activities.TransactionSafeActivity;
+import com.android.contacts.common.activity.TransactionSafeActivity;
import com.android.contacts.test.InjectedServices;
/**
diff --git a/src/com/android/contacts/ContactsApplication.java b/src/com/android/contacts/ContactsApplication.java
index 3380553..d6c5702 100644
--- a/src/com/android/contacts/ContactsApplication.java
+++ b/src/com/android/contacts/ContactsApplication.java
@@ -29,6 +29,7 @@
import android.provider.ContactsContract.Contacts;
import android.util.Log;
+import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.list.ContactListFilterController;
import com.android.contacts.model.AccountTypeManager;
import com.android.contacts.test.InjectedServices;
@@ -104,14 +105,6 @@
return mContactPhotoManager;
}
- if (ContactListFilterController.CONTACT_LIST_FILTER_SERVICE.equals(name)) {
- if (mContactListFilterController == null) {
- mContactListFilterController =
- ContactListFilterController.createContactListFilterController(this);
- }
- return mContactListFilterController;
- }
-
return super.getSystemService(name);
}
diff --git a/src/com/android/contacts/ContactsUtils.java b/src/com/android/contacts/ContactsUtils.java
index 05eb4f6..b6e4772 100644
--- a/src/com/android/contacts/ContactsUtils.java
+++ b/src/com/android/contacts/ContactsUtils.java
@@ -18,14 +18,11 @@
import android.content.Context;
import android.content.Intent;
-import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Rect;
-import android.location.CountryDetector;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Im;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.DisplayPhoto;
import android.provider.ContactsContract.QuickContact;
import android.telephony.PhoneNumberUtils;
@@ -33,12 +30,10 @@
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;
@@ -110,63 +105,6 @@
}
/**
- * Returns true if two data with mimetypes which represent values in contact entries are
- * considered equal for collapsing in the GUI. For caller-id, use
- * {@link PhoneNumberUtils#compare(Context, String, String)} instead
- */
- public static final boolean shouldCollapse(CharSequence mimetype1, CharSequence data1,
- CharSequence mimetype2, CharSequence data2) {
- // different mimetypes? don't collapse
- if (!TextUtils.equals(mimetype1, mimetype2)) return false;
-
- // exact same string? good, bail out early
- if (TextUtils.equals(data1, data2)) return true;
-
- // so if either is null, these two must be different
- if (data1 == null || data2 == null) return false;
-
- // if this is not about phone numbers, we know this is not a match (of course, some
- // mimetypes could have more sophisticated matching is the future, e.g. addresses)
- if (!TextUtils.equals(Phone.CONTENT_ITEM_TYPE, mimetype1)) return false;
-
- return shouldCollapsePhoneNumbers(data1.toString(), data2.toString());
- }
-
- private static final boolean shouldCollapsePhoneNumbers(
- String number1WithLetters, String number2WithLetters) {
- final String number1 = PhoneNumberUtils.convertKeypadLettersToDigits(number1WithLetters);
- final String number2 = PhoneNumberUtils.convertKeypadLettersToDigits(number2WithLetters);
-
- int index1 = 0;
- int index2 = 0;
- for (;;) {
- // Skip formatting characters.
- while (index1 < number1.length() &&
- !PhoneNumberUtils.isNonSeparator(number1.charAt(index1))) {
- index1++;
- }
- while (index2 < number2.length() &&
- !PhoneNumberUtils.isNonSeparator(number2.charAt(index2))) {
- index2++;
- }
- // If both have finished, match. If only one has finished, not match.
- final boolean number1End = (index1 == number1.length());
- final boolean number2End = (index2 == number2.length());
- if (number1End) {
- return number2End;
- }
- if (number2End) return false;
-
- // If the non-formatting characters are different, not match.
- if (number1.charAt(index1) != number2.charAt(index2)) return false;
-
- // Go to the next characters.
- index1++;
- index2++;
- }
- }
-
- /**
* Returns true if two {@link Intent}s are both null, or have the same action.
*/
public static final boolean areIntentActionEqual(Intent a, Intent b) {
@@ -179,16 +117,6 @@
return TextUtils.equals(a.getAction(), b.getAction());
}
- /**
- * @return The ISO 3166-1 two letters country code of the country the user
- * is in.
- */
- public static final String getCurrentCountryIso(Context context) {
- CountryDetector detector =
- (CountryDetector) context.getSystemService(Context.COUNTRY_DETECTOR);
- return detector.detectCountry().getCountryIso();
- }
-
public static boolean areContactWritableAccountsAvailable(Context context) {
final List<AccountWithDataSet> accounts =
AccountTypeManager.getInstance(context).getAccounts(true /* writeable */);
@@ -224,64 +152,6 @@
}
/**
- * Return Uri with an appropriate scheme, accepting Voicemail, SIP, and usual phone call
- * numbers.
- */
- public static Uri getCallUri(String number) {
- if (PhoneNumberUtils.isUriNumber(number)) {
- return Uri.fromParts(Constants.SCHEME_SIP, number, null);
- }
- return Uri.fromParts(Constants.SCHEME_TEL, number, null);
- }
-
- /**
- * Return an Intent for making a phone call. Scheme (e.g. tel, sip) will be determined
- * automatically.
- */
- public static Intent getCallIntent(String number) {
- return getCallIntent(number, null);
- }
-
- /**
- * Return an Intent for making a phone call. A given Uri will be used as is (without any
- * sanity check).
- */
- public static Intent getCallIntent(Uri uri) {
- return getCallIntent(uri, null);
- }
-
- /**
- * A variant of {@link #getCallIntent(String)} but also accept a call origin. For more
- * information about call origin, see comments in Phone package (PhoneApp).
- */
- public static Intent getCallIntent(String number, String callOrigin) {
- return getCallIntent(getCallUri(number), callOrigin);
- }
-
- /**
- * A variant of {@link #getCallIntent(Uri)} but also accept a call origin. For more
- * information about call origin, see comments in Phone package (PhoneApp).
- */
- public static Intent getCallIntent(Uri uri, String callOrigin) {
- final Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED, uri);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- if (callOrigin != null) {
- intent.putExtra(DialtactsActivity.EXTRA_CALL_ORIGIN, callOrigin);
- }
- return intent;
- }
-
- /**
- * Return an Intent for launching voicemail screen.
- */
- public static Intent getVoicemailIntent() {
- final Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
- Uri.fromParts("voicemail", "", null));
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- return intent;
- }
-
- /**
* Returns a header view based on the R.layout.list_separator, where the
* containing {@link TextView} is set using the given textResourceId.
*/
@@ -330,11 +200,4 @@
return sThumbnailSize;
}
- /**
- * @return if the context is in landscape orientation.
- */
- public static boolean isLandscape(Context context) {
- return context.getResources().getConfiguration().orientation
- == Configuration.ORIENTATION_LANDSCAPE;
- }
}
diff --git a/src/com/android/contacts/activities/NonPhoneActivity.java b/src/com/android/contacts/NonPhoneActivity.java
similarity index 94%
rename from src/com/android/contacts/activities/NonPhoneActivity.java
rename to src/com/android/contacts/NonPhoneActivity.java
index fc22146..4f0696f 100644
--- a/src/com/android/contacts/activities/NonPhoneActivity.java
+++ b/src/com/android/contacts/NonPhoneActivity.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.contacts.activities;
+package com.android.contacts;
import android.app.Activity;
import android.app.AlertDialog;
@@ -29,9 +29,7 @@
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;
+import com.android.contacts.common.CallUtil;
/**
* Activity that intercepts DIAL and VIEW intents for phone numbers for devices that can not
@@ -62,7 +60,7 @@
final Uri data = getIntent().getData();
if (data == null) return null;
final String scheme = data.getScheme();
- if (!Constants.SCHEME_TEL.equals(scheme)) return null;
+ if (!CallUtil.SCHEME_TEL.equals(scheme)) return null;
return getIntent().getData().getSchemeSpecificPart();
}
diff --git a/src/com/android/contacts/PhoneCallDetails.java b/src/com/android/contacts/PhoneCallDetails.java
deleted file mode 100644
index 547695c..0000000
--- a/src/com/android/contacts/PhoneCallDetails.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-import android.net.Uri;
-import android.provider.CallLog.Calls;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-
-/**
- * The details of a phone call to be shown in the UI.
- */
-public class PhoneCallDetails {
- /** The number of the other party involved in the call. */
- public final CharSequence number;
- /** The formatted version of {@link #number}. */
- public final CharSequence formattedNumber;
- /** The country corresponding with the phone number. */
- public final String countryIso;
- /** The geocoded location for the phone number. */
- public final String geocode;
- /**
- * The type of calls, as defined in the call log table, e.g., {@link Calls#INCOMING_TYPE}.
- * <p>
- * There might be multiple types if this represents a set of entries grouped together.
- */
- public final int[] callTypes;
- /** The date of the call, in milliseconds since the epoch. */
- public final long date;
- /** The duration of the call in milliseconds, or 0 for missed calls. */
- public final long duration;
- /** The name of the contact, or the empty string. */
- public final CharSequence name;
- /** The type of phone, e.g., {@link Phone#TYPE_HOME}, 0 if not available. */
- public final int numberType;
- /** The custom label associated with the phone number in the contact, or the empty string. */
- public final CharSequence numberLabel;
- /** The URI of the contact associated with this phone call. */
- public final Uri contactUri;
- /**
- * The photo URI of the picture of the contact that is associated with this phone call or
- * null if there is none.
- * <p>
- * This is meant to store the high-res photo only.
- */
- public final Uri photoUri;
-
- /** Create the details for a call with a number not associated with a contact. */
- public PhoneCallDetails(CharSequence number, CharSequence formattedNumber,
- String countryIso, String geocode, int[] callTypes, long date, long duration) {
- this(number, formattedNumber, countryIso, geocode, callTypes, date, duration, "", 0, "",
- null, null);
- }
-
- /** Create the details for a call with a number associated with a contact. */
- public PhoneCallDetails(CharSequence number, CharSequence formattedNumber,
- String countryIso, String geocode, int[] callTypes, long date, long duration,
- CharSequence name, int numberType, CharSequence numberLabel, Uri contactUri,
- Uri photoUri) {
- this.number = number;
- this.formattedNumber = formattedNumber;
- this.countryIso = countryIso;
- this.geocode = geocode;
- this.callTypes = callTypes;
- this.date = date;
- this.duration = duration;
- this.name = name;
- this.numberType = numberType;
- this.numberLabel = numberLabel;
- this.contactUri = contactUri;
- this.photoUri = photoUri;
- }
-}
diff --git a/src/com/android/contacts/PhoneCallDetailsHelper.java b/src/com/android/contacts/PhoneCallDetailsHelper.java
deleted file mode 100644
index 8192975..0000000
--- a/src/com/android/contacts/PhoneCallDetailsHelper.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-import android.content.res.Resources;
-import android.graphics.Typeface;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.telephony.PhoneNumberUtils;
-import android.text.SpannableString;
-import android.text.Spanned;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-import android.text.style.ForegroundColorSpan;
-import android.text.style.StyleSpan;
-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}.
- */
-public class PhoneCallDetailsHelper {
- /** The maximum number of icons will be shown to represent the call types in a group. */
- private static final int MAX_CALL_TYPE_ICONS = 3;
-
- private final Resources mResources;
- /** The injected current time in milliseconds since the epoch. Used only by tests. */
- private Long mCurrentTimeMillisForTest;
- // Helper classes.
- private final CallTypeHelper mCallTypeHelper;
- private final PhoneNumberHelper mPhoneNumberHelper;
-
- /**
- * Creates a new instance of the helper.
- * <p>
- * Generally you should have a single instance of this helper in any context.
- *
- * @param resources used to look up strings
- */
- public PhoneCallDetailsHelper(Resources resources, CallTypeHelper callTypeHelper,
- PhoneNumberHelper phoneNumberHelper) {
- mResources = resources;
- mCallTypeHelper = callTypeHelper;
- mPhoneNumberHelper = phoneNumberHelper;
- }
-
- /** Fills the call details views with content. */
- public void setPhoneCallDetails(PhoneCallDetailsViews views, PhoneCallDetails details,
- boolean isHighlighted) {
- // Display up to a given number of icons.
- views.callTypeIcons.clear();
- int count = details.callTypes.length;
- for (int index = 0; index < count && index < MAX_CALL_TYPE_ICONS; ++index) {
- views.callTypeIcons.add(details.callTypes[index]);
- }
- views.callTypeIcons.setVisibility(View.VISIBLE);
-
- // Show the total call count only if there are more than the maximum number of icons.
- final Integer callCount;
- if (count > MAX_CALL_TYPE_ICONS) {
- callCount = count;
- } else {
- callCount = null;
- }
- // The color to highlight the count and date in, if any. This is based on the first call.
- Integer highlightColor =
- isHighlighted ? mCallTypeHelper.getHighlightedColor(details.callTypes[0]) : null;
-
- // The date of this call, relative to the current time.
- CharSequence dateText =
- DateUtils.getRelativeTimeSpanString(details.date,
- getCurrentTimeMillis(),
- DateUtils.MINUTE_IN_MILLIS,
- DateUtils.FORMAT_ABBREV_RELATIVE);
-
- // Set the call count and date.
- setCallCountAndDate(views, callCount, dateText, highlightColor);
-
- CharSequence numberFormattedLabel = null;
- // Only show a label if the number is shown and it is not a SIP address.
- if (!TextUtils.isEmpty(details.number)
- && !PhoneNumberUtils.isUriNumber(details.number.toString())) {
- numberFormattedLabel = Phone.getTypeLabel(mResources, details.numberType,
- details.numberLabel);
- }
-
- final CharSequence nameText;
- final CharSequence numberText;
- final CharSequence labelText;
- final CharSequence displayNumber =
- mPhoneNumberHelper.getDisplayNumber(details.number, details.formattedNumber);
- if (TextUtils.isEmpty(details.name)) {
- nameText = displayNumber;
- if (TextUtils.isEmpty(details.geocode)
- || mPhoneNumberHelper.isVoicemailNumber(details.number)) {
- numberText = mResources.getString(R.string.call_log_empty_gecode);
- } else {
- numberText = details.geocode;
- }
- labelText = null;
- } else {
- nameText = details.name;
- numberText = displayNumber;
- labelText = numberFormattedLabel;
- }
-
- views.nameView.setText(nameText);
- views.numberView.setText(numberText);
- views.labelView.setText(labelText);
- views.labelView.setVisibility(TextUtils.isEmpty(labelText) ? View.GONE : View.VISIBLE);
- }
-
- /** Sets the text of the header view for the details page of a phone call. */
- public void setCallDetailsHeader(TextView nameView, PhoneCallDetails details) {
- final CharSequence nameText;
- final CharSequence displayNumber =
- mPhoneNumberHelper.getDisplayNumber(details.number,
- mResources.getString(R.string.recentCalls_addToContact));
- if (TextUtils.isEmpty(details.name)) {
- nameText = displayNumber;
- } else {
- nameText = details.name;
- }
-
- nameView.setText(nameText);
- }
-
- @NeededForTesting
- public void setCurrentTimeForTest(long currentTimeMillis) {
- mCurrentTimeMillisForTest = currentTimeMillis;
- }
-
- /**
- * Returns the current time in milliseconds since the epoch.
- * <p>
- * It can be injected in tests using {@link #setCurrentTimeForTest(long)}.
- */
- private long getCurrentTimeMillis() {
- if (mCurrentTimeMillisForTest == null) {
- return System.currentTimeMillis();
- } else {
- return mCurrentTimeMillisForTest;
- }
- }
-
- /** Sets the call count and date. */
- private void setCallCountAndDate(PhoneCallDetailsViews views, Integer callCount,
- CharSequence dateText, Integer highlightColor) {
- // Combine the count (if present) and the date.
- final CharSequence text;
- if (callCount != null) {
- text = mResources.getString(
- R.string.call_log_item_count_and_date, callCount.intValue(), dateText);
- } else {
- text = dateText;
- }
-
- // Apply the highlight color if present.
- final CharSequence formattedText;
- if (highlightColor != null) {
- formattedText = addBoldAndColor(text, highlightColor);
- } else {
- formattedText = text;
- }
-
- views.callTypeAndDate.setText(formattedText);
- }
-
- /** Creates a SpannableString for the given text which is bold and in the given color. */
- private CharSequence addBoldAndColor(CharSequence text, int color) {
- int flags = Spanned.SPAN_INCLUSIVE_INCLUSIVE;
- SpannableString result = new SpannableString(text);
- result.setSpan(new StyleSpan(Typeface.BOLD), 0, text.length(), flags);
- result.setSpan(new ForegroundColorSpan(color), 0, text.length(), flags);
- return result;
- }
-}
diff --git a/src/com/android/contacts/PhoneCallDetailsViews.java b/src/com/android/contacts/PhoneCallDetailsViews.java
deleted file mode 100644
index 8be7f0c..0000000
--- a/src/com/android/contacts/PhoneCallDetailsViews.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-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.
- */
-public final class PhoneCallDetailsViews {
- public final TextView nameView;
- public final View callTypeView;
- public final CallTypeIconsView callTypeIcons;
- public final TextView callTypeAndDate;
- public final TextView numberView;
- public final TextView labelView;
-
- private PhoneCallDetailsViews(TextView nameView, View callTypeView,
- CallTypeIconsView callTypeIcons, TextView callTypeAndDate, TextView numberView,
- TextView labelView) {
- this.nameView = nameView;
- this.callTypeView = callTypeView;
- this.callTypeIcons = callTypeIcons;
- this.callTypeAndDate = callTypeAndDate;
- this.numberView = numberView;
- this.labelView = labelView;
- }
-
- /**
- * Create a new instance by extracting the elements from the given view.
- * <p>
- * The view should contain three text views with identifiers {@code R.id.name},
- * {@code R.id.date}, and {@code R.id.number}, and a linear layout with identifier
- * {@code R.id.call_types}.
- */
- public static PhoneCallDetailsViews fromView(View view) {
- return new PhoneCallDetailsViews((TextView) view.findViewById(R.id.name),
- view.findViewById(R.id.call_type),
- (CallTypeIconsView) view.findViewById(R.id.call_type_icons),
- (TextView) view.findViewById(R.id.call_count_and_date),
- (TextView) view.findViewById(R.id.number),
- (TextView) view.findViewById(R.id.label));
- }
-
- public static PhoneCallDetailsViews createForTest(Context context) {
- return new PhoneCallDetailsViews(
- new TextView(context),
- new View(context),
- new CallTypeIconsView(context),
- new TextView(context),
- new TextView(context),
- new TextView(context));
- }
-}
diff --git a/src/com/android/contacts/ProximitySensorAware.java b/src/com/android/contacts/ProximitySensorAware.java
deleted file mode 100644
index 0fb233d..0000000
--- a/src/com/android/contacts/ProximitySensorAware.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-/**
- * An object that is aware of the state of the proximity sensor.
- */
-public interface ProximitySensorAware {
- /** Start tracking the state of the proximity sensor. */
- public void enableProximitySensor();
-
- /**
- * Stop tracking the state of the proximity sensor.
- *
- * @param waitForFarState if true and the sensor is currently in the near state, it will wait
- * until it is again in the far state before stopping to track its state.
- */
- public void disableProximitySensor(boolean waitForFarState);
-}
diff --git a/src/com/android/contacts/ProximitySensorManager.java b/src/com/android/contacts/ProximitySensorManager.java
deleted file mode 100644
index 69601bf..0000000
--- a/src/com/android/contacts/ProximitySensorManager.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-import android.content.Context;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
-
-import javax.annotation.concurrent.GuardedBy;
-
-/**
- * Manages the proximity sensor and notifies a listener when enabled.
- */
-public class ProximitySensorManager {
- /**
- * Listener of the state of the proximity sensor.
- * <p>
- * This interface abstracts two possible states for the proximity sensor, near and far.
- * <p>
- * The actual meaning of these states depends on the actual sensor.
- */
- public interface Listener {
- /** Called when the proximity sensor transitions from the far to the near state. */
- public void onNear();
- /** Called when the proximity sensor transitions from the near to the far state. */
- public void onFar();
- }
-
- public static enum State {
- NEAR, FAR
- }
-
- private final ProximitySensorEventListener mProximitySensorListener;
-
- /**
- * The current state of the manager, i.e., whether it is currently tracking the state of the
- * sensor.
- */
- private boolean mManagerEnabled;
-
- /**
- * The listener to the state of the sensor.
- * <p>
- * Contains most of the logic concerning tracking of the sensor.
- * <p>
- * After creating an instance of this object, one should call {@link #register()} and
- * {@link #unregister()} to enable and disable the notifications.
- * <p>
- * Instead of calling unregister, one can call {@link #unregisterWhenFar()} to unregister the
- * listener the next time the sensor reaches the {@link State#FAR} state if currently in the
- * {@link State#NEAR} state.
- */
- private static class ProximitySensorEventListener implements SensorEventListener {
- private static final float FAR_THRESHOLD = 5.0f;
-
- private final SensorManager mSensorManager;
- private final Sensor mProximitySensor;
- private final float mMaxValue;
- private final Listener mListener;
-
- /**
- * The last state of the sensor.
- * <p>
- * Before registering and after unregistering we are always in the {@link State#FAR} state.
- */
- @GuardedBy("this") private State mLastState;
- /**
- * If this flag is set to true, we are waiting to reach the {@link State#FAR} state and
- * should notify the listener and unregister when that happens.
- */
- @GuardedBy("this") private boolean mWaitingForFarState;
-
- public ProximitySensorEventListener(SensorManager sensorManager, Sensor proximitySensor,
- Listener listener) {
- mSensorManager = sensorManager;
- mProximitySensor = proximitySensor;
- mMaxValue = proximitySensor.getMaximumRange();
- mListener = listener;
- // Initialize at far state.
- mLastState = State.FAR;
- mWaitingForFarState = false;
- }
-
- @Override
- public void onSensorChanged(SensorEvent event) {
- // Make sure we have a valid value.
- if (event.values == null) return;
- if (event.values.length == 0) return;
- float value = event.values[0];
- // Convert the sensor into a NEAR/FAR state.
- State state = getStateFromValue(value);
- synchronized (this) {
- // No change in state, do nothing.
- if (state == mLastState) return;
- // Keep track of the current state.
- mLastState = state;
- // If we are waiting to reach the far state and we are now in it, unregister.
- if (mWaitingForFarState && mLastState == State.FAR) {
- unregisterWithoutNotification();
- }
- }
- // Notify the listener of the state change.
- switch (state) {
- case NEAR:
- mListener.onNear();
- break;
-
- case FAR:
- mListener.onFar();
- break;
- }
- }
-
- @Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- // Nothing to do here.
- }
-
- /** Returns the state of the sensor given its current value. */
- private State getStateFromValue(float value) {
- // Determine if the current value corresponds to the NEAR or FAR state.
- // Take case of the case where the proximity sensor is binary: if the current value is
- // equal to the maximum, we are always in the FAR state.
- return (value > FAR_THRESHOLD || value == mMaxValue) ? State.FAR : State.NEAR;
- }
-
- /**
- * Unregister the next time the sensor reaches the {@link State#FAR} state.
- */
- public synchronized void unregisterWhenFar() {
- if (mLastState == State.FAR) {
- // We are already in the far state, just unregister now.
- unregisterWithoutNotification();
- } else {
- mWaitingForFarState = true;
- }
- }
-
- /** Register the listener and call the listener as necessary. */
- public synchronized void register() {
- // It is okay to register multiple times.
- mSensorManager.registerListener(this, mProximitySensor, SensorManager.SENSOR_DELAY_UI);
- // We should no longer be waiting for the far state if we are registering again.
- mWaitingForFarState = false;
- }
-
- public void unregister() {
- State lastState;
- synchronized (this) {
- unregisterWithoutNotification();
- lastState = mLastState;
- // Always go back to the FAR state. That way, when we register again we will get a
- // transition when the sensor gets into the NEAR state.
- mLastState = State.FAR;
- }
- // Notify the listener if we changed the state to FAR while unregistering.
- if (lastState != State.FAR) {
- mListener.onFar();
- }
- }
-
- @GuardedBy("this")
- private void unregisterWithoutNotification() {
- mSensorManager.unregisterListener(this);
- mWaitingForFarState = false;
- }
- }
-
- public ProximitySensorManager(Context context, Listener listener) {
- SensorManager sensorManager =
- (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
- Sensor proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
- if (proximitySensor == null) {
- // If there is no sensor, we should not do anything.
- mProximitySensorListener = null;
- } else {
- mProximitySensorListener =
- new ProximitySensorEventListener(sensorManager, proximitySensor, listener);
- }
- }
-
- /**
- * Enables the proximity manager.
- * <p>
- * The listener will start getting notifications of events.
- * <p>
- * This method is idempotent.
- */
- public void enable() {
- if (mProximitySensorListener != null && !mManagerEnabled) {
- mProximitySensorListener.register();
- mManagerEnabled = true;
- }
- }
-
- /**
- * Disables the proximity manager.
- * <p>
- * The listener will stop receiving notifications of events, possibly after receiving a last
- * {@link Listener#onFar()} callback.
- * <p>
- * If {@code waitForFarState} is true, if the sensor is not currently in the {@link State#FAR}
- * state, the listener will receive a {@link Listener#onFar()} callback the next time the sensor
- * actually reaches the {@link State#FAR} state.
- * <p>
- * If {@code waitForFarState} is false, the listener will receive a {@link Listener#onFar()}
- * callback immediately if the sensor is currently not in the {@link State#FAR} state.
- * <p>
- * This method is idempotent.
- */
- public void disable(boolean waitForFarState) {
- if (mProximitySensorListener != null && mManagerEnabled) {
- if (waitForFarState) {
- mProximitySensorListener.unregisterWhenFar();
- } else {
- mProximitySensorListener.unregister();
- }
- mManagerEnabled = false;
- }
- }
-}
diff --git a/src/com/android/contacts/SpecialCharSequenceMgr.java b/src/com/android/contacts/SpecialCharSequenceMgr.java
deleted file mode 100644
index 4902fde..0000000
--- a/src/com/android/contacts/SpecialCharSequenceMgr.java
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * Copyright (C) 2006 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.internal.telephony.ITelephony;
-import com.android.internal.telephony.TelephonyCapabilities;
-import com.android.internal.telephony.TelephonyIntents;
-
-import android.app.AlertDialog;
-import android.app.KeyguardManager;
-import android.app.ProgressDialog;
-import android.content.AsyncQueryHandler;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-import android.view.WindowManager;
-import android.widget.EditText;
-import android.widget.Toast;
-
-/**
- * Helper class to listen for some magic character sequences
- * that are handled specially by the dialer.
- *
- * Note the Phone app also handles these sequences too (in a couple of
- * relativly obscure places in the UI), so there's a separate version of
- * this class under apps/Phone.
- *
- * TODO: there's lots of duplicated code between this class and the
- * corresponding class under apps/Phone. Let's figure out a way to
- * unify these two classes (in the framework? in a common shared library?)
- */
-public class SpecialCharSequenceMgr {
- private static final String TAG = "SpecialCharSequenceMgr";
- private static final String MMI_IMEI_DISPLAY = "*#06#";
-
- /**
- * Remembers the previous {@link QueryHandler} and cancel the operation when needed, to
- * prevent possible crash.
- *
- * QueryHandler may call {@link ProgressDialog#dismiss()} when the screen is already gone,
- * which will cause the app crash. This variable enables the class to prevent the crash
- * on {@link #cleanup()}.
- *
- * TODO: Remove this and replace it (and {@link #cleanup()}) with better implementation.
- * One complication is that we have SpecialCharSequencMgr in Phone package too, which has
- * *slightly* different implementation. Note that Phone package doesn't have this problem,
- * so the class on Phone side doesn't have this functionality.
- * Fundamental fix would be to have one shared implementation and resolve this corner case more
- * gracefully.
- */
- private static QueryHandler sPreviousAdnQueryHandler;
-
- /** This class is never instantiated. */
- private SpecialCharSequenceMgr() {
- }
-
- public static boolean handleChars(Context context, String input, EditText textField) {
- return handleChars(context, input, false, textField);
- }
-
- static boolean handleChars(Context context, String input) {
- return handleChars(context, input, false, null);
- }
-
- static boolean handleChars(Context context, String input, boolean useSystemWindow,
- EditText textField) {
-
- //get rid of the separators so that the string gets parsed correctly
- String dialString = PhoneNumberUtils.stripSeparators(input);
-
- if (handleIMEIDisplay(context, dialString, useSystemWindow)
- || handlePinEntry(context, dialString)
- || handleAdnEntry(context, dialString, textField)
- || handleSecretCode(context, dialString)) {
- return true;
- }
-
- return false;
- }
-
- /**
- * Cleanup everything around this class. Must be run inside the main thread.
- *
- * This should be called when the screen becomes background.
- */
- public static void cleanup() {
- if (Looper.myLooper() != Looper.getMainLooper()) {
- Log.wtf(TAG, "cleanup() is called outside the main thread");
- return;
- }
-
- if (sPreviousAdnQueryHandler != null) {
- sPreviousAdnQueryHandler.cancel();
- sPreviousAdnQueryHandler = null;
- }
- }
-
- /**
- * Handles secret codes to launch arbitrary activities in the form of *#*#<code>#*#*.
- * If a secret code is encountered an Intent is started with the android_secret_code://<code>
- * URI.
- *
- * @param context the context to use
- * @param input the text to check for a secret code in
- * @return true if a secret code was encountered
- */
- static boolean handleSecretCode(Context context, String input) {
- // Secret codes are in the form *#*#<code>#*#*
- int len = input.length();
- if (len > 8 && input.startsWith("*#*#") && input.endsWith("#*#*")) {
- Intent intent = new Intent(TelephonyIntents.SECRET_CODE_ACTION,
- Uri.parse("android_secret_code://" + input.substring(4, len - 4)));
- context.sendBroadcast(intent);
- return true;
- }
-
- return false;
- }
-
- /**
- * Handle ADN requests by filling in the SIM contact number into the requested
- * EditText.
- *
- * This code works alongside the Asynchronous query handler {@link QueryHandler}
- * and query cancel handler implemented in {@link SimContactQueryCookie}.
- */
- static boolean handleAdnEntry(Context context, String input, EditText textField) {
- /* ADN entries are of the form "N(N)(N)#" */
-
- TelephonyManager telephonyManager =
- (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
- if (telephonyManager == null
- || !TelephonyCapabilities.supportsAdn(telephonyManager.getCurrentPhoneType())) {
- return false;
- }
-
- // if the phone is keyguard-restricted, then just ignore this
- // input. We want to make sure that sim card contacts are NOT
- // exposed unless the phone is unlocked, and this code can be
- // accessed from the emergency dialer.
- KeyguardManager keyguardManager =
- (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
- if (keyguardManager.inKeyguardRestrictedInputMode()) {
- return false;
- }
-
- int len = input.length();
- if ((len > 1) && (len < 5) && (input.endsWith("#"))) {
- try {
- // get the ordinal number of the sim contact
- int index = Integer.parseInt(input.substring(0, len-1));
-
- // The original code that navigated to a SIM Contacts list view did not
- // highlight the requested contact correctly, a requirement for PTCRB
- // certification. This behaviour is consistent with the UI paradigm
- // for touch-enabled lists, so it does not make sense to try to work
- // around it. Instead we fill in the the requested phone number into
- // the dialer text field.
-
- // create the async query handler
- QueryHandler handler = new QueryHandler (context.getContentResolver());
-
- // create the cookie object
- SimContactQueryCookie sc = new SimContactQueryCookie(index - 1, handler,
- ADN_QUERY_TOKEN);
-
- // setup the cookie fields
- sc.contactNum = index - 1;
- sc.setTextField(textField);
-
- // create the progress dialog
- sc.progressDialog = new ProgressDialog(context);
- sc.progressDialog.setTitle(R.string.simContacts_title);
- sc.progressDialog.setMessage(context.getText(R.string.simContacts_emptyLoading));
- sc.progressDialog.setIndeterminate(true);
- sc.progressDialog.setCancelable(true);
- sc.progressDialog.setOnCancelListener(sc);
- sc.progressDialog.getWindow().addFlags(
- WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
-
- // display the progress dialog
- sc.progressDialog.show();
-
- // run the query.
- handler.startQuery(ADN_QUERY_TOKEN, sc, Uri.parse("content://icc/adn"),
- new String[]{ADN_PHONE_NUMBER_COLUMN_NAME}, null, null, null);
-
- if (sPreviousAdnQueryHandler != null) {
- // It is harmless to call cancel() even after the handler's gone.
- sPreviousAdnQueryHandler.cancel();
- }
- sPreviousAdnQueryHandler = handler;
- return true;
- } catch (NumberFormatException ex) {
- // Ignore
- }
- }
- return false;
- }
-
- static boolean handlePinEntry(Context context, String input) {
- if ((input.startsWith("**04") || input.startsWith("**05")) && input.endsWith("#")) {
- try {
- return ITelephony.Stub.asInterface(ServiceManager.getService("phone"))
- .handlePinMmi(input);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to handlePinMmi due to remote exception");
- return false;
- }
- }
- return false;
- }
-
- static boolean handleIMEIDisplay(Context context, String input, boolean useSystemWindow) {
- TelephonyManager telephonyManager =
- (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
- if (telephonyManager != null && input.equals(MMI_IMEI_DISPLAY)) {
- int phoneType = telephonyManager.getCurrentPhoneType();
- if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
- showIMEIPanel(context, useSystemWindow, telephonyManager);
- return true;
- } else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
- showMEIDPanel(context, useSystemWindow, telephonyManager);
- return true;
- }
- }
-
- return false;
- }
-
- // TODO: Combine showIMEIPanel() and showMEIDPanel() into a single
- // generic "showDeviceIdPanel()" method, like in the apps/Phone
- // version of SpecialCharSequenceMgr.java. (This will require moving
- // the phone app's TelephonyCapabilities.getDeviceIdLabel() method
- // into the telephony framework, though.)
-
- private static void showIMEIPanel(Context context, boolean useSystemWindow,
- TelephonyManager telephonyManager) {
- String imeiStr = telephonyManager.getDeviceId();
-
- AlertDialog alert = new AlertDialog.Builder(context)
- .setTitle(R.string.imei)
- .setMessage(imeiStr)
- .setPositiveButton(android.R.string.ok, null)
- .setCancelable(false)
- .show();
- }
-
- private static void showMEIDPanel(Context context, boolean useSystemWindow,
- TelephonyManager telephonyManager) {
- String meidStr = telephonyManager.getDeviceId();
-
- AlertDialog alert = new AlertDialog.Builder(context)
- .setTitle(R.string.meid)
- .setMessage(meidStr)
- .setPositiveButton(android.R.string.ok, null)
- .setCancelable(false)
- .show();
- }
-
- /*******
- * This code is used to handle SIM Contact queries
- *******/
- private static final String ADN_PHONE_NUMBER_COLUMN_NAME = "number";
- private static final String ADN_NAME_COLUMN_NAME = "name";
- private static final int ADN_QUERY_TOKEN = -1;
-
- /**
- * Cookie object that contains everything we need to communicate to the
- * handler's onQuery Complete, as well as what we need in order to cancel
- * the query (if requested).
- *
- * Note, access to the textField field is going to be synchronized, because
- * the user can request a cancel at any time through the UI.
- */
- private static class SimContactQueryCookie implements DialogInterface.OnCancelListener{
- public ProgressDialog progressDialog;
- public int contactNum;
-
- // Used to identify the query request.
- private int mToken;
- private QueryHandler mHandler;
-
- // The text field we're going to update
- private EditText textField;
-
- public SimContactQueryCookie(int number, QueryHandler handler, int token) {
- contactNum = number;
- mHandler = handler;
- mToken = token;
- }
-
- /**
- * Synchronized getter for the EditText.
- */
- public synchronized EditText getTextField() {
- return textField;
- }
-
- /**
- * Synchronized setter for the EditText.
- */
- public synchronized void setTextField(EditText text) {
- textField = text;
- }
-
- /**
- * Cancel the ADN query by stopping the operation and signaling
- * the cookie that a cancel request is made.
- */
- public synchronized void onCancel(DialogInterface dialog) {
- // close the progress dialog
- if (progressDialog != null) {
- progressDialog.dismiss();
- }
-
- // setting the textfield to null ensures that the UI does NOT get
- // updated.
- textField = null;
-
- // Cancel the operation if possible.
- mHandler.cancelOperation(mToken);
- }
- }
-
- /**
- * Asynchronous query handler that services requests to look up ADNs
- *
- * Queries originate from {@link handleAdnEntry}.
- */
- private static class QueryHandler extends AsyncQueryHandler {
-
- private boolean mCanceled;
-
- public QueryHandler(ContentResolver cr) {
- super(cr);
- }
-
- /**
- * Override basic onQueryComplete to fill in the textfield when
- * we're handed the ADN cursor.
- */
- @Override
- protected void onQueryComplete(int token, Object cookie, Cursor c) {
- sPreviousAdnQueryHandler = null;
- if (mCanceled) {
- return;
- }
-
- SimContactQueryCookie sc = (SimContactQueryCookie) cookie;
-
- // close the progress dialog.
- sc.progressDialog.dismiss();
-
- // get the EditText to update or see if the request was cancelled.
- EditText text = sc.getTextField();
-
- // if the textview is valid, and the cursor is valid and postionable
- // on the Nth number, then we update the text field and display a
- // toast indicating the caller name.
- if ((c != null) && (text != null) && (c.moveToPosition(sc.contactNum))) {
- String name = c.getString(c.getColumnIndexOrThrow(ADN_NAME_COLUMN_NAME));
- String number = c.getString(c.getColumnIndexOrThrow(ADN_PHONE_NUMBER_COLUMN_NAME));
-
- // fill the text in.
- text.getText().replace(0, 0, number);
-
- // display the name as a toast
- Context context = sc.progressDialog.getContext();
- name = context.getString(R.string.menu_callNumber, name);
- Toast.makeText(context, name, Toast.LENGTH_SHORT)
- .show();
- }
- }
-
- public void cancel() {
- mCanceled = true;
- // Ask AsyncQueryHandler to cancel the whole request. This will fails when the
- // query already started.
- cancelOperation(ADN_QUERY_TOKEN);
- }
- }
-}
diff --git a/src/com/android/contacts/activities/AttachPhotoActivity.java b/src/com/android/contacts/activities/AttachPhotoActivity.java
index 2f7651f..b6d7c2d 100644
--- a/src/com/android/contacts/activities/AttachPhotoActivity.java
+++ b/src/com/android/contacts/activities/AttachPhotoActivity.java
@@ -35,9 +35,9 @@
import com.android.contacts.ContactsUtils;
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.RawContactModifier;
import com.android.contacts.model.account.AccountType;
import com.android.contacts.util.ContactPhotoUtils;
diff --git a/src/com/android/contacts/activities/ConfirmAddDetailActivity.java b/src/com/android/contacts/activities/ConfirmAddDetailActivity.java
index c8adf95..84206f8 100644
--- a/src/com/android/contacts/activities/ConfirmAddDetailActivity.java
+++ b/src/com/android/contacts/activities/ConfirmAddDetailActivity.java
@@ -630,7 +630,7 @@
editableAccount.type, editableAccount.dataSet);
// Create a new RawContactDelta for the new raw_contact.
- final RawContact rawContact = new RawContact(context);
+ final RawContact rawContact = new RawContact();
rawContact.setAccount(editableAccount);
final RawContactDelta entityDelta = new RawContactDelta(ValuesDelta.fromAfter(
diff --git a/src/com/android/contacts/activities/DialtactsActivity.java b/src/com/android/contacts/activities/DialtactsActivity.java
deleted file mode 100644
index ea68407..0000000
--- a/src/com/android/contacts/activities/DialtactsActivity.java
+++ /dev/null
@@ -1,1270 +0,0 @@
-/*
- * Copyright (C) 2008 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.activities;
-
-import android.app.ActionBar;
-import android.app.ActionBar.LayoutParams;
-import android.app.ActionBar.Tab;
-import android.app.ActionBar.TabListener;
-import android.app.Activity;
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.preference.PreferenceManager;
-import android.provider.CallLog.Calls;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Intents.UI;
-import android.support.v13.app.FragmentPagerAdapter;
-import android.support.v4.view.ViewPager;
-import android.support.v4.view.ViewPager.OnPageChangeListener;
-import android.text.TextUtils;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.MenuItem.OnMenuItemClickListener;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnFocusChangeListener;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.PopupMenu;
-import android.widget.SearchView;
-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
- * a tab with the favorite. This is the container and the tabs are
- * embedded using intents.
- * The dialer tab's title is 'phone', a more common name (see strings.xml).
- */
-public class DialtactsActivity extends TransactionSafeActivity
- implements View.OnClickListener {
- private static final String TAG = "DialtactsActivity";
-
- public static final boolean DEBUG = false;
-
- /** Used to open Call Setting */
- private static final String PHONE_PACKAGE = "com.android.phone";
- private static final String CALL_SETTINGS_CLASS_NAME =
- "com.android.phone.CallFeaturesSetting";
-
- /**
- * Copied from PhoneApp. See comments in Phone app for more detail.
- */
- public static final String EXTRA_CALL_ORIGIN = "com.android.phone.CALL_ORIGIN";
- /** @see #getCallOrigin() */
- private static final String CALL_ORIGIN_DIALTACTS =
- "com.android.contacts.activities.DialtactsActivity";
-
- /**
- * Just for backward compatibility. Should behave as same as {@link Intent#ACTION_DIAL}.
- */
- private static final String ACTION_TOUCH_DIALER = "com.android.phone.action.TOUCH_DIALER";
-
- /** Used both by {@link ActionBar} and {@link ViewPagerAdapter} */
- private static final int TAB_INDEX_DIALER = 0;
- private static final int TAB_INDEX_CALL_LOG = 1;
- private static final int TAB_INDEX_FAVORITES = 2;
-
- private static final int TAB_INDEX_COUNT = 3;
-
- private SharedPreferences mPrefs;
-
- /** Last manually selected tab index */
- private static final String PREF_LAST_MANUALLY_SELECTED_TAB =
- "DialtactsActivity_last_manually_selected_tab";
- private static final int PREF_LAST_MANUALLY_SELECTED_TAB_DEFAULT = TAB_INDEX_DIALER;
-
- private static final int SUBACTIVITY_ACCOUNT_FILTER = 1;
-
- public class ViewPagerAdapter extends FragmentPagerAdapter {
- public ViewPagerAdapter(FragmentManager fm) {
- super(fm);
- }
-
- @Override
- public Fragment getItem(int position) {
- switch (position) {
- case TAB_INDEX_DIALER:
- return new DialpadFragment();
- case TAB_INDEX_CALL_LOG:
- return new CallLogFragment();
- case TAB_INDEX_FAVORITES:
- return new PhoneFavoriteFragment();
- }
- throw new IllegalStateException("No fragment at position " + position);
- }
-
- @Override
- public void setPrimaryItem(ViewGroup container, int position, Object object) {
- // The parent's setPrimaryItem() also calls setMenuVisibility(), so we want to know
- // when it happens.
- if (DEBUG) {
- Log.d(TAG, "FragmentPagerAdapter#setPrimaryItem(), position: " + position);
- }
- super.setPrimaryItem(container, position, object);
- }
-
- @Override
- public int getCount() {
- return TAB_INDEX_COUNT;
- }
- }
-
- /**
- * True when the app detects user's drag event. This variable should not become true when
- * mUserTabClick is true.
- *
- * During user's drag or tab click, we shouldn't show fake buttons but just show real
- * ActionBar at the bottom of the screen, for transition animation.
- */
- boolean mDuringSwipe = false;
- /**
- * True when the app detects user's tab click (at the top of the screen). This variable should
- * not become true when mDuringSwipe is true.
- *
- * During user's drag or tab click, we shouldn't show fake buttons but just show real
- * ActionBar at the bottom of the screen, for transition animation.
- */
- boolean mUserTabClick = false;
-
- private class PageChangeListener implements OnPageChangeListener {
- private int mCurrentPosition = -1;
- /**
- * Used during page migration, to remember the next position {@link #onPageSelected(int)}
- * specified.
- */
- private int mNextPosition = -1;
-
- @Override
- public void onPageScrolled(
- int position, float positionOffset, int positionOffsetPixels) {
- }
-
- @Override
- public void onPageSelected(int position) {
- if (DEBUG) Log.d(TAG, "onPageSelected: position: " + position);
- final ActionBar actionBar = getActionBar();
- if (mDialpadFragment != null) {
- if (mDuringSwipe && position == TAB_INDEX_DIALER) {
- // TODO: Figure out if we want this or not. Right now
- // - with this call, both fake buttons and real action bar overlap
- // - without this call, there's tiny flicker happening to search/menu buttons.
- // If we can reduce the flicker without this call, it would be much better.
- // updateFakeMenuButtonsVisibility(true);
- }
- }
-
- if (mCurrentPosition == position) {
- Log.w(TAG, "Previous position and next position became same (" + position + ")");
- }
-
- actionBar.selectTab(actionBar.getTabAt(position));
- mNextPosition = position;
- }
-
- public void setCurrentPosition(int position) {
- mCurrentPosition = position;
- }
-
- public int getCurrentPosition() {
- return mCurrentPosition;
- }
-
- @Override
- public void onPageScrollStateChanged(int state) {
- switch (state) {
- case ViewPager.SCROLL_STATE_IDLE: {
- if (mNextPosition == -1) {
- // This happens when the user drags the screen just after launching the
- // application, and settle down the same screen without actually swiping it.
- // At that moment mNextPosition is apparently -1 yet, and we expect it
- // being updated by onPageSelected(), which is *not* called if the user
- // settle down the exact same tab after the dragging.
- if (DEBUG) {
- Log.d(TAG, "Next position is not specified correctly. Use current tab ("
- + mViewPager.getCurrentItem() + ")");
- }
- mNextPosition = mViewPager.getCurrentItem();
- }
- if (DEBUG) {
- Log.d(TAG, "onPageScrollStateChanged() with SCROLL_STATE_IDLE. "
- + "mCurrentPosition: " + mCurrentPosition
- + ", mNextPosition: " + mNextPosition);
- }
- // Interpret IDLE as the end of migration (both swipe and tab click)
- mDuringSwipe = false;
- mUserTabClick = false;
-
- updateFakeMenuButtonsVisibility(mNextPosition == TAB_INDEX_DIALER);
- sendFragmentVisibilityChange(mCurrentPosition, false);
- sendFragmentVisibilityChange(mNextPosition, true);
-
- invalidateOptionsMenu();
-
- mCurrentPosition = mNextPosition;
- break;
- }
- case ViewPager.SCROLL_STATE_DRAGGING: {
- if (DEBUG) Log.d(TAG, "onPageScrollStateChanged() with SCROLL_STATE_DRAGGING");
- mDuringSwipe = true;
- mUserTabClick = false;
- break;
- }
- case ViewPager.SCROLL_STATE_SETTLING: {
- if (DEBUG) Log.d(TAG, "onPageScrollStateChanged() with SCROLL_STATE_SETTLING");
- mDuringSwipe = true;
- mUserTabClick = false;
- break;
- }
- default:
- break;
- }
- }
- }
-
- private String mFilterText;
-
- /** Enables horizontal swipe between Fragments. */
- private ViewPager mViewPager;
- private final PageChangeListener mPageChangeListener = new PageChangeListener();
- private DialpadFragment mDialpadFragment;
- private CallLogFragment mCallLogFragment;
- private PhoneFavoriteFragment mPhoneFavoriteFragment;
-
- private View mSearchButton;
- private View mMenuButton;
-
- private final ContactListFilterListener mContactListFilterListener =
- new ContactListFilterListener() {
- @Override
- public void onContactListFilterChanged() {
- boolean doInvalidateOptionsMenu = false;
-
- if (mPhoneFavoriteFragment != null && mPhoneFavoriteFragment.isAdded()) {
- mPhoneFavoriteFragment.setFilter(mContactListFilterController.getFilter());
- doInvalidateOptionsMenu = true;
- }
-
- if (mSearchFragment != null && mSearchFragment.isAdded()) {
- mSearchFragment.setFilter(mContactListFilterController.getFilter());
- doInvalidateOptionsMenu = true;
- } else {
- Log.w(TAG, "Search Fragment isn't available when ContactListFilter is changed");
- }
-
- if (doInvalidateOptionsMenu) {
- invalidateOptionsMenu();
- }
- }
- };
-
- private final TabListener mTabListener = new TabListener() {
- @Override
- public void onTabUnselected(Tab tab, FragmentTransaction ft) {
- if (DEBUG) Log.d(TAG, "onTabUnselected(). tab: " + tab);
- }
-
- @Override
- public void onTabSelected(Tab tab, FragmentTransaction ft) {
- if (DEBUG) {
- Log.d(TAG, "onTabSelected(). tab: " + tab + ", mDuringSwipe: " + mDuringSwipe);
- }
- // When the user swipes the screen horizontally, this method will be called after
- // ViewPager.SCROLL_STATE_DRAGGING and ViewPager.SCROLL_STATE_SETTLING events, while
- // when the user clicks a tab at the ActionBar at the top, this will be called before
- // them. This logic interprets the order difference as a difference of the user action.
- if (!mDuringSwipe) {
- if (DEBUG) {
- Log.d(TAG, "Tab select. from: " + mPageChangeListener.getCurrentPosition()
- + ", to: " + tab.getPosition());
- }
- if (mDialpadFragment != null) {
- updateFakeMenuButtonsVisibility(tab.getPosition() == TAB_INDEX_DIALER);
- }
- mUserTabClick = true;
- }
-
- if (mViewPager.getCurrentItem() != tab.getPosition()) {
- mViewPager.setCurrentItem(tab.getPosition(), true);
- }
-
- // During the call, we don't remember the tab position.
- if (!DialpadFragment.phoneIsInUse()) {
- // Remember this tab index. This function is also called, if the tab is set
- // automatically in which case the setter (setCurrentTab) has to set this to its old
- // value afterwards
- mLastManuallySelectedFragment = tab.getPosition();
- }
- }
-
- @Override
- public void onTabReselected(Tab tab, FragmentTransaction ft) {
- if (DEBUG) Log.d(TAG, "onTabReselected");
- }
- };
-
- /**
- * Fragment for searching phone numbers. Unlike the other Fragments, this doesn't correspond
- * to tab but is shown by a search action.
- */
- private PhoneNumberPickerFragment mSearchFragment;
- /**
- * True when this Activity is in its search UI (with a {@link SearchView} and
- * {@link PhoneNumberPickerFragment}).
- */
- private boolean mInSearchUi;
- private SearchView mSearchView;
-
- private final OnClickListener mFilterOptionClickListener = new OnClickListener() {
- @Override
- public void onClick(View view) {
- final PopupMenu popupMenu = new PopupMenu(DialtactsActivity.this, view);
- final Menu menu = popupMenu.getMenu();
- popupMenu.inflate(R.menu.dialtacts_search_options);
- final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option);
- filterOptionMenuItem.setOnMenuItemClickListener(mFilterOptionsMenuItemClickListener);
- final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact);
- addContactOptionMenuItem.setIntent(
- new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI));
- popupMenu.show();
- }
- };
-
- /**
- * The index of the Fragment (or, the tab) that has last been manually selected.
- * This value does not keep track of programmatically set Tabs (e.g. Call Log after a Call)
- */
- private int mLastManuallySelectedFragment;
-
- private ContactListFilterController mContactListFilterController;
- private OnMenuItemClickListener mFilterOptionsMenuItemClickListener =
- new OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- AccountFilterUtil.startAccountFilterActivityForResult(
- DialtactsActivity.this, SUBACTIVITY_ACCOUNT_FILTER,
- mContactListFilterController.getFilter());
- return true;
- }
- };
-
- private OnMenuItemClickListener mSearchMenuItemClickListener =
- new OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- enterSearchUi();
- return true;
- }
- };
-
- /**
- * Listener used when one of phone numbers in search UI is selected. This will initiate a
- * phone call using the phone number.
- */
- private final OnPhoneNumberPickerActionListener mPhoneNumberPickerActionListener =
- new OnPhoneNumberPickerActionListener() {
- @Override
- public void onPickPhoneNumberAction(Uri dataUri) {
- // Specify call-origin so that users will see the previous tab instead of
- // CallLog screen (search UI will be automatically exited).
- PhoneNumberInteraction.startInteractionForPhoneCall(
- DialtactsActivity.this, dataUri, getCallOrigin());
- }
-
- @Override
- public void onShortcutIntentCreated(Intent intent) {
- Log.w(TAG, "Unsupported intent has come (" + intent + "). Ignoring.");
- }
-
- @Override
- public void onHomeInActionBarSelected() {
- exitSearchUi();
- }
- };
-
- /**
- * Listener used to send search queries to the phone search fragment.
- */
- private final OnQueryTextListener mPhoneSearchQueryTextListener =
- new OnQueryTextListener() {
- @Override
- public boolean onQueryTextSubmit(String query) {
- View view = getCurrentFocus();
- if (view != null) {
- hideInputMethod(view);
- view.clearFocus();
- }
- return true;
- }
-
- @Override
- public boolean onQueryTextChange(String newText) {
- // Show search result with non-empty text. Show a bare list otherwise.
- if (mSearchFragment != null) {
- mSearchFragment.setQueryString(newText, true);
- }
- return true;
- }
- };
-
- /**
- * Listener used to handle the "close" button on the right side of {@link SearchView}.
- * If some text is in the search view, this will clean it up. Otherwise this will exit
- * the search UI and let users go back to usual Phone UI.
- *
- * This does _not_ handle back button.
- */
- private final OnCloseListener mPhoneSearchCloseListener =
- new OnCloseListener() {
- @Override
- public boolean onClose() {
- if (!TextUtils.isEmpty(mSearchView.getQuery())) {
- mSearchView.setQuery(null, true);
- }
- return true;
- }
- };
-
- private final View.OnLayoutChangeListener mFirstLayoutListener
- = new View.OnLayoutChangeListener() {
- @Override
- public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
- int oldTop, int oldRight, int oldBottom) {
- v.removeOnLayoutChangeListener(this); // Unregister self.
- addSearchFragment();
- }
- };
-
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- final Intent intent = getIntent();
- fixIntent(intent);
-
- setContentView(R.layout.dialtacts_activity);
-
- mContactListFilterController = ContactListFilterController.getInstance(this);
- mContactListFilterController.addListener(mContactListFilterListener);
-
- findViewById(R.id.dialtacts_frame).addOnLayoutChangeListener(mFirstLayoutListener);
-
- mViewPager = (ViewPager) findViewById(R.id.pager);
- mViewPager.setAdapter(new ViewPagerAdapter(getFragmentManager()));
- mViewPager.setOnPageChangeListener(mPageChangeListener);
- mViewPager.setOffscreenPageLimit(2);
-
- // Do same width calculation as ActionBar does
- DisplayMetrics dm = getResources().getDisplayMetrics();
- int minCellSize = getResources().getDimensionPixelSize(R.dimen.fake_menu_button_min_width);
- int cellCount = dm.widthPixels / minCellSize;
- int fakeMenuItemWidth = dm.widthPixels / cellCount;
- if (DEBUG) Log.d(TAG, "The size of fake menu buttons (in pixel): " + fakeMenuItemWidth);
-
- // Soft menu button should appear only when there's no hardware menu button.
- mMenuButton = findViewById(R.id.overflow_menu);
- if (mMenuButton != null) {
- mMenuButton.setMinimumWidth(fakeMenuItemWidth);
- if (ViewConfiguration.get(this).hasPermanentMenuKey()) {
- // This is required for dialpad button's layout, so must not use GONE here.
- mMenuButton.setVisibility(View.INVISIBLE);
- } else {
- mMenuButton.setOnClickListener(this);
- }
- }
- mSearchButton = findViewById(R.id.searchButton);
- if (mSearchButton != null) {
- mSearchButton.setMinimumWidth(fakeMenuItemWidth);
- mSearchButton.setOnClickListener(this);
- }
-
- // Setup the ActionBar tabs (the order matches the tab-index contants TAB_INDEX_*)
- setupDialer();
- setupCallLog();
- setupFavorites();
- getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
- getActionBar().setDisplayShowTitleEnabled(false);
- getActionBar().setDisplayShowHomeEnabled(false);
-
- // Load the last manually loaded tab
- mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
- mLastManuallySelectedFragment = mPrefs.getInt(PREF_LAST_MANUALLY_SELECTED_TAB,
- PREF_LAST_MANUALLY_SELECTED_TAB_DEFAULT);
- if (mLastManuallySelectedFragment >= TAB_INDEX_COUNT) {
- // Stored value may have exceeded the number of current tabs. Reset it.
- mLastManuallySelectedFragment = PREF_LAST_MANUALLY_SELECTED_TAB_DEFAULT;
- }
-
- setCurrentTab(intent);
-
- if (UI.FILTER_CONTACTS_ACTION.equals(intent.getAction())
- && icicle == null) {
- setupFilterText(intent);
- }
- }
-
- @Override
- public void onStart() {
- super.onStart();
- if (mPhoneFavoriteFragment != null) {
- mPhoneFavoriteFragment.setFilter(mContactListFilterController.getFilter());
- }
- if (mSearchFragment != null) {
- mSearchFragment.setFilter(mContactListFilterController.getFilter());
- }
-
- if (mDuringSwipe || mUserTabClick) {
- if (DEBUG) Log.d(TAG, "reset buggy flag state..");
- mDuringSwipe = false;
- mUserTabClick = false;
- }
-
- final int currentPosition = mPageChangeListener.getCurrentPosition();
- if (DEBUG) {
- Log.d(TAG, "onStart(). current position: " + mPageChangeListener.getCurrentPosition()
- + ". Reset all menu visibility state.");
- }
- updateFakeMenuButtonsVisibility(currentPosition == TAB_INDEX_DIALER && !mInSearchUi);
- for (int i = 0; i < TAB_INDEX_COUNT; i++) {
- sendFragmentVisibilityChange(i, i == currentPosition);
- }
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- mContactListFilterController.removeListener(mContactListFilterListener);
- }
-
- @Override
- public void onClick(View view) {
- switch (view.getId()) {
- case R.id.searchButton: {
- enterSearchUi();
- break;
- }
- case R.id.overflow_menu: {
- if (mDialpadFragment != null) {
- PopupMenu popup = mDialpadFragment.constructPopupMenu(view);
- if (popup != null) {
- popup.show();
- }
- } else {
- Log.w(TAG, "DialpadFragment is null during onClick() event for " + view);
- }
- break;
- }
- default: {
- Log.wtf(TAG, "Unexpected onClick event from " + view);
- break;
- }
- }
- }
-
- /**
- * Add search fragment. Note this is called during onLayout, so there's some restrictions,
- * such as executePendingTransaction can't be used in it.
- */
- private void addSearchFragment() {
- // In order to take full advantage of "fragment deferred start", we need to create the
- // search fragment after all other fragments are created.
- // The other fragments are created by the ViewPager on the first onMeasure().
- // We use the first onLayout call, which is after onMeasure().
-
- // Just return if the fragment is already created, which happens after configuration
- // changes.
- if (mSearchFragment != null) return;
-
- final FragmentTransaction ft = getFragmentManager().beginTransaction();
- final Fragment searchFragment = new PhoneNumberPickerFragment();
-
- searchFragment.setUserVisibleHint(false);
- ft.add(R.id.dialtacts_frame, searchFragment);
- ft.hide(searchFragment);
- ft.commitAllowingStateLoss();
- }
-
- private void prepareSearchView() {
- final View searchViewLayout =
- getLayoutInflater().inflate(R.layout.dialtacts_custom_action_bar, null);
- mSearchView = (SearchView) searchViewLayout.findViewById(R.id.search_view);
- mSearchView.setOnQueryTextListener(mPhoneSearchQueryTextListener);
- mSearchView.setOnCloseListener(mPhoneSearchCloseListener);
- // Since we're using a custom layout for showing SearchView instead of letting the
- // search menu icon do that job, we need to manually configure the View so it looks
- // "shown via search menu".
- // - it should be iconified by default
- // - it should not be iconified at this time
- // See also comments for onActionViewExpanded()/onActionViewCollapsed()
- mSearchView.setIconifiedByDefault(true);
- mSearchView.setQueryHint(getString(R.string.hint_findContacts));
- mSearchView.setIconified(false);
- mSearchView.setOnQueryTextFocusChangeListener(new OnFocusChangeListener() {
- @Override
- public void onFocusChange(View view, boolean hasFocus) {
- if (hasFocus) {
- showInputMethod(view.findFocus());
- }
- }
- });
-
- if (!ViewConfiguration.get(this).hasPermanentMenuKey()) {
- // Filter option menu should be shown on the right side of SearchView.
- final View filterOptionView = searchViewLayout.findViewById(R.id.search_option);
- filterOptionView.setVisibility(View.VISIBLE);
- filterOptionView.setOnClickListener(mFilterOptionClickListener);
- }
-
- getActionBar().setCustomView(searchViewLayout,
- new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
- }
-
- @Override
- public void onAttachFragment(Fragment fragment) {
- // This method can be called before onCreate(), at which point we cannot rely on ViewPager.
- // In that case, we will setup the "current position" soon after the ViewPager is ready.
- final int currentPosition = mViewPager != null ? mViewPager.getCurrentItem() : -1;
-
- if (fragment instanceof DialpadFragment) {
- mDialpadFragment = (DialpadFragment) fragment;
- } else if (fragment instanceof CallLogFragment) {
- mCallLogFragment = (CallLogFragment) fragment;
- } else if (fragment instanceof PhoneFavoriteFragment) {
- mPhoneFavoriteFragment = (PhoneFavoriteFragment) fragment;
- mPhoneFavoriteFragment.setListener(mPhoneFavoriteListener);
- if (mContactListFilterController != null
- && mContactListFilterController.getFilter() != null) {
- mPhoneFavoriteFragment.setFilter(mContactListFilterController.getFilter());
- }
- } else if (fragment instanceof PhoneNumberPickerFragment) {
- mSearchFragment = (PhoneNumberPickerFragment) fragment;
- mSearchFragment.setOnPhoneNumberPickerActionListener(mPhoneNumberPickerActionListener);
- mSearchFragment.setQuickContactEnabled(true);
- mSearchFragment.setDarkTheme(true);
- mSearchFragment.setPhotoPosition(ContactListItemView.PhotoPosition.LEFT);
- mSearchFragment.setUseCallableUri(true);
- if (mContactListFilterController != null
- && mContactListFilterController.getFilter() != null) {
- mSearchFragment.setFilter(mContactListFilterController.getFilter());
- }
- // Here we assume that we're not on the search mode, so let's hide the fragment.
- //
- // We get here either when the fragment is created (normal case), or after configuration
- // changes. In the former case, we're not in search mode because we can only
- // enter search mode if the fragment is created. (see enterSearchUi())
- // In the latter case we're not in search mode either because we don't retain
- // mInSearchUi -- ideally we should but at this point it's not supported.
- mSearchFragment.setUserVisibleHint(false);
- // After configuration changes fragments will forget their "hidden" state, so make
- // sure to hide it.
- if (!mSearchFragment.isHidden()) {
- final FragmentTransaction transaction = getFragmentManager().beginTransaction();
- transaction.hide(mSearchFragment);
- transaction.commitAllowingStateLoss();
- }
- }
- }
-
- @Override
- protected void onPause() {
- super.onPause();
-
- mPrefs.edit().putInt(PREF_LAST_MANUALLY_SELECTED_TAB, mLastManuallySelectedFragment)
- .apply();
- }
-
- private void fixIntent(Intent intent) {
- // This should be cleaned up: the call key used to send an Intent
- // that just said to go to the recent calls list. It now sends this
- // abstract action, but this class hasn't been rewritten to deal with it.
- if (Intent.ACTION_CALL_BUTTON.equals(intent.getAction())) {
- intent.setDataAndType(Calls.CONTENT_URI, Calls.CONTENT_TYPE);
- intent.putExtra("call_key", true);
- setIntent(intent);
- }
- }
-
- private void setupDialer() {
- final Tab tab = getActionBar().newTab();
- tab.setContentDescription(R.string.dialerIconLabel);
- tab.setTabListener(mTabListener);
- tab.setIcon(R.drawable.ic_tab_dialer);
- getActionBar().addTab(tab);
- }
-
- private void setupCallLog() {
- final Tab tab = getActionBar().newTab();
- tab.setContentDescription(R.string.recentCallsIconLabel);
- tab.setIcon(R.drawable.ic_tab_recent);
- tab.setTabListener(mTabListener);
- getActionBar().addTab(tab);
- }
-
- private void setupFavorites() {
- final Tab tab = getActionBar().newTab();
- tab.setContentDescription(R.string.contactsFavoritesLabel);
- tab.setIcon(R.drawable.ic_tab_all);
- tab.setTabListener(mTabListener);
- getActionBar().addTab(tab);
- }
-
- /**
- * 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
- * @return true if the intent is due to hitting the green send key while in a call
- */
- private boolean isSendKeyWhileInCall(final Intent intent,
- final boolean recentCallsRequest) {
- // If there is a call in progress go to the call screen
- if (recentCallsRequest) {
- final boolean callKey = intent.getBooleanExtra("call_key", false);
-
- try {
- ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
- if (callKey && phone != null && phone.showCallScreen()) {
- return true;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to handle send while in call", e);
- }
- }
-
- return false;
- }
-
- /**
- * Sets the current tab based on the intent's request type
- *
- * @param intent Intent that contains information about which tab should be selected
- */
- private void setCurrentTab(Intent intent) {
- // If we got here by hitting send and we're in call forward along to the in-call activity
- boolean recentCallsRequest = Calls.CONTENT_TYPE.equals(intent.resolveType(
- getContentResolver()));
- if (isSendKeyWhileInCall(intent, recentCallsRequest)) {
- finish();
- return;
- }
-
- // Remember the old manually selected tab index so that it can be restored if it is
- // overwritten by one of the programmatic tab selections
- final int savedTabIndex = mLastManuallySelectedFragment;
-
- final int tabIndex;
- if (DialpadFragment.phoneIsInUse() || isDialIntent(intent)) {
- tabIndex = TAB_INDEX_DIALER;
- } else if (recentCallsRequest) {
- tabIndex = TAB_INDEX_CALL_LOG;
- } else {
- tabIndex = mLastManuallySelectedFragment;
- }
-
- final int previousItemIndex = mViewPager.getCurrentItem();
- mViewPager.setCurrentItem(tabIndex, false /* smoothScroll */);
- if (previousItemIndex != tabIndex) {
- sendFragmentVisibilityChange(previousItemIndex, false /* not visible */ );
- }
- mPageChangeListener.setCurrentPosition(tabIndex);
- sendFragmentVisibilityChange(tabIndex, true /* visible */ );
-
- // Restore to the previous manual selection
- mLastManuallySelectedFragment = savedTabIndex;
- mDuringSwipe = false;
- mUserTabClick = false;
- }
-
- @Override
- public void onNewIntent(Intent newIntent) {
- setIntent(newIntent);
- fixIntent(newIntent);
- setCurrentTab(newIntent);
- final String action = newIntent.getAction();
- if (UI.FILTER_CONTACTS_ACTION.equals(action)) {
- setupFilterText(newIntent);
- }
- if (mInSearchUi || (mSearchFragment != null && mSearchFragment.isVisible())) {
- exitSearchUi();
- }
-
- if (mViewPager.getCurrentItem() == TAB_INDEX_DIALER) {
- if (mDialpadFragment != null) {
- mDialpadFragment.configureScreenFromIntent(newIntent);
- } else {
- Log.e(TAG, "DialpadFragment isn't ready yet when the tab is already selected.");
- }
- } else if (mViewPager.getCurrentItem() == TAB_INDEX_CALL_LOG) {
- if (mCallLogFragment != null) {
- mCallLogFragment.configureScreenFromIntent(newIntent);
- } else {
- Log.e(TAG, "CallLogFragment isn't ready yet when the tab is already selected.");
- }
- }
- invalidateOptionsMenu();
- }
-
- /** Returns true if the given intent contains a phone number to populate the dialer with */
- private boolean isDialIntent(Intent intent) {
- final String action = intent.getAction();
- if (Intent.ACTION_DIAL.equals(action) || ACTION_TOUCH_DIALER.equals(action)) {
- return true;
- }
- if (Intent.ACTION_VIEW.equals(action)) {
- final Uri data = intent.getData();
- if (data != null && Constants.SCHEME_TEL.equals(data.getScheme())) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns an appropriate call origin for this Activity. May return null when no call origin
- * should be used (e.g. when some 3rd party application launched the screen. Call origin is
- * for remembering the tab in which the user made a phone call, so the external app's DIAL
- * request should not be counted.)
- */
- public String getCallOrigin() {
- return !isDialIntent(getIntent()) ? CALL_ORIGIN_DIALTACTS : null;
- }
-
- /**
- * Retrieves the filter text stored in {@link #setupFilterText(Intent)}.
- * This text originally came from a FILTER_CONTACTS_ACTION intent received
- * by this activity. The stored text will then be cleared after after this
- * method returns.
- *
- * @return The stored filter text
- */
- public String getAndClearFilterText() {
- String filterText = mFilterText;
- mFilterText = null;
- return filterText;
- }
-
- /**
- * Stores the filter text associated with a FILTER_CONTACTS_ACTION intent.
- * This is so child activities can check if they are supposed to display a filter.
- *
- * @param intent The intent received in {@link #onNewIntent(Intent)}
- */
- private void setupFilterText(Intent intent) {
- // If the intent was relaunched from history, don't apply the filter text.
- if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
- return;
- }
- String filter = intent.getStringExtra(UI.FILTER_TEXT_EXTRA_KEY);
- if (filter != null && filter.length() > 0) {
- mFilterText = filter;
- }
- }
-
- @Override
- public void onBackPressed() {
- if (mInSearchUi) {
- // We should let the user go back to usual screens with tabs.
- exitSearchUi();
- } else if (isTaskRoot()) {
- // Instead of stopping, simply push this to the back of the stack.
- // This is only done when running at the top of the stack;
- // otherwise, we have been launched by someone else so need to
- // allow the user to go back to the caller.
- moveTaskToBack(false);
- } else {
- super.onBackPressed();
- }
- }
-
- private final PhoneFavoriteFragment.Listener mPhoneFavoriteListener =
- new PhoneFavoriteFragment.Listener() {
- @Override
- public void onContactSelected(Uri contactUri) {
- PhoneNumberInteraction.startInteractionForPhoneCall(
- DialtactsActivity.this, contactUri, getCallOrigin());
- }
-
- @Override
- public void onCallNumberDirectly(String phoneNumber) {
- Intent intent = ContactsUtils.getCallIntent(phoneNumber, getCallOrigin());
- startActivity(intent);
- }
- };
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.dialtacts_options, menu);
-
- // set up intents and onClick listeners
- final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings);
- final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar);
- final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option);
- final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact);
-
- callSettingsMenuItem.setIntent(DialtactsActivity.getCallSettingsIntent());
- searchMenuItem.setOnMenuItemClickListener(mSearchMenuItemClickListener);
- filterOptionMenuItem.setOnMenuItemClickListener(mFilterOptionsMenuItemClickListener);
- addContactOptionMenuItem.setIntent(
- new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI));
-
- return true;
- }
-
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- if (mInSearchUi) {
- prepareOptionsMenuInSearchMode(menu);
- } else {
- // get reference to the currently selected tab
- final Tab tab = getActionBar().getSelectedTab();
- if (tab != null) {
- switch(tab.getPosition()) {
- case TAB_INDEX_DIALER:
- prepareOptionsMenuForDialerTab(menu);
- break;
- case TAB_INDEX_CALL_LOG:
- prepareOptionsMenuForCallLogTab(menu);
- break;
- case TAB_INDEX_FAVORITES:
- prepareOptionsMenuForFavoritesTab(menu);
- break;
- }
- }
- }
- return true;
- }
-
- private void prepareOptionsMenuInSearchMode(Menu menu) {
- // get references to menu items
- final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar);
- final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option);
- final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact);
- final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings);
- final MenuItem emptyRightMenuItem = menu.findItem(R.id.empty_right_menu_item);
-
- // prepare the menu items
- searchMenuItem.setVisible(false);
- filterOptionMenuItem.setVisible(ViewConfiguration.get(this).hasPermanentMenuKey());
- addContactOptionMenuItem.setVisible(false);
- callSettingsMenuItem.setVisible(false);
- emptyRightMenuItem.setVisible(false);
- }
-
- private void prepareOptionsMenuForDialerTab(Menu menu) {
- if (DEBUG) {
- Log.d(TAG, "onPrepareOptionsMenu(dialer). swipe: " + mDuringSwipe
- + ", user tab click: " + mUserTabClick);
- }
-
- // get references to menu items
- final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar);
- final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option);
- final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact);
- final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings);
- final MenuItem emptyRightMenuItem = menu.findItem(R.id.empty_right_menu_item);
-
- // prepare the menu items
- filterOptionMenuItem.setVisible(false);
- addContactOptionMenuItem.setVisible(false);
- if (mDuringSwipe || mUserTabClick) {
- // During horizontal movement, the real ActionBar menu items are shown
- searchMenuItem.setVisible(true);
- callSettingsMenuItem.setVisible(true);
- // When there is a permanent menu key, there is no overflow icon on the right of
- // the action bar which would force the search menu item (if it is visible) to the
- // left. This is the purpose of showing the emptyRightMenuItem.
- emptyRightMenuItem.setVisible(ViewConfiguration.get(this).hasPermanentMenuKey());
- } else {
- // This is when the user is looking at the dialer pad. In this case, the real
- // ActionBar is hidden and fake menu items are shown.
- // Except in landscape, in which case the real search menu item is shown.
- searchMenuItem.setVisible(ContactsUtils.isLandscape(this));
- // If a permanent menu key is available, then we need to show the call settings item
- // so that the call settings item can be invoked by the permanent menu key.
- callSettingsMenuItem.setVisible(ViewConfiguration.get(this).hasPermanentMenuKey());
- emptyRightMenuItem.setVisible(false);
- }
- }
-
- private void prepareOptionsMenuForCallLogTab(Menu menu) {
- // get references to menu items
- final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar);
- final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option);
- final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact);
- final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings);
- final MenuItem emptyRightMenuItem = menu.findItem(R.id.empty_right_menu_item);
-
- // prepare the menu items
- searchMenuItem.setVisible(true);
- filterOptionMenuItem.setVisible(false);
- addContactOptionMenuItem.setVisible(false);
- callSettingsMenuItem.setVisible(true);
- emptyRightMenuItem.setVisible(ViewConfiguration.get(this).hasPermanentMenuKey());
- }
-
- private void prepareOptionsMenuForFavoritesTab(Menu menu) {
- // get references to menu items
- final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar);
- final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option);
- final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact);
- final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings);
- final MenuItem emptyRightMenuItem = menu.findItem(R.id.empty_right_menu_item);
-
- // prepare the menu items
- searchMenuItem.setVisible(true);
- filterOptionMenuItem.setVisible(true);
- addContactOptionMenuItem.setVisible(true);
- callSettingsMenuItem.setVisible(true);
- emptyRightMenuItem.setVisible(false);
- }
-
- @Override
- public void startSearch(String initialQuery, boolean selectInitialQuery,
- Bundle appSearchData, boolean globalSearch) {
- if (mSearchFragment != null && mSearchFragment.isAdded() && !globalSearch) {
- if (mInSearchUi) {
- if (mSearchView.hasFocus()) {
- showInputMethod(mSearchView.findFocus());
- } else {
- mSearchView.requestFocus();
- }
- } else {
- enterSearchUi();
- }
- } else {
- super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
- }
- }
-
- /**
- * Hides every tab and shows search UI for phone lookup.
- */
- private void enterSearchUi() {
- if (mSearchFragment == null) {
- // We add the search fragment dynamically in the first onLayoutChange() and
- // mSearchFragment is set sometime later when the fragment transaction is actually
- // executed, which means there's a window when users are able to hit the (physical)
- // search key but mSearchFragment is still null.
- // It's quite hard to handle this case right, so let's just ignore the search key
- // in this case. Users can just hit it again and it will work this time.
- return;
- }
- if (mSearchView == null) {
- prepareSearchView();
- }
-
- final ActionBar actionBar = getActionBar();
-
- final Tab tab = actionBar.getSelectedTab();
-
- // User can search during the call, but we don't want to remember the status.
- if (tab != null && !DialpadFragment.phoneIsInUse()) {
- mLastManuallySelectedFragment = tab.getPosition();
- }
-
- mSearchView.setQuery(null, true);
-
- actionBar.setDisplayShowCustomEnabled(true);
- actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
- actionBar.setDisplayShowHomeEnabled(true);
- actionBar.setDisplayHomeAsUpEnabled(true);
-
- updateFakeMenuButtonsVisibility(false);
-
- for (int i = 0; i < TAB_INDEX_COUNT; i++) {
- sendFragmentVisibilityChange(i, false /* not visible */ );
- }
-
- // Show the search fragment and hide everything else.
- mSearchFragment.setUserVisibleHint(true);
- final FragmentTransaction transaction = getFragmentManager().beginTransaction();
- transaction.show(mSearchFragment);
- transaction.commitAllowingStateLoss();
- mViewPager.setVisibility(View.GONE);
-
- // We need to call this and onActionViewCollapsed() manually, since we are using a custom
- // layout instead of asking the search menu item to take care of SearchView.
- mSearchView.onActionViewExpanded();
- mInSearchUi = true;
- }
-
- private void showInputMethod(View view) {
- InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
- if (imm != null) {
- if (!imm.showSoftInput(view, 0)) {
- Log.w(TAG, "Failed to show soft input method.");
- }
- }
- }
-
- private void hideInputMethod(View view) {
- InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
- if (imm != null && view != null) {
- imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
- }
- }
-
- /**
- * Goes back to usual Phone UI with tags. Previously selected Tag and associated Fragment
- * should be automatically focused again.
- */
- private void exitSearchUi() {
- final ActionBar actionBar = getActionBar();
-
- // Hide the search fragment, if exists.
- if (mSearchFragment != null) {
- mSearchFragment.setUserVisibleHint(false);
-
- final FragmentTransaction transaction = getFragmentManager().beginTransaction();
- transaction.hide(mSearchFragment);
- transaction.commitAllowingStateLoss();
- }
-
- // We want to hide SearchView and show Tabs. Also focus on previously selected one.
- actionBar.setDisplayShowCustomEnabled(false);
- actionBar.setDisplayShowHomeEnabled(false);
- actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
-
- for (int i = 0; i < TAB_INDEX_COUNT; i++) {
- sendFragmentVisibilityChange(i, i == mViewPager.getCurrentItem());
- }
-
- // Before exiting the search screen, reset swipe state.
- mDuringSwipe = false;
- mUserTabClick = false;
-
- mViewPager.setVisibility(View.VISIBLE);
-
- hideInputMethod(getCurrentFocus());
-
- // Request to update option menu.
- invalidateOptionsMenu();
-
- // See comments in onActionViewExpanded()
- mSearchView.onActionViewCollapsed();
- mInSearchUi = false;
- }
-
- private Fragment getFragmentAt(int position) {
- switch (position) {
- case TAB_INDEX_DIALER:
- return mDialpadFragment;
- case TAB_INDEX_CALL_LOG:
- return mCallLogFragment;
- case TAB_INDEX_FAVORITES:
- return mPhoneFavoriteFragment;
- default:
- throw new IllegalStateException("Unknown fragment index: " + position);
- }
- }
-
- private void sendFragmentVisibilityChange(int position, boolean visibility) {
- if (DEBUG) {
- Log.d(TAG, "sendFragmentVisibiltyChange(). position: " + position
- + ", visibility: " + visibility);
- }
- // Position can be -1 initially. See PageChangeListener.
- if (position >= 0) {
- final Fragment fragment = getFragmentAt(position);
- if (fragment != null) {
- fragment.setMenuVisibility(visibility);
- fragment.setUserVisibleHint(visibility);
- }
- }
- }
-
- /**
- * Update visibility of the search button and menu button at the bottom.
- * They should be invisible when bottom ActionBar's real items are available, and be visible
- * otherwise.
- *
- * @param visible True when visible.
- */
- private void updateFakeMenuButtonsVisibility(boolean visible) {
- // Note: Landscape mode does not have the fake menu and search buttons.
- if (DEBUG) {
- Log.d(TAG, "updateFakeMenuButtonVisibility(" + visible + ")");
- }
-
- if (mSearchButton != null) {
- if (visible) {
- mSearchButton.setVisibility(View.VISIBLE);
- } else {
- mSearchButton.setVisibility(View.INVISIBLE);
- }
- }
- if (mMenuButton != null) {
- if (visible && !ViewConfiguration.get(this).hasPermanentMenuKey()) {
- mMenuButton.setVisibility(View.VISIBLE);
- } else {
- mMenuButton.setVisibility(View.INVISIBLE);
- }
- }
- }
-
- /** Returns an Intent to launch Call Settings screen */
- public static Intent getCallSettingsIntent() {
- final Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.setClassName(PHONE_PACKAGE, CALL_SETTINGS_CLASS_NAME);
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- return intent;
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (resultCode != Activity.RESULT_OK) {
- return;
- }
- switch (requestCode) {
- case SUBACTIVITY_ACCOUNT_FILTER: {
- AccountFilterUtil.handleAccountFilterResult(
- mContactListFilterController, resultCode, data);
- }
- break;
- }
- }
-}
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index b811dd9..576806a 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -63,7 +63,6 @@
import com.android.contacts.group.GroupDetailFragment;
import com.android.contacts.interactions.ContactDeletionInteraction;
import com.android.contacts.interactions.ImportExportDialogFragment;
-import com.android.contacts.interactions.PhoneNumberInteraction;
import com.android.contacts.list.ContactBrowseListFragment;
import com.android.contacts.list.ContactEntryListFragment;
import com.android.contacts.list.ContactListFilter;
@@ -90,7 +89,7 @@
import com.android.contacts.util.DialogManager;
import com.android.contacts.util.HelpUtils;
import com.android.contacts.util.PhoneCapabilityTester;
-import com.android.contacts.util.UriUtils;
+import com.android.contacts.common.util.UriUtils;
import com.android.contacts.widget.TransitionAnimationView;
import java.util.ArrayList;
@@ -1130,16 +1129,6 @@
}
@Override
- public void onCallContactAction(Uri contactUri) {
- PhoneNumberInteraction.startInteractionForPhoneCall(PeopleActivity.this, contactUri);
- }
-
- @Override
- public void onSmsContactAction(Uri contactUri) {
- PhoneNumberInteraction.startInteractionForTextMessage(PeopleActivity.this, contactUri);
- }
-
- @Override
public void onDeleteContactAction(Uri contactUri) {
ContactDeletionInteraction.start(PeopleActivity.this, contactUri, false);
}
diff --git a/src/com/android/contacts/activities/PhotoSelectionActivity.java b/src/com/android/contacts/activities/PhotoSelectionActivity.java
index 6f3da00..3b1032f 100644
--- a/src/com/android/contacts/activities/PhotoSelectionActivity.java
+++ b/src/com/android/contacts/activities/PhotoSelectionActivity.java
@@ -33,7 +33,7 @@
import android.widget.FrameLayout.LayoutParams;
import android.widget.ImageView;
-import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.ContactSaveService;
import com.android.contacts.R;
import com.android.contacts.detail.PhotoSelectionHandler;
diff --git a/src/com/android/contacts/activities/ShowOrCreateActivity.java b/src/com/android/contacts/activities/ShowOrCreateActivity.java
index 1dc0197..a8077cb 100755
--- a/src/com/android/contacts/activities/ShowOrCreateActivity.java
+++ b/src/com/android/contacts/activities/ShowOrCreateActivity.java
@@ -32,9 +32,9 @@
import android.provider.ContactsContract.RawContacts;
import android.util.Log;
+import com.android.contacts.common.CallUtil;
import com.android.contacts.ContactsActivity;
import com.android.contacts.R;
-import com.android.contacts.util.Constants;
import com.android.contacts.util.NotifyingAsyncQueryHandler;
/**
@@ -119,13 +119,13 @@
mCreateForce = intent.getBooleanExtra(Intents.EXTRA_FORCE_CREATE, false);
// Handle specific query request
- if (Constants.SCHEME_MAILTO.equals(scheme)) {
+ if (CallUtil.SCHEME_MAILTO.equals(scheme)) {
mCreateExtras.putString(Intents.Insert.EMAIL, ssp);
Uri uri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, Uri.encode(ssp));
mQueryHandler.startQuery(QUERY_TOKEN, null, uri, CONTACTS_PROJECTION, null, null, null);
- } else if (Constants.SCHEME_TEL.equals(scheme)) {
+ } else if (CallUtil.SCHEME_TEL.equals(scheme)) {
mCreateExtras.putString(Intents.Insert.PHONE, ssp);
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, ssp);
diff --git a/src/com/android/contacts/activities/TransactionSafeActivity.java b/src/com/android/contacts/activities/TransactionSafeActivity.java
deleted file mode 100644
index b177665..0000000
--- a/src/com/android/contacts/activities/TransactionSafeActivity.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.activities;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-/**
- * A common superclass that keeps track of whether an {@link Activity} has saved its state yet or
- * not.
- */
-public abstract class TransactionSafeActivity extends Activity {
-
- private boolean mIsSafeToCommitTransactions;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mIsSafeToCommitTransactions = true;
- }
-
- @Override
- protected void onStart() {
- super.onStart();
- mIsSafeToCommitTransactions = true;
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- mIsSafeToCommitTransactions = true;
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mIsSafeToCommitTransactions = false;
- }
-
- /**
- * Returns true if it is safe to commit {@link FragmentTransaction}s at this time, based on
- * whether {@link Activity#onSaveInstanceState} has been called or not.
- *
- * Make sure that the current activity calls into
- * {@link super.onSaveInstanceState(Bundle outState)} (if that method is overridden),
- * so the flag is properly set.
- */
- public boolean isSafeToCommitTransactions() {
- return mIsSafeToCommitTransactions;
- }
-}
diff --git a/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java b/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java
deleted file mode 100644
index 9183208..0000000
--- a/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-import android.content.Context;
-import android.provider.CallLog.Calls;
-import android.text.format.DateUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-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.
- */
-public class CallDetailHistoryAdapter extends BaseAdapter {
- /** The top element is a blank header, which is hidden under the rest of the UI. */
- private static final int VIEW_TYPE_HEADER = 0;
- /** Each history item shows the detail of a call. */
- private static final int VIEW_TYPE_HISTORY_ITEM = 1;
-
- private final Context mContext;
- private final LayoutInflater mLayoutInflater;
- private final CallTypeHelper mCallTypeHelper;
- private final PhoneCallDetails[] mPhoneCallDetails;
- /** Whether the voicemail controls are shown. */
- private final boolean mShowVoicemail;
- /** Whether the call and SMS controls are shown. */
- private final boolean mShowCallAndSms;
- /** The controls that are shown on top of the history list. */
- private final View mControls;
- /** The listener to changes of focus of the header. */
- private View.OnFocusChangeListener mHeaderFocusChangeListener =
- new View.OnFocusChangeListener() {
- @Override
- public void onFocusChange(View v, boolean hasFocus) {
- // When the header is focused, focus the controls above it instead.
- if (hasFocus) {
- mControls.requestFocus();
- }
- }
- };
-
- public CallDetailHistoryAdapter(Context context, LayoutInflater layoutInflater,
- CallTypeHelper callTypeHelper, PhoneCallDetails[] phoneCallDetails,
- boolean showVoicemail, boolean showCallAndSms, View controls) {
- mContext = context;
- mLayoutInflater = layoutInflater;
- mCallTypeHelper = callTypeHelper;
- mPhoneCallDetails = phoneCallDetails;
- mShowVoicemail = showVoicemail;
- mShowCallAndSms = showCallAndSms;
- mControls = controls;
- }
-
- @Override
- public boolean isEnabled(int position) {
- // None of history will be clickable.
- return false;
- }
-
- @Override
- public int getCount() {
- return mPhoneCallDetails.length + 1;
- }
-
- @Override
- public Object getItem(int position) {
- if (position == 0) {
- return null;
- }
- return mPhoneCallDetails[position - 1];
- }
-
- @Override
- public long getItemId(int position) {
- if (position == 0) {
- return -1;
- }
- return position - 1;
- }
-
- @Override
- public int getViewTypeCount() {
- return 2;
- }
-
- @Override
- public int getItemViewType(int position) {
- if (position == 0) {
- return VIEW_TYPE_HEADER;
- }
- return VIEW_TYPE_HISTORY_ITEM;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- if (position == 0) {
- final View header = convertView == null
- ? mLayoutInflater.inflate(R.layout.call_detail_history_header, parent, false)
- : convertView;
- // Voicemail controls are only shown in the main UI if there is a voicemail.
- View voicemailContainer = header.findViewById(R.id.header_voicemail_container);
- voicemailContainer.setVisibility(mShowVoicemail ? View.VISIBLE : View.GONE);
- // Call and SMS controls are only shown in the main UI if there is a known number.
- View callAndSmsContainer = header.findViewById(R.id.header_call_and_sms_container);
- callAndSmsContainer.setVisibility(mShowCallAndSms ? View.VISIBLE : View.GONE);
- header.setFocusable(true);
- header.setOnFocusChangeListener(mHeaderFocusChangeListener);
- return header;
- }
-
- // Make sure we have a valid convertView to start with
- final View result = convertView == null
- ? mLayoutInflater.inflate(R.layout.call_detail_history_item, parent, false)
- : convertView;
-
- PhoneCallDetails details = mPhoneCallDetails[position - 1];
- CallTypeIconsView callTypeIconView =
- (CallTypeIconsView) result.findViewById(R.id.call_type_icon);
- TextView callTypeTextView = (TextView) result.findViewById(R.id.call_type_text);
- TextView dateView = (TextView) result.findViewById(R.id.date);
- TextView durationView = (TextView) result.findViewById(R.id.duration);
-
- int callType = details.callTypes[0];
- callTypeIconView.clear();
- callTypeIconView.add(callType);
- callTypeTextView.setText(mCallTypeHelper.getCallTypeText(callType));
- // Set the date.
- CharSequence dateValue = DateUtils.formatDateRange(mContext, details.date, details.date,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE |
- DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_YEAR);
- dateView.setText(dateValue);
- // Set the duration
- if (callType == Calls.MISSED_TYPE || callType == Calls.VOICEMAIL_TYPE) {
- durationView.setVisibility(View.GONE);
- } else {
- durationView.setVisibility(View.VISIBLE);
- durationView.setText(formatDuration(details.duration));
- }
-
- return result;
- }
-
- private String formatDuration(long elapsedSeconds) {
- long minutes = 0;
- long seconds = 0;
-
- if (elapsedSeconds >= 60) {
- minutes = elapsedSeconds / 60;
- elapsedSeconds -= minutes * 60;
- }
- seconds = elapsedSeconds;
-
- return mContext.getString(R.string.callDetailsDurationFormat, minutes, seconds);
- }
-}
diff --git a/src/com/android/contacts/calllog/CallLogAdapter.java b/src/com/android/contacts/calllog/CallLogAdapter.java
deleted file mode 100644
index 3688dca..0000000
--- a/src/com/android/contacts/calllog/CallLogAdapter.java
+++ /dev/null
@@ -1,802 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.CallLog.Calls;
-import android.provider.ContactsContract.PhoneLookup;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-
-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 java.util.LinkedList;
-
-/**
- * Adapter class to fill in data for the Call Log.
- */
-/*package*/ class CallLogAdapter extends GroupingListAdapter
- implements ViewTreeObserver.OnPreDrawListener, CallLogGroupBuilder.GroupCreator {
- /** Interface used to initiate a refresh of the content. */
- public interface CallFetcher {
- public void fetchCalls();
- }
-
- /**
- * Stores a phone number of a call with the country code where it originally occurred.
- * <p>
- * Note the country does not necessarily specifies the country of the phone number itself, but
- * it is the country in which the user was in when the call was placed or received.
- */
- private static final class NumberWithCountryIso {
- public final String number;
- public final String countryIso;
-
- public NumberWithCountryIso(String number, String countryIso) {
- this.number = number;
- this.countryIso = countryIso;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == null) return false;
- if (!(o instanceof NumberWithCountryIso)) return false;
- NumberWithCountryIso other = (NumberWithCountryIso) o;
- return TextUtils.equals(number, other.number)
- && TextUtils.equals(countryIso, other.countryIso);
- }
-
- @Override
- public int hashCode() {
- return (number == null ? 0 : number.hashCode())
- ^ (countryIso == null ? 0 : countryIso.hashCode());
- }
- }
-
- /** The time in millis to delay starting the thread processing requests. */
- private static final int START_PROCESSING_REQUESTS_DELAY_MILLIS = 1000;
-
- /** The size of the cache of contact info. */
- private static final int CONTACT_INFO_CACHE_SIZE = 100;
-
- private final Context mContext;
- private final ContactInfoHelper mContactInfoHelper;
- private final CallFetcher mCallFetcher;
- private ViewTreeObserver mViewTreeObserver = null;
-
- /**
- * A cache of the contact details for the phone numbers in the call log.
- * <p>
- * The content of the cache is expired (but not purged) whenever the application comes to
- * the foreground.
- * <p>
- * The key is number with the country in which the call was placed or received.
- */
- private ExpirableCache<NumberWithCountryIso, ContactInfo> mContactInfoCache;
-
- /**
- * A request for contact details for the given number.
- */
- private static final class ContactInfoRequest {
- /** The number to look-up. */
- public final String number;
- /** The country in which a call to or from this number was placed or received. */
- public final String countryIso;
- /** The cached contact information stored in the call log. */
- public final ContactInfo callLogInfo;
-
- public ContactInfoRequest(String number, String countryIso, ContactInfo callLogInfo) {
- this.number = number;
- this.countryIso = countryIso;
- this.callLogInfo = callLogInfo;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (obj == null) return false;
- if (!(obj instanceof ContactInfoRequest)) return false;
-
- ContactInfoRequest other = (ContactInfoRequest) obj;
-
- if (!TextUtils.equals(number, other.number)) return false;
- if (!TextUtils.equals(countryIso, other.countryIso)) return false;
- if (!Objects.equal(callLogInfo, other.callLogInfo)) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((callLogInfo == null) ? 0 : callLogInfo.hashCode());
- result = prime * result + ((countryIso == null) ? 0 : countryIso.hashCode());
- result = prime * result + ((number == null) ? 0 : number.hashCode());
- return result;
- }
- }
-
- /**
- * List of requests to update contact details.
- * <p>
- * Each request is made of a phone number to look up, and the contact info currently stored in
- * the call log for this number.
- * <p>
- * The requests are added when displaying the contacts and are processed by a background
- * thread.
- */
- private final LinkedList<ContactInfoRequest> mRequests;
-
- private boolean mLoading = true;
- private static final int REDRAW = 1;
- private static final int START_THREAD = 2;
-
- private QueryThread mCallerIdThread;
-
- /** Instance of helper class for managing views. */
- private final CallLogListItemHelper mCallLogViewsHelper;
-
- /** Helper to set up contact photos. */
- private final ContactPhotoManager mContactPhotoManager;
- /** Helper to parse and process phone numbers. */
- private PhoneNumberHelper mPhoneNumberHelper;
- /** Helper to group call log entries. */
- private final CallLogGroupBuilder mCallLogGroupBuilder;
-
- /** Can be set to true by tests to disable processing of requests. */
- private volatile boolean mRequestProcessingDisabled = false;
-
- /** Listener for the primary action in the list, opens the call details. */
- private final View.OnClickListener mPrimaryActionListener = new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- IntentProvider intentProvider = (IntentProvider) view.getTag();
- if (intentProvider != null) {
- mContext.startActivity(intentProvider.getIntent(mContext));
- }
- }
- };
- /** Listener for the secondary action in the list, either call or play. */
- private final View.OnClickListener mSecondaryActionListener = new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- IntentProvider intentProvider = (IntentProvider) view.getTag();
- if (intentProvider != null) {
- mContext.startActivity(intentProvider.getIntent(mContext));
- }
- }
- };
-
- @Override
- public boolean onPreDraw() {
- // We only wanted to listen for the first draw (and this is it).
- unregisterPreDrawListener();
-
- // Only schedule a thread-creation message if the thread hasn't been
- // created yet. This is purely an optimization, to queue fewer messages.
- if (mCallerIdThread == null) {
- mHandler.sendEmptyMessageDelayed(START_THREAD, START_PROCESSING_REQUESTS_DELAY_MILLIS);
- }
-
- return true;
- }
-
- private Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case REDRAW:
- notifyDataSetChanged();
- break;
- case START_THREAD:
- startRequestProcessing();
- break;
- }
- }
- };
-
- CallLogAdapter(Context context, CallFetcher callFetcher,
- ContactInfoHelper contactInfoHelper) {
- super(context);
-
- mContext = context;
- mCallFetcher = callFetcher;
- mContactInfoHelper = contactInfoHelper;
-
- mContactInfoCache = ExpirableCache.create(CONTACT_INFO_CACHE_SIZE);
- mRequests = new LinkedList<ContactInfoRequest>();
-
- Resources resources = mContext.getResources();
- CallTypeHelper callTypeHelper = new CallTypeHelper(resources);
-
- mContactPhotoManager = ContactPhotoManager.getInstance(mContext);
- mPhoneNumberHelper = new PhoneNumberHelper(resources);
- PhoneCallDetailsHelper phoneCallDetailsHelper = new PhoneCallDetailsHelper(
- resources, callTypeHelper, mPhoneNumberHelper);
- mCallLogViewsHelper =
- new CallLogListItemHelper(
- phoneCallDetailsHelper, mPhoneNumberHelper, resources);
- mCallLogGroupBuilder = new CallLogGroupBuilder(this);
- }
-
- /**
- * Requery on background thread when {@link Cursor} changes.
- */
- @Override
- protected void onContentChanged() {
- mCallFetcher.fetchCalls();
- }
-
- void setLoading(boolean loading) {
- mLoading = loading;
- }
-
- @Override
- public boolean isEmpty() {
- if (mLoading) {
- // We don't want the empty state to show when loading.
- return false;
- } else {
- return super.isEmpty();
- }
- }
-
- /**
- * Starts a background thread to process contact-lookup requests, unless one
- * has already been started.
- */
- private synchronized void startRequestProcessing() {
- // For unit-testing.
- if (mRequestProcessingDisabled) return;
-
- // Idempotence... if a thread is already started, don't start another.
- if (mCallerIdThread != null) return;
-
- mCallerIdThread = new QueryThread();
- mCallerIdThread.setPriority(Thread.MIN_PRIORITY);
- mCallerIdThread.start();
- }
-
- /**
- * Stops the background thread that processes updates and cancels any
- * pending requests to start it.
- */
- public synchronized void stopRequestProcessing() {
- // Remove any pending requests to start the processing thread.
- mHandler.removeMessages(START_THREAD);
- if (mCallerIdThread != null) {
- // Stop the thread; we are finished with it.
- mCallerIdThread.stopProcessing();
- mCallerIdThread.interrupt();
- mCallerIdThread = null;
- }
- }
-
- /**
- * Stop receiving onPreDraw() notifications.
- */
- private void unregisterPreDrawListener() {
- if (mViewTreeObserver != null && mViewTreeObserver.isAlive()) {
- mViewTreeObserver.removeOnPreDrawListener(this);
- }
- mViewTreeObserver = null;
- }
-
- public void invalidateCache() {
- mContactInfoCache.expireAll();
-
- // Restart the request-processing thread after the next draw.
- stopRequestProcessing();
- unregisterPreDrawListener();
- }
-
- /**
- * Enqueues a request to look up the contact details for the given phone number.
- * <p>
- * It also provides the current contact info stored in the call log for this number.
- * <p>
- * If the {@code immediate} parameter is true, it will start immediately the thread that looks
- * up the contact information (if it has not been already started). Otherwise, it will be
- * started with a delay. See {@link #START_PROCESSING_REQUESTS_DELAY_MILLIS}.
- */
- @VisibleForTesting
- void enqueueRequest(String number, String countryIso, ContactInfo callLogInfo,
- boolean immediate) {
- ContactInfoRequest request = new ContactInfoRequest(number, countryIso, callLogInfo);
- synchronized (mRequests) {
- if (!mRequests.contains(request)) {
- mRequests.add(request);
- mRequests.notifyAll();
- }
- }
- if (immediate) startRequestProcessing();
- }
-
- /**
- * Queries the appropriate content provider for the contact associated with the number.
- * <p>
- * Upon completion it also updates the cache in the call log, if it is different from
- * {@code callLogInfo}.
- * <p>
- * The number might be either a SIP address or a phone number.
- * <p>
- * It returns true if it updated the content of the cache and we should therefore tell the
- * view to update its content.
- */
- private boolean queryContactInfo(String number, String countryIso, ContactInfo callLogInfo) {
- final ContactInfo info = mContactInfoHelper.lookupNumber(number, countryIso);
-
- if (info == null) {
- // The lookup failed, just return without requesting to update the view.
- return false;
- }
-
- // Check the existing entry in the cache: only if it has changed we should update the
- // view.
- NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(number, countryIso);
- ContactInfo existingInfo = mContactInfoCache.getPossiblyExpired(numberCountryIso);
- boolean updated = (existingInfo != ContactInfo.EMPTY) && !info.equals(existingInfo);
-
- // Store the data in the cache so that the UI thread can use to display it. Store it
- // even if it has not changed so that it is marked as not expired.
- mContactInfoCache.put(numberCountryIso, info);
- // Update the call log even if the cache it is up-to-date: it is possible that the cache
- // contains the value from a different call log entry.
- updateCallLogContactInfoCache(number, countryIso, info, callLogInfo);
- return updated;
- }
-
- /*
- * Handles requests for contact name and number type.
- */
- private class QueryThread extends Thread {
- private volatile boolean mDone = false;
-
- public QueryThread() {
- super("CallLogAdapter.QueryThread");
- }
-
- public void stopProcessing() {
- mDone = true;
- }
-
- @Override
- public void run() {
- boolean needRedraw = false;
- while (true) {
- // Check if thread is finished, and if so return immediately.
- if (mDone) return;
-
- // Obtain next request, if any is available.
- // Keep synchronized section small.
- ContactInfoRequest req = null;
- synchronized (mRequests) {
- if (!mRequests.isEmpty()) {
- req = mRequests.removeFirst();
- }
- }
-
- if (req != null) {
- // Process the request. If the lookup succeeds, schedule a
- // redraw.
- needRedraw |= queryContactInfo(req.number, req.countryIso, req.callLogInfo);
- } else {
- // Throttle redraw rate by only sending them when there are
- // more requests.
- if (needRedraw) {
- needRedraw = false;
- mHandler.sendEmptyMessage(REDRAW);
- }
-
- // Wait until another request is available, or until this
- // thread is no longer needed (as indicated by being
- // interrupted).
- try {
- synchronized (mRequests) {
- mRequests.wait(1000);
- }
- } catch (InterruptedException ie) {
- // Ignore, and attempt to continue processing requests.
- }
- }
- }
- }
- }
-
- @Override
- protected void addGroups(Cursor cursor) {
- mCallLogGroupBuilder.addGroups(cursor);
- }
-
- @Override
- protected View newStandAloneView(Context context, ViewGroup parent) {
- LayoutInflater inflater =
- (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- View view = inflater.inflate(R.layout.call_log_list_item, parent, false);
- findAndCacheViews(view);
- return view;
- }
-
- @Override
- protected void bindStandAloneView(View view, Context context, Cursor cursor) {
- bindView(view, cursor, 1);
- }
-
- @Override
- protected View newChildView(Context context, ViewGroup parent) {
- LayoutInflater inflater =
- (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- View view = inflater.inflate(R.layout.call_log_list_item, parent, false);
- findAndCacheViews(view);
- return view;
- }
-
- @Override
- protected void bindChildView(View view, Context context, Cursor cursor) {
- bindView(view, cursor, 1);
- }
-
- @Override
- protected View newGroupView(Context context, ViewGroup parent) {
- LayoutInflater inflater =
- (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- View view = inflater.inflate(R.layout.call_log_list_item, parent, false);
- findAndCacheViews(view);
- return view;
- }
-
- @Override
- protected void bindGroupView(View view, Context context, Cursor cursor, int groupSize,
- boolean expanded) {
- bindView(view, cursor, groupSize);
- }
-
- private void findAndCacheViews(View view) {
- // Get the views to bind to.
- CallLogListItemViews views = CallLogListItemViews.fromView(view);
- views.primaryActionView.setOnClickListener(mPrimaryActionListener);
- views.secondaryActionView.setOnClickListener(mSecondaryActionListener);
- view.setTag(views);
- }
-
- /**
- * Binds the views in the entry to the data in the call log.
- *
- * @param view the view corresponding to this entry
- * @param c the cursor pointing to the entry in the call log
- * @param count the number of entries in the current item, greater than 1 if it is a group
- */
- private void bindView(View view, Cursor c, int count) {
- final CallLogListItemViews views = (CallLogListItemViews) view.getTag();
- final int section = c.getInt(CallLogQuery.SECTION);
-
- // This might be a header: check the value of the section column in the cursor.
- if (section == CallLogQuery.SECTION_NEW_HEADER
- || section == CallLogQuery.SECTION_OLD_HEADER) {
- views.primaryActionView.setVisibility(View.GONE);
- views.bottomDivider.setVisibility(View.GONE);
- views.listHeaderTextView.setVisibility(View.VISIBLE);
- views.listHeaderTextView.setText(
- section == CallLogQuery.SECTION_NEW_HEADER
- ? R.string.call_log_new_header
- : R.string.call_log_old_header);
- // Nothing else to set up for a header.
- return;
- }
- // Default case: an item in the call log.
- views.primaryActionView.setVisibility(View.VISIBLE);
- views.bottomDivider.setVisibility(isLastOfSection(c) ? View.GONE : View.VISIBLE);
- views.listHeaderTextView.setVisibility(View.GONE);
-
- final String number = c.getString(CallLogQuery.NUMBER);
- final long date = c.getLong(CallLogQuery.DATE);
- final long duration = c.getLong(CallLogQuery.DURATION);
- final int callType = c.getInt(CallLogQuery.CALL_TYPE);
- final String countryIso = c.getString(CallLogQuery.COUNTRY_ISO);
-
- final ContactInfo cachedContactInfo = getContactInfoFromCallLog(c);
-
- views.primaryActionView.setTag(
- IntentProvider.getCallDetailIntentProvider(
- this, c.getPosition(), c.getLong(CallLogQuery.ID), count));
- // Store away the voicemail information so we can play it directly.
- if (callType == Calls.VOICEMAIL_TYPE) {
- String voicemailUri = c.getString(CallLogQuery.VOICEMAIL_URI);
- final long rowId = c.getLong(CallLogQuery.ID);
- views.secondaryActionView.setTag(
- IntentProvider.getPlayVoicemailIntentProvider(rowId, voicemailUri));
- } else if (!TextUtils.isEmpty(number)) {
- // Store away the number so we can call it directly if you click on the call icon.
- views.secondaryActionView.setTag(
- IntentProvider.getReturnCallIntentProvider(number));
- } else {
- // No action enabled.
- views.secondaryActionView.setTag(null);
- }
-
- // Lookup contacts with this number
- NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(number, countryIso);
- ExpirableCache.CachedValue<ContactInfo> cachedInfo =
- mContactInfoCache.getCachedValue(numberCountryIso);
- ContactInfo info = cachedInfo == null ? null : cachedInfo.getValue();
- if (!mPhoneNumberHelper.canPlaceCallsTo(number)
- || mPhoneNumberHelper.isVoicemailNumber(number)) {
- // If this is a number that cannot be dialed, there is no point in looking up a contact
- // for it.
- info = ContactInfo.EMPTY;
- } else if (cachedInfo == null) {
- mContactInfoCache.put(numberCountryIso, ContactInfo.EMPTY);
- // Use the cached contact info from the call log.
- info = cachedContactInfo;
- // The db request should happen on a non-UI thread.
- // Request the contact details immediately since they are currently missing.
- enqueueRequest(number, countryIso, cachedContactInfo, true);
- // We will format the phone number when we make the background request.
- } else {
- if (cachedInfo.isExpired()) {
- // The contact info is no longer up to date, we should request it. However, we
- // do not need to request them immediately.
- enqueueRequest(number, countryIso, cachedContactInfo, false);
- } else if (!callLogInfoMatches(cachedContactInfo, info)) {
- // The call log information does not match the one we have, look it up again.
- // We could simply update the call log directly, but that needs to be done in a
- // background thread, so it is easier to simply request a new lookup, which will, as
- // a side-effect, update the call log.
- enqueueRequest(number, countryIso, cachedContactInfo, false);
- }
-
- if (info == ContactInfo.EMPTY) {
- // Use the cached contact info from the call log.
- info = cachedContactInfo;
- }
- }
-
- final Uri lookupUri = info.lookupUri;
- final String name = info.name;
- final int ntype = info.type;
- final String label = info.label;
- final long photoId = info.photoId;
- CharSequence formattedNumber = info.formattedNumber;
- final int[] callTypes = getCallTypes(c, count);
- final String geocode = c.getString(CallLogQuery.GEOCODED_LOCATION);
- final PhoneCallDetails details;
- if (TextUtils.isEmpty(name)) {
- details = new PhoneCallDetails(number, formattedNumber, countryIso, geocode,
- callTypes, date, duration);
- } else {
- // We do not pass a photo id since we do not need the high-res picture.
- details = new PhoneCallDetails(number, formattedNumber, countryIso, geocode,
- callTypes, date, duration, name, ntype, label, lookupUri, null);
- }
-
- final boolean isNew = c.getInt(CallLogQuery.IS_READ) == 0;
- // New items also use the highlighted version of the text.
- final boolean isHighlighted = isNew;
- mCallLogViewsHelper.setPhoneCallDetails(views, details, isHighlighted);
- setPhoto(views, photoId, lookupUri);
-
- // Listen for the first draw
- if (mViewTreeObserver == null) {
- mViewTreeObserver = view.getViewTreeObserver();
- mViewTreeObserver.addOnPreDrawListener(this);
- }
- }
-
- /** Returns true if this is the last item of a section. */
- private boolean isLastOfSection(Cursor c) {
- if (c.isLast()) return true;
- final int section = c.getInt(CallLogQuery.SECTION);
- if (!c.moveToNext()) return true;
- final int nextSection = c.getInt(CallLogQuery.SECTION);
- c.moveToPrevious();
- return section != nextSection;
- }
-
- /** Checks whether the contact info from the call log matches the one from the contacts db. */
- private boolean callLogInfoMatches(ContactInfo callLogInfo, ContactInfo info) {
- // The call log only contains a subset of the fields in the contacts db.
- // Only check those.
- return TextUtils.equals(callLogInfo.name, info.name)
- && callLogInfo.type == info.type
- && TextUtils.equals(callLogInfo.label, info.label);
- }
-
- /** Stores the updated contact info in the call log if it is different from the current one. */
- private void updateCallLogContactInfoCache(String number, String countryIso,
- ContactInfo updatedInfo, ContactInfo callLogInfo) {
- final ContentValues values = new ContentValues();
- boolean needsUpdate = false;
-
- if (callLogInfo != null) {
- if (!TextUtils.equals(updatedInfo.name, callLogInfo.name)) {
- values.put(Calls.CACHED_NAME, updatedInfo.name);
- needsUpdate = true;
- }
-
- if (updatedInfo.type != callLogInfo.type) {
- values.put(Calls.CACHED_NUMBER_TYPE, updatedInfo.type);
- needsUpdate = true;
- }
-
- if (!TextUtils.equals(updatedInfo.label, callLogInfo.label)) {
- values.put(Calls.CACHED_NUMBER_LABEL, updatedInfo.label);
- needsUpdate = true;
- }
- if (!UriUtils.areEqual(updatedInfo.lookupUri, callLogInfo.lookupUri)) {
- values.put(Calls.CACHED_LOOKUP_URI, UriUtils.uriToString(updatedInfo.lookupUri));
- needsUpdate = true;
- }
- if (!TextUtils.equals(updatedInfo.normalizedNumber, callLogInfo.normalizedNumber)) {
- values.put(Calls.CACHED_NORMALIZED_NUMBER, updatedInfo.normalizedNumber);
- needsUpdate = true;
- }
- if (!TextUtils.equals(updatedInfo.number, callLogInfo.number)) {
- values.put(Calls.CACHED_MATCHED_NUMBER, updatedInfo.number);
- needsUpdate = true;
- }
- if (updatedInfo.photoId != callLogInfo.photoId) {
- values.put(Calls.CACHED_PHOTO_ID, updatedInfo.photoId);
- needsUpdate = true;
- }
- if (!TextUtils.equals(updatedInfo.formattedNumber, callLogInfo.formattedNumber)) {
- values.put(Calls.CACHED_FORMATTED_NUMBER, updatedInfo.formattedNumber);
- needsUpdate = true;
- }
- } else {
- // No previous values, store all of them.
- values.put(Calls.CACHED_NAME, updatedInfo.name);
- values.put(Calls.CACHED_NUMBER_TYPE, updatedInfo.type);
- values.put(Calls.CACHED_NUMBER_LABEL, updatedInfo.label);
- values.put(Calls.CACHED_LOOKUP_URI, UriUtils.uriToString(updatedInfo.lookupUri));
- values.put(Calls.CACHED_MATCHED_NUMBER, updatedInfo.number);
- values.put(Calls.CACHED_NORMALIZED_NUMBER, updatedInfo.normalizedNumber);
- values.put(Calls.CACHED_PHOTO_ID, updatedInfo.photoId);
- values.put(Calls.CACHED_FORMATTED_NUMBER, updatedInfo.formattedNumber);
- needsUpdate = true;
- }
-
- if (!needsUpdate) return;
-
- if (countryIso == null) {
- mContext.getContentResolver().update(Calls.CONTENT_URI_WITH_VOICEMAIL, values,
- Calls.NUMBER + " = ? AND " + Calls.COUNTRY_ISO + " IS NULL",
- new String[]{ number });
- } else {
- mContext.getContentResolver().update(Calls.CONTENT_URI_WITH_VOICEMAIL, values,
- Calls.NUMBER + " = ? AND " + Calls.COUNTRY_ISO + " = ?",
- new String[]{ number, countryIso });
- }
- }
-
- /** Returns the contact information as stored in the call log. */
- private ContactInfo getContactInfoFromCallLog(Cursor c) {
- ContactInfo info = new ContactInfo();
- info.lookupUri = UriUtils.parseUriOrNull(c.getString(CallLogQuery.CACHED_LOOKUP_URI));
- info.name = c.getString(CallLogQuery.CACHED_NAME);
- info.type = c.getInt(CallLogQuery.CACHED_NUMBER_TYPE);
- info.label = c.getString(CallLogQuery.CACHED_NUMBER_LABEL);
- String matchedNumber = c.getString(CallLogQuery.CACHED_MATCHED_NUMBER);
- info.number = matchedNumber == null ? c.getString(CallLogQuery.NUMBER) : matchedNumber;
- info.normalizedNumber = c.getString(CallLogQuery.CACHED_NORMALIZED_NUMBER);
- info.photoId = c.getLong(CallLogQuery.CACHED_PHOTO_ID);
- info.photoUri = null; // We do not cache the photo URI.
- info.formattedNumber = c.getString(CallLogQuery.CACHED_FORMATTED_NUMBER);
- return info;
- }
-
- /**
- * Returns the call types for the given number of items in the cursor.
- * <p>
- * It uses the next {@code count} rows in the cursor to extract the types.
- * <p>
- * It position in the cursor is unchanged by this function.
- */
- private int[] getCallTypes(Cursor cursor, int count) {
- int position = cursor.getPosition();
- int[] callTypes = new int[count];
- for (int index = 0; index < count; ++index) {
- callTypes[index] = cursor.getInt(CallLogQuery.CALL_TYPE);
- cursor.moveToNext();
- }
- cursor.moveToPosition(position);
- return callTypes;
- }
-
- private void setPhoto(CallLogListItemViews views, long photoId, Uri contactUri) {
- views.quickContactView.assignContactUri(contactUri);
- mContactPhotoManager.loadThumbnail(views.quickContactView, photoId, true);
- }
-
- /**
- * Sets whether processing of requests for contact details should be enabled.
- * <p>
- * This method should be called in tests to disable such processing of requests when not
- * needed.
- */
- @VisibleForTesting
- void disableRequestProcessingForTest() {
- mRequestProcessingDisabled = true;
- }
-
- @VisibleForTesting
- void injectContactInfoForTest(String number, String countryIso, ContactInfo contactInfo) {
- NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(number, countryIso);
- mContactInfoCache.put(numberCountryIso, contactInfo);
- }
-
- @Override
- public void addGroup(int cursorPosition, int size, boolean expanded) {
- super.addGroup(cursorPosition, size, expanded);
- }
-
- /*
- * Get the number from the Contacts, if available, since sometimes
- * the number provided by caller id may not be formatted properly
- * depending on the carrier (roaming) in use at the time of the
- * incoming call.
- * Logic : If the caller-id number starts with a "+", use it
- * Else if the number in the contacts starts with a "+", use that one
- * Else if the number in the contacts is longer, use that one
- */
- public String getBetterNumberFromContacts(String number, String countryIso) {
- String matchingNumber = null;
- // Look in the cache first. If it's not found then query the Phones db
- NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(number, countryIso);
- ContactInfo ci = mContactInfoCache.getPossiblyExpired(numberCountryIso);
- if (ci != null && ci != ContactInfo.EMPTY) {
- matchingNumber = ci.number;
- } else {
- try {
- Cursor phonesCursor = mContext.getContentResolver().query(
- Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, number),
- PhoneQuery._PROJECTION, null, null, null);
- if (phonesCursor != null) {
- if (phonesCursor.moveToFirst()) {
- matchingNumber = phonesCursor.getString(PhoneQuery.MATCHED_NUMBER);
- }
- phonesCursor.close();
- }
- } catch (Exception e) {
- // Use the number from the call log
- }
- }
- if (!TextUtils.isEmpty(matchingNumber) &&
- (matchingNumber.startsWith("+")
- || matchingNumber.length() > number.length())) {
- number = matchingNumber;
- }
- return number;
- }
-}
diff --git a/src/com/android/contacts/calllog/CallLogFragment.java b/src/com/android/contacts/calllog/CallLogFragment.java
deleted file mode 100644
index a8c2f06..0000000
--- a/src/com/android/contacts/calllog/CallLogFragment.java
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-import android.app.Activity;
-import android.app.KeyguardManager;
-import android.app.ListFragment;
-import android.content.Context;
-import android.content.Intent;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.provider.CallLog;
-import android.provider.CallLog.Calls;
-import android.provider.ContactsContract;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.PhoneStateListener;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-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;
-
-/**
- * Displays a list of call log entries.
- */
-public class CallLogFragment extends ListFragment
- implements CallLogQueryHandler.Listener, CallLogAdapter.CallFetcher {
- private static final String TAG = "CallLogFragment";
-
- /**
- * ID of the empty loader to defer other fragments.
- */
- private static final int EMPTY_LOADER_ID = 0;
-
- private CallLogAdapter mAdapter;
- private CallLogQueryHandler mCallLogQueryHandler;
- private boolean mScrollToTop;
-
- /** Whether there is at least one voicemail source installed. */
- private boolean mVoicemailSourcesAvailable = false;
- /** Whether we are currently filtering over voicemail. */
- private boolean mShowingVoicemailOnly = false;
-
- private VoicemailStatusHelper mVoicemailStatusHelper;
- private View mStatusMessageView;
- private TextView mStatusMessageText;
- private TextView mStatusMessageAction;
- private TextView mFilterStatusView;
- private KeyguardManager mKeyguardManager;
-
- private boolean mEmptyLoaderRunning;
- private boolean mCallLogFetched;
- private boolean mVoicemailStatusFetched;
-
- private final Handler mHandler = new Handler();
-
- private TelephonyManager mTelephonyManager;
- private PhoneStateListener mPhoneStateListener;
-
- private class CustomContentObserver extends ContentObserver {
- public CustomContentObserver() {
- super(mHandler);
- }
- @Override
- public void onChange(boolean selfChange) {
- mRefreshDataRequired = true;
- }
- }
-
- // See issue 6363009
- private final ContentObserver mCallLogObserver = new CustomContentObserver();
- private final ContentObserver mContactsObserver = new CustomContentObserver();
- private boolean mRefreshDataRequired = true;
-
- // 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);
-
- mCallLogQueryHandler = new CallLogQueryHandler(getActivity().getContentResolver(), this);
- mKeyguardManager =
- (KeyguardManager) getActivity().getSystemService(Context.KEYGUARD_SERVICE);
- getActivity().getContentResolver().registerContentObserver(
- CallLog.CONTENT_URI, true, mCallLogObserver);
- getActivity().getContentResolver().registerContentObserver(
- ContactsContract.Contacts.CONTENT_URI, true, mContactsObserver);
- setHasOptionsMenu(true);
- }
-
- /** Called by the CallLogQueryHandler when the list of calls has been fetched or updated. */
- @Override
- public void onCallsFetched(Cursor cursor) {
- if (getActivity() == null || getActivity().isFinishing()) {
- return;
- }
- mAdapter.setLoading(false);
- mAdapter.changeCursor(cursor);
- // This will update the state of the "Clear call log" menu item.
- getActivity().invalidateOptionsMenu();
- if (mScrollToTop) {
- final ListView listView = getListView();
- // The smooth-scroll animation happens over a fixed time period.
- // As a result, if it scrolls through a large portion of the list,
- // each frame will jump so far from the previous one that the user
- // will not experience the illusion of downward motion. Instead,
- // if we're not already near the top of the list, we instantly jump
- // near the top, and animate from there.
- if (listView.getFirstVisiblePosition() > 5) {
- listView.setSelection(5);
- }
- // Workaround for framework issue: the smooth-scroll doesn't
- // occur if setSelection() is called immediately before.
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- if (getActivity() == null || getActivity().isFinishing()) {
- return;
- }
- listView.smoothScrollToPosition(0);
- }
- });
-
- mScrollToTop = false;
- }
- mCallLogFetched = true;
- destroyEmptyLoaderIfAllDataFetched();
- }
-
- /**
- * Called by {@link CallLogQueryHandler} after a successful query to voicemail status provider.
- */
- @Override
- public void onVoicemailStatusFetched(Cursor statusCursor) {
- if (getActivity() == null || getActivity().isFinishing()) {
- return;
- }
- updateVoicemailStatusMessage(statusCursor);
-
- int activeSources = mVoicemailStatusHelper.getNumberActivityVoicemailSources(statusCursor);
- setVoicemailSourcesAvailable(activeSources != 0);
- MoreCloseables.closeQuietly(statusCursor);
- mVoicemailStatusFetched = true;
- destroyEmptyLoaderIfAllDataFetched();
- }
-
- private void destroyEmptyLoaderIfAllDataFetched() {
- if (mCallLogFetched && mVoicemailStatusFetched && mEmptyLoaderRunning) {
- mEmptyLoaderRunning = false;
- getLoaderManager().destroyLoader(EMPTY_LOADER_ID);
- }
- }
-
- /** Sets whether there are any voicemail sources available in the platform. */
- private void setVoicemailSourcesAvailable(boolean voicemailSourcesAvailable) {
- if (mVoicemailSourcesAvailable == voicemailSourcesAvailable) return;
- mVoicemailSourcesAvailable = voicemailSourcesAvailable;
-
- Activity activity = getActivity();
- if (activity != null) {
- // This is so that the options menu content is updated.
- activity.invalidateOptionsMenu();
- }
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
- View view = inflater.inflate(R.layout.call_log_fragment, container, false);
- mVoicemailStatusHelper = new VoicemailStatusHelperImpl();
- 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;
- }
-
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- String currentCountryIso = ContactsUtils.getCurrentCountryIso(getActivity());
- mAdapter = new CallLogAdapter(getActivity(), this,
- new ContactInfoHelper(getActivity(), currentCountryIso));
- setListAdapter(mAdapter);
- getListView().setItemsCanFocus(true);
- }
-
- /**
- * Based on the new intent, decide whether the list should be configured
- * to scroll up to display the first item.
- */
- public void configureScreenFromIntent(Intent newIntent) {
- // Typically, when switching to the call-log we want to show the user
- // the same section of the list that they were most recently looking
- // at. However, under some circumstances, we want to automatically
- // scroll to the top of the list to present the newest call items.
- // For example, immediately after a call is finished, we want to
- // display information about that call.
- mScrollToTop = Calls.CONTENT_TYPE.equals(newIntent.getType());
- }
-
- @Override
- public void onStart() {
- // Start the empty loader now to defer other fragments. We destroy it when both calllog
- // and the voicemail status are fetched.
- getLoaderManager().initLoader(EMPTY_LOADER_ID, null,
- new EmptyLoader.Callback(getActivity()));
- mEmptyLoaderRunning = true;
- super.onStart();
- }
-
- @Override
- public void onResume() {
- super.onResume();
- refreshData();
- }
-
- private void updateVoicemailStatusMessage(Cursor statusCursor) {
- List<StatusMessage> messages = mVoicemailStatusHelper.getStatusMessages(statusCursor);
- if (messages.size() == 0) {
- mStatusMessageView.setVisibility(View.GONE);
- } else {
- mStatusMessageView.setVisibility(View.VISIBLE);
- // TODO: Change the code to show all messages. For now just pick the first message.
- final StatusMessage message = messages.get(0);
- if (message.showInCallLog()) {
- mStatusMessageText.setText(message.callLogMessageId);
- }
- if (message.actionMessageId != -1) {
- mStatusMessageAction.setText(message.actionMessageId);
- }
- if (message.actionUri != null) {
- mStatusMessageAction.setVisibility(View.VISIBLE);
- mStatusMessageAction.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- getActivity().startActivity(
- new Intent(Intent.ACTION_VIEW, message.actionUri));
- }
- });
- } else {
- mStatusMessageAction.setVisibility(View.GONE);
- }
- }
- }
-
- @Override
- public void onPause() {
- super.onPause();
- // Kill the requests thread
- mAdapter.stopRequestProcessing();
- }
-
- @Override
- public void onStop() {
- super.onStop();
- updateOnExit();
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- mAdapter.stopRequestProcessing();
- mAdapter.changeCursor(null);
- getActivity().getContentResolver().unregisterContentObserver(mCallLogObserver);
- getActivity().getContentResolver().unregisterContentObserver(mContactsObserver);
- unregisterPhoneCallReceiver();
- }
-
- @Override
- public void fetchCalls() {
- mCallLogQueryHandler.fetchCalls(mCallTypeFilter);
- }
-
- public void startCallsQuery() {
- mAdapter.setLoading(true);
- mCallLogQueryHandler.fetchCalls(mCallTypeFilter);
- if (mShowingVoicemailOnly) {
- mShowingVoicemailOnly = false;
- getActivity().invalidateOptionsMenu();
- }
- }
-
- private void startVoicemailStatusQuery() {
- mCallLogQueryHandler.fetchVoicemailStatus();
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- super.onCreateOptionsMenu(menu, inflater);
- inflater.inflate(R.menu.call_log_options, menu);
- }
-
- @Override
- public void onPrepareOptionsMenu(Menu menu) {
- final MenuItem itemDeleteAll = menu.findItem(R.id.delete_all);
- // Check if all the menu items are inflated correctly. As a shortcut, we assume all
- // 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);
- }
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.delete_all:
- ClearCallLogDialog.show(getFragmentManager());
- return true;
-
- case R.id.show_outgoing_only:
- // We only need the phone call receiver when there is an active call type filter.
- // Not many people may use the filters so don't register the receiver until now .
- registerPhoneCallReceiver();
- mCallLogQueryHandler.fetchCalls(Calls.OUTGOING_TYPE);
- updateFilterTypeAndHeader(Calls.OUTGOING_TYPE);
- return true;
-
- case R.id.show_incoming_only:
- registerPhoneCallReceiver();
- mCallLogQueryHandler.fetchCalls(Calls.INCOMING_TYPE);
- updateFilterTypeAndHeader(Calls.INCOMING_TYPE);
- return true;
-
- case R.id.show_missed_only:
- registerPhoneCallReceiver();
- mCallLogQueryHandler.fetchCalls(Calls.MISSED_TYPE);
- updateFilterTypeAndHeader(Calls.MISSED_TYPE);
- return true;
-
- case R.id.show_voicemails_only:
- registerPhoneCallReceiver();
- mCallLogQueryHandler.fetchCalls(Calls.VOICEMAIL_TYPE);
- updateFilterTypeAndHeader(Calls.VOICEMAIL_TYPE);
- mShowingVoicemailOnly = true;
- return true;
-
- case R.id.show_all_calls:
- // Filter is being turned off, receiver no longer needed.
- unregisterPhoneCallReceiver();
- mCallLogQueryHandler.fetchCalls(CallLogQueryHandler.CALL_TYPE_ALL);
- updateFilterTypeAndHeader(CallLogQueryHandler.CALL_TYPE_ALL);
- mShowingVoicemailOnly = false;
- return true;
-
- default:
- return false;
- }
- }
-
- private void updateFilterTypeAndHeader(int filterType) {
- mCallTypeFilter = filterType;
-
- switch (filterType) {
- 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) {
- // In touch mode you may often not have something selected, so
- // just call the first entry to make sure that [send] [send] calls the
- // most recent entry.
- position = 0;
- }
- final Cursor cursor = (Cursor)mAdapter.getItem(position);
- if (cursor != null) {
- String number = cursor.getString(CallLogQuery.NUMBER);
- if (TextUtils.isEmpty(number)
- || number.equals(CallerInfo.UNKNOWN_NUMBER)
- || number.equals(CallerInfo.PRIVATE_NUMBER)
- || number.equals(CallerInfo.PAYPHONE_NUMBER)) {
- // This number can't be called, do nothing
- return;
- }
- Intent intent;
- // If "number" is really a SIP address, construct a sip: URI.
- if (PhoneNumberUtils.isUriNumber(number)) {
- intent = ContactsUtils.getCallIntent(
- Uri.fromParts(Constants.SCHEME_SIP, number, null));
- } else {
- // We're calling a regular PSTN phone number.
- // Construct a tel: URI, but do some other possible cleanup first.
- int callType = cursor.getInt(CallLogQuery.CALL_TYPE);
- if (!number.startsWith("+") &&
- (callType == Calls.INCOMING_TYPE
- || callType == Calls.MISSED_TYPE)) {
- // If the caller-id matches a contact with a better qualified number, use it
- String countryIso = cursor.getString(CallLogQuery.COUNTRY_ISO);
- number = mAdapter.getBetterNumberFromContacts(number, countryIso);
- }
- intent = ContactsUtils.getCallIntent(
- Uri.fromParts(Constants.SCHEME_TEL, number, null));
- }
- intent.setFlags(
- Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
- startActivity(intent);
- }
- }
-
- @VisibleForTesting
- CallLogAdapter getAdapter() {
- return mAdapter;
- }
-
- @Override
- public void setMenuVisibility(boolean menuVisible) {
- super.setMenuVisibility(menuVisible);
- if (mMenuVisible != menuVisible) {
- mMenuVisible = menuVisible;
- if (!menuVisible) {
- updateOnExit();
- } else if (isResumed()) {
- refreshData();
- }
- }
- }
-
- /** Requests updates to the data to be shown. */
- private void refreshData() {
- // Prevent unnecessary refresh.
- if (mRefreshDataRequired) {
- // Mark all entries in the contact info cache as out of date, so they will be looked up
- // again once being shown.
- mAdapter.invalidateCache();
- startCallsQuery();
- startVoicemailStatusQuery();
- updateOnEntry();
- mRefreshDataRequired = false;
- }
- }
-
- /** Removes the missed call notifications. */
- private void removeMissedCallNotifications() {
- try {
- ITelephony telephony =
- ITelephony.Stub.asInterface(ServiceManager.getService("phone"));
- if (telephony != null) {
- telephony.cancelMissedCallsNotification();
- } else {
- Log.w(TAG, "Telephony service is null, can't call " +
- "cancelMissedCallsNotification");
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to clear missed calls notification due to remote exception");
- }
- }
-
- /** Updates call data and notification state while leaving the call log tab. */
- private void updateOnExit() {
- updateOnTransition(false);
- }
-
- /** Updates call data and notification state while entering the call log tab. */
- private void updateOnEntry() {
- updateOnTransition(true);
- }
-
- private void updateOnTransition(boolean onEntry) {
- // We don't want to update any call data when keyguard is on because the user has likely not
- // seen the new calls yet.
- // This might be called before onCreate() and thus we need to check null explicitly.
- if (mKeyguardManager != null && !mKeyguardManager.inKeyguardRestrictedInputMode()) {
- // On either of the transitions we reset the new flag and update the notifications.
- // While exiting we additionally consume all missed calls (by marking them as read).
- // This will ensure that they no more appear in the "new" section when we return back.
- mCallLogQueryHandler.markNewCallsAsOld();
- if (!onEntry) {
- mCallLogQueryHandler.markMissedCallsAsRead();
- }
- removeMissedCallNotifications();
- updateVoicemailNotifications();
- }
- }
-
- private void updateVoicemailNotifications() {
- Intent serviceIntent = new Intent(getActivity(), CallLogNotificationsService.class);
- serviceIntent.setAction(CallLogNotificationsService.ACTION_UPDATE_NOTIFICATIONS);
- getActivity().startService(serviceIntent);
- }
-
- /**
- * Register a phone call filter to reset the call type when a phone call is place.
- */
- private void registerPhoneCallReceiver() {
- if (mPhoneStateListener != null) {
- return; // Already registered.
- }
- mTelephonyManager = (TelephonyManager) getActivity().getSystemService(
- Context.TELEPHONY_SERVICE);
- mPhoneStateListener = new PhoneStateListener() {
- @Override
- public void onCallStateChanged(int state, String incomingNumber) {
- if (state != TelephonyManager.CALL_STATE_OFFHOOK &&
- state != TelephonyManager.CALL_STATE_RINGING) {
- return;
- }
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- if (getActivity() == null || getActivity().isFinishing()) {
- return;
- }
- updateFilterTypeAndHeader(CallLogQueryHandler.CALL_TYPE_ALL);
- }
- });
- }
- };
- mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
- }
-
- /**
- * Un-registers the phone call receiver.
- */
- private void unregisterPhoneCallReceiver() {
- if (mPhoneStateListener != null) {
- mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
- mPhoneStateListener = null;
- }
- }
-}
diff --git a/src/com/android/contacts/calllog/CallLogGroupBuilder.java b/src/com/android/contacts/calllog/CallLogGroupBuilder.java
deleted file mode 100644
index 5c7d3ee..0000000
--- a/src/com/android/contacts/calllog/CallLogGroupBuilder.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-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>
- * This class is meant to be used in conjunction with {@link GroupingListAdapter}.
- */
-public class CallLogGroupBuilder {
- public interface GroupCreator {
- public void addGroup(int cursorPosition, int size, boolean expanded);
- }
-
- /** The object on which the groups are created. */
- private final GroupCreator mGroupCreator;
-
- public CallLogGroupBuilder(GroupCreator groupCreator) {
- mGroupCreator = groupCreator;
- }
-
- /**
- * Finds all groups of adjacent entries in the call log which should be grouped together and
- * calls {@link GroupCreator#addGroup(int, int, boolean)} on {@link #mGroupCreator} for each of
- * them.
- * <p>
- * For entries that are not grouped with others, we do not need to create a group of size one.
- * <p>
- * It assumes that the cursor will not change during its execution.
- *
- * @see GroupingListAdapter#addGroups(Cursor)
- */
- public void addGroups(Cursor cursor) {
- final int count = cursor.getCount();
- if (count == 0) {
- return;
- }
-
- int currentGroupSize = 1;
- cursor.moveToFirst();
- // The number of the first entry in the group.
- String firstNumber = cursor.getString(CallLogQuery.NUMBER);
- // This is the type of the first call in the group.
- int firstCallType = cursor.getInt(CallLogQuery.CALL_TYPE);
- while (cursor.moveToNext()) {
- // The number of the current row in the cursor.
- final String currentNumber = cursor.getString(CallLogQuery.NUMBER);
- final int callType = cursor.getInt(CallLogQuery.CALL_TYPE);
- final boolean sameNumber = equalNumbers(firstNumber, currentNumber);
- final boolean shouldGroup;
-
- if (CallLogQuery.isSectionHeader(cursor)) {
- // Cannot group headers.
- shouldGroup = false;
- } else if (!sameNumber) {
- // Should only group with calls from the same number.
- shouldGroup = false;
- } else if (firstCallType == Calls.VOICEMAIL_TYPE) {
- // never group voicemail.
- shouldGroup = false;
- } else {
- // Incoming, outgoing, and missed calls group together.
- shouldGroup = (callType == Calls.INCOMING_TYPE || callType == Calls.OUTGOING_TYPE ||
- callType == Calls.MISSED_TYPE);
- }
-
- if (shouldGroup) {
- // Increment the size of the group to include the current call, but do not create
- // the group until we find a call that does not match.
- currentGroupSize++;
- } else {
- // Create a group for the previous set of calls, excluding the current one, but do
- // not create a group for a single call.
- if (currentGroupSize > 1) {
- addGroup(cursor.getPosition() - currentGroupSize, currentGroupSize);
- }
- // Start a new group; it will include at least the current call.
- currentGroupSize = 1;
- // The current entry is now the first in the group.
- firstNumber = currentNumber;
- firstCallType = callType;
- }
- }
- // If the last set of calls at the end of the call log was itself a group, create it now.
- if (currentGroupSize > 1) {
- addGroup(count - currentGroupSize, currentGroupSize);
- }
- }
-
- /**
- * Creates a group of items in the cursor.
- * <p>
- * The group is always unexpanded.
- *
- * @see CallLogAdapter#addGroup(int, int, boolean)
- */
- private void addGroup(int cursorPosition, int size) {
- mGroupCreator.addGroup(cursorPosition, size, false);
- }
-
- @VisibleForTesting
- boolean equalNumbers(String number1, String number2) {
- if (PhoneNumberUtils.isUriNumber(number1) || PhoneNumberUtils.isUriNumber(number2)) {
- return compareSipAddresses(number1, number2);
- } else {
- return PhoneNumberUtils.compare(number1, number2);
- }
- }
-
- @VisibleForTesting
- boolean compareSipAddresses(String number1, String number2) {
- if (number1 == null || number2 == null) return number1 == number2;
-
- int index1 = number1.indexOf('@');
- final String userinfo1;
- final String rest1;
- if (index1 != -1) {
- userinfo1 = number1.substring(0, index1);
- rest1 = number1.substring(index1);
- } else {
- userinfo1 = number1;
- rest1 = "";
- }
-
- int index2 = number2.indexOf('@');
- final String userinfo2;
- final String rest2;
- if (index2 != -1) {
- userinfo2 = number2.substring(0, index2);
- rest2 = number2.substring(index2);
- } else {
- userinfo2 = number2;
- rest2 = "";
- }
-
- return userinfo1.equals(userinfo2) && rest1.equalsIgnoreCase(rest2);
- }
-}
diff --git a/src/com/android/contacts/calllog/CallLogListItemHelper.java b/src/com/android/contacts/calllog/CallLogListItemHelper.java
deleted file mode 100644
index eb30c81..0000000
--- a/src/com/android/contacts/calllog/CallLogListItemHelper.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-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.
- */
-/*package*/ class CallLogListItemHelper {
- /** Helper for populating the details of a phone call. */
- private final PhoneCallDetailsHelper mPhoneCallDetailsHelper;
- /** Helper for handling phone numbers. */
- private final PhoneNumberHelper mPhoneNumberHelper;
- /** Resources to look up strings. */
- private final Resources mResources;
-
- /**
- * Creates a new helper instance.
- *
- * @param phoneCallDetailsHelper used to set the details of a phone call
- * @param phoneNumberHelper used to process phone number
- */
- public CallLogListItemHelper(PhoneCallDetailsHelper phoneCallDetailsHelper,
- PhoneNumberHelper phoneNumberHelper, Resources resources) {
- mPhoneCallDetailsHelper = phoneCallDetailsHelper;
- mPhoneNumberHelper = phoneNumberHelper;
- mResources = resources;
- }
-
- /**
- * Sets the name, label, and number for a contact.
- *
- * @param views the views to populate
- * @param details the details of a phone call needed to fill in the data
- * @param isHighlighted whether to use the highlight text for the call
- */
- public void setPhoneCallDetails(CallLogListItemViews views, PhoneCallDetails details,
- boolean isHighlighted) {
- mPhoneCallDetailsHelper.setPhoneCallDetails(views.phoneCallDetailsViews, details,
- isHighlighted);
- boolean canCall = mPhoneNumberHelper.canPlaceCallsTo(details.number);
- boolean canPlay = details.callTypes[0] == Calls.VOICEMAIL_TYPE;
-
- if (canPlay) {
- // Playback action takes preference.
- configurePlaySecondaryAction(views, isHighlighted);
- views.dividerView.setVisibility(View.VISIBLE);
- } else if (canCall) {
- // Call is the secondary action.
- configureCallSecondaryAction(views, details);
- views.dividerView.setVisibility(View.VISIBLE);
- } else {
- // No action available.
- views.secondaryActionView.setVisibility(View.GONE);
- views.dividerView.setVisibility(View.GONE);
- }
- }
-
- /** Sets the secondary action to correspond to the call button. */
- private void configureCallSecondaryAction(CallLogListItemViews views,
- PhoneCallDetails details) {
- views.secondaryActionView.setVisibility(View.VISIBLE);
- views.secondaryActionView.setImageResource(R.drawable.ic_ab_dialer_holo_dark);
- views.secondaryActionView.setContentDescription(getCallActionDescription(details));
- }
-
- /** Returns the description used by the call action for this phone call. */
- private CharSequence getCallActionDescription(PhoneCallDetails details) {
- final CharSequence recipient;
- if (!TextUtils.isEmpty(details.name)) {
- recipient = details.name;
- } else {
- recipient = mPhoneNumberHelper.getDisplayNumber(
- details.number, details.formattedNumber);
- }
- return mResources.getString(R.string.description_call, recipient);
- }
-
- /** Sets the secondary action to correspond to the play button. */
- private void configurePlaySecondaryAction(CallLogListItemViews views, boolean isHighlighted) {
- views.secondaryActionView.setVisibility(View.VISIBLE);
- views.secondaryActionView.setImageResource(
- isHighlighted ? R.drawable.ic_play_active_holo_dark : R.drawable.ic_play_holo_dark);
- views.secondaryActionView.setContentDescription(
- mResources.getString(R.string.description_call_log_play_button));
- }
-}
diff --git a/src/com/android/contacts/calllog/CallLogListItemView.java b/src/com/android/contacts/calllog/CallLogListItemView.java
deleted file mode 100644
index 584a7f2..0000000
--- a/src/com/android/contacts/calllog/CallLogListItemView.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.LinearLayout;
-
-/**
- * An entry in the call log.
- */
-public class CallLogListItemView extends LinearLayout {
- public CallLogListItemView(Context context) {
- super(context);
- }
-
- public CallLogListItemView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public CallLogListItemView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
-
- @Override
- public void requestLayout() {
- // We will assume that once measured this will not need to resize
- // itself, so there is no need to pass the layout request to the parent
- // view (ListView).
- forceLayout();
- }
-}
diff --git a/src/com/android/contacts/calllog/CallLogListItemViews.java b/src/com/android/contacts/calllog/CallLogListItemViews.java
deleted file mode 100644
index 348cd2f..0000000
--- a/src/com/android/contacts/calllog/CallLogListItemViews.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-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.
- */
-public final class CallLogListItemViews {
- /** The quick contact badge for the contact. */
- public final QuickContactBadge quickContactView;
- /** The primary action view of the entry. */
- public final View primaryActionView;
- /** The secondary action button on the entry. */
- public final ImageView secondaryActionView;
- /** The divider between the primary and secondary actions. */
- public final View dividerView;
- /** The details of the phone call. */
- public final PhoneCallDetailsViews phoneCallDetailsViews;
- /** The text of the header of a section. */
- public final TextView listHeaderTextView;
- /** The divider to be shown below items. */
- public final View bottomDivider;
-
- private CallLogListItemViews(QuickContactBadge quickContactView, View primaryActionView,
- ImageView secondaryActionView, View dividerView,
- PhoneCallDetailsViews phoneCallDetailsViews,
- TextView listHeaderTextView, View bottomDivider) {
- this.quickContactView = quickContactView;
- this.primaryActionView = primaryActionView;
- this.secondaryActionView = secondaryActionView;
- this.dividerView = dividerView;
- this.phoneCallDetailsViews = phoneCallDetailsViews;
- this.listHeaderTextView = listHeaderTextView;
- this.bottomDivider = bottomDivider;
- }
-
- public static CallLogListItemViews fromView(View view) {
- return new CallLogListItemViews(
- (QuickContactBadge) view.findViewById(R.id.quick_contact_photo),
- view.findViewById(R.id.primary_action_view),
- (ImageView) view.findViewById(R.id.secondary_action_icon),
- view.findViewById(R.id.divider),
- PhoneCallDetailsViews.fromView(view),
- (TextView) view.findViewById(R.id.call_log_header),
- view.findViewById(R.id.call_log_divider));
- }
-
- @NeededForTesting
- public static CallLogListItemViews createForTest(Context context) {
- return new CallLogListItemViews(
- new QuickContactBadge(context),
- new View(context),
- new ImageView(context),
- new View(context),
- PhoneCallDetailsViews.createForTest(context),
- new TextView(context),
- new View(context));
- }
-}
diff --git a/src/com/android/contacts/calllog/CallLogNotificationsService.java b/src/com/android/contacts/calllog/CallLogNotificationsService.java
deleted file mode 100644
index be540ad..0000000
--- a/src/com/android/contacts/calllog/CallLogNotificationsService.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-import android.app.IntentService;
-import android.content.Intent;
-import android.net.Uri;
-import android.util.Log;
-
-/**
- * Provides operations for managing notifications.
- * <p>
- * It handles the following actions:
- * <ul>
- * <li>{@link #ACTION_MARK_NEW_VOICEMAILS_AS_OLD}: marks all the new voicemails in the call log as
- * old; this is called when a notification is dismissed.</li>
- * <li>{@link #ACTION_UPDATE_NOTIFICATIONS}: updates the content of the new items notification; it
- * may include an optional extra {@link #EXTRA_NEW_VOICEMAIL_URI}, containing the URI of the new
- * voicemail that has triggered this update (if any).</li>
- * </ul>
- */
-public class CallLogNotificationsService extends IntentService {
- private static final String TAG = "CallLogNotificationsService";
-
- /** Action to mark all the new voicemails as old. */
- public static final String ACTION_MARK_NEW_VOICEMAILS_AS_OLD =
- "com.android.contacts.calllog.ACTION_MARK_NEW_VOICEMAILS_AS_OLD";
-
- /**
- * Action to update the notifications.
- * <p>
- * May include an optional extra {@link #EXTRA_NEW_VOICEMAIL_URI}.
- */
- public static final String ACTION_UPDATE_NOTIFICATIONS =
- "com.android.contacts.calllog.UPDATE_NOTIFICATIONS";
-
- /**
- * Extra to included with {@link #ACTION_UPDATE_NOTIFICATIONS} to identify the new voicemail
- * that triggered an update.
- * <p>
- * It must be a {@link Uri}.
- */
- public static final String EXTRA_NEW_VOICEMAIL_URI = "NEW_VOICEMAIL_URI";
-
- private CallLogQueryHandler mCallLogQueryHandler;
-
- public CallLogNotificationsService() {
- super("CallLogNotificationsService");
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
- mCallLogQueryHandler = new CallLogQueryHandler(getContentResolver(), null /*listener*/);
- }
-
- @Override
- protected void onHandleIntent(Intent intent) {
- if (ACTION_MARK_NEW_VOICEMAILS_AS_OLD.equals(intent.getAction())) {
- mCallLogQueryHandler.markNewVoicemailsAsOld();
- } else if (ACTION_UPDATE_NOTIFICATIONS.equals(intent.getAction())) {
- Uri voicemailUri = (Uri) intent.getParcelableExtra(EXTRA_NEW_VOICEMAIL_URI);
- DefaultVoicemailNotifier.getInstance(this).updateNotification(voicemailUri);
- } else {
- Log.d(TAG, "onHandleIntent: could not handle: " + intent);
- }
- }
-}
diff --git a/src/com/android/contacts/calllog/CallLogQuery.java b/src/com/android/contacts/calllog/CallLogQuery.java
deleted file mode 100644
index 90017b7..0000000
--- a/src/com/android/contacts/calllog/CallLogQuery.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-import android.database.Cursor;
-import android.provider.CallLog.Calls;
-
-/**
- * The query for the call log table.
- */
-public final class CallLogQuery {
- // If you alter this, you must also alter the method that inserts a fake row to the headers
- // in the CallLogQueryHandler class called createHeaderCursorFor().
- public static final String[] _PROJECTION = new String[] {
- Calls._ID, // 0
- Calls.NUMBER, // 1
- Calls.DATE, // 2
- Calls.DURATION, // 3
- Calls.TYPE, // 4
- Calls.COUNTRY_ISO, // 5
- Calls.VOICEMAIL_URI, // 6
- Calls.GEOCODED_LOCATION, // 7
- Calls.CACHED_NAME, // 8
- Calls.CACHED_NUMBER_TYPE, // 9
- Calls.CACHED_NUMBER_LABEL, // 10
- Calls.CACHED_LOOKUP_URI, // 11
- Calls.CACHED_MATCHED_NUMBER, // 12
- Calls.CACHED_NORMALIZED_NUMBER, // 13
- Calls.CACHED_PHOTO_ID, // 14
- Calls.CACHED_FORMATTED_NUMBER, // 15
- Calls.IS_READ, // 16
- };
-
- public static final int ID = 0;
- public static final int NUMBER = 1;
- public static final int DATE = 2;
- public static final int DURATION = 3;
- public static final int CALL_TYPE = 4;
- public static final int COUNTRY_ISO = 5;
- public static final int VOICEMAIL_URI = 6;
- public static final int GEOCODED_LOCATION = 7;
- public static final int CACHED_NAME = 8;
- public static final int CACHED_NUMBER_TYPE = 9;
- public static final int CACHED_NUMBER_LABEL = 10;
- public static final int CACHED_LOOKUP_URI = 11;
- public static final int CACHED_MATCHED_NUMBER = 12;
- public static final int CACHED_NORMALIZED_NUMBER = 13;
- public static final int CACHED_PHOTO_ID = 14;
- public static final int CACHED_FORMATTED_NUMBER = 15;
- public static final int IS_READ = 16;
- /** The index of the synthetic "section" column in the extended projection. */
- public static final int SECTION = 17;
-
- /**
- * The name of the synthetic "section" column.
- * <p>
- * This column identifies whether a row is a header or an actual item, and whether it is
- * part of the new or old calls.
- */
- public static final String SECTION_NAME = "section";
- /** The value of the "section" column for the header of the new section. */
- public static final int SECTION_NEW_HEADER = 0;
- /** The value of the "section" column for the items of the new section. */
- public static final int SECTION_NEW_ITEM = 1;
- /** The value of the "section" column for the header of the old section. */
- public static final int SECTION_OLD_HEADER = 2;
- /** The value of the "section" column for the items of the old section. */
- public static final int SECTION_OLD_ITEM = 3;
-
- /** The call log projection including the section name. */
- public static final String[] EXTENDED_PROJECTION;
- static {
- EXTENDED_PROJECTION = new String[_PROJECTION.length + 1];
- System.arraycopy(_PROJECTION, 0, EXTENDED_PROJECTION, 0, _PROJECTION.length);
- EXTENDED_PROJECTION[_PROJECTION.length] = SECTION_NAME;
- }
-
- public static boolean isSectionHeader(Cursor cursor) {
- int section = cursor.getInt(CallLogQuery.SECTION);
- return section == CallLogQuery.SECTION_NEW_HEADER
- || section == CallLogQuery.SECTION_OLD_HEADER;
- }
-
- public static boolean isNewSection(Cursor cursor) {
- int section = cursor.getInt(CallLogQuery.SECTION);
- return section == CallLogQuery.SECTION_NEW_ITEM
- || section == CallLogQuery.SECTION_NEW_HEADER;
- }
-}
\ No newline at end of file
diff --git a/src/com/android/contacts/calllog/CallLogQueryHandler.java b/src/com/android/contacts/calllog/CallLogQueryHandler.java
deleted file mode 100644
index a6382b6..0000000
--- a/src/com/android/contacts/calllog/CallLogQueryHandler.java
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-import android.content.AsyncQueryHandler;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.database.MergeCursor;
-import android.database.sqlite.SQLiteDatabaseCorruptException;
-import android.database.sqlite.SQLiteDiskIOException;
-import android.database.sqlite.SQLiteException;
-import android.database.sqlite.SQLiteFullException;
-import android.net.Uri;
-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;
-
-import javax.annotation.concurrent.GuardedBy;
-
-/** Handles asynchronous queries to the call log. */
-/*package*/ class CallLogQueryHandler extends AsyncQueryHandler {
- private static final String[] EMPTY_STRING_ARRAY = new String[0];
-
- private static final String TAG = "CallLogQueryHandler";
- private static final int NUM_LOGS_TO_DISPLAY = 1000;
-
- /** The token for the query to fetch the new entries from the call log. */
- private static final int QUERY_NEW_CALLS_TOKEN = 53;
- /** The token for the query to fetch the old entries from the call log. */
- private static final int QUERY_OLD_CALLS_TOKEN = 54;
- /** The token for the query to mark all missed calls as old after seeing the call log. */
- private static final int UPDATE_MARK_AS_OLD_TOKEN = 55;
- /** The token for the query to mark all new voicemails as old. */
- private static final int UPDATE_MARK_VOICEMAILS_AS_OLD_TOKEN = 56;
- /** The token for the query to mark all missed calls as read after seeing the call log. */
- private static final int UPDATE_MARK_MISSED_CALL_AS_READ_TOKEN = 57;
- /** The token for the query to fetch voicemail status messages. */
- 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.
- */
- private static final long NEW_SECTION_TIME_WINDOW = TimeUnit.DAYS.toMillis(7);
-
- private final WeakReference<Listener> mListener;
-
- /** The cursor containing the new calls, or null if they have not yet been fetched. */
- @GuardedBy("this") private Cursor mNewCallsCursor;
- /** The cursor containing the old calls, or null if they have not yet been fetched. */
- @GuardedBy("this") private Cursor mOldCallsCursor;
- /**
- * The identifier of the latest calls request.
- * <p>
- * A request for the list of calls requires two queries and hence the two cursor
- * {@link #mNewCallsCursor} and {@link #mOldCallsCursor} above, corresponding to
- * {@link #QUERY_NEW_CALLS_TOKEN} and {@link #QUERY_OLD_CALLS_TOKEN}.
- * <p>
- * When a new request is about to be started, existing cursors are closed. However, it is
- * possible that one of the queries completes after the new request has started. This means that
- * we might merge two cursors that do not correspond to the same request. Moreover, this may
- * lead to a resource leak if the same query completes and we override the cursor without
- * closing it first.
- * <p>
- * To make sure we only join two cursors from the same request, we use this variable to store
- * the request id of the latest request and make sure we only process cursors corresponding to
- * the this request.
- */
- @GuardedBy("this") private int mCallsRequestId;
-
- /**
- * Simple handler that wraps background calls to catch
- * {@link SQLiteException}, such as when the disk is full.
- */
- protected class CatchingWorkerHandler extends AsyncQueryHandler.WorkerHandler {
- public CatchingWorkerHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- try {
- // Perform same query while catching any exceptions
- super.handleMessage(msg);
- } catch (SQLiteDiskIOException e) {
- Log.w(TAG, "Exception on background worker thread", e);
- } catch (SQLiteFullException e) {
- Log.w(TAG, "Exception on background worker thread", e);
- } catch (SQLiteDatabaseCorruptException e) {
- Log.w(TAG, "Exception on background worker thread", e);
- }
- }
- }
-
- @Override
- protected Handler createHandler(Looper looper) {
- // Provide our special handler that catches exceptions
- return new CatchingWorkerHandler(looper);
- }
-
- public CallLogQueryHandler(ContentResolver contentResolver, Listener listener) {
- super(contentResolver);
- mListener = new WeakReference<Listener>(listener);
- }
-
- /** Creates a cursor that contains a single row and maps the section to the given value. */
- private Cursor createHeaderCursorFor(int section) {
- MatrixCursor matrixCursor =
- new MatrixCursor(CallLogQuery.EXTENDED_PROJECTION);
- // The values in this row correspond to default values for _PROJECTION from CallLogQuery
- // plus the section value.
- matrixCursor.addRow(new Object[]{
- 0L, "", 0L, 0L, 0, "", "", "", null, 0, null, null, null, null, 0L, null, 0,
- section
- });
- return matrixCursor;
- }
-
- /** Returns a cursor for the old calls header. */
- private Cursor createOldCallsHeaderCursor() {
- return createHeaderCursorFor(CallLogQuery.SECTION_OLD_HEADER);
- }
-
- /** Returns a cursor for the new calls header. */
- private Cursor createNewCallsHeaderCursor() {
- return createHeaderCursorFor(CallLogQuery.SECTION_NEW_HEADER);
- }
-
- /**
- * 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 fetchCalls(int callType) {
- cancelFetch();
- int requestId = newCallsRequest();
- fetchCalls(QUERY_NEW_CALLS_TOKEN, requestId, true /*isNew*/, callType);
- fetchCalls(QUERY_OLD_CALLS_TOKEN, requestId, false /*isNew*/, callType);
- }
-
- 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, 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".
- String selection = String.format("%s IS NOT NULL AND %s = 0 AND %s > ?",
- Calls.IS_READ, Calls.IS_READ, Calls.DATE);
- List<String> selectionArgs = Lists.newArrayList(
- Long.toString(System.currentTimeMillis() - NEW_SECTION_TIME_WINDOW));
- if (!isNew) {
- // Negate the query.
- selection = String.format("NOT (%s)", selection);
- }
- 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(callType));
- }
- Uri uri = Calls.CONTENT_URI_WITH_VOICEMAIL.buildUpon()
- .appendQueryParameter(Calls.LIMIT_PARAM_KEY, Integer.toString(NUM_LOGS_TO_DISPLAY))
- .build();
- startQuery(token, requestId, uri,
- CallLogQuery._PROJECTION, selection, selectionArgs.toArray(EMPTY_STRING_ARRAY),
- Calls.DEFAULT_SORT_ORDER);
- }
-
- /** Cancel any pending fetch request. */
- private void cancelFetch() {
- cancelOperation(QUERY_NEW_CALLS_TOKEN);
- cancelOperation(QUERY_OLD_CALLS_TOKEN);
- }
-
- /** Updates all new calls to mark them as old. */
- public void markNewCallsAsOld() {
- // Mark all "new" calls as not new anymore.
- StringBuilder where = new StringBuilder();
- where.append(Calls.NEW);
- where.append(" = 1");
-
- ContentValues values = new ContentValues(1);
- values.put(Calls.NEW, "0");
-
- startUpdate(UPDATE_MARK_AS_OLD_TOKEN, null, Calls.CONTENT_URI_WITH_VOICEMAIL,
- values, where.toString(), null);
- }
-
- /** Updates all new voicemails to mark them as old. */
- public void markNewVoicemailsAsOld() {
- // Mark all "new" voicemails as not new anymore.
- StringBuilder where = new StringBuilder();
- where.append(Calls.NEW);
- where.append(" = 1 AND ");
- where.append(Calls.TYPE);
- where.append(" = ?");
-
- ContentValues values = new ContentValues(1);
- values.put(Calls.NEW, "0");
-
- startUpdate(UPDATE_MARK_VOICEMAILS_AS_OLD_TOKEN, null, Calls.CONTENT_URI_WITH_VOICEMAIL,
- values, where.toString(), new String[]{ Integer.toString(Calls.VOICEMAIL_TYPE) });
- }
-
- /** Updates all missed calls to mark them as read. */
- public void markMissedCallsAsRead() {
- // Mark all "new" calls as not new anymore.
- StringBuilder where = new StringBuilder();
- where.append(Calls.IS_READ).append(" = 0");
- where.append(" AND ");
- where.append(Calls.TYPE).append(" = ").append(Calls.MISSED_TYPE);
-
- ContentValues values = new ContentValues(1);
- values.put(Calls.IS_READ, "1");
-
- startUpdate(UPDATE_MARK_MISSED_CALL_AS_READ_TOKEN, null, Calls.CONTENT_URI, values,
- where.toString(), null);
- }
-
- /**
- * Start a new request and return its id. The request id will be used as the cookie for the
- * background request.
- * <p>
- * Closes any open cursor that has not yet been sent to the requester.
- */
- private synchronized int newCallsRequest() {
- MoreCloseables.closeQuietly(mNewCallsCursor);
- MoreCloseables.closeQuietly(mOldCallsCursor);
- mNewCallsCursor = null;
- mOldCallsCursor = null;
- return ++mCallsRequestId;
- }
-
- @Override
- protected synchronized void onQueryComplete(int token, Object cookie, Cursor cursor) {
- if (token == QUERY_NEW_CALLS_TOKEN) {
- int requestId = ((Integer) cookie).intValue();
- if (requestId != mCallsRequestId) {
- // Ignore this query since it does not correspond to the latest request.
- return;
- }
-
- // Store the returned cursor.
- MoreCloseables.closeQuietly(mNewCallsCursor);
- mNewCallsCursor = new ExtendedCursor(
- cursor, CallLogQuery.SECTION_NAME, CallLogQuery.SECTION_NEW_ITEM);
- } else if (token == QUERY_OLD_CALLS_TOKEN) {
- int requestId = ((Integer) cookie).intValue();
- if (requestId != mCallsRequestId) {
- // Ignore this query since it does not correspond to the latest request.
- return;
- }
-
- // Store the returned cursor.
- MoreCloseables.closeQuietly(mOldCallsCursor);
- mOldCallsCursor = new ExtendedCursor(
- cursor, CallLogQuery.SECTION_NAME, CallLogQuery.SECTION_OLD_ITEM);
- } else if (token == QUERY_VOICEMAIL_STATUS_TOKEN) {
- updateVoicemailStatus(cursor);
- return;
- } else {
- Log.w(TAG, "Unknown query completed: ignoring: " + token);
- return;
- }
-
- if (mNewCallsCursor != null && mOldCallsCursor != null) {
- updateAdapterData(createMergedCursor());
- }
- }
-
- /** Creates the merged cursor representing the data to show in the call log. */
- @GuardedBy("this")
- private Cursor createMergedCursor() {
- try {
- final boolean hasNewCalls = mNewCallsCursor.getCount() != 0;
- final boolean hasOldCalls = mOldCallsCursor.getCount() != 0;
-
- if (!hasNewCalls) {
- // Return only the old calls, without the header.
- MoreCloseables.closeQuietly(mNewCallsCursor);
- return mOldCallsCursor;
- }
-
- if (!hasOldCalls) {
- // Return only the new calls.
- MoreCloseables.closeQuietly(mOldCallsCursor);
- return new MergeCursor(
- new Cursor[]{ createNewCallsHeaderCursor(), mNewCallsCursor });
- }
-
- return new MergeCursor(new Cursor[]{
- createNewCallsHeaderCursor(), mNewCallsCursor,
- createOldCallsHeaderCursor(), mOldCallsCursor});
- } finally {
- // Any cursor still open is now owned, directly or indirectly, by the caller.
- mNewCallsCursor = null;
- mOldCallsCursor = null;
- }
- }
-
- /**
- * Updates the adapter in the call log fragment to show the new cursor data.
- */
- private void updateAdapterData(Cursor combinedCursor) {
- final Listener listener = mListener.get();
- if (listener != null) {
- listener.onCallsFetched(combinedCursor);
- }
- }
-
- private void updateVoicemailStatus(Cursor statusCursor) {
- final Listener listener = mListener.get();
- if (listener != null) {
- listener.onVoicemailStatusFetched(statusCursor);
- }
- }
-
- /** Listener to completion of various queries. */
- public interface Listener {
- /** Called when {@link CallLogQueryHandler#fetchVoicemailStatus()} completes. */
- void onVoicemailStatusFetched(Cursor statusCursor);
-
- /**
- * Called when {@link CallLogQueryHandler#fetchCalls(int)}complete.
- */
- void onCallsFetched(Cursor combinedCursor);
- }
-}
diff --git a/src/com/android/contacts/calllog/CallLogReceiver.java b/src/com/android/contacts/calllog/CallLogReceiver.java
deleted file mode 100644
index 14bfa64..0000000
--- a/src/com/android/contacts/calllog/CallLogReceiver.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.contacts.calllog;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.provider.VoicemailContract;
-import android.util.Log;
-
-/**
- * Receiver for call log events.
- * <p>
- * It is currently used to handle {@link VoicemailContract#ACTION_NEW_VOICEMAIL} and
- * {@link Intent#ACTION_BOOT_COMPLETED}.
- */
-public class CallLogReceiver extends BroadcastReceiver {
- private static final String TAG = "CallLogReceiver";
-
- @Override
- public void onReceive(Context context, Intent intent) {
- if (VoicemailContract.ACTION_NEW_VOICEMAIL.equals(intent.getAction())) {
- Intent serviceIntent = new Intent(context, CallLogNotificationsService.class);
- serviceIntent.setAction(CallLogNotificationsService.ACTION_UPDATE_NOTIFICATIONS);
- serviceIntent.putExtra(
- CallLogNotificationsService.EXTRA_NEW_VOICEMAIL_URI, intent.getData());
- context.startService(serviceIntent);
- } else if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
- Intent serviceIntent = new Intent(context, CallLogNotificationsService.class);
- serviceIntent.setAction(CallLogNotificationsService.ACTION_UPDATE_NOTIFICATIONS);
- context.startService(serviceIntent);
- } else {
- Log.w(TAG, "onReceive: could not handle: " + intent);
- }
- }
-}
diff --git a/src/com/android/contacts/calllog/CallTypeHelper.java b/src/com/android/contacts/calllog/CallTypeHelper.java
deleted file mode 100644
index 2ca0db0..0000000
--- a/src/com/android/contacts/calllog/CallTypeHelper.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-import android.content.res.Resources;
-import android.provider.CallLog.Calls;
-
-import com.android.contacts.R;
-
-/**
- * Helper class to perform operations related to call types.
- */
-public class CallTypeHelper {
- /** Name used to identify incoming calls. */
- private final CharSequence mIncomingName;
- /** Name used to identify outgoing calls. */
- private final CharSequence mOutgoingName;
- /** Name used to identify missed calls. */
- private final CharSequence mMissedName;
- /** Name used to identify voicemail calls. */
- private final CharSequence mVoicemailName;
- /** Color used to identify new missed calls. */
- private final int mNewMissedColor;
- /** Color used to identify new voicemail calls. */
- private final int mNewVoicemailColor;
-
- public CallTypeHelper(Resources resources) {
- // Cache these values so that we do not need to look them up each time.
- mIncomingName = resources.getString(R.string.type_incoming);
- mOutgoingName = resources.getString(R.string.type_outgoing);
- mMissedName = resources.getString(R.string.type_missed);
- mVoicemailName = resources.getString(R.string.type_voicemail);
- mNewMissedColor = resources.getColor(R.color.call_log_missed_call_highlight_color);
- mNewVoicemailColor = resources.getColor(R.color.call_log_voicemail_highlight_color);
- }
-
- /** Returns the text used to represent the given call type. */
- public CharSequence getCallTypeText(int callType) {
- switch (callType) {
- case Calls.INCOMING_TYPE:
- return mIncomingName;
-
- case Calls.OUTGOING_TYPE:
- return mOutgoingName;
-
- case Calls.MISSED_TYPE:
- return mMissedName;
-
- case Calls.VOICEMAIL_TYPE:
- return mVoicemailName;
-
- default:
- throw new IllegalArgumentException("invalid call type: " + callType);
- }
- }
-
- /** Returns the color used to highlight the given call type, null if not highlight is needed. */
- public Integer getHighlightedColor(int callType) {
- switch (callType) {
- case Calls.INCOMING_TYPE:
- // New incoming calls are not highlighted.
- return null;
-
- case Calls.OUTGOING_TYPE:
- // New outgoing calls are not highlighted.
- return null;
-
- case Calls.MISSED_TYPE:
- return mNewMissedColor;
-
- case Calls.VOICEMAIL_TYPE:
- return mNewVoicemailColor;
-
- default:
- throw new IllegalArgumentException("invalid call type: " + callType);
- }
- }
-}
diff --git a/src/com/android/contacts/calllog/CallTypeIconsView.java b/src/com/android/contacts/calllog/CallTypeIconsView.java
deleted file mode 100644
index 384b597..0000000
--- a/src/com/android/contacts/calllog/CallTypeIconsView.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.provider.CallLog.Calls;
-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;
-
-/**
- * View that draws one or more symbols for different types of calls (missed calls, outgoing etc).
- * The symbols are set up horizontally. As this view doesn't create subviews, it is better suited
- * for ListView-recycling that a regular LinearLayout using ImageViews.
- */
-public class CallTypeIconsView extends View {
- private List<Integer> mCallTypes = Lists.newArrayListWithCapacity(3);
- private Resources mResources;
- private int mWidth;
- private int mHeight;
-
- public CallTypeIconsView(Context context) {
- this(context, null);
- }
-
- public CallTypeIconsView(Context context, AttributeSet attrs) {
- super(context, attrs);
- mResources = new Resources(context);
- }
-
- public void clear() {
- mCallTypes.clear();
- mWidth = 0;
- mHeight = 0;
- invalidate();
- }
-
- public void add(int callType) {
- mCallTypes.add(callType);
-
- final Drawable drawable = getCallTypeDrawable(callType);
- mWidth += drawable.getIntrinsicWidth() + mResources.iconMargin;
- mHeight = Math.max(mHeight, drawable.getIntrinsicHeight());
- invalidate();
- }
-
- @NeededForTesting
- public int getCount() {
- return mCallTypes.size();
- }
-
- @NeededForTesting
- public int getCallType(int index) {
- return mCallTypes.get(index);
- }
-
- private Drawable getCallTypeDrawable(int callType) {
- switch (callType) {
- case Calls.INCOMING_TYPE:
- return mResources.incoming;
- case Calls.OUTGOING_TYPE:
- return mResources.outgoing;
- case Calls.MISSED_TYPE:
- return mResources.missed;
- case Calls.VOICEMAIL_TYPE:
- return mResources.voicemail;
- default:
- throw new IllegalArgumentException("invalid call type: " + callType);
- }
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- setMeasuredDimension(mWidth, mHeight);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- int left = 0;
- for (Integer callType : mCallTypes) {
- final Drawable drawable = getCallTypeDrawable(callType);
- final int right = left + drawable.getIntrinsicWidth();
- drawable.setBounds(left, 0, right, drawable.getIntrinsicHeight());
- drawable.draw(canvas);
- left = right + mResources.iconMargin;
- }
- }
-
- private static class Resources {
- public final Drawable incoming;
- public final Drawable outgoing;
- public final Drawable missed;
- public final Drawable voicemail;
- public final int iconMargin;
-
- public Resources(Context context) {
- final android.content.res.Resources r = context.getResources();
- incoming = r.getDrawable(R.drawable.ic_call_incoming_holo_dark);
- outgoing = r.getDrawable(R.drawable.ic_call_outgoing_holo_dark);
- missed = r.getDrawable(R.drawable.ic_call_missed_holo_dark);
- voicemail = r.getDrawable(R.drawable.ic_call_voicemail_holo_dark);
- iconMargin = r.getDimensionPixelSize(R.dimen.call_log_icon_margin);
- }
- }
-}
diff --git a/src/com/android/contacts/calllog/ClearCallLogDialog.java b/src/com/android/contacts/calllog/ClearCallLogDialog.java
deleted file mode 100644
index c4dbb7e..0000000
--- a/src/com/android/contacts/calllog/ClearCallLogDialog.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.contacts.calllog;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.app.FragmentManager;
-import android.app.ProgressDialog;
-import android.content.ContentResolver;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.os.AsyncTask;
-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
- */
-public class ClearCallLogDialog extends DialogFragment {
- /** Preferred way to show this dialog */
- public static void show(FragmentManager fragmentManager) {
- ClearCallLogDialog dialog = new ClearCallLogDialog();
- dialog.show(fragmentManager, "deleteCallLog");
- }
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final ContentResolver resolver = getActivity().getContentResolver();
- final OnClickListener okListener = new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- final ProgressDialog progressDialog = ProgressDialog.show(getActivity(),
- getString(R.string.clearCallLogProgress_title),
- "", true, false);
- final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... params) {
- resolver.delete(Calls.CONTENT_URI, null, null);
- return null;
- }
- @Override
- protected void onPostExecute(Void result) {
- progressDialog.dismiss();
- }
- };
- // TODO: Once we have the API, we should configure this ProgressDialog
- // to only show up after a certain time (e.g. 150ms)
- progressDialog.show();
- task.execute();
- }
- };
- return new AlertDialog.Builder(getActivity())
- .setTitle(R.string.clearCallLogConfirmation_title)
- .setIconAttribute(android.R.attr.alertDialogIcon)
- .setMessage(R.string.clearCallLogConfirmation)
- .setNegativeButton(android.R.string.cancel, null)
- .setPositiveButton(android.R.string.ok, okListener)
- .setCancelable(true)
- .create();
- }
-}
diff --git a/src/com/android/contacts/calllog/ContactInfo.java b/src/com/android/contacts/calllog/ContactInfo.java
deleted file mode 100644
index 30e7e71..0000000
--- a/src/com/android/contacts/calllog/ContactInfo.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-import android.net.Uri;
-import android.text.TextUtils;
-
-import com.android.contacts.util.UriUtils;
-
-/**
- * Information for a contact as needed by the Call Log.
- */
-public final class ContactInfo {
- public Uri lookupUri;
- public String name;
- public int type;
- public String label;
- public String number;
- public String formattedNumber;
- public String normalizedNumber;
- /** The photo for the contact, if available. */
- public long photoId;
- /** The high-res photo for the contact, if available. */
- public Uri photoUri;
-
- public static ContactInfo EMPTY = new ContactInfo();
-
- @Override
- public int hashCode() {
- // Uses only name and contactUri to determine hashcode.
- // This should be sufficient to have a reasonable distribution of hash codes.
- // Moreover, there should be no two people with the same lookupUri.
- final int prime = 31;
- int result = 1;
- result = prime * result + ((lookupUri == null) ? 0 : lookupUri.hashCode());
- result = prime * result + ((name == null) ? 0 : name.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (obj == null) return false;
- if (getClass() != obj.getClass()) return false;
- ContactInfo other = (ContactInfo) obj;
- if (!UriUtils.areEqual(lookupUri, other.lookupUri)) return false;
- if (!TextUtils.equals(name, other.name)) return false;
- if (type != other.type) return false;
- if (!TextUtils.equals(label, other.label)) return false;
- if (!TextUtils.equals(number, other.number)) return false;
- if (!TextUtils.equals(formattedNumber, other.formattedNumber)) return false;
- if (!TextUtils.equals(normalizedNumber, other.normalizedNumber)) return false;
- if (photoId != other.photoId) return false;
- if (!UriUtils.areEqual(photoUri, other.photoUri)) return false;
- return true;
- }
-}
diff --git a/src/com/android/contacts/calllog/ContactInfoHelper.java b/src/com/android/contacts/calllog/ContactInfoHelper.java
deleted file mode 100644
index edca00c..0000000
--- a/src/com/android/contacts/calllog/ContactInfoHelper.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.PhoneLookup;
-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.
- */
-public class ContactInfoHelper {
- private final Context mContext;
- private final String mCurrentCountryIso;
-
- public ContactInfoHelper(Context context, String currentCountryIso) {
- mContext = context;
- mCurrentCountryIso = currentCountryIso;
- }
-
- /**
- * Returns the contact information for the given number.
- * <p>
- * If the number does not match any contact, returns a contact info containing only the number
- * and the formatted number.
- * <p>
- * If an error occurs during the lookup, it returns null.
- *
- * @param number the number to look up
- * @param countryIso the country associated with this number
- */
- public ContactInfo lookupNumber(String number, String countryIso) {
- final ContactInfo info;
-
- // Determine the contact info.
- if (PhoneNumberUtils.isUriNumber(number)) {
- // This "number" is really a SIP address.
- ContactInfo sipInfo = queryContactInfoForSipAddress(number);
- if (sipInfo == null || sipInfo == ContactInfo.EMPTY) {
- // Check whether the "username" part of the SIP address is
- // actually the phone number of a contact.
- String username = PhoneNumberUtils.getUsernameFromUriNumber(number);
- if (PhoneNumberUtils.isGlobalPhoneNumber(username)) {
- sipInfo = queryContactInfoForPhoneNumber(username, countryIso);
- }
- }
- info = sipInfo;
- } else {
- // Look for a contact that has the given phone number.
- ContactInfo phoneInfo = queryContactInfoForPhoneNumber(number, countryIso);
-
- if (phoneInfo == null || phoneInfo == ContactInfo.EMPTY) {
- // Check whether the phone number has been saved as an "Internet call" number.
- phoneInfo = queryContactInfoForSipAddress(number);
- }
- info = phoneInfo;
- }
-
- final ContactInfo updatedInfo;
- if (info == null) {
- // The lookup failed.
- updatedInfo = null;
- } else {
- // If we did not find a matching contact, generate an empty contact info for the number.
- if (info == ContactInfo.EMPTY) {
- // Did not find a matching contact.
- updatedInfo = new ContactInfo();
- updatedInfo.number = number;
- updatedInfo.formattedNumber = formatPhoneNumber(number, null, countryIso);
- } else {
- updatedInfo = info;
- }
- }
- return updatedInfo;
- }
-
- /**
- * Looks up a contact using the given URI.
- * <p>
- * It returns null if an error occurs, {@link ContactInfo#EMPTY} if no matching contact is
- * found, or the {@link ContactInfo} for the given contact.
- * <p>
- * The {@link ContactInfo#formattedNumber} field is always set to {@code null} in the returned
- * value.
- */
- private ContactInfo lookupContactFromUri(Uri uri) {
- final ContactInfo info;
- Cursor phonesCursor =
- mContext.getContentResolver().query(
- uri, PhoneQuery._PROJECTION, null, null, null);
-
- if (phonesCursor != null) {
- try {
- if (phonesCursor.moveToFirst()) {
- info = new ContactInfo();
- long contactId = phonesCursor.getLong(PhoneQuery.PERSON_ID);
- String lookupKey = phonesCursor.getString(PhoneQuery.LOOKUP_KEY);
- info.lookupUri = Contacts.getLookupUri(contactId, lookupKey);
- info.name = phonesCursor.getString(PhoneQuery.NAME);
- info.type = phonesCursor.getInt(PhoneQuery.PHONE_TYPE);
- info.label = phonesCursor.getString(PhoneQuery.LABEL);
- info.number = phonesCursor.getString(PhoneQuery.MATCHED_NUMBER);
- info.normalizedNumber = phonesCursor.getString(PhoneQuery.NORMALIZED_NUMBER);
- info.photoId = phonesCursor.getLong(PhoneQuery.PHOTO_ID);
- info.photoUri =
- UriUtils.parseUriOrNull(phonesCursor.getString(PhoneQuery.PHOTO_URI));
- info.formattedNumber = null;
- } else {
- info = ContactInfo.EMPTY;
- }
- } finally {
- phonesCursor.close();
- }
- } else {
- // Failed to fetch the data, ignore this request.
- info = null;
- }
- return info;
- }
-
- /**
- * Determines the contact information for the given SIP address.
- * <p>
- * It returns the contact info if found.
- * <p>
- * If no contact corresponds to the given SIP address, returns {@link ContactInfo#EMPTY}.
- * <p>
- * If the lookup fails for some other reason, it returns null.
- */
- private ContactInfo queryContactInfoForSipAddress(String sipAddress) {
- final ContactInfo info;
-
- // "contactNumber" is a SIP address, so use the PhoneLookup table with the SIP parameter.
- Uri.Builder uriBuilder = PhoneLookup.CONTENT_FILTER_URI.buildUpon();
- uriBuilder.appendPath(Uri.encode(sipAddress));
- uriBuilder.appendQueryParameter(PhoneLookup.QUERY_PARAMETER_SIP_ADDRESS, "1");
- return lookupContactFromUri(uriBuilder.build());
- }
-
- /**
- * Determines the contact information for the given phone number.
- * <p>
- * It returns the contact info if found.
- * <p>
- * If no contact corresponds to the given phone number, returns {@link ContactInfo#EMPTY}.
- * <p>
- * If the lookup fails for some other reason, it returns null.
- */
- private ContactInfo queryContactInfoForPhoneNumber(String number, String countryIso) {
- String contactNumber = number;
- if (!TextUtils.isEmpty(countryIso)) {
- // Normalize the number: this is needed because the PhoneLookup query below does not
- // accept a country code as an input.
- String numberE164 = PhoneNumberUtils.formatNumberToE164(number, countryIso);
- if (!TextUtils.isEmpty(numberE164)) {
- // Only use it if the number could be formatted to E164.
- contactNumber = numberE164;
- }
- }
-
- // The "contactNumber" is a regular phone number, so use the PhoneLookup table.
- Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(contactNumber));
- ContactInfo info = lookupContactFromUri(uri);
- if (info != null && info != ContactInfo.EMPTY) {
- info.formattedNumber = formatPhoneNumber(number, null, countryIso);
- }
- return info;
- }
-
- /**
- * Format the given phone number
- *
- * @param number the number to be formatted.
- * @param normalizedNumber the normalized number of the given number.
- * @param countryIso the ISO 3166-1 two letters country code, the country's
- * convention will be used to format the number if the normalized
- * phone is null.
- *
- * @return the formatted number, or the given number if it was formatted.
- */
- private String formatPhoneNumber(String number, String normalizedNumber,
- String countryIso) {
- if (TextUtils.isEmpty(number)) {
- return "";
- }
- // If "number" is really a SIP address, don't try to do any formatting at all.
- if (PhoneNumberUtils.isUriNumber(number)) {
- return number;
- }
- if (TextUtils.isEmpty(countryIso)) {
- countryIso = mCurrentCountryIso;
- }
- return PhoneNumberUtils.formatNumber(number, normalizedNumber, countryIso);
- }
-}
diff --git a/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java b/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
deleted file mode 100644
index cfac1de..0000000
--- a/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.contacts.calllog;
-
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.CallLog.Calls;
-import android.provider.ContactsContract.PhoneLookup;
-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;
-
-/**
- * Implementation of {@link VoicemailNotifier} that shows a notification in the
- * status bar.
- */
-public class DefaultVoicemailNotifier implements VoicemailNotifier {
- public static final String TAG = "DefaultVoicemailNotifier";
-
- /** The tag used to identify notifications from this class. */
- private static final String NOTIFICATION_TAG = "DefaultVoicemailNotifier";
- /** The identifier of the notification of new voicemails. */
- private static final int NOTIFICATION_ID = 1;
-
- /** The singleton instance of {@link DefaultVoicemailNotifier}. */
- private static DefaultVoicemailNotifier sInstance;
-
- private final Context mContext;
- private final NotificationManager mNotificationManager;
- private final NewCallsQuery mNewCallsQuery;
- private final NameLookupQuery mNameLookupQuery;
- private final PhoneNumberHelper mPhoneNumberHelper;
-
- /** Returns the singleton instance of the {@link DefaultVoicemailNotifier}. */
- public static synchronized DefaultVoicemailNotifier getInstance(Context context) {
- if (sInstance == null) {
- NotificationManager notificationManager =
- (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
- ContentResolver contentResolver = context.getContentResolver();
- sInstance = new DefaultVoicemailNotifier(context, notificationManager,
- createNewCallsQuery(contentResolver),
- createNameLookupQuery(contentResolver),
- createPhoneNumberHelper(context));
- }
- return sInstance;
- }
-
- private DefaultVoicemailNotifier(Context context,
- NotificationManager notificationManager, NewCallsQuery newCallsQuery,
- NameLookupQuery nameLookupQuery, PhoneNumberHelper phoneNumberHelper) {
- mContext = context;
- mNotificationManager = notificationManager;
- mNewCallsQuery = newCallsQuery;
- mNameLookupQuery = nameLookupQuery;
- mPhoneNumberHelper = phoneNumberHelper;
- }
-
- /** Updates the notification and notifies of the call with the given URI. */
- @Override
- public void updateNotification(Uri newCallUri) {
- // Lookup the list of new voicemails to include in the notification.
- // TODO: Move this into a service, to avoid holding the receiver up.
- final NewCall[] newCalls = mNewCallsQuery.query();
-
- if (newCalls == null) {
- // Query failed, just return.
- return;
- }
-
- if (newCalls.length == 0) {
- // No voicemails to notify about: clear the notification.
- clearNotification();
- return;
- }
-
- Resources resources = mContext.getResources();
-
- // This represents a list of names to include in the notification.
- String callers = null;
-
- // Maps each number into a name: if a number is in the map, it has already left a more
- // recent voicemail.
- final Map<String, String> names = Maps.newHashMap();
-
- // Determine the call corresponding to the new voicemail we have to notify about.
- NewCall callToNotify = null;
-
- // Iterate over the new voicemails to determine all the information above.
- for (NewCall newCall : newCalls) {
- // Check if we already know the name associated with this number.
- String name = names.get(newCall.number);
- if (name == null) {
- // Look it up in the database.
- name = mNameLookupQuery.query(newCall.number);
- // If we cannot lookup the contact, use the number instead.
- if (name == null) {
- name = mPhoneNumberHelper.getDisplayNumber(newCall.number, "").toString();
- if (TextUtils.isEmpty(name)) {
- name = newCall.number;
- }
- }
- names.put(newCall.number, name);
- // This is a new caller. Add it to the back of the list of callers.
- if (TextUtils.isEmpty(callers)) {
- callers = name;
- } else {
- callers = resources.getString(
- R.string.notification_voicemail_callers_list, callers, name);
- }
- }
- // Check if this is the new call we need to notify about.
- if (newCallUri != null && newCallUri.equals(newCall.voicemailUri)) {
- callToNotify = newCall;
- }
- }
-
- if (newCallUri != null && callToNotify == null) {
- Log.e(TAG, "The new call could not be found in the call log: " + newCallUri);
- }
-
- // Determine the title of the notification and the icon for it.
- final String title = resources.getQuantityString(
- R.plurals.notification_voicemail_title, newCalls.length, newCalls.length);
- // TODO: Use the photo of contact if all calls are from the same person.
- final int icon = android.R.drawable.stat_notify_voicemail;
-
- Notification.Builder notificationBuilder = new Notification.Builder(mContext)
- .setSmallIcon(icon)
- .setContentTitle(title)
- .setContentText(callers)
- .setDefaults(callToNotify != null ? Notification.DEFAULT_ALL : 0)
- .setDeleteIntent(createMarkNewVoicemailsAsOldIntent())
- .setAutoCancel(true);
-
- // Determine the intent to fire when the notification is clicked on.
- final Intent contentIntent;
- if (newCalls.length == 1) {
- // Open the voicemail directly.
- contentIntent = new Intent(mContext, CallDetailActivity.class);
- contentIntent.setData(newCalls[0].callsUri);
- contentIntent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI,
- newCalls[0].voicemailUri);
- Intent playIntent = new Intent(mContext, CallDetailActivity.class);
- playIntent.setData(newCalls[0].callsUri);
- playIntent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI,
- newCalls[0].voicemailUri);
- playIntent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_START_PLAYBACK, true);
- playIntent.putExtra(CallDetailActivity.EXTRA_FROM_NOTIFICATION, true);
- notificationBuilder.addAction(R.drawable.ic_play_holo_dark,
- resources.getString(R.string.notification_action_voicemail_play),
- PendingIntent.getActivity(mContext, 0, playIntent, 0));
- } else {
- // Open the call log.
- contentIntent = new Intent(Intent.ACTION_VIEW, Calls.CONTENT_URI);
- }
- notificationBuilder.setContentIntent(
- PendingIntent.getActivity(mContext, 0, contentIntent, 0));
-
- // The text to show in the ticker, describing the new event.
- if (callToNotify != null) {
- notificationBuilder.setTicker(resources.getString(
- R.string.notification_new_voicemail_ticker, names.get(callToNotify.number)));
- }
-
- mNotificationManager.notify(NOTIFICATION_TAG, NOTIFICATION_ID, notificationBuilder.build());
- }
-
- /** Creates a pending intent that marks all new voicemails as old. */
- private PendingIntent createMarkNewVoicemailsAsOldIntent() {
- Intent intent = new Intent(mContext, CallLogNotificationsService.class);
- intent.setAction(CallLogNotificationsService.ACTION_MARK_NEW_VOICEMAILS_AS_OLD);
- return PendingIntent.getService(mContext, 0, intent, 0);
- }
-
- @Override
- public void clearNotification() {
- mNotificationManager.cancel(NOTIFICATION_TAG, NOTIFICATION_ID);
- }
-
- /** Information about a new voicemail. */
- private static final class NewCall {
- public final Uri callsUri;
- public final Uri voicemailUri;
- public final String number;
-
- public NewCall(Uri callsUri, Uri voicemailUri, String number) {
- this.callsUri = callsUri;
- this.voicemailUri = voicemailUri;
- this.number = number;
- }
- }
-
- /** Allows determining the new calls for which a notification should be generated. */
- public interface NewCallsQuery {
- /**
- * Returns the new calls for which a notification should be generated.
- */
- public NewCall[] query();
- }
-
- /** Create a new instance of {@link NewCallsQuery}. */
- public static NewCallsQuery createNewCallsQuery(ContentResolver contentResolver) {
- return new DefaultNewCallsQuery(contentResolver);
- }
-
- /**
- * Default implementation of {@link NewCallsQuery} that looks up the list of new calls to
- * notify about in the call log.
- */
- private static final class DefaultNewCallsQuery implements NewCallsQuery {
- private static final String[] PROJECTION = {
- Calls._ID, Calls.NUMBER, Calls.VOICEMAIL_URI
- };
- private static final int ID_COLUMN_INDEX = 0;
- private static final int NUMBER_COLUMN_INDEX = 1;
- private static final int VOICEMAIL_URI_COLUMN_INDEX = 2;
-
- private final ContentResolver mContentResolver;
-
- private DefaultNewCallsQuery(ContentResolver contentResolver) {
- mContentResolver = contentResolver;
- }
-
- @Override
- public NewCall[] query() {
- final String selection = String.format("%s = 1 AND %s = ?", Calls.NEW, Calls.TYPE);
- final String[] selectionArgs = new String[]{ Integer.toString(Calls.VOICEMAIL_TYPE) };
- Cursor cursor = null;
- try {
- cursor = mContentResolver.query(Calls.CONTENT_URI_WITH_VOICEMAIL, PROJECTION,
- selection, selectionArgs, Calls.DEFAULT_SORT_ORDER);
- if (cursor == null) {
- return null;
- }
- NewCall[] newCalls = new NewCall[cursor.getCount()];
- while (cursor.moveToNext()) {
- newCalls[cursor.getPosition()] = createNewCallsFromCursor(cursor);
- }
- return newCalls;
- } finally {
- MoreCloseables.closeQuietly(cursor);
- }
- }
-
- /** Returns an instance of {@link NewCall} created by using the values of the cursor. */
- private NewCall createNewCallsFromCursor(Cursor cursor) {
- String voicemailUriString = cursor.getString(VOICEMAIL_URI_COLUMN_INDEX);
- Uri callsUri = ContentUris.withAppendedId(
- Calls.CONTENT_URI_WITH_VOICEMAIL, cursor.getLong(ID_COLUMN_INDEX));
- Uri voicemailUri = voicemailUriString == null ? null : Uri.parse(voicemailUriString);
- return new NewCall(callsUri, voicemailUri, cursor.getString(NUMBER_COLUMN_INDEX));
- }
- }
-
- /** Allows determining the name associated with a given phone number. */
- public interface NameLookupQuery {
- /**
- * Returns the name associated with the given number in the contacts database, or null if
- * the number does not correspond to any of the contacts.
- * <p>
- * If there are multiple contacts with the same phone number, it will return the name of one
- * of the matching contacts.
- */
- public String query(String number);
- }
-
- /** Create a new instance of {@link NameLookupQuery}. */
- public static NameLookupQuery createNameLookupQuery(ContentResolver contentResolver) {
- return new DefaultNameLookupQuery(contentResolver);
- }
-
- /**
- * Default implementation of {@link NameLookupQuery} that looks up the name of a contact in the
- * contacts database.
- */
- private static final class DefaultNameLookupQuery implements NameLookupQuery {
- private static final String[] PROJECTION = { PhoneLookup.DISPLAY_NAME };
- private static final int DISPLAY_NAME_COLUMN_INDEX = 0;
-
- private final ContentResolver mContentResolver;
-
- private DefaultNameLookupQuery(ContentResolver contentResolver) {
- mContentResolver = contentResolver;
- }
-
- @Override
- public String query(String number) {
- Cursor cursor = null;
- try {
- cursor = mContentResolver.query(
- Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)),
- PROJECTION, null, null, null);
- if (cursor == null || !cursor.moveToFirst()) return null;
- return cursor.getString(DISPLAY_NAME_COLUMN_INDEX);
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
- }
- }
-
- /**
- * Create a new PhoneNumberHelper.
- * <p>
- * This will cause some Disk I/O, at least the first time it is created, so it should not be
- * called from the main thread.
- */
- public static PhoneNumberHelper createPhoneNumberHelper(Context context) {
- return new PhoneNumberHelper(context.getResources());
- }
-}
diff --git a/src/com/android/contacts/calllog/ExtendedCursor.java b/src/com/android/contacts/calllog/ExtendedCursor.java
deleted file mode 100644
index 3894192..0000000
--- a/src/com/android/contacts/calllog/ExtendedCursor.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-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>
- * The number of rows in the cursor and the set of columns is determined by the cursor being
- * wrapped.
- */
-public class ExtendedCursor extends AbstractCursor {
- /** The cursor to wrap. */
- private final Cursor mCursor;
- /** The name of the additional column. */
- private final String mColumnName;
- /** The value to be assigned to the additional column. */
- private final Object mValue;
-
- /**
- * Creates a new cursor which extends the given cursor by adding a column with a constant value.
- *
- * @param cursor the cursor to extend
- * @param columnName the name of the additional column
- * @param value the value to be assigned to the additional column
- */
- public ExtendedCursor(Cursor cursor, String columnName, Object value) {
- mCursor = cursor;
- mColumnName = columnName;
- mValue = value;
- }
-
- @Override
- public int getCount() {
- return mCursor.getCount();
- }
-
- @Override
- public String[] getColumnNames() {
- String[] columnNames = mCursor.getColumnNames();
- int length = columnNames.length;
- String[] extendedColumnNames = new String[length + 1];
- System.arraycopy(columnNames, 0, extendedColumnNames, 0, length);
- extendedColumnNames[length] = mColumnName;
- return extendedColumnNames;
- }
-
- @Override
- public String getString(int column) {
- if (column == mCursor.getColumnCount()) {
- return (String) mValue;
- }
- return mCursor.getString(column);
- }
-
- @Override
- public short getShort(int column) {
- if (column == mCursor.getColumnCount()) {
- return (Short) mValue;
- }
- return mCursor.getShort(column);
- }
-
- @Override
- public int getInt(int column) {
- if (column == mCursor.getColumnCount()) {
- return (Integer) mValue;
- }
- return mCursor.getInt(column);
- }
-
- @Override
- public long getLong(int column) {
- if (column == mCursor.getColumnCount()) {
- return (Long) mValue;
- }
- return mCursor.getLong(column);
- }
-
- @Override
- public float getFloat(int column) {
- if (column == mCursor.getColumnCount()) {
- return (Float) mValue;
- }
- return mCursor.getFloat(column);
- }
-
- @Override
- public double getDouble(int column) {
- if (column == mCursor.getColumnCount()) {
- return (Double) mValue;
- }
- return mCursor.getDouble(column);
- }
-
- @Override
- public boolean isNull(int column) {
- if (column == mCursor.getColumnCount()) {
- return mValue == null;
- }
- return mCursor.isNull(column);
- }
-
- @Override
- public boolean onMove(int oldPosition, int newPosition) {
- return mCursor.moveToPosition(newPosition);
- }
-
- @Override
- public void close() {
- MoreCloseables.closeQuietly(mCursor);
- super.close();
- }
-
- @Override
- public void registerContentObserver(ContentObserver observer) {
- mCursor.registerContentObserver(observer);
- }
-
- @Override
- public void unregisterContentObserver(ContentObserver observer) {
- mCursor.unregisterContentObserver(observer);
- }
-
- @Override
- public void registerDataSetObserver(DataSetObserver observer) {
- mCursor.registerDataSetObserver(observer);
- }
-
- @Override
- public void unregisterDataSetObserver(DataSetObserver observer) {
- mCursor.unregisterDataSetObserver(observer);
- }
-}
diff --git a/src/com/android/contacts/calllog/IntentProvider.java b/src/com/android/contacts/calllog/IntentProvider.java
deleted file mode 100644
index 487799c..0000000
--- a/src/com/android/contacts/calllog/IntentProvider.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-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 com.android.contacts.CallDetailActivity;
-import com.android.contacts.ContactsUtils;
-
-/**
- * Used to create an intent to attach to an action in the call log.
- * <p>
- * The intent is constructed lazily with the given information.
- */
-public abstract class IntentProvider {
- public abstract Intent getIntent(Context context);
-
- public static IntentProvider getReturnCallIntentProvider(final String number) {
- return new IntentProvider() {
- @Override
- public Intent getIntent(Context context) {
- return ContactsUtils.getCallIntent(number);
- }
- };
- }
-
- public static IntentProvider getPlayVoicemailIntentProvider(final long rowId,
- final String voicemailUri) {
- return new IntentProvider() {
- @Override
- public Intent getIntent(Context context) {
- Intent intent = new Intent(context, CallDetailActivity.class);
- intent.setData(ContentUris.withAppendedId(
- Calls.CONTENT_URI_WITH_VOICEMAIL, rowId));
- if (voicemailUri != null) {
- intent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI,
- Uri.parse(voicemailUri));
- }
- intent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_START_PLAYBACK, true);
- return intent;
- }
- };
- }
-
- public static IntentProvider getCallDetailIntentProvider(
- final CallLogAdapter adapter, final int position, final long id, final int groupSize) {
- return new IntentProvider() {
- @Override
- public Intent getIntent(Context context) {
- Cursor cursor = adapter.getCursor();
- cursor.moveToPosition(position);
- if (CallLogQuery.isSectionHeader(cursor)) {
- // Do nothing when a header is clicked.
- return null;
- }
- Intent intent = new Intent(context, CallDetailActivity.class);
- // Check if the first item is a voicemail.
- String voicemailUri = cursor.getString(CallLogQuery.VOICEMAIL_URI);
- if (voicemailUri != null) {
- intent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI,
- Uri.parse(voicemailUri));
- }
- intent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_START_PLAYBACK, false);
-
- if (groupSize > 1) {
- // We want to restore the position in the cursor at the end.
- long[] ids = new long[groupSize];
- // Copy the ids of the rows in the group.
- for (int index = 0; index < groupSize; ++index) {
- ids[index] = cursor.getLong(CallLogQuery.ID);
- cursor.moveToNext();
- }
- intent.putExtra(CallDetailActivity.EXTRA_CALL_LOG_IDS, ids);
- } else {
- // If there is a single item, use the direct URI for it.
- intent.setData(ContentUris.withAppendedId(
- Calls.CONTENT_URI_WITH_VOICEMAIL, id));
- }
- return intent;
- }
- };
- }
-}
diff --git a/src/com/android/contacts/calllog/PhoneNumberHelper.java b/src/com/android/contacts/calllog/PhoneNumberHelper.java
deleted file mode 100644
index e24d0ae..0000000
--- a/src/com/android/contacts/calllog/PhoneNumberHelper.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-import android.content.res.Resources;
-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.
- */
-public class PhoneNumberHelper {
- private final Resources mResources;
-
- public PhoneNumberHelper(Resources resources) {
- mResources = resources;
- }
-
- /** Returns true if it is possible to place a call to the given number. */
- public boolean canPlaceCallsTo(CharSequence number) {
- return !(TextUtils.isEmpty(number)
- || number.equals(CallerInfo.UNKNOWN_NUMBER)
- || number.equals(CallerInfo.PRIVATE_NUMBER)
- || number.equals(CallerInfo.PAYPHONE_NUMBER));
- }
-
- /** Returns true if it is possible to send an SMS to the given number. */
- public boolean canSendSmsTo(CharSequence number) {
- return canPlaceCallsTo(number) && !isVoicemailNumber(number) && !isSipNumber(number);
- }
-
- /**
- * Returns the string to display for the given phone number.
- *
- * @param number the number to display
- * @param formattedNumber the formatted number if available, may be null
- */
- public CharSequence getDisplayNumber(CharSequence number, CharSequence formattedNumber) {
- if (TextUtils.isEmpty(number)) {
- return "";
- }
- if (number.equals(CallerInfo.UNKNOWN_NUMBER)) {
- return mResources.getString(R.string.unknown);
- }
- if (number.equals(CallerInfo.PRIVATE_NUMBER)) {
- return mResources.getString(R.string.private_num);
- }
- if (number.equals(CallerInfo.PAYPHONE_NUMBER)) {
- return mResources.getString(R.string.payphone);
- }
- if (isVoicemailNumber(number)) {
- return mResources.getString(R.string.voicemail);
- }
- if (TextUtils.isEmpty(formattedNumber)) {
- return number;
- } else {
- return formattedNumber;
- }
- }
-
- /**
- * Returns true if the given number is the number of the configured voicemail.
- * To be able to mock-out this, it is not a static method.
- */
- public boolean isVoicemailNumber(CharSequence number) {
- return PhoneNumberUtils.isVoiceMailNumber(number.toString());
- }
-
- /**
- * Returns true if the given number is a SIP address.
- * To be able to mock-out this, it is not a static method.
- */
- public boolean isSipNumber(CharSequence number) {
- return PhoneNumberUtils.isUriNumber(number.toString());
- }
-}
diff --git a/src/com/android/contacts/calllog/PhoneQuery.java b/src/com/android/contacts/calllog/PhoneQuery.java
deleted file mode 100644
index af44add..0000000
--- a/src/com/android/contacts/calllog/PhoneQuery.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-import android.provider.ContactsContract.PhoneLookup;
-
-/**
- * The query to look up the {@link ContactInfo} for a given number in the Call Log.
- */
-final class PhoneQuery {
- public static final String[] _PROJECTION = new String[] {
- PhoneLookup._ID,
- PhoneLookup.DISPLAY_NAME,
- PhoneLookup.TYPE,
- PhoneLookup.LABEL,
- PhoneLookup.NUMBER,
- PhoneLookup.NORMALIZED_NUMBER,
- PhoneLookup.PHOTO_ID,
- PhoneLookup.LOOKUP_KEY,
- PhoneLookup.PHOTO_URI};
-
- public static final int PERSON_ID = 0;
- public static final int NAME = 1;
- public static final int PHONE_TYPE = 2;
- public static final int LABEL = 3;
- public static final int MATCHED_NUMBER = 4;
- public static final int NORMALIZED_NUMBER = 5;
- public static final int PHOTO_ID = 6;
- public static final int LOOKUP_KEY = 7;
- public static final int PHOTO_URI = 8;
-}
\ No newline at end of file
diff --git a/src/com/android/contacts/calllog/VoicemailNotifier.java b/src/com/android/contacts/calllog/VoicemailNotifier.java
deleted file mode 100644
index 8d45486..0000000
--- a/src/com/android/contacts/calllog/VoicemailNotifier.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.contacts.calllog;
-
-import android.net.Uri;
-
-/**
- * Handles notifications for voicemails.
- */
-public interface VoicemailNotifier {
- /**
- * Updates the notification and clears it if there are no new voicemails.
- * <p>
- * If the given URI corresponds to a new voicemail, also notifies about it.
- * <p>
- * It is not safe to call this method from the main thread.
- *
- * @param newCallUri URI of the new call, may be null
- */
- public void updateNotification(Uri newCallUri);
-
- /** Clears the new voicemail notification. */
- public void clearNotification();
-}
diff --git a/src/com/android/contacts/detail/ContactDetailDisplayUtils.java b/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
index 1908e96..bda4918 100644
--- a/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
+++ b/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
@@ -39,7 +39,7 @@
import android.widget.ListView;
import android.widget.TextView;
-import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.R;
import com.android.contacts.model.Contact;
import com.android.contacts.model.RawContact;
diff --git a/src/com/android/contacts/detail/ContactDetailFragment.java b/src/com/android/contacts/detail/ContactDetailFragment.java
index 3dfaf8d..35ca00b 100644
--- a/src/com/android/contacts/detail/ContactDetailFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailFragment.java
@@ -68,8 +68,6 @@
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;
@@ -77,6 +75,12 @@
import com.android.contacts.R;
import com.android.contacts.TypePrecedence;
import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
+import com.android.contacts.common.CallUtil;
+import com.android.contacts.common.ClipboardUtils;
+import com.android.contacts.common.Collapser;
+import com.android.contacts.common.Collapser.Collapsible;
+import com.android.contacts.common.GeoUtil;
+import com.android.contacts.common.MoreContactUtils;
import com.android.contacts.editor.SelectAccountDialogFragment;
import com.android.contacts.model.AccountTypeManager;
import com.android.contacts.model.Contact;
@@ -104,8 +108,6 @@
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;
@@ -281,7 +283,7 @@
public void onAttach(Activity activity) {
super.onAttach(activity);
mContext = activity;
- mDefaultCountryIso = ContactsUtils.getCurrentCountryIso(mContext);
+ mDefaultCountryIso = GeoUtil.getCurrentCountryIso(mContext);
mViewEntryDimensions = new ViewEntryDimensions(mContext.getResources());
}
@@ -543,6 +545,7 @@
ArrayList<String> groups = new ArrayList<String>();
for (RawContact rawContact: mContactData.getRawContacts()) {
final long rawContactId = rawContact.getId();
+ final AccountType accountType = rawContact.getAccountType(mContext);
for (DataItem dataItem : rawContact.getDataItems()) {
dataItem.setRawContactId(rawContactId);
@@ -558,11 +561,12 @@
continue;
}
- final DataKind kind = dataItem.getDataKind();
+ final DataKind kind = AccountTypeManager.getInstance(mContext)
+ .getKindOrFallback(accountType, dataItem.getMimeType());
if (kind == null) continue;
final DetailViewEntry entry = DetailViewEntry.fromValues(mContext, dataItem,
- mContactData.isDirectoryEntry(), mContactData.getDirectoryId());
+ mContactData.isDirectoryEntry(), mContactData.getDirectoryId(), kind);
entry.maxLines = kind.maxLinesForDisplay;
final boolean hasData = !TextUtils.isEmpty(entry.data);
@@ -575,9 +579,9 @@
// Build phone entries
entry.data = phone.getFormattedPhoneNumber();
final Intent phoneIntent = mHasPhone ?
- ContactsUtils.getCallIntent(entry.data) : null;
+ CallUtil.getCallIntent(entry.data) : null;
final Intent smsIntent = mHasSms ? new Intent(Intent.ACTION_SENDTO,
- Uri.fromParts(Constants.SCHEME_SMSTO, entry.data, null)) : null;
+ Uri.fromParts(CallUtil.SCHEME_SMSTO, entry.data, null)) : null;
// Configure Icons and Intents.
if (mHasPhone && mHasSms) {
@@ -609,7 +613,7 @@
} else if (dataItem instanceof EmailDataItem && hasData) {
// Build email entries
entry.intent = new Intent(Intent.ACTION_SENDTO,
- Uri.fromParts(Constants.SCHEME_MAILTO, entry.data, null));
+ Uri.fromParts(CallUtil.SCHEME_MAILTO, entry.data, null));
entry.isPrimary = isSuperPrimary;
// If entry is a primary entry, then render it first in the view.
if (entry.isPrimary) {
@@ -625,7 +629,8 @@
ImDataItem im = ImDataItem.createFromEmail(email);
final DetailViewEntry imEntry = DetailViewEntry.fromValues(mContext, im,
- mContactData.isDirectoryEntry(), mContactData.getDirectoryId());
+ mContactData.isDirectoryEntry(), mContactData.getDirectoryId(),
+ kind);
buildImActions(mContext, imEntry, im);
imEntry.setPresence(status.getPresence());
imEntry.maxLines = kind.maxLinesForDisplay;
@@ -680,8 +685,8 @@
// Build SipAddress entries
entry.uri = null;
if (mHasSip) {
- entry.intent = ContactsUtils.getCallIntent(
- Uri.fromParts(Constants.SCHEME_SIP, entry.data, null));
+ entry.intent = CallUtil.getCallIntent(
+ Uri.fromParts(CallUtil.SCHEME_SIP, entry.data, null));
} else {
entry.intent = null;
}
@@ -706,20 +711,19 @@
entry.intent = new Intent(Intent.ACTION_VIEW);
entry.intent.setDataAndType(entry.uri, entry.mimetype);
- entry.data = dataItem.buildDataString();
+ entry.data = dataItem.buildDataString(getContext(), kind);
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);
+ if (mOtherEntriesMap.containsKey(accountType)) {
+ List<DetailViewEntry> listEntries = mOtherEntriesMap.get(accountType);
listEntries.add(entry);
} else {
// Otherwise create a new list with the entry and add it to the hash map
List<DetailViewEntry> listEntries = new ArrayList<DetailViewEntry>();
listEntries.add(entry);
- mOtherEntriesMap.put(type, listEntries);
+ mOtherEntriesMap.put(accountType, listEntries);
}
}
}
@@ -990,7 +994,7 @@
if (!TextUtils.isEmpty(host)) {
final String authority = host.toLowerCase();
- final Uri imUri = new Uri.Builder().scheme(Constants.SCHEME_IMTO).authority(
+ final Uri imUri = new Uri.Builder().scheme(CallUtil.SCHEME_IMTO).authority(
authority).appendPath(data).build();
entry.intent = new Intent(Intent.ACTION_SENDTO, imUri);
}
@@ -1244,7 +1248,7 @@
* Build new {@link DetailViewEntry} and populate from the given values.
*/
public static DetailViewEntry fromValues(Context context, DataItem item,
- boolean isDirectoryEntry, long directoryId) {
+ boolean isDirectoryEntry, long directoryId, DataKind dataKind) {
final DetailViewEntry entry = new DetailViewEntry();
entry.id = item.getId();
entry.context = context;
@@ -1254,15 +1258,15 @@
ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId)).build();
}
entry.mimetype = item.getMimeType();
- entry.kind = item.getKindString();
- entry.data = item.buildDataString();
+ entry.kind = dataKind.getKindString(context);
+ entry.data = item.buildDataString(context, dataKind);
- if (item.hasKindTypeColumn()) {
- entry.type = item.getKindTypeColumn();
+ if (item.hasKindTypeColumn(dataKind)) {
+ entry.type = item.getKindTypeColumn(dataKind);
// get type string
entry.typeString = "";
- for (EditType type : item.getDataKind().typeList) {
+ for (EditType type : dataKind.typeList) {
if (type.rawValue == entry.type) {
if (type.customColumn == null) {
// Non-custom type. Get its description from the resource
@@ -1335,7 +1339,7 @@
return false;
}
- if (!ContactsUtils.shouldCollapse(mimetype, data, entry.mimetype, entry.data)) {
+ if (!MoreContactUtils.shouldCollapse(mimetype, data, entry.mimetype, entry.data)) {
return false;
}
@@ -1955,7 +1959,7 @@
}
} else if (mPrimaryPhoneUri != null) {
// There isn't anything selected, call the default number
- mContext.startActivity(ContactsUtils.getCallIntent(mPrimaryPhoneUri));
+ mContext.startActivity(CallUtil.getCallIntent(mPrimaryPhoneUri));
return true;
}
return false;
@@ -1998,7 +2002,7 @@
if (defaultGroupId == -1) return false;
final RawContact rawContact = (RawContact) mContactData.getRawContacts().get(0);
- final AccountType type = rawContact.getAccountType();
+ final AccountType type = rawContact.getAccountType(getContext());
// Offline or non-writeable account? Nothing to fix
if (type == null || !type.areContactsWritable()) return false;
diff --git a/src/com/android/contacts/detail/ContactDetailLayoutController.java b/src/com/android/contacts/detail/ContactDetailLayoutController.java
index fca426c..1e1ebd3 100644
--- a/src/com/android/contacts/detail/ContactDetailLayoutController.java
+++ b/src/com/android/contacts/detail/ContactDetailLayoutController.java
@@ -39,7 +39,7 @@
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.common.util.UriUtils;
import com.android.contacts.widget.FrameLayoutWithOverlay;
import com.android.contacts.widget.TransitionAnimationView;
diff --git a/src/com/android/contacts/detail/ContactDetailPhotoSetter.java b/src/com/android/contacts/detail/ContactDetailPhotoSetter.java
index eb832e9..2c4c2c9 100644
--- a/src/com/android/contacts/detail/ContactDetailPhotoSetter.java
+++ b/src/com/android/contacts/detail/ContactDetailPhotoSetter.java
@@ -25,7 +25,7 @@
import android.view.View.OnClickListener;
import android.widget.ImageView;
-import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.activities.PhotoSelectionActivity;
import com.android.contacts.model.Contact;
import com.android.contacts.model.RawContactDeltaList;
diff --git a/src/com/android/contacts/dialpad/DialpadFragment.java b/src/com/android/contacts/dialpad/DialpadFragment.java
deleted file mode 100644
index 6ba4178..0000000
--- a/src/com/android/contacts/dialpad/DialpadFragment.java
+++ /dev/null
@@ -1,1629 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.dialpad;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.app.Fragment;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.media.AudioManager;
-import android.media.ToneGenerator;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemProperties;
-import android.provider.Contacts.Intents.Insert;
-import android.provider.Contacts.People;
-import android.provider.Contacts.Phones;
-import android.provider.Contacts.PhonesColumns;
-import android.provider.Settings;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.PhoneStateListener;
-import android.telephony.TelephonyManager;
-import android.text.Editable;
-import android.text.SpannableString;
-import android.text.TextUtils;
-import android.text.TextWatcher;
-import android.text.method.DialerKeyListener;
-import android.text.style.RelativeSizeSpan;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.EditText;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.PopupMenu;
-import android.widget.TextView;
-
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.R;
-import com.android.contacts.SpecialCharSequenceMgr;
-import com.android.contacts.activities.DialtactsActivity;
-import com.android.contacts.util.Constants;
-import com.android.contacts.util.PhoneNumberFormatter;
-import com.android.contacts.util.StopWatch;
-import com.android.internal.telephony.ITelephony;
-import com.android.phone.CallLogAsync;
-import com.android.phone.HapticFeedback;
-
-/**
- * Fragment that displays a twelve-key phone dialpad.
- */
-public class DialpadFragment extends Fragment
- implements View.OnClickListener,
- View.OnLongClickListener, View.OnKeyListener,
- AdapterView.OnItemClickListener, TextWatcher,
- PopupMenu.OnMenuItemClickListener,
- DialpadImageButton.OnPressedListener {
- private static final String TAG = DialpadFragment.class.getSimpleName();
-
- private static final boolean DEBUG = DialtactsActivity.DEBUG;
-
- private static final String EMPTY_NUMBER = "";
-
- /** The length of DTMF tones in milliseconds */
- private static final int TONE_LENGTH_MS = 150;
- private static final int TONE_LENGTH_INFINITE = -1;
-
- /** The DTMF tone volume relative to other sounds in the stream */
- private static final int TONE_RELATIVE_VOLUME = 80;
-
- /** Stream type used to play the DTMF tones off call, and mapped to the volume control keys */
- private static final int DIAL_TONE_STREAM_TYPE = AudioManager.STREAM_DTMF;
-
- /**
- * View (usually FrameLayout) containing mDigits field. This can be null, in which mDigits
- * isn't enclosed by the container.
- */
- private View mDigitsContainer;
- private EditText mDigits;
-
- /** Remembers if we need to clear digits field when the screen is completely gone. */
- private boolean mClearDigitsOnStop;
-
- private View mDelete;
- private ToneGenerator mToneGenerator;
- private final Object mToneGeneratorLock = new Object();
- private View mDialpad;
- /**
- * Remembers the number of dialpad buttons which are pressed at this moment.
- * If it becomes 0, meaning no buttons are pressed, we'll call
- * {@link ToneGenerator#stopTone()}; the method shouldn't be called unless the last key is
- * released.
- */
- private int mDialpadPressCount;
-
- private View mDialButtonContainer;
- private View mDialButton;
- private ListView mDialpadChooser;
- private DialpadChooserAdapter mDialpadChooserAdapter;
-
- /**
- * Regular expression prohibiting manual phone call. Can be empty, which means "no rule".
- */
- private String mProhibitedPhoneNumberRegexp;
-
-
- // Last number dialed, retrieved asynchronously from the call DB
- // in onCreate. This number is displayed when the user hits the
- // send key and cleared in onPause.
- private final CallLogAsync mCallLog = new CallLogAsync();
- private String mLastNumberDialed = EMPTY_NUMBER;
-
- // determines if we want to playback local DTMF tones.
- private boolean mDTMFToneEnabled;
-
- // Vibration (haptic feedback) for dialer key presses.
- private final HapticFeedback mHaptic = new HapticFeedback();
-
- /** Identifier for the "Add Call" intent extra. */
- private static final String ADD_CALL_MODE_KEY = "add_call_mode";
-
- /**
- * Identifier for intent extra for sending an empty Flash message for
- * CDMA networks. This message is used by the network to simulate a
- * press/depress of the "hookswitch" of a landline phone. Aka "empty flash".
- *
- * TODO: Using an intent extra to tell the phone to send this flash is a
- * temporary measure. To be replaced with an ITelephony call in the future.
- * TODO: Keep in sync with the string defined in OutgoingCallBroadcaster.java
- * in Phone app until this is replaced with the ITelephony API.
- */
- private static final String EXTRA_SEND_EMPTY_FLASH
- = "com.android.phone.extra.SEND_EMPTY_FLASH";
-
- private String mCurrentCountryIso;
-
- private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
- /**
- * Listen for phone state changes so that we can take down the
- * "dialpad chooser" if the phone becomes idle while the
- * chooser UI is visible.
- */
- @Override
- public void onCallStateChanged(int state, String incomingNumber) {
- // Log.i(TAG, "PhoneStateListener.onCallStateChanged: "
- // + state + ", '" + incomingNumber + "'");
- if ((state == TelephonyManager.CALL_STATE_IDLE) && dialpadChooserVisible()) {
- // Log.i(TAG, "Call ended with dialpad chooser visible! Taking it down...");
- // Note there's a race condition in the UI here: the
- // dialpad chooser could conceivably disappear (on its
- // own) at the exact moment the user was trying to select
- // one of the choices, which would be confusing. (But at
- // least that's better than leaving the dialpad chooser
- // onscreen, but useless...)
- showDialpadChooser(false);
- }
- }
- };
-
- private boolean mWasEmptyBeforeTextChange;
-
- /**
- * This field is set to true while processing an incoming DIAL intent, in order to make sure
- * that SpecialCharSequenceMgr actions can be triggered by user input but *not* by a
- * tel: URI passed by some other app. It will be set to false when all digits are cleared.
- */
- private boolean mDigitsFilledByIntent;
-
- private static final String PREF_DIGITS_FILLED_BY_INTENT = "pref_digits_filled_by_intent";
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- mWasEmptyBeforeTextChange = TextUtils.isEmpty(s);
- }
-
- @Override
- public void onTextChanged(CharSequence input, int start, int before, int changeCount) {
- if (mWasEmptyBeforeTextChange != TextUtils.isEmpty(input)) {
- final Activity activity = getActivity();
- if (activity != null) {
- activity.invalidateOptionsMenu();
- }
- }
-
- // DTMF Tones do not need to be played here any longer -
- // the DTMF dialer handles that functionality now.
- }
-
- @Override
- public void afterTextChanged(Editable input) {
- // When DTMF dialpad buttons are being pressed, we delay SpecialCharSequencMgr sequence,
- // since some of SpecialCharSequenceMgr's behavior is too abrupt for the "touch-down"
- // behavior.
- if (!mDigitsFilledByIntent &&
- SpecialCharSequenceMgr.handleChars(getActivity(), input.toString(), mDigits)) {
- // A special sequence was entered, clear the digits
- mDigits.getText().clear();
- }
-
- if (isDigitsEmpty()) {
- mDigitsFilledByIntent = false;
- mDigits.setCursorVisible(false);
- }
-
- updateDialAndDeleteButtonEnabledState();
- }
-
- @Override
- public void onCreate(Bundle state) {
- super.onCreate(state);
-
- mCurrentCountryIso = ContactsUtils.getCurrentCountryIso(getActivity());
-
- try {
- mHaptic.init(getActivity(),
- getResources().getBoolean(R.bool.config_enable_dialer_key_vibration));
- } catch (Resources.NotFoundException nfe) {
- Log.e(TAG, "Vibrate control bool missing.", nfe);
- }
-
- setHasOptionsMenu(true);
-
- mProhibitedPhoneNumberRegexp = getResources().getString(
- R.string.config_prohibited_phone_number_regexp);
-
- if (state != null) {
- mDigitsFilledByIntent = state.getBoolean(PREF_DIGITS_FILLED_BY_INTENT);
- }
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
- View fragmentView = inflater.inflate(R.layout.dialpad_fragment, container, false);
-
- // Load up the resources for the text field.
- Resources r = getResources();
-
- mDigitsContainer = fragmentView.findViewById(R.id.digits_container);
- mDigits = (EditText) fragmentView.findViewById(R.id.digits);
- mDigits.setKeyListener(DialerKeyListener.getInstance());
- mDigits.setOnClickListener(this);
- mDigits.setOnKeyListener(this);
- mDigits.setOnLongClickListener(this);
- mDigits.addTextChangedListener(this);
-
- PhoneNumberFormatter.setPhoneNumberFormattingTextWatcher(getActivity(), mDigits);
-
- // Check for the presence of the keypad
- View oneButton = fragmentView.findViewById(R.id.one);
- if (oneButton != null) {
- setupKeypad(fragmentView);
- }
-
- DisplayMetrics dm = getResources().getDisplayMetrics();
- int minCellSize = (int) (56 * dm.density); // 56dip == minimum size of menu buttons
- int cellCount = dm.widthPixels / minCellSize;
- int fakeMenuItemWidth = dm.widthPixels / cellCount;
- mDialButtonContainer = fragmentView.findViewById(R.id.dialButtonContainer);
- // If in portrait, add padding to the dial button since we need space for the
- // search and menu/overflow buttons.
- if (mDialButtonContainer != null && !ContactsUtils.isLandscape(this.getActivity())) {
- mDialButtonContainer.setPadding(
- fakeMenuItemWidth, mDialButtonContainer.getPaddingTop(),
- fakeMenuItemWidth, mDialButtonContainer.getPaddingBottom());
- }
- mDialButton = fragmentView.findViewById(R.id.dialButton);
- if (r.getBoolean(R.bool.config_show_onscreen_dial_button)) {
- mDialButton.setOnClickListener(this);
- mDialButton.setOnLongClickListener(this);
- } else {
- mDialButton.setVisibility(View.GONE); // It's VISIBLE by default
- mDialButton = null;
- }
-
- mDelete = fragmentView.findViewById(R.id.deleteButton);
- if (mDelete != null) {
- mDelete.setOnClickListener(this);
- mDelete.setOnLongClickListener(this);
- }
-
- mDialpad = fragmentView.findViewById(R.id.dialpad); // This is null in landscape mode.
-
- // In landscape we put the keyboard in phone mode.
- if (null == mDialpad) {
- mDigits.setInputType(android.text.InputType.TYPE_CLASS_PHONE);
- } else {
- mDigits.setCursorVisible(false);
- }
-
- // Set up the "dialpad chooser" UI; see showDialpadChooser().
- mDialpadChooser = (ListView) fragmentView.findViewById(R.id.dialpadChooser);
- mDialpadChooser.setOnItemClickListener(this);
-
- configureScreenFromIntent(getActivity().getIntent());
-
- return fragmentView;
- }
-
- private boolean isLayoutReady() {
- return mDigits != null;
- }
-
- public EditText getDigitsWidget() {
- return mDigits;
- }
-
- /**
- * @return true when {@link #mDigits} is actually filled by the Intent.
- */
- private boolean fillDigitsIfNecessary(Intent intent) {
- final String action = intent.getAction();
- if (Intent.ACTION_DIAL.equals(action) || Intent.ACTION_VIEW.equals(action)) {
- Uri uri = intent.getData();
- if (uri != null) {
- if (Constants.SCHEME_TEL.equals(uri.getScheme())) {
- // Put the requested number into the input area
- String data = uri.getSchemeSpecificPart();
- // Remember it is filled via Intent.
- mDigitsFilledByIntent = true;
- setFormattedDigits(data, null);
- return true;
- } else {
- String type = intent.getType();
- if (People.CONTENT_ITEM_TYPE.equals(type)
- || Phones.CONTENT_ITEM_TYPE.equals(type)) {
- // Query the phone number
- Cursor c = getActivity().getContentResolver().query(intent.getData(),
- new String[] {PhonesColumns.NUMBER, PhonesColumns.NUMBER_KEY},
- null, null, null);
- if (c != null) {
- try {
- if (c.moveToFirst()) {
- // Remember it is filled via Intent.
- mDigitsFilledByIntent = true;
- // Put the number into the input area
- setFormattedDigits(c.getString(0), c.getString(1));
- return true;
- }
- } finally {
- c.close();
- }
- }
- }
- }
- }
- }
-
- return false;
- }
-
- /**
- * @see #showDialpadChooser(boolean)
- */
- private static boolean needToShowDialpadChooser(Intent intent, boolean isAddCallMode) {
- final String action = intent.getAction();
-
- boolean needToShowDialpadChooser = false;
-
- if (Intent.ACTION_DIAL.equals(action) || Intent.ACTION_VIEW.equals(action)) {
- Uri uri = intent.getData();
- if (uri == null) {
- // ACTION_DIAL or ACTION_VIEW with no data.
- // This behaves basically like ACTION_MAIN: If there's
- // already an active call, bring up an intermediate UI to
- // make the user confirm what they really want to do.
- // Be sure *not* to show the dialpad chooser if this is an
- // explicit "Add call" action, though.
- if (!isAddCallMode && phoneIsInUse()) {
- needToShowDialpadChooser = true;
- }
- }
- } else if (Intent.ACTION_MAIN.equals(action)) {
- // The MAIN action means we're bringing up a blank dialer
- // (e.g. by selecting the Home shortcut, or tabbing over from
- // Contacts or Call log.)
- //
- // At this point, IF there's already an active call, there's a
- // good chance that the user got here accidentally (but really
- // wanted the in-call dialpad instead). So we bring up an
- // intermediate UI to make the user confirm what they really
- // want to do.
- if (phoneIsInUse()) {
- // Log.i(TAG, "resolveIntent(): phone is in use; showing dialpad chooser!");
- needToShowDialpadChooser = true;
- }
- }
-
- return needToShowDialpadChooser;
- }
-
- private static boolean isAddCallMode(Intent intent) {
- final String action = intent.getAction();
- if (Intent.ACTION_DIAL.equals(action) || Intent.ACTION_VIEW.equals(action)) {
- // see if we are "adding a call" from the InCallScreen; false by default.
- return intent.getBooleanExtra(ADD_CALL_MODE_KEY, false);
- } else {
- return false;
- }
- }
-
- /**
- * Checks the given Intent and changes dialpad's UI state. For example, if the Intent requires
- * the screen to enter "Add Call" mode, this method will show correct UI for the mode.
- */
- public void configureScreenFromIntent(Intent intent) {
- if (!isLayoutReady()) {
- // This happens typically when parent's Activity#onNewIntent() is called while
- // Fragment#onCreateView() isn't called yet, and thus we cannot configure Views at
- // this point. onViewCreate() should call this method after preparing layouts, so
- // just ignore this call now.
- Log.i(TAG,
- "Screen configuration is requested before onCreateView() is called. Ignored");
- return;
- }
-
- boolean needToShowDialpadChooser = false;
-
- final boolean isAddCallMode = isAddCallMode(intent);
- if (!isAddCallMode) {
- final boolean digitsFilled = fillDigitsIfNecessary(intent);
- if (!digitsFilled) {
- needToShowDialpadChooser = needToShowDialpadChooser(intent, isAddCallMode);
- }
- }
- showDialpadChooser(needToShowDialpadChooser);
- }
-
- /**
- * Sets formatted digits to digits field.
- */
- private void setFormattedDigits(String data, String normalizedNumber) {
- // strip the non-dialable numbers out of the data string.
- String dialString = PhoneNumberUtils.extractNetworkPortion(data);
- dialString =
- PhoneNumberUtils.formatNumber(dialString, normalizedNumber, mCurrentCountryIso);
- if (!TextUtils.isEmpty(dialString)) {
- Editable digits = mDigits.getText();
- digits.replace(0, digits.length(), dialString);
- // for some reason this isn't getting called in the digits.replace call above..
- // but in any case, this will make sure the background drawable looks right
- afterTextChanged(digits);
- }
- }
-
- private void setupKeypad(View fragmentView) {
- int[] buttonIds = new int[] { R.id.one, R.id.two, R.id.three, R.id.four, R.id.five,
- R.id.six, R.id.seven, R.id.eight, R.id.nine, R.id.zero, R.id.star, R.id.pound};
- for (int id : buttonIds) {
- ((DialpadImageButton) fragmentView.findViewById(id)).setOnPressedListener(this);
- }
-
- // Long-pressing one button will initiate Voicemail.
- fragmentView.findViewById(R.id.one).setOnLongClickListener(this);
-
- // Long-pressing zero button will enter '+' instead.
- fragmentView.findViewById(R.id.zero).setOnLongClickListener(this);
-
- }
-
- @Override
- public void onResume() {
- super.onResume();
-
- final StopWatch stopWatch = StopWatch.start("Dialpad.onResume");
-
- // Query the last dialed number. Do it first because hitting
- // the DB is 'slow'. This call is asynchronous.
- queryLastOutgoingCall();
-
- stopWatch.lap("qloc");
-
- // retrieve the DTMF tone play back setting.
- mDTMFToneEnabled = Settings.System.getInt(getActivity().getContentResolver(),
- Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
-
- stopWatch.lap("dtwd");
-
- // Retrieve the haptic feedback setting.
- mHaptic.checkSystemSetting();
-
- stopWatch.lap("hptc");
-
- // if the mToneGenerator creation fails, just continue without it. It is
- // a local audio signal, and is not as important as the dtmf tone itself.
- synchronized (mToneGeneratorLock) {
- if (mToneGenerator == null) {
- try {
- mToneGenerator = new ToneGenerator(DIAL_TONE_STREAM_TYPE, TONE_RELATIVE_VOLUME);
- } catch (RuntimeException e) {
- Log.w(TAG, "Exception caught while creating local tone generator: " + e);
- mToneGenerator = null;
- }
- }
- }
- stopWatch.lap("tg");
- // Prevent unnecessary confusion. Reset the press count anyway.
- mDialpadPressCount = 0;
-
- Activity parent = getActivity();
- if (parent instanceof DialtactsActivity) {
- // See if we were invoked with a DIAL intent. If we were, fill in the appropriate
- // digits in the dialer field.
- fillDigitsIfNecessary(parent.getIntent());
- }
-
- stopWatch.lap("fdin");
-
- // While we're in the foreground, listen for phone state changes,
- // purely so that we can take down the "dialpad chooser" if the
- // phone becomes idle while the chooser UI is visible.
- TelephonyManager telephonyManager =
- (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
- telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
-
- stopWatch.lap("tm");
-
- // Potentially show hint text in the mDigits field when the user
- // hasn't typed any digits yet. (If there's already an active call,
- // this hint text will remind the user that he's about to add a new
- // call.)
- //
- // TODO: consider adding better UI for the case where *both* lines
- // are currently in use. (Right now we let the user try to add
- // another call, but that call is guaranteed to fail. Perhaps the
- // entire dialer UI should be disabled instead.)
- if (phoneIsInUse()) {
- final SpannableString hint = new SpannableString(
- getActivity().getString(R.string.dialerDialpadHintText));
- hint.setSpan(new RelativeSizeSpan(0.8f), 0, hint.length(), 0);
- mDigits.setHint(hint);
- } else {
- // Common case; no hint necessary.
- mDigits.setHint(null);
-
- // Also, a sanity-check: the "dialpad chooser" UI should NEVER
- // be visible if the phone is idle!
- showDialpadChooser(false);
- }
-
- stopWatch.lap("hnt");
-
- updateDialAndDeleteButtonEnabledState();
-
- stopWatch.lap("bes");
-
- stopWatch.stopAndLog(TAG, 50);
- }
-
- @Override
- public void onPause() {
- super.onPause();
-
- // Stop listening for phone state changes.
- TelephonyManager telephonyManager =
- (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
- telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
-
- // Make sure we don't leave this activity with a tone still playing.
- stopTone();
- // Just in case reset the counter too.
- mDialpadPressCount = 0;
-
- synchronized (mToneGeneratorLock) {
- if (mToneGenerator != null) {
- mToneGenerator.release();
- mToneGenerator = null;
- }
- }
- // TODO: I wonder if we should not check if the AsyncTask that
- // lookup the last dialed number has completed.
- mLastNumberDialed = EMPTY_NUMBER; // Since we are going to query again, free stale number.
-
- SpecialCharSequenceMgr.cleanup();
- }
-
- @Override
- public void onStop() {
- super.onStop();
- if (mClearDigitsOnStop) {
- mClearDigitsOnStop = false;
- mDigits.getText().clear();
- }
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putBoolean(PREF_DIGITS_FILLED_BY_INTENT, mDigitsFilledByIntent);
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- super.onCreateOptionsMenu(menu, inflater);
- // Landscape dialer uses the real actionbar menu, whereas portrait uses a fake one
- // that is created using constructPopupMenu()
- if (ContactsUtils.isLandscape(this.getActivity()) ||
- ViewConfiguration.get(getActivity()).hasPermanentMenuKey() &&
- isLayoutReady() && mDialpadChooser != null) {
- inflater.inflate(R.menu.dialpad_options, menu);
- }
- }
-
- @Override
- public void onPrepareOptionsMenu(Menu menu) {
- // Hardware menu key should be available and Views should already be ready.
- if (ContactsUtils.isLandscape(this.getActivity()) ||
- ViewConfiguration.get(getActivity()).hasPermanentMenuKey() &&
- isLayoutReady() && mDialpadChooser != null) {
- setupMenuItems(menu);
- }
- }
-
- private void setupMenuItems(Menu menu) {
- final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings_dialpad);
- final MenuItem addToContactMenuItem = menu.findItem(R.id.menu_add_contacts);
- final MenuItem twoSecPauseMenuItem = menu.findItem(R.id.menu_2s_pause);
- final MenuItem waitMenuItem = menu.findItem(R.id.menu_add_wait);
-
- // Check if all the menu items are inflated correctly. As a shortcut, we assume all menu
- // items are ready if the first item is non-null.
- if (callSettingsMenuItem == null) {
- return;
- }
-
- final Activity activity = getActivity();
- if (activity != null && ViewConfiguration.get(activity).hasPermanentMenuKey()) {
- // Call settings should be available via its parent Activity.
- callSettingsMenuItem.setVisible(false);
- } else {
- callSettingsMenuItem.setVisible(true);
- callSettingsMenuItem.setIntent(DialtactsActivity.getCallSettingsIntent());
- }
-
- // We show "add to contacts", "2sec pause", and "add wait" menus only when the user is
- // seeing usual dialpads and has typed at least one digit.
- // We never show a menu if the "choose dialpad" UI is up.
- if (dialpadChooserVisible() || isDigitsEmpty()) {
- addToContactMenuItem.setVisible(false);
- twoSecPauseMenuItem.setVisible(false);
- waitMenuItem.setVisible(false);
- } else {
- final CharSequence digits = mDigits.getText();
-
- // Put the current digits string into an intent
- addToContactMenuItem.setIntent(getAddToContactIntent(digits));
- addToContactMenuItem.setVisible(true);
-
- // Check out whether to show Pause & Wait option menu items
- int selectionStart;
- int selectionEnd;
- String strDigits = digits.toString();
-
- selectionStart = mDigits.getSelectionStart();
- selectionEnd = mDigits.getSelectionEnd();
-
- if (selectionStart != -1) {
- if (selectionStart > selectionEnd) {
- // swap it as we want start to be less then end
- int tmp = selectionStart;
- selectionStart = selectionEnd;
- selectionEnd = tmp;
- }
-
- if (selectionStart != 0) {
- // Pause can be visible if cursor is not in the begining
- twoSecPauseMenuItem.setVisible(true);
-
- // For Wait to be visible set of condition to meet
- waitMenuItem.setVisible(showWait(selectionStart, selectionEnd, strDigits));
- } else {
- // cursor in the beginning both pause and wait to be invisible
- twoSecPauseMenuItem.setVisible(false);
- waitMenuItem.setVisible(false);
- }
- } else {
- twoSecPauseMenuItem.setVisible(true);
-
- // cursor is not selected so assume new digit is added to the end
- int strLength = strDigits.length();
- waitMenuItem.setVisible(showWait(strLength, strLength, strDigits));
- }
- }
- }
-
- private static Intent getAddToContactIntent(CharSequence digits) {
- final Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
- intent.putExtra(Insert.PHONE, digits);
- intent.setType(People.CONTENT_ITEM_TYPE);
- return intent;
- }
-
- private void keyPressed(int keyCode) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_1:
- playTone(ToneGenerator.TONE_DTMF_1, TONE_LENGTH_INFINITE);
- break;
- case KeyEvent.KEYCODE_2:
- playTone(ToneGenerator.TONE_DTMF_2, TONE_LENGTH_INFINITE);
- break;
- case KeyEvent.KEYCODE_3:
- playTone(ToneGenerator.TONE_DTMF_3, TONE_LENGTH_INFINITE);
- break;
- case KeyEvent.KEYCODE_4:
- playTone(ToneGenerator.TONE_DTMF_4, TONE_LENGTH_INFINITE);
- break;
- case KeyEvent.KEYCODE_5:
- playTone(ToneGenerator.TONE_DTMF_5, TONE_LENGTH_INFINITE);
- break;
- case KeyEvent.KEYCODE_6:
- playTone(ToneGenerator.TONE_DTMF_6, TONE_LENGTH_INFINITE);
- break;
- case KeyEvent.KEYCODE_7:
- playTone(ToneGenerator.TONE_DTMF_7, TONE_LENGTH_INFINITE);
- break;
- case KeyEvent.KEYCODE_8:
- playTone(ToneGenerator.TONE_DTMF_8, TONE_LENGTH_INFINITE);
- break;
- case KeyEvent.KEYCODE_9:
- playTone(ToneGenerator.TONE_DTMF_9, TONE_LENGTH_INFINITE);
- break;
- case KeyEvent.KEYCODE_0:
- playTone(ToneGenerator.TONE_DTMF_0, TONE_LENGTH_INFINITE);
- break;
- case KeyEvent.KEYCODE_POUND:
- playTone(ToneGenerator.TONE_DTMF_P, TONE_LENGTH_INFINITE);
- break;
- case KeyEvent.KEYCODE_STAR:
- playTone(ToneGenerator.TONE_DTMF_S, TONE_LENGTH_INFINITE);
- break;
- default:
- break;
- }
-
- mHaptic.vibrate();
- KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
- mDigits.onKeyDown(keyCode, event);
-
- // If the cursor is at the end of the text we hide it.
- final int length = mDigits.length();
- if (length == mDigits.getSelectionStart() && length == mDigits.getSelectionEnd()) {
- mDigits.setCursorVisible(false);
- }
- }
-
- @Override
- public boolean onKey(View view, int keyCode, KeyEvent event) {
- switch (view.getId()) {
- case R.id.digits:
- if (keyCode == KeyEvent.KEYCODE_ENTER) {
- dialButtonPressed();
- return true;
- }
- break;
- }
- return false;
- }
-
- /**
- * When a key is pressed, we start playing DTMF tone, do vibration, and enter the digit
- * immediately. When a key is released, we stop the tone. Note that the "key press" event will
- * be delivered by the system with certain amount of delay, it won't be synced with user's
- * actual "touch-down" behavior.
- */
- @Override
- public void onPressed(View view, boolean pressed) {
- if (DEBUG) Log.d(TAG, "onPressed(). view: " + view + ", pressed: " + pressed);
- if (pressed) {
- switch (view.getId()) {
- case R.id.one: {
- keyPressed(KeyEvent.KEYCODE_1);
- break;
- }
- case R.id.two: {
- keyPressed(KeyEvent.KEYCODE_2);
- break;
- }
- case R.id.three: {
- keyPressed(KeyEvent.KEYCODE_3);
- break;
- }
- case R.id.four: {
- keyPressed(KeyEvent.KEYCODE_4);
- break;
- }
- case R.id.five: {
- keyPressed(KeyEvent.KEYCODE_5);
- break;
- }
- case R.id.six: {
- keyPressed(KeyEvent.KEYCODE_6);
- break;
- }
- case R.id.seven: {
- keyPressed(KeyEvent.KEYCODE_7);
- break;
- }
- case R.id.eight: {
- keyPressed(KeyEvent.KEYCODE_8);
- break;
- }
- case R.id.nine: {
- keyPressed(KeyEvent.KEYCODE_9);
- break;
- }
- case R.id.zero: {
- keyPressed(KeyEvent.KEYCODE_0);
- break;
- }
- case R.id.pound: {
- keyPressed(KeyEvent.KEYCODE_POUND);
- break;
- }
- case R.id.star: {
- keyPressed(KeyEvent.KEYCODE_STAR);
- break;
- }
- default: {
- Log.wtf(TAG, "Unexpected onTouch(ACTION_DOWN) event from: " + view);
- break;
- }
- }
- mDialpadPressCount++;
- } else {
- view.jumpDrawablesToCurrentState();
- mDialpadPressCount--;
- if (mDialpadPressCount < 0) {
- // e.g.
- // - when the user action is detected as horizontal swipe, at which only
- // "up" event is thrown.
- // - when the user long-press '0' button, at which dialpad will decrease this count
- // while it still gets press-up event here.
- if (DEBUG) Log.d(TAG, "mKeyPressCount become negative.");
- stopTone();
- mDialpadPressCount = 0;
- } else if (mDialpadPressCount == 0) {
- stopTone();
- }
- }
- }
-
- @Override
- public void onClick(View view) {
- switch (view.getId()) {
- case R.id.deleteButton: {
- keyPressed(KeyEvent.KEYCODE_DEL);
- return;
- }
- case R.id.dialButton: {
- mHaptic.vibrate(); // Vibrate here too, just like we do for the regular keys
- dialButtonPressed();
- return;
- }
- case R.id.digits: {
- if (!isDigitsEmpty()) {
- mDigits.setCursorVisible(true);
- }
- return;
- }
- default: {
- Log.wtf(TAG, "Unexpected onClick() event from: " + view);
- return;
- }
- }
- }
-
- public PopupMenu constructPopupMenu(View anchorView) {
- final Context context = getActivity();
- if (context == null) {
- return null;
- }
- final PopupMenu popupMenu = new PopupMenu(context, anchorView);
- final Menu menu = popupMenu.getMenu();
- popupMenu.inflate(R.menu.dialpad_options);
- popupMenu.setOnMenuItemClickListener(this);
- setupMenuItems(menu);
- return popupMenu;
- }
-
- @Override
- public boolean onLongClick(View view) {
- final Editable digits = mDigits.getText();
- final int id = view.getId();
- switch (id) {
- case R.id.deleteButton: {
- digits.clear();
- // TODO: The framework forgets to clear the pressed
- // status of disabled button. Until this is fixed,
- // clear manually the pressed status. b/2133127
- mDelete.setPressed(false);
- return true;
- }
- case R.id.one: {
- // '1' may be already entered since we rely on onTouch() event for numeric buttons.
- // Just for safety we also check if the digits field is empty or not.
- if (isDigitsEmpty() || TextUtils.equals(mDigits.getText(), "1")) {
- // We'll try to initiate voicemail and thus we want to remove irrelevant string.
- removePreviousDigitIfPossible();
-
- if (isVoicemailAvailable()) {
- callVoicemail();
- } else if (getActivity() != null) {
- // Voicemail is unavailable maybe because Airplane mode is turned on.
- // Check the current status and show the most appropriate error message.
- final boolean isAirplaneModeOn =
- Settings.System.getInt(getActivity().getContentResolver(),
- Settings.System.AIRPLANE_MODE_ON, 0) != 0;
- if (isAirplaneModeOn) {
- DialogFragment dialogFragment = ErrorDialogFragment.newInstance(
- R.string.dialog_voicemail_airplane_mode_message);
- dialogFragment.show(getFragmentManager(),
- "voicemail_request_during_airplane_mode");
- } else {
- DialogFragment dialogFragment = ErrorDialogFragment.newInstance(
- R.string.dialog_voicemail_not_ready_message);
- dialogFragment.show(getFragmentManager(), "voicemail_not_ready");
- }
- }
- return true;
- }
- return false;
- }
- case R.id.zero: {
- // Remove tentative input ('0') done by onTouch().
- removePreviousDigitIfPossible();
- keyPressed(KeyEvent.KEYCODE_PLUS);
-
- // Stop tone immediately and decrease the press count, so that possible subsequent
- // dial button presses won't honor the 0 click any more.
- // Note: this *will* make mDialpadPressCount negative when the 0 key is released,
- // which should be handled appropriately.
- stopTone();
- if (mDialpadPressCount > 0) mDialpadPressCount--;
-
- return true;
- }
- case R.id.digits: {
- // Right now EditText does not show the "paste" option when cursor is not visible.
- // To show that, make the cursor visible, and return false, letting the EditText
- // show the option by itself.
- mDigits.setCursorVisible(true);
- return false;
- }
- case R.id.dialButton: {
- if (isDigitsEmpty()) {
- handleDialButtonClickWithEmptyDigits();
- // This event should be consumed so that onClick() won't do the exactly same
- // thing.
- return true;
- } else {
- return false;
- }
- }
- }
- return false;
- }
-
- /**
- * Remove the digit just before the current position. This can be used if we want to replace
- * the previous digit or cancel previously entered character.
- */
- private void removePreviousDigitIfPossible() {
- final Editable editable = mDigits.getText();
- final int currentPosition = mDigits.getSelectionStart();
- if (currentPosition > 0) {
- mDigits.setSelection(currentPosition);
- mDigits.getText().delete(currentPosition - 1, currentPosition);
- }
- }
-
- public void callVoicemail() {
- startActivity(ContactsUtils.getVoicemailIntent());
- mClearDigitsOnStop = true;
- getActivity().finish();
- }
-
- public static class ErrorDialogFragment extends DialogFragment {
- private int mTitleResId;
- private int mMessageResId;
-
- private static final String ARG_TITLE_RES_ID = "argTitleResId";
- private static final String ARG_MESSAGE_RES_ID = "argMessageResId";
-
- public static ErrorDialogFragment newInstance(int messageResId) {
- return newInstance(0, messageResId);
- }
-
- public static ErrorDialogFragment newInstance(int titleResId, int messageResId) {
- final ErrorDialogFragment fragment = new ErrorDialogFragment();
- final Bundle args = new Bundle();
- args.putInt(ARG_TITLE_RES_ID, titleResId);
- args.putInt(ARG_MESSAGE_RES_ID, messageResId);
- fragment.setArguments(args);
- return fragment;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mTitleResId = getArguments().getInt(ARG_TITLE_RES_ID);
- mMessageResId = getArguments().getInt(ARG_MESSAGE_RES_ID);
- }
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
- if (mTitleResId != 0) {
- builder.setTitle(mTitleResId);
- }
- if (mMessageResId != 0) {
- builder.setMessage(mMessageResId);
- }
- builder.setPositiveButton(android.R.string.ok,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dismiss();
- }
- });
- return builder.create();
- }
- }
-
- /**
- * In most cases, when the dial button is pressed, there is a
- * number in digits area. Pack it in the intent, start the
- * outgoing call broadcast as a separate task and finish this
- * activity.
- *
- * When there is no digit and the phone is CDMA and off hook,
- * we're sending a blank flash for CDMA. CDMA networks use Flash
- * messages when special processing needs to be done, mainly for
- * 3-way or call waiting scenarios. Presumably, here we're in a
- * special 3-way scenario where the network needs a blank flash
- * before being able to add the new participant. (This is not the
- * case with all 3-way calls, just certain CDMA infrastructures.)
- *
- * Otherwise, there is no digit, display the last dialed
- * number. Don't finish since the user may want to edit it. The
- * user needs to press the dial button again, to dial it (general
- * case described above).
- */
- public void dialButtonPressed() {
- if (isDigitsEmpty()) { // No number entered.
- handleDialButtonClickWithEmptyDigits();
- } else {
- final String number = mDigits.getText().toString();
-
- // "persist.radio.otaspdial" is a temporary hack needed for one carrier's automated
- // test equipment.
- // TODO: clean it up.
- if (number != null
- && !TextUtils.isEmpty(mProhibitedPhoneNumberRegexp)
- && number.matches(mProhibitedPhoneNumberRegexp)
- && (SystemProperties.getInt("persist.radio.otaspdial", 0) != 1)) {
- Log.i(TAG, "The phone number is prohibited explicitly by a rule.");
- if (getActivity() != null) {
- DialogFragment dialogFragment = ErrorDialogFragment.newInstance(
- R.string.dialog_phone_call_prohibited_message);
- dialogFragment.show(getFragmentManager(), "phone_prohibited_dialog");
- }
-
- // Clear the digits just in case.
- mDigits.getText().clear();
- } else {
- final Intent intent = ContactsUtils.getCallIntent(number,
- (getActivity() instanceof DialtactsActivity ?
- ((DialtactsActivity)getActivity()).getCallOrigin() : null));
- startActivity(intent);
- mClearDigitsOnStop = true;
- getActivity().finish();
- }
- }
- }
-
- private void handleDialButtonClickWithEmptyDigits() {
- if (phoneIsCdma() && phoneIsOffhook()) {
- // This is really CDMA specific. On GSM is it possible
- // to be off hook and wanted to add a 3rd party using
- // the redial feature.
- startActivity(newFlashIntent());
- } else {
- if (!TextUtils.isEmpty(mLastNumberDialed)) {
- // Recall the last number dialed.
- mDigits.setText(mLastNumberDialed);
-
- // ...and move the cursor to the end of the digits string,
- // so you'll be able to delete digits using the Delete
- // button (just as if you had typed the number manually.)
- //
- // Note we use mDigits.getText().length() here, not
- // mLastNumberDialed.length(), since the EditText widget now
- // contains a *formatted* version of mLastNumberDialed (due to
- // mTextWatcher) and its length may have changed.
- mDigits.setSelection(mDigits.getText().length());
- } else {
- // There's no "last number dialed" or the
- // background query is still running. There's
- // nothing useful for the Dial button to do in
- // this case. Note: with a soft dial button, this
- // can never happens since the dial button is
- // disabled under these conditons.
- playTone(ToneGenerator.TONE_PROP_NACK);
- }
- }
- }
-
- /**
- * Plays the specified tone for TONE_LENGTH_MS milliseconds.
- */
- private void playTone(int tone) {
- playTone(tone, TONE_LENGTH_MS);
- }
-
- /**
- * Play the specified tone for the specified milliseconds
- *
- * The tone is played locally, using the audio stream for phone calls.
- * Tones are played only if the "Audible touch tones" user preference
- * is checked, and are NOT played if the device is in silent mode.
- *
- * The tone length can be -1, meaning "keep playing the tone." If the caller does so, it should
- * call stopTone() afterward.
- *
- * @param tone a tone code from {@link ToneGenerator}
- * @param durationMs tone length.
- */
- private void playTone(int tone, int durationMs) {
- // if local tone playback is disabled, just return.
- if (!mDTMFToneEnabled) {
- return;
- }
-
- // Also do nothing if the phone is in silent mode.
- // We need to re-check the ringer mode for *every* playTone()
- // call, rather than keeping a local flag that's updated in
- // onResume(), since it's possible to toggle silent mode without
- // leaving the current activity (via the ENDCALL-longpress menu.)
- AudioManager audioManager =
- (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
- int ringerMode = audioManager.getRingerMode();
- if ((ringerMode == AudioManager.RINGER_MODE_SILENT)
- || (ringerMode == AudioManager.RINGER_MODE_VIBRATE)) {
- return;
- }
-
- synchronized (mToneGeneratorLock) {
- if (mToneGenerator == null) {
- Log.w(TAG, "playTone: mToneGenerator == null, tone: " + tone);
- return;
- }
-
- // Start the new tone (will stop any playing tone)
- mToneGenerator.startTone(tone, durationMs);
- }
- }
-
- /**
- * Stop the tone if it is played.
- */
- private void stopTone() {
- // if local tone playback is disabled, just return.
- if (!mDTMFToneEnabled) {
- return;
- }
- synchronized (mToneGeneratorLock) {
- if (mToneGenerator == null) {
- Log.w(TAG, "stopTone: mToneGenerator == null");
- return;
- }
- mToneGenerator.stopTone();
- }
- }
-
- /**
- * Brings up the "dialpad chooser" UI in place of the usual Dialer
- * elements (the textfield/button and the dialpad underneath).
- *
- * We show this UI if the user brings up the Dialer while a call is
- * already in progress, since there's a good chance we got here
- * accidentally (and the user really wanted the in-call dialpad instead).
- * So in this situation we display an intermediate UI that lets the user
- * explicitly choose between the in-call dialpad ("Use touch tone
- * keypad") and the regular Dialer ("Add call"). (Or, the option "Return
- * to call in progress" just goes back to the in-call UI with no dialpad
- * at all.)
- *
- * @param enabled If true, show the "dialpad chooser" instead
- * of the regular Dialer UI
- */
- private void showDialpadChooser(boolean enabled) {
- // Check if onCreateView() is already called by checking one of View objects.
- if (!isLayoutReady()) {
- return;
- }
-
- if (enabled) {
- // Log.i(TAG, "Showing dialpad chooser!");
- if (mDigitsContainer != null) {
- mDigitsContainer.setVisibility(View.GONE);
- } else {
- // mDigits is not enclosed by the container. Make the digits field itself gone.
- mDigits.setVisibility(View.GONE);
- }
- if (mDialpad != null) mDialpad.setVisibility(View.GONE);
- if (mDialButtonContainer != null) mDialButtonContainer.setVisibility(View.GONE);
-
- mDialpadChooser.setVisibility(View.VISIBLE);
-
- // Instantiate the DialpadChooserAdapter and hook it up to the
- // ListView. We do this only once.
- if (mDialpadChooserAdapter == null) {
- mDialpadChooserAdapter = new DialpadChooserAdapter(getActivity());
- }
- mDialpadChooser.setAdapter(mDialpadChooserAdapter);
- } else {
- // Log.i(TAG, "Displaying normal Dialer UI.");
- if (mDigitsContainer != null) {
- mDigitsContainer.setVisibility(View.VISIBLE);
- } else {
- mDigits.setVisibility(View.VISIBLE);
- }
- if (mDialpad != null) mDialpad.setVisibility(View.VISIBLE);
- if (mDialButtonContainer != null) mDialButtonContainer.setVisibility(View.VISIBLE);
- mDialpadChooser.setVisibility(View.GONE);
- }
- }
-
- /**
- * @return true if we're currently showing the "dialpad chooser" UI.
- */
- private boolean dialpadChooserVisible() {
- return mDialpadChooser.getVisibility() == View.VISIBLE;
- }
-
- /**
- * Simple list adapter, binding to an icon + text label
- * for each item in the "dialpad chooser" list.
- */
- private static class DialpadChooserAdapter extends BaseAdapter {
- private LayoutInflater mInflater;
-
- // Simple struct for a single "choice" item.
- static class ChoiceItem {
- String text;
- Bitmap icon;
- int id;
-
- public ChoiceItem(String s, Bitmap b, int i) {
- text = s;
- icon = b;
- id = i;
- }
- }
-
- // IDs for the possible "choices":
- static final int DIALPAD_CHOICE_USE_DTMF_DIALPAD = 101;
- static final int DIALPAD_CHOICE_RETURN_TO_CALL = 102;
- static final int DIALPAD_CHOICE_ADD_NEW_CALL = 103;
-
- private static final int NUM_ITEMS = 3;
- private ChoiceItem mChoiceItems[] = new ChoiceItem[NUM_ITEMS];
-
- public DialpadChooserAdapter(Context context) {
- // Cache the LayoutInflate to avoid asking for a new one each time.
- mInflater = LayoutInflater.from(context);
-
- // Initialize the possible choices.
- // TODO: could this be specified entirely in XML?
-
- // - "Use touch tone keypad"
- mChoiceItems[0] = new ChoiceItem(
- context.getString(R.string.dialer_useDtmfDialpad),
- BitmapFactory.decodeResource(context.getResources(),
- R.drawable.ic_dialer_fork_tt_keypad),
- DIALPAD_CHOICE_USE_DTMF_DIALPAD);
-
- // - "Return to call in progress"
- mChoiceItems[1] = new ChoiceItem(
- context.getString(R.string.dialer_returnToInCallScreen),
- BitmapFactory.decodeResource(context.getResources(),
- R.drawable.ic_dialer_fork_current_call),
- DIALPAD_CHOICE_RETURN_TO_CALL);
-
- // - "Add call"
- mChoiceItems[2] = new ChoiceItem(
- context.getString(R.string.dialer_addAnotherCall),
- BitmapFactory.decodeResource(context.getResources(),
- R.drawable.ic_dialer_fork_add_call),
- DIALPAD_CHOICE_ADD_NEW_CALL);
- }
-
- @Override
- public int getCount() {
- return NUM_ITEMS;
- }
-
- /**
- * Return the ChoiceItem for a given position.
- */
- @Override
- public Object getItem(int position) {
- return mChoiceItems[position];
- }
-
- /**
- * Return a unique ID for each possible choice.
- */
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- /**
- * Make a view for each row.
- */
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- // When convertView is non-null, we can reuse it (there's no need
- // to reinflate it.)
- if (convertView == null) {
- convertView = mInflater.inflate(R.layout.dialpad_chooser_list_item, null);
- }
-
- TextView text = (TextView) convertView.findViewById(R.id.text);
- text.setText(mChoiceItems[position].text);
-
- ImageView icon = (ImageView) convertView.findViewById(R.id.icon);
- icon.setImageBitmap(mChoiceItems[position].icon);
-
- return convertView;
- }
- }
-
- /**
- * Handle clicks from the dialpad chooser.
- */
- @Override
- public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
- DialpadChooserAdapter.ChoiceItem item =
- (DialpadChooserAdapter.ChoiceItem) parent.getItemAtPosition(position);
- int itemId = item.id;
- switch (itemId) {
- case DialpadChooserAdapter.DIALPAD_CHOICE_USE_DTMF_DIALPAD:
- // Log.i(TAG, "DIALPAD_CHOICE_USE_DTMF_DIALPAD");
- // Fire off an intent to go back to the in-call UI
- // with the dialpad visible.
- returnToInCallScreen(true);
- break;
-
- case DialpadChooserAdapter.DIALPAD_CHOICE_RETURN_TO_CALL:
- // Log.i(TAG, "DIALPAD_CHOICE_RETURN_TO_CALL");
- // Fire off an intent to go back to the in-call UI
- // (with the dialpad hidden).
- returnToInCallScreen(false);
- break;
-
- case DialpadChooserAdapter.DIALPAD_CHOICE_ADD_NEW_CALL:
- // Log.i(TAG, "DIALPAD_CHOICE_ADD_NEW_CALL");
- // Ok, guess the user really did want to be here (in the
- // regular Dialer) after all. Bring back the normal Dialer UI.
- showDialpadChooser(false);
- break;
-
- default:
- Log.w(TAG, "onItemClick: unexpected itemId: " + itemId);
- break;
- }
- }
-
- /**
- * Returns to the in-call UI (where there's presumably a call in
- * progress) in response to the user selecting "use touch tone keypad"
- * or "return to call" from the dialpad chooser.
- */
- private void returnToInCallScreen(boolean showDialpad) {
- try {
- ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
- if (phone != null) phone.showCallScreenWithDialpad(showDialpad);
- } catch (RemoteException e) {
- Log.w(TAG, "phone.showCallScreenWithDialpad() failed", e);
- }
-
- // Finally, finish() ourselves so that we don't stay on the
- // activity stack.
- // Note that we do this whether or not the showCallScreenWithDialpad()
- // call above had any effect or not! (That call is a no-op if the
- // phone is idle, which can happen if the current call ends while
- // the dialpad chooser is up. In this case we can't show the
- // InCallScreen, and there's no point staying here in the Dialer,
- // so we just take the user back where he came from...)
- getActivity().finish();
- }
-
- /**
- * @return true if the phone is "in use", meaning that at least one line
- * is active (ie. off hook or ringing or dialing).
- */
- public static boolean phoneIsInUse() {
- boolean phoneInUse = false;
- try {
- ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
- if (phone != null) phoneInUse = !phone.isIdle();
- } catch (RemoteException e) {
- Log.w(TAG, "phone.isIdle() failed", e);
- }
- return phoneInUse;
- }
-
- /**
- * @return true if the phone is a CDMA phone type
- */
- private boolean phoneIsCdma() {
- boolean isCdma = false;
- try {
- ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
- if (phone != null) {
- isCdma = (phone.getActivePhoneType() == TelephonyManager.PHONE_TYPE_CDMA);
- }
- } catch (RemoteException e) {
- Log.w(TAG, "phone.getActivePhoneType() failed", e);
- }
- return isCdma;
- }
-
- /**
- * @return true if the phone state is OFFHOOK
- */
- private boolean phoneIsOffhook() {
- boolean phoneOffhook = false;
- try {
- ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
- if (phone != null) phoneOffhook = phone.isOffhook();
- } catch (RemoteException e) {
- Log.w(TAG, "phone.isOffhook() failed", e);
- }
- return phoneOffhook;
- }
-
- /**
- * Returns true whenever any one of the options from the menu is selected.
- * Code changes to support dialpad options
- */
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.menu_2s_pause:
- updateDialString(",");
- return true;
- case R.id.menu_add_wait:
- updateDialString(";");
- return true;
- default:
- return false;
- }
- }
-
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- return onOptionsItemSelected(item);
- }
-
- /**
- * Updates the dial string (mDigits) after inserting a Pause character (,)
- * or Wait character (;).
- */
- private void updateDialString(String newDigits) {
- int selectionStart;
- int selectionEnd;
-
- // SpannableStringBuilder editable_text = new SpannableStringBuilder(mDigits.getText());
- int anchor = mDigits.getSelectionStart();
- int point = mDigits.getSelectionEnd();
-
- selectionStart = Math.min(anchor, point);
- selectionEnd = Math.max(anchor, point);
-
- Editable digits = mDigits.getText();
- if (selectionStart != -1) {
- if (selectionStart == selectionEnd) {
- // then there is no selection. So insert the pause at this
- // position and update the mDigits.
- digits.replace(selectionStart, selectionStart, newDigits);
- } else {
- digits.replace(selectionStart, selectionEnd, newDigits);
- // Unselect: back to a regular cursor, just pass the character inserted.
- mDigits.setSelection(selectionStart + 1);
- }
- } else {
- int len = mDigits.length();
- digits.replace(len, len, newDigits);
- }
- }
-
- /**
- * Update the enabledness of the "Dial" and "Backspace" buttons if applicable.
- */
- private void updateDialAndDeleteButtonEnabledState() {
- final boolean digitsNotEmpty = !isDigitsEmpty();
-
- if (mDialButton != null) {
- // On CDMA phones, if we're already on a call, we *always*
- // enable the Dial button (since you can press it without
- // entering any digits to send an empty flash.)
- if (phoneIsCdma() && phoneIsOffhook()) {
- mDialButton.setEnabled(true);
- } else {
- // Common case: GSM, or CDMA but not on a call.
- // Enable the Dial button if some digits have
- // been entered, or if there is a last dialed number
- // that could be redialed.
- mDialButton.setEnabled(digitsNotEmpty ||
- !TextUtils.isEmpty(mLastNumberDialed));
- }
- }
- mDelete.setEnabled(digitsNotEmpty);
- }
-
- /**
- * Check if voicemail is enabled/accessible.
- *
- * @return true if voicemail is enabled and accessibly. Note that this can be false
- * "temporarily" after the app boot.
- * @see TelephonyManager#getVoiceMailNumber()
- */
- private boolean isVoicemailAvailable() {
- try {
- return (TelephonyManager.getDefault().getVoiceMailNumber() != null);
- } catch (SecurityException se) {
- // Possibly no READ_PHONE_STATE privilege.
- Log.w(TAG, "SecurityException is thrown. Maybe privilege isn't sufficient.");
- }
- return false;
- }
-
- /**
- * This function return true if Wait menu item can be shown
- * otherwise returns false. Assumes the passed string is non-empty
- * and the 0th index check is not required.
- */
- private static boolean showWait(int start, int end, String digits) {
- if (start == end) {
- // visible false in this case
- if (start > digits.length()) return false;
-
- // preceding char is ';', so visible should be false
- if (digits.charAt(start - 1) == ';') return false;
-
- // next char is ';', so visible should be false
- if ((digits.length() > start) && (digits.charAt(start) == ';')) return false;
- } else {
- // visible false in this case
- if (start > digits.length() || end > digits.length()) return false;
-
- // In this case we need to just check for ';' preceding to start
- // or next to end
- if (digits.charAt(start - 1) == ';') return false;
- }
- return true;
- }
-
- /**
- * @return true if the widget with the phone number digits is empty.
- */
- private boolean isDigitsEmpty() {
- return mDigits.length() == 0;
- }
-
- /**
- * Starts the asyn query to get the last dialed/outgoing
- * number. When the background query finishes, mLastNumberDialed
- * is set to the last dialed number or an empty string if none
- * exists yet.
- */
- private void queryLastOutgoingCall() {
- mLastNumberDialed = EMPTY_NUMBER;
- CallLogAsync.GetLastOutgoingCallArgs lastCallArgs =
- new CallLogAsync.GetLastOutgoingCallArgs(
- getActivity(),
- new CallLogAsync.OnLastOutgoingCallComplete() {
- @Override
- public void lastOutgoingCall(String number) {
- // TODO: Filter out emergency numbers if
- // the carrier does not want redial for
- // these.
- mLastNumberDialed = number;
- updateDialAndDeleteButtonEnabledState();
- }
- });
- mCallLog.getLastOutgoingCall(lastCallArgs);
- }
-
- private Intent newFlashIntent() {
- final Intent intent = ContactsUtils.getCallIntent(EMPTY_NUMBER);
- intent.putExtra(EXTRA_SEND_EMPTY_FLASH, true);
- return intent;
- }
-}
diff --git a/src/com/android/contacts/dialpad/DialpadImageButton.java b/src/com/android/contacts/dialpad/DialpadImageButton.java
deleted file mode 100644
index 040eeb4..0000000
--- a/src/com/android/contacts/dialpad/DialpadImageButton.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.dialpad;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.accessibility.AccessibilityManager;
-import android.widget.ImageButton;
-
-/**
- * Custom {@link ImageButton} for dialpad buttons.
- * <p>
- * This class implements lift-to-type interaction when touch exploration is
- * enabled.
- */
-public class DialpadImageButton extends ImageButton {
- /** Accessibility manager instance used to check touch exploration state. */
- private AccessibilityManager mAccessibilityManager;
-
- /** Bounds used to filter HOVER_EXIT events. */
- private Rect mHoverBounds = new Rect();
-
- public interface OnPressedListener {
- public void onPressed(View view, boolean pressed);
- }
-
- private OnPressedListener mOnPressedListener;
-
- public void setOnPressedListener(OnPressedListener onPressedListener) {
- mOnPressedListener = onPressedListener;
- }
-
- public DialpadImageButton(Context context, AttributeSet attrs) {
- super(context, attrs);
- initForAccessibility(context);
- }
-
- public DialpadImageButton(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- initForAccessibility(context);
- }
-
- private void initForAccessibility(Context context) {
- mAccessibilityManager = (AccessibilityManager) context.getSystemService(
- Context.ACCESSIBILITY_SERVICE);
- }
-
- @Override
- public void setPressed(boolean pressed) {
- super.setPressed(pressed);
- if (mOnPressedListener != null) {
- mOnPressedListener.onPressed(this, pressed);
- }
- }
-
- @Override
- public void onSizeChanged(int w, int h, int oldw, int oldh) {
- super.onSizeChanged(w, h, oldw, oldh);
-
- mHoverBounds.left = getPaddingLeft();
- mHoverBounds.right = w - getPaddingRight();
- mHoverBounds.top = getPaddingTop();
- mHoverBounds.bottom = h - getPaddingBottom();
- }
-
- @Override
- public boolean performClick() {
- // When accessibility is on, simulate press and release to preserve the
- // semantic meaning of performClick(). Required for Braille support.
- if (mAccessibilityManager.isEnabled()) {
- // Checking the press state prevents double activation.
- if (!isPressed()) {
- setPressed(true);
- setPressed(false);
- }
-
- return true;
- }
-
- return super.performClick();
- }
-
- @Override
- public boolean onHoverEvent(MotionEvent event) {
- // When touch exploration is turned on, lifting a finger while inside
- // the button's hover target bounds should perform a click action.
- if (mAccessibilityManager.isEnabled()
- && mAccessibilityManager.isTouchExplorationEnabled()) {
- switch (event.getActionMasked()) {
- case MotionEvent.ACTION_HOVER_ENTER:
- // Lift-to-type temporarily disables double-tap activation.
- setClickable(false);
- break;
- case MotionEvent.ACTION_HOVER_EXIT:
- if (mHoverBounds.contains((int) event.getX(), (int) event.getY())) {
- performClick();
- }
- setClickable(true);
- break;
- }
- }
-
- return super.onHoverEvent(event);
- }
-}
diff --git a/src/com/android/contacts/dialpad/DigitsEditText.java b/src/com/android/contacts/dialpad/DigitsEditText.java
deleted file mode 100644
index 7b3e8b2..0000000
--- a/src/com/android/contacts/dialpad/DigitsEditText.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.dialpad;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.text.InputType;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.EditText;
-
-/**
- * EditText which suppresses IME show up.
- */
-public class DigitsEditText extends EditText {
- public DigitsEditText(Context context, AttributeSet attrs) {
- super(context, attrs);
- setInputType(getInputType() | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
- setShowSoftInputOnFocus(false);
- }
-
- @Override
- protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
- super.onFocusChanged(focused, direction, previouslyFocusedRect);
- final InputMethodManager imm = ((InputMethodManager) getContext()
- .getSystemService(Context.INPUT_METHOD_SERVICE));
- if (imm != null && imm.isActive(this)) {
- imm.hideSoftInputFromWindow(getApplicationWindowToken(), 0);
- }
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- final boolean ret = super.onTouchEvent(event);
- // Must be done after super.onTouchEvent()
- final InputMethodManager imm = ((InputMethodManager) getContext()
- .getSystemService(Context.INPUT_METHOD_SERVICE));
- if (imm != null && imm.isActive(this)) {
- imm.hideSoftInputFromWindow(getApplicationWindowToken(), 0);
- }
- return ret;
- }
-
- @Override
- public void sendAccessibilityEventUnchecked(AccessibilityEvent event) {
- if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED) {
- // Since we're replacing the text every time we add or remove a
- // character, only read the difference. (issue 5337550)
- final int added = event.getAddedCount();
- final int removed = event.getRemovedCount();
- final int length = event.getBeforeText().length();
- if (added > removed) {
- event.setRemovedCount(0);
- event.setAddedCount(1);
- event.setFromIndex(length);
- } else if (removed > added) {
- event.setRemovedCount(1);
- event.setAddedCount(0);
- event.setFromIndex(length - 1);
- } else {
- return;
- }
- } else if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
- // The parent EditText class lets tts read "edit box" when this View has a focus, which
- // confuses users on app launch (issue 5275935).
- return;
- }
- super.sendAccessibilityEventUnchecked(event);
- }
-}
\ No newline at end of file
diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
index 66c1686..f840bb5 100644
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorFragment.java
@@ -118,8 +118,12 @@
private static final String KEY_IS_USER_PROFILE = "isUserProfile";
private static final String KEY_UPDATED_PHOTOS = "updatedPhotos";
+ private static final String[] VALID_ACTIONS = {Intent.ACTION_EDIT, Intent.ACTION_INSERT,
+ ContactEditorActivity.ACTION_SAVE_COMPLETED};
+
public static final String SAVE_MODE_EXTRA_KEY = "saveMode";
+
/**
* An intent extra that forces the editor to add the edited contact
* to the default group (e.g. "My Contacts").
@@ -347,11 +351,6 @@
setHasOptionsMenu(true);
- // If we are in an orientation change, we already have mState (it was loaded by onCreate)
- if (mState != null) {
- bindEditors();
- }
-
return view;
}
@@ -359,13 +358,29 @@
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
+ validateAction(mAction);
+
// Handle initial actions only when existing state missing
final boolean hasIncomingState = savedInstanceState != null;
- if (!hasIncomingState) {
+ if (mState == null) {
+ // The delta list may not have finished loading before orientation change happens.
+ // In this case, there will be a saved state but deltas will be missing. Reload from
+ // database.
if (Intent.ACTION_EDIT.equals(mAction)) {
+ // Either...
+ // 1) orientation change but load never finished.
+ // or
+ // 2) not an orientation change. data needs to be loaded for first time.
getLoaderManager().initLoader(LOADER_DATA, null, mDataLoaderListener);
- } else if (Intent.ACTION_INSERT.equals(mAction)) {
+ }
+ } else {
+ // Orientation change, we already have mState, it was loaded by onCreate
+ bindEditors();
+ }
+
+ if (!hasIncomingState) {
+ if (Intent.ACTION_INSERT.equals(mAction)) {
final Account account = mIntentExtras == null ? null :
(Account) mIntentExtras.getParcelable(Intents.Insert.ACCOUNT);
final String dataSet = mIntentExtras == null ? null :
@@ -379,13 +394,26 @@
// Load Accounts async so that we can present them
selectAccountAndCreateContact();
}
- } else if (ContactEditorActivity.ACTION_SAVE_COMPLETED.equals(mAction)) {
- // do nothing
- } else throw new IllegalArgumentException("Unknown Action String " + mAction +
- ". Only support " + Intent.ACTION_EDIT + " or " + Intent.ACTION_INSERT);
+ }
}
}
+ /**
+ * Checks if the requested action is valid.
+ *
+ * @param action The action to test.
+ * @throws IllegalArgumentException when the action is invalid.
+ */
+ private void validateAction(String action) {
+ for (String validAction : VALID_ACTIONS) {
+ if (validAction.equals(action)) {
+ return;
+ }
+ }
+ throw new IllegalArgumentException("Unknown Action String " + mAction +
+ ". Only support " + Intent.ACTION_EDIT + " or " + Intent.ACTION_INSERT);
+ }
+
@Override
public void onStart() {
getLoaderManager().initLoader(LOADER_GROUPS, null, mGroupLoaderListener);
@@ -451,7 +479,7 @@
RawContact rawContact = rawContacts.get(0);
String type = rawContact.getAccountTypeString();
String dataSet = rawContact.getDataSet();
- AccountType accountType = rawContact.getAccountType();
+ AccountType accountType = rawContact.getAccountType(mContext);
if (accountType.getEditContactActivityClassName() != null &&
!accountType.areContactsWritable()) {
if (mListener != null) {
@@ -496,7 +524,7 @@
}
// Editor should always present a local profile for editing
if (!localProfileExists) {
- final RawContact rawContact = new RawContact(mContext);
+ final RawContact rawContact = new RawContact();
rawContact.setAccountToLocal();
RawContactDelta insert = new RawContactDelta(ValuesDelta.fromAfter(
@@ -631,7 +659,7 @@
AccountType oldAccountType) {
mStatus = Status.EDITING;
- final RawContact rawContact = new RawContact(mContext);
+ final RawContact rawContact = new RawContact();
if (newAccount != null) {
rawContact.setAccount(newAccount);
} else {
diff --git a/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java b/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
index 8e51d18..e963d48 100644
--- a/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
+++ b/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
@@ -37,8 +37,8 @@
import android.widget.TextView;
import android.widget.Toast;
-import com.android.contacts.ContactsUtils;
import com.android.contacts.R;
+import com.android.contacts.common.GeoUtil;
import com.android.contacts.model.RawContactModifier;
import com.android.contacts.model.RawContactDelta;
import com.android.contacts.model.RawContactDelta.ValuesDelta;
@@ -204,7 +204,7 @@
final String phoneNumber = PhoneNumberUtils.formatNumber(
phone.getPhoneNumber(),
phone.getPhoneNormalizedNumber(),
- ContactsUtils.getCurrentCountryIso(getContext()));
+ GeoUtil.getCurrentCountryIso(getContext()));
final CharSequence phoneType;
if (phone.phoneHasType()) {
phoneType = Phone.getTypeLabel(
diff --git a/src/com/android/contacts/editor/StructuredNameEditorView.java b/src/com/android/contacts/editor/StructuredNameEditorView.java
index 3c4476d..bac3b79 100644
--- a/src/com/android/contacts/editor/StructuredNameEditorView.java
+++ b/src/com/android/contacts/editor/StructuredNameEditorView.java
@@ -67,7 +67,7 @@
ViewIdGenerator vig) {
super.setValues(kind, entry, state, readOnly, vig);
if (mSnapshot == null) {
- mSnapshot = (StructuredNameDataItem) DataItem.createFrom(null,
+ mSnapshot = (StructuredNameDataItem) DataItem.createFrom(
new ContentValues(getValues().getCompleteValues()));
mChanged = entry.isInsert();
} else {
@@ -214,7 +214,7 @@
super.onRestoreInstanceState(ss.mSuperState);
mChanged = ss.mChanged;
- mSnapshot = (StructuredNameDataItem) DataItem.createFrom(null, ss.mSnapshot);
+ mSnapshot = (StructuredNameDataItem) DataItem.createFrom(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 8558b11..e48ba51 100644
--- a/src/com/android/contacts/editor/TextFieldsEditorView.java
+++ b/src/com/android/contacts/editor/TextFieldsEditorView.java
@@ -41,7 +41,7 @@
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;
+import com.android.contacts.common.util.PhoneNumberFormatter;
/**
* Simple editor that handles labels and any {@link EditField} defined for the
diff --git a/src/com/android/contacts/format/FormatUtils.java b/src/com/android/contacts/format/FormatUtils.java
index dd25c8d..2c5427d 100644
--- a/src/com/android/contacts/format/FormatUtils.java
+++ b/src/com/android/contacts/format/FormatUtils.java
@@ -28,8 +28,6 @@
* Assorted utility methods related to text formatting in Contacts.
*/
public class FormatUtils {
- private static final char LEFT_TO_RIGHT_EMBEDDING = '\u202A';
- private static final char POP_DIRECTIONAL_FORMATTING = '\u202C';
/**
* Finds the earliest point in buffer1 at which the first part of buffer2 matches. For example,
@@ -183,12 +181,4 @@
return -1;
}
- /** Returns the given text, forced to be left-to-right. */
- public static CharSequence forceLeftToRight(CharSequence text) {
- StringBuilder sb = new StringBuilder();
- sb.append(LEFT_TO_RIGHT_EMBEDDING);
- sb.append(text);
- sb.append(POP_DIRECTIONAL_FORMATTING);
- return sb.toString();
- }
}
diff --git a/src/com/android/contacts/group/GroupDetailFragment.java b/src/com/android/contacts/group/GroupDetailFragment.java
index 6294b40..04ccb44 100644
--- a/src/com/android/contacts/group/GroupDetailFragment.java
+++ b/src/com/android/contacts/group/GroupDetailFragment.java
@@ -45,7 +45,7 @@
import android.widget.ListView;
import android.widget.TextView;
-import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.GroupMemberLoader;
import com.android.contacts.GroupMetaDataLoader;
import com.android.contacts.R;
diff --git a/src/com/android/contacts/group/GroupEditorFragment.java b/src/com/android/contacts/group/GroupEditorFragment.java
index 762867c..355cca7 100644
--- a/src/com/android/contacts/group/GroupEditorFragment.java
+++ b/src/com/android/contacts/group/GroupEditorFragment.java
@@ -57,7 +57,7 @@
import android.widget.TextView;
import android.widget.Toast;
-import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.ContactSaveService;
import com.android.contacts.GroupMemberLoader;
import com.android.contacts.GroupMemberLoader.GroupEditorQuery;
diff --git a/src/com/android/contacts/interactions/PhoneNumberInteraction.java b/src/com/android/contacts/interactions/PhoneNumberInteraction.java
index 207ceea..2cf0601 100644
--- a/src/com/android/contacts/interactions/PhoneNumberInteraction.java
+++ b/src/com/android/contacts/interactions/PhoneNumberInteraction.java
@@ -20,7 +20,6 @@
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.FragmentManager;
-import android.content.ContentValues;
import android.content.Context;
import android.content.CursorLoader;
import android.content.DialogInterface;
@@ -46,17 +45,14 @@
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.android.contacts.common.CallUtil;
+import com.android.contacts.common.Collapser;
+import com.android.contacts.common.Collapser.Collapsible;
+import com.android.contacts.common.MoreContactUtils;
+import com.android.contacts.common.activity.TransactionSafeActivity;
+import com.android.contacts.common.util.ContactDisplayUtils;
import com.google.common.annotations.VisibleForTesting;
import java.util.ArrayList;
@@ -75,12 +71,6 @@
public class PhoneNumberInteraction implements OnLoadCompleteListener<Cursor> {
private static final String TAG = PhoneNumberInteraction.class.getSimpleName();
- @VisibleForTesting
- /* package */ enum InteractionType {
- PHONE_CALL,
- SMS
- }
-
/**
* A model object for capturing a phone number for a given contact.
*/
@@ -135,7 +125,7 @@
@Override
public boolean shouldCollapseWith(PhoneItem phoneItem) {
- return ContactsUtils.shouldCollapse(Phone.CONTENT_ITEM_TYPE, phoneNumber,
+ return MoreContactUtils.shouldCollapse(Phone.CONTENT_ITEM_TYPE, phoneNumber,
Phone.CONTENT_ITEM_TYPE, phoneItem.phoneNumber);
}
@@ -162,14 +152,12 @@
* A list adapter that populates the list of contact's phone numbers.
*/
private static class PhoneItemAdapter extends ArrayAdapter<PhoneItem> {
- private final InteractionType mInteractionType;
- private final AccountTypeManager mAccountTypeManager;
+ private final int mInteractionType;
public PhoneItemAdapter(Context context, List<PhoneItem> list,
- InteractionType interactionType) {
+ int interactionType) {
super(context, R.layout.phone_disambig_item, android.R.id.text2, list);
mInteractionType = interactionType;
- mAccountTypeManager = AccountTypeManager.getInstance(context);
}
@Override
@@ -177,20 +165,11 @@
final View view = super.getView(position, convertView, parent);
final PhoneItem item = getItem(position);
- final AccountType accountType = mAccountTypeManager.getAccountType(
- item.accountType, item.dataSet);
final TextView typeView = (TextView) view.findViewById(android.R.id.text1);
- final DataKind kind = accountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
- if (kind != null) {
- ContentValues values = new ContentValues();
- values.put(Phone.TYPE, item.type);
- values.put(Phone.LABEL, item.label);
- StringInflater header = (mInteractionType == InteractionType.SMS)
- ? kind.actionAltHeader : kind.actionHeader;
- typeView.setText(header.inflateUsing(getContext(), values));
- } else {
- typeView.setText(R.string.call_other);
- }
+ CharSequence value = ContactDisplayUtils.getLabelForCallOrSms((int) item.type,
+ item.label, mInteractionType, getContext());
+
+ typeView.setText(value);
return view;
}
}
@@ -213,13 +192,13 @@
private static final String ARG_INTERACTION_TYPE = "interactionType";
private static final String ARG_CALL_ORIGIN = "callOrigin";
- private InteractionType mInteractionType;
+ private int mInteractionType;
private ListAdapter mPhonesAdapter;
private List<PhoneItem> mPhoneList;
private String mCallOrigin;
public static void show(FragmentManager fragmentManager,
- ArrayList<PhoneItem> phoneList, InteractionType interactionType,
+ ArrayList<PhoneItem> phoneList, int interactionType,
String callOrigin) {
PhoneDisambiguationDialogFragment fragment = new PhoneDisambiguationDialogFragment();
Bundle bundle = new Bundle();
@@ -234,8 +213,7 @@
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Activity activity = getActivity();
mPhoneList = getArguments().getParcelableArrayList(ARG_PHONE_LIST);
- mInteractionType =
- (InteractionType) getArguments().getSerializable(ARG_INTERACTION_TYPE);
+ mInteractionType = getArguments().getInt(ARG_INTERACTION_TYPE);
mCallOrigin = getArguments().getString(ARG_CALL_ORIGIN);
mPhonesAdapter = new PhoneItemAdapter(activity, mPhoneList, mInteractionType);
@@ -243,7 +221,7 @@
final View setPrimaryView = inflater.inflate(R.layout.set_primary_checkbox, null);
return new AlertDialog.Builder(activity)
.setAdapter(mPhonesAdapter, this)
- .setTitle(mInteractionType == InteractionType.SMS
+ .setTitle(mInteractionType == ContactDisplayUtils.INTERACTION_SMS
? R.string.sms_disambig_title : R.string.call_disambig_title)
.setView(setPrimaryView)
.create();
@@ -291,7 +269,7 @@
private final Context mContext;
private final OnDismissListener mDismissListener;
- private final InteractionType mInteractionType;
+ private final int mInteractionType;
private final String mCallOrigin;
@@ -304,12 +282,12 @@
* require a {@link TransactionSafeActivity} (i.e. see {@link #startInteractionForPhoneCall}).
*/
@VisibleForTesting
- /* package */ PhoneNumberInteraction(Context context, InteractionType interactionType,
+ /* package */ PhoneNumberInteraction(Context context, int interactionType,
DialogInterface.OnDismissListener dismissListener) {
this(context, interactionType, dismissListener, null);
}
- private PhoneNumberInteraction(Context context, InteractionType interactionType,
+ private PhoneNumberInteraction(Context context, int interactionType,
DialogInterface.OnDismissListener dismissListener, String callOrigin) {
mContext = context;
mInteractionType = interactionType;
@@ -322,16 +300,16 @@
}
private static void performAction(
- Context context, String phoneNumber, InteractionType interactionType,
+ Context context, String phoneNumber, int interactionType,
String callOrigin) {
Intent intent;
switch (interactionType) {
- case SMS:
+ case ContactDisplayUtils.INTERACTION_SMS:
intent = new Intent(
Intent.ACTION_SENDTO, Uri.fromParts("sms", phoneNumber, null));
break;
default:
- intent = ContactsUtils.getCallIntent(phoneNumber, callOrigin);
+ intent = CallUtil.getCallIntent(phoneNumber, callOrigin);
break;
}
context.startActivity(intent);
@@ -448,7 +426,7 @@
* data Uri won't.
*/
public static void startInteractionForPhoneCall(TransactionSafeActivity activity, Uri uri) {
- (new PhoneNumberInteraction(activity, InteractionType.PHONE_CALL, null))
+ (new PhoneNumberInteraction(activity, ContactDisplayUtils.INTERACTION_CALL, null))
.startInteraction(uri);
}
@@ -456,13 +434,13 @@
* @param activity that is calling this interaction. This must be of type
* {@link TransactionSafeActivity} because we need to check on the activity state after the
* phone numbers have been queried for.
- * @param callOrigin If non null, {@link DialtactsActivity#EXTRA_CALL_ORIGIN} will be
+ * @param callOrigin If non null, {@link PhoneConstants#EXTRA_CALL_ORIGIN} will be
* appended to the Intent initiating phone call. See comments in Phone package (PhoneApp)
* for more detail.
*/
public static void startInteractionForPhoneCall(TransactionSafeActivity activity, Uri uri,
String callOrigin) {
- (new PhoneNumberInteraction(activity, InteractionType.PHONE_CALL, null, callOrigin))
+ (new PhoneNumberInteraction(activity, ContactDisplayUtils.INTERACTION_CALL, null, callOrigin))
.startInteraction(uri);
}
@@ -479,7 +457,8 @@
* data Uri won't.
*/
public static void startInteractionForTextMessage(TransactionSafeActivity activity, Uri uri) {
- (new PhoneNumberInteraction(activity, InteractionType.SMS, null)).startInteraction(uri);
+ (new PhoneNumberInteraction(activity, ContactDisplayUtils.INTERACTION_SMS, null))
+ .startInteraction(uri);
}
@VisibleForTesting
diff --git a/src/com/android/contacts/list/ContactBrowseListFragment.java b/src/com/android/contacts/list/ContactBrowseListFragment.java
index 3e8e4a3..da4a644 100644
--- a/src/com/android/contacts/list/ContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/ContactBrowseListFragment.java
@@ -631,14 +631,6 @@
if (mListener != null) mListener.onRemoveFromFavoritesAction(contactUri);
}
- public void callContact(Uri contactUri) {
- if (mListener != null) mListener.onCallContactAction(contactUri);
- }
-
- public void smsContact(Uri contactUri) {
- if (mListener != null) mListener.onSmsContactAction(contactUri);
- }
-
private void notifyInvalidSelection() {
if (mListener != null) mListener.onInvalidSelection();
}
diff --git a/src/com/android/contacts/list/ContactEntryListAdapter.java b/src/com/android/contacts/list/ContactEntryListAdapter.java
index 00c26ff..1f0373f 100644
--- a/src/com/android/contacts/list/ContactEntryListAdapter.java
+++ b/src/com/android/contacts/list/ContactEntryListAdapter.java
@@ -33,7 +33,7 @@
import android.widget.SectionIndexer;
import android.widget.TextView;
-import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.R;
import com.android.contacts.widget.IndexerListAdapter;
diff --git a/src/com/android/contacts/list/ContactEntryListFragment.java b/src/com/android/contacts/list/ContactEntryListFragment.java
index e422d1b..7efc57a 100644
--- a/src/com/android/contacts/list/ContactEntryListFragment.java
+++ b/src/com/android/contacts/list/ContactEntryListFragment.java
@@ -55,7 +55,7 @@
import com.android.common.widget.CompositeCursorAdapter.Partition;
import com.android.contacts.ContactListEmptyView;
-import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.R;
import com.android.contacts.preference.ContactsPreferences;
import com.android.contacts.widget.ContextMenuAdapter;
diff --git a/src/com/android/contacts/list/ContactListFilterController.java b/src/com/android/contacts/list/ContactListFilterController.java
index ddcb1ae..5377df2 100644
--- a/src/com/android/contacts/list/ContactListFilterController.java
+++ b/src/com/android/contacts/list/ContactListFilterController.java
@@ -30,20 +30,19 @@
*/
public abstract class ContactListFilterController {
- public static final String CONTACT_LIST_FILTER_SERVICE = "contactListFilter";
+ // singleton to cache the filter controller
+ private static ContactListFilterControllerImpl sFilterController = null;
public interface ContactListFilterListener {
void onContactListFilterChanged();
}
public static ContactListFilterController getInstance(Context context) {
- return (ContactListFilterController)
- context.getApplicationContext().getSystemService(CONTACT_LIST_FILTER_SERVICE);
- }
-
- public static ContactListFilterController
- createContactListFilterController(Context context) {
- return new ContactListFilterControllerImpl(context);
+ // We may need to synchronize this in the future if background task will call this.
+ if (sFilterController == null) {
+ sFilterController = new ContactListFilterControllerImpl(context);
+ }
+ return sFilterController;
}
public abstract void addListener(ContactListFilterListener listener);
diff --git a/src/com/android/contacts/list/ContactTileAdapter.java b/src/com/android/contacts/list/ContactTileAdapter.java
index 75e3149..a5a8c65 100644
--- a/src/com/android/contacts/list/ContactTileAdapter.java
+++ b/src/com/android/contacts/list/ContactTileAdapter.java
@@ -28,7 +28,7 @@
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
-import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.ContactPresenceIconUtil;
import com.android.contacts.ContactStatusUtil;
import com.android.contacts.ContactTileLoaderFactory;
diff --git a/src/com/android/contacts/list/ContactTileListFragment.java b/src/com/android/contacts/list/ContactTileListFragment.java
index f5de15f..a69e125 100644
--- a/src/com/android/contacts/list/ContactTileListFragment.java
+++ b/src/com/android/contacts/list/ContactTileListFragment.java
@@ -32,7 +32,7 @@
import android.widget.ListView;
import android.widget.TextView;
-import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.ContactTileLoaderFactory;
import com.android.contacts.R;
import com.android.contacts.list.ContactTileAdapter.DisplayType;
diff --git a/src/com/android/contacts/list/ContactTileView.java b/src/com/android/contacts/list/ContactTileView.java
index c108827..91a28bd 100644
--- a/src/com/android/contacts/list/ContactTileView.java
+++ b/src/com/android/contacts/list/ContactTileView.java
@@ -26,7 +26,7 @@
import android.widget.QuickContactBadge;
import android.widget.TextView;
-import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.ContactsUtils;
import com.android.contacts.R;
import com.android.contacts.list.ContactTileAdapter.ContactEntry;
diff --git a/src/com/android/contacts/list/OnContactBrowserActionListener.java b/src/com/android/contacts/list/OnContactBrowserActionListener.java
index 771f251..6d28bac 100644
--- a/src/com/android/contacts/list/OnContactBrowserActionListener.java
+++ b/src/com/android/contacts/list/OnContactBrowserActionListener.java
@@ -61,16 +61,6 @@
void onRemoveFromFavoritesAction(Uri contactUri);
/**
- * Places a call to the specified contact.
- */
- void onCallContactAction(Uri contactUri);
-
- /**
- * Initiates a text message to the specified contact.
- */
- void onSmsContactAction(Uri contactUri);
-
- /**
* Closes the contact browser.
*/
void onFinishAction();
diff --git a/src/com/android/contacts/list/PhoneFavoriteFragment.java b/src/com/android/contacts/list/PhoneFavoriteFragment.java
deleted file mode 100644
index 5ef19ff..0000000
--- a/src/com/android/contacts/list/PhoneFavoriteFragment.java
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.contacts.list;
-
-import android.app.Activity;
-import android.app.Fragment;
-import android.app.LoaderManager;
-import android.content.CursorLoader;
-import android.content.Intent;
-import android.content.Loader;
-import android.database.Cursor;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.Directory;
-import android.provider.Settings;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.AbsListView;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.FrameLayout;
-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.
- *
- * This fragment contains three kinds of contacts in one screen: "starred", "frequent", and "all"
- * contacts. To show them at once, this merges results from {@link ContactTileAdapter} and
- * {@link PhoneNumberListAdapter} into one unified list using {@link PhoneFavoriteMergedAdapter}.
- * A contact filter header is also inserted between those adapters' results.
- */
-public class PhoneFavoriteFragment extends Fragment implements OnItemClickListener {
- private static final String TAG = PhoneFavoriteFragment.class.getSimpleName();
- private static final boolean DEBUG = false;
-
- /**
- * Used with LoaderManager.
- */
- private static int LOADER_ID_CONTACT_TILE = 1;
- private static int LOADER_ID_ALL_CONTACTS = 2;
-
- private static final String KEY_FILTER = "filter";
-
- private static final int REQUEST_CODE_ACCOUNT_FILTER = 1;
-
- public interface Listener {
- public void onContactSelected(Uri contactUri);
- public void onCallNumberDirectly(String phoneNumber);
- }
-
- private class ContactTileLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> {
- @Override
- public CursorLoader onCreateLoader(int id, Bundle args) {
- if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onCreateLoader.");
- return ContactTileLoaderFactory.createStrequentPhoneOnlyLoader(getActivity());
- }
-
- @Override
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onLoadFinished");
- mContactTileAdapter.setContactCursor(data);
-
- if (mAllContactsForceReload) {
- mAllContactsAdapter.onDataReload();
- // Use restartLoader() to make LoaderManager to load the section again.
- getLoaderManager().restartLoader(
- LOADER_ID_ALL_CONTACTS, null, mAllContactsLoaderListener);
- } else if (!mAllContactsLoaderStarted) {
- // Load "all" contacts if not loaded yet.
- getLoaderManager().initLoader(
- LOADER_ID_ALL_CONTACTS, null, mAllContactsLoaderListener);
- }
- mAllContactsForceReload = false;
- mAllContactsLoaderStarted = true;
-
- // Show the filter header with "loading" state.
- updateFilterHeaderView();
- mAccountFilterHeader.setVisibility(View.VISIBLE);
-
- // invalidate the options menu if needed
- invalidateOptionsMenuIfNeeded();
- }
-
- @Override
- public void onLoaderReset(Loader<Cursor> loader) {
- if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onLoaderReset. ");
- }
- }
-
- private class AllContactsLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> {
- @Override
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- if (DEBUG) Log.d(TAG, "AllContactsLoaderListener#onCreateLoader");
- CursorLoader loader = new CursorLoader(getActivity(), null, null, null, null, null);
- mAllContactsAdapter.configureLoader(loader, Directory.DEFAULT);
- return loader;
- }
-
- @Override
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- if (DEBUG) Log.d(TAG, "AllContactsLoaderListener#onLoadFinished");
- mAllContactsAdapter.changeCursor(0, data);
- updateFilterHeaderView();
- mHandler.removeMessages(MESSAGE_SHOW_LOADING_EFFECT);
- mLoadingView.setVisibility(View.VISIBLE);
- }
-
- @Override
- public void onLoaderReset(Loader<Cursor> loader) {
- if (DEBUG) Log.d(TAG, "AllContactsLoaderListener#onLoaderReset. ");
- }
- }
-
- private class ContactTileAdapterListener implements ContactTileView.Listener {
- @Override
- public void onContactSelected(Uri contactUri, Rect targetRect) {
- if (mListener != null) {
- mListener.onContactSelected(contactUri);
- }
- }
-
- @Override
- public void onCallNumberDirectly(String phoneNumber) {
- if (mListener != null) {
- mListener.onCallNumberDirectly(phoneNumber);
- }
- }
-
- @Override
- public int getApproximateTileWidth() {
- return getView().getWidth() / mContactTileAdapter.getColumnCount();
- }
- }
-
- private class FilterHeaderClickListener implements OnClickListener {
- @Override
- public void onClick(View view) {
- AccountFilterUtil.startAccountFilterActivityForResult(
- PhoneFavoriteFragment.this,
- REQUEST_CODE_ACCOUNT_FILTER,
- mFilter);
- }
- }
-
- private class ContactsPreferenceChangeListener
- implements ContactsPreferences.ChangeListener {
- @Override
- public void onChange() {
- if (loadContactsPreferences()) {
- requestReloadAllContacts();
- }
- }
- }
-
- private class ScrollListener implements ListView.OnScrollListener {
- private boolean mShouldShowFastScroller;
- @Override
- public void onScroll(AbsListView view,
- int firstVisibleItem, int visibleItemCount, int totalItemCount) {
- // FastScroller should be visible only when the user is seeing "all" contacts section.
- final boolean shouldShow = mAdapter.shouldShowFirstScroller(firstVisibleItem);
- if (shouldShow != mShouldShowFastScroller) {
- mListView.setVerticalScrollBarEnabled(shouldShow);
- mListView.setFastScrollEnabled(shouldShow);
- mListView.setFastScrollAlwaysVisible(shouldShow);
- mShouldShowFastScroller = shouldShow;
- }
- }
-
- @Override
- public void onScrollStateChanged(AbsListView view, int scrollState) {
- }
- }
-
- private static final int MESSAGE_SHOW_LOADING_EFFECT = 1;
- private static final int LOADING_EFFECT_DELAY = 500; // ms
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MESSAGE_SHOW_LOADING_EFFECT:
- mLoadingView.setVisibility(View.VISIBLE);
- break;
- }
- }
- };
-
- private Listener mListener;
- private PhoneFavoriteMergedAdapter mAdapter;
- private ContactTileAdapter mContactTileAdapter;
- private PhoneNumberListAdapter mAllContactsAdapter;
-
- /**
- * true when the loader for {@link PhoneNumberListAdapter} has started already.
- */
- private boolean mAllContactsLoaderStarted;
- /**
- * true when the loader for {@link PhoneNumberListAdapter} must reload "all" contacts again.
- * It typically happens when {@link ContactsPreferences} has changed its settings
- * (display order and sort order)
- */
- private boolean mAllContactsForceReload;
-
- private ContactsPreferences mContactsPrefs;
- private ContactListFilter mFilter;
-
- private TextView mEmptyView;
- private ListView mListView;
- /**
- * Layout containing {@link #mAccountFilterHeader}. Used to limit area being "pressed".
- */
- private FrameLayout mAccountFilterHeaderContainer;
- private View mAccountFilterHeader;
-
- /**
- * Layout used when contacts load is slower than expected and thus "loading" view should be
- * shown.
- */
- private View mLoadingView;
-
- private final ContactTileView.Listener mContactTileAdapterListener =
- new ContactTileAdapterListener();
- private final LoaderManager.LoaderCallbacks<Cursor> mContactTileLoaderListener =
- new ContactTileLoaderListener();
- private final LoaderManager.LoaderCallbacks<Cursor> mAllContactsLoaderListener =
- new AllContactsLoaderListener();
- private final OnClickListener mFilterHeaderClickListener = new FilterHeaderClickListener();
- private final ContactsPreferenceChangeListener mContactsPreferenceChangeListener =
- new ContactsPreferenceChangeListener();
- private final ScrollListener mScrollListener = new ScrollListener();
-
- private boolean mOptionsMenuHasFrequents;
-
- @Override
- public void onAttach(Activity activity) {
- if (DEBUG) Log.d(TAG, "onAttach()");
- super.onAttach(activity);
-
- mContactsPrefs = new ContactsPreferences(activity);
-
- // Construct two base adapters which will become part of PhoneFavoriteMergedAdapter.
- // We don't construct the resultant adapter at this moment since it requires LayoutInflater
- // that will be available on onCreateView().
-
- mContactTileAdapter = new ContactTileAdapter(activity, mContactTileAdapterListener,
- getResources().getInteger(R.integer.contact_tile_column_count_in_favorites),
- ContactTileAdapter.DisplayType.STREQUENT_PHONE_ONLY);
- mContactTileAdapter.setPhotoLoader(ContactPhotoManager.getInstance(activity));
-
- // Setup the "all" adapter manually. See also the setup logic in ContactEntryListFragment.
- mAllContactsAdapter = new PhoneNumberListAdapter(activity);
- mAllContactsAdapter.setDisplayPhotos(true);
- mAllContactsAdapter.setQuickContactEnabled(true);
- mAllContactsAdapter.setSearchMode(false);
- mAllContactsAdapter.setIncludeProfile(false);
- mAllContactsAdapter.setSelectionVisible(false);
- mAllContactsAdapter.setDarkTheme(true);
- mAllContactsAdapter.setPhotoLoader(ContactPhotoManager.getInstance(activity));
- // Disable directory header.
- mAllContactsAdapter.setHasHeader(0, false);
- // Show A-Z section index.
- mAllContactsAdapter.setSectionHeaderDisplayEnabled(true);
- // Disable pinned header. It doesn't work with this fragment.
- mAllContactsAdapter.setPinnedPartitionHeadersEnabled(false);
- // Put photos on left for consistency with "frequent" contacts section.
- mAllContactsAdapter.setPhotoPosition(ContactListItemView.PhotoPosition.LEFT);
-
- // Use Callable.CONTENT_URI which will include not only phone numbers but also SIP
- // addresses.
- mAllContactsAdapter.setUseCallableUri(true);
-
- mAllContactsAdapter.setContactNameDisplayOrder(mContactsPrefs.getDisplayOrder());
- mAllContactsAdapter.setSortOrder(mContactsPrefs.getSortOrder());
- }
-
- @Override
- public void onCreate(Bundle savedState) {
- if (DEBUG) Log.d(TAG, "onCreate()");
- super.onCreate(savedState);
- if (savedState != null) {
- mFilter = savedState.getParcelable(KEY_FILTER);
-
- if (mFilter != null) {
- mAllContactsAdapter.setFilter(mFilter);
- }
- }
- setHasOptionsMenu(true);
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putParcelable(KEY_FILTER, mFilter);
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- final View listLayout = inflater.inflate(
- R.layout.phone_contact_tile_list, container, false);
-
- mListView = (ListView) listLayout.findViewById(R.id.contact_tile_list);
- mListView.setItemsCanFocus(true);
- mListView.setOnItemClickListener(this);
- mListView.setVerticalScrollBarEnabled(false);
- mListView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_RIGHT);
- mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY);
-
- // Create the account filter header but keep it hidden until "all" contacts are loaded.
- mAccountFilterHeaderContainer = new FrameLayout(getActivity(), null);
- mAccountFilterHeader = inflater.inflate(R.layout.account_filter_header_for_phone_favorite,
- mListView, false);
- mAccountFilterHeader.setOnClickListener(mFilterHeaderClickListener);
- mAccountFilterHeaderContainer.addView(mAccountFilterHeader);
-
- mLoadingView = inflater.inflate(R.layout.phone_loading_contacts, mListView, false);
-
- mAdapter = new PhoneFavoriteMergedAdapter(getActivity(),
- mContactTileAdapter, mAccountFilterHeaderContainer, mAllContactsAdapter,
- mLoadingView);
-
- mListView.setAdapter(mAdapter);
-
- mListView.setOnScrollListener(mScrollListener);
- mListView.setFastScrollEnabled(false);
- mListView.setFastScrollAlwaysVisible(false);
-
- mEmptyView = (TextView) listLayout.findViewById(R.id.contact_tile_list_empty);
- mEmptyView.setText(getString(R.string.listTotalAllContactsZero));
- mListView.setEmptyView(mEmptyView);
-
- updateFilterHeaderView();
-
- return listLayout;
- }
-
- private boolean isOptionsMenuChanged() {
- return mOptionsMenuHasFrequents != hasFrequents();
- }
-
- private void invalidateOptionsMenuIfNeeded() {
- if (isOptionsMenuChanged()) {
- getActivity().invalidateOptionsMenu();
- }
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- super.onCreateOptionsMenu(menu, inflater);
- inflater.inflate(R.menu.phone_favorite_options, menu);
- }
-
- @Override
- public void onPrepareOptionsMenu(Menu menu) {
- final MenuItem clearFrequents = menu.findItem(R.id.menu_clear_frequents);
- mOptionsMenuHasFrequents = hasFrequents();
- clearFrequents.setVisible(mOptionsMenuHasFrequents);
- }
-
- private boolean hasFrequents() {
- return mContactTileAdapter.getNumFrequents() > 0;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.menu_import_export:
- // We hard-code the "contactsAreAvailable" argument because doing it properly would
- // involve querying a {@link ProviderStatusLoader}, which we don't want to do right
- // now in Dialtacts for (potential) performance reasons. Compare with how it is
- // done in {@link PeopleActivity}.
- ImportExportDialogFragment.show(getFragmentManager(), true);
- return true;
- case R.id.menu_accounts:
- final Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS);
- intent.putExtra(Settings.EXTRA_AUTHORITIES, new String[] {
- ContactsContract.AUTHORITY
- });
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
- startActivity(intent);
- return true;
- case R.id.menu_clear_frequents:
- ClearFrequentsDialog.show(getFragmentManager());
- return true;
- }
- return false;
- }
-
- @Override
- public void onStart() {
- super.onStart();
-
- mContactsPrefs.registerChangeListener(mContactsPreferenceChangeListener);
-
- // If ContactsPreferences has changed, we need to reload "all" contacts with the new
- // settings. If mAllContactsFoarceReload is already true, it should be kept.
- if (loadContactsPreferences()) {
- mAllContactsForceReload = true;
- }
-
- // Use initLoader() instead of restartLoader() to refraining unnecessary reload.
- // This method call implicitly assures ContactTileLoaderListener's onLoadFinished() will
- // be called, on which we'll check if "all" contacts should be reloaded again or not.
- getLoaderManager().initLoader(LOADER_ID_CONTACT_TILE, null, mContactTileLoaderListener);
-
- // Delay showing "loading" view until certain amount of time so that users won't see
- // instant flash of the view when the contacts load is fast enough.
- // This will be kept shown until both tile and all sections are loaded.
- mLoadingView.setVisibility(View.INVISIBLE);
- mHandler.sendEmptyMessageDelayed(MESSAGE_SHOW_LOADING_EFFECT, LOADING_EFFECT_DELAY);
- }
-
- @Override
- public void onStop() {
- super.onStop();
- mContactsPrefs.unregisterChangeListener();
- }
-
- /**
- * {@inheritDoc}
- *
- * This is only effective for elements provided by {@link #mContactTileAdapter}.
- * {@link #mContactTileAdapter} has its own logic for click events.
- */
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- final int contactTileAdapterCount = mContactTileAdapter.getCount();
- if (position <= contactTileAdapterCount) {
- Log.e(TAG, "onItemClick() event for unexpected position. "
- + "The position " + position + " is before \"all\" section. Ignored.");
- } else {
- final int localPosition = position - mContactTileAdapter.getCount() - 1;
- if (mListener != null) {
- mListener.onContactSelected(mAllContactsAdapter.getDataUri(localPosition));
- }
- }
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == REQUEST_CODE_ACCOUNT_FILTER) {
- if (getActivity() != null) {
- AccountFilterUtil.handleAccountFilterResult(
- ContactListFilterController.getInstance(getActivity()), resultCode, data);
- } else {
- Log.e(TAG, "getActivity() returns null during Fragment#onActivityResult()");
- }
- }
- }
-
- private boolean loadContactsPreferences() {
- if (mContactsPrefs == null || mAllContactsAdapter == null) {
- return false;
- }
-
- boolean changed = false;
- final int currentDisplayOrder = mContactsPrefs.getDisplayOrder();
- if (mAllContactsAdapter.getContactNameDisplayOrder() != currentDisplayOrder) {
- mAllContactsAdapter.setContactNameDisplayOrder(currentDisplayOrder);
- changed = true;
- }
-
- final int currentSortOrder = mContactsPrefs.getSortOrder();
- if (mAllContactsAdapter.getSortOrder() != currentSortOrder) {
- mAllContactsAdapter.setSortOrder(currentSortOrder);
- changed = true;
- }
-
- return changed;
- }
-
- /**
- * Requests to reload "all" contacts. If the section is already loaded, this method will
- * force reloading it now. If the section isn't loaded yet, the actual load may be done later
- * (on {@link #onStart()}.
- */
- private void requestReloadAllContacts() {
- if (DEBUG) {
- Log.d(TAG, "requestReloadAllContacts()"
- + " mAllContactsAdapter: " + mAllContactsAdapter
- + ", mAllContactsLoaderStarted: " + mAllContactsLoaderStarted);
- }
-
- if (mAllContactsAdapter == null || !mAllContactsLoaderStarted) {
- // Remember this request until next load on onStart().
- mAllContactsForceReload = true;
- return;
- }
-
- if (DEBUG) Log.d(TAG, "Reload \"all\" contacts now.");
-
- mAllContactsAdapter.onDataReload();
- // Use restartLoader() to make LoaderManager to load the section again.
- getLoaderManager().restartLoader(LOADER_ID_ALL_CONTACTS, null, mAllContactsLoaderListener);
- }
-
- private void updateFilterHeaderView() {
- final ContactListFilter filter = getFilter();
- if (mAccountFilterHeader == null || mAllContactsAdapter == null || filter == null) {
- return;
- }
- AccountFilterUtil.updateAccountFilterTitleForPhone(mAccountFilterHeader, filter, true);
- }
-
- public ContactListFilter getFilter() {
- return mFilter;
- }
-
- public void setFilter(ContactListFilter filter) {
- if ((mFilter == null && filter == null) || (mFilter != null && mFilter.equals(filter))) {
- return;
- }
-
- if (DEBUG) {
- Log.d(TAG, "setFilter(). old filter (" + mFilter
- + ") will be replaced with new filter (" + filter + ")");
- }
-
- mFilter = filter;
-
- if (mAllContactsAdapter != null) {
- mAllContactsAdapter.setFilter(mFilter);
- requestReloadAllContacts();
- updateFilterHeaderView();
- }
- }
-
- public void setListener(Listener listener) {
- mListener = listener;
- }
-}
diff --git a/src/com/android/contacts/list/PhoneFavoriteMergedAdapter.java b/src/com/android/contacts/list/PhoneFavoriteMergedAdapter.java
deleted file mode 100644
index 3aa9fe5..0000000
--- a/src/com/android/contacts/list/PhoneFavoriteMergedAdapter.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc.
- * Licensed to 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.list;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.database.DataSetObserver;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-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,
- * an account filter header will be inserted.
- */
-public class PhoneFavoriteMergedAdapter extends BaseAdapter implements SectionIndexer {
-
- private class CustomDataSetObserver extends DataSetObserver {
- @Override
- public void onChanged() {
- notifyDataSetChanged();
- }
- }
-
- private final ContactTileAdapter mContactTileAdapter;
- private final ContactEntryListAdapter mContactEntryListAdapter;
- private final View mAccountFilterHeaderContainer;
- private final View mLoadingView;
-
- private final int mItemPaddingLeft;
- private final int mItemPaddingRight;
-
- // Make frequent header consistent with account filter header.
- private final int mFrequentHeaderPaddingTop;
-
- private final DataSetObserver mObserver;
-
- public PhoneFavoriteMergedAdapter(Context context,
- ContactTileAdapter contactTileAdapter,
- View accountFilterHeaderContainer,
- ContactEntryListAdapter contactEntryListAdapter,
- View loadingView) {
- Resources resources = context.getResources();
- mItemPaddingLeft = resources.getDimensionPixelSize(R.dimen.detail_item_side_margin);
- mItemPaddingRight = resources.getDimensionPixelSize(R.dimen.list_visible_scrollbar_padding);
- mFrequentHeaderPaddingTop = resources.getDimensionPixelSize(
- R.dimen.contact_browser_list_top_margin);
- mContactTileAdapter = contactTileAdapter;
- mContactEntryListAdapter = contactEntryListAdapter;
-
- mAccountFilterHeaderContainer = accountFilterHeaderContainer;
-
- mObserver = new CustomDataSetObserver();
- mContactTileAdapter.registerDataSetObserver(mObserver);
- mContactEntryListAdapter.registerDataSetObserver(mObserver);
-
- mLoadingView = loadingView;
- }
-
- @Override
- public boolean isEmpty() {
- // Cannot use the super's method here because we add extra rows in getCount() to account
- // for headers
- return mContactTileAdapter.getCount() + mContactEntryListAdapter.getCount() == 0;
- }
-
- @Override
- public int getCount() {
- final int contactTileAdapterCount = mContactTileAdapter.getCount();
- final int contactEntryListAdapterCount = mContactEntryListAdapter.getCount();
- if (mContactEntryListAdapter.isLoading()) {
- // Hide "all" contacts during its being loaded. Instead show "loading" view.
- //
- // "+2" for mAccountFilterHeaderContainer and mLoadingView
- return contactTileAdapterCount + 2;
- } else {
- // "+1" for mAccountFilterHeaderContainer
- return contactTileAdapterCount + contactEntryListAdapterCount + 1;
- }
- }
-
- @Override
- public Object getItem(int position) {
- final int contactTileAdapterCount = mContactTileAdapter.getCount();
- final int contactEntryListAdapterCount = mContactEntryListAdapter.getCount();
- if (position < contactTileAdapterCount) { // For "tile" and "frequent" sections
- return mContactTileAdapter.getItem(position);
- } else if (position == contactTileAdapterCount) { // For "all" section's account header
- return mAccountFilterHeaderContainer;
- } else { // For "all" section
- if (mContactEntryListAdapter.isLoading()) { // "All" section is being loaded.
- return mLoadingView;
- } else {
- // "-1" for mAccountFilterHeaderContainer
- final int localPosition = position - contactTileAdapterCount - 1;
- return mContactTileAdapter.getItem(localPosition);
- }
- }
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
- public int getViewTypeCount() {
- // "+2" for mAccountFilterHeaderContainer and mLoadingView
- return (mContactTileAdapter.getViewTypeCount()
- + mContactEntryListAdapter.getViewTypeCount()
- + 2);
- }
-
- @Override
- public int getItemViewType(int position) {
- final int contactTileAdapterCount = mContactTileAdapter.getCount();
- final int contactEntryListAdapterCount = mContactEntryListAdapter.getCount();
- // There should be four kinds of types that are usually used, and one more exceptional
- // type (IGNORE_ITEM_VIEW_TYPE), which sometimes comes from mContactTileAdapter.
- //
- // The four ordinary view types have the index equal to or more than 0, and less than
- // mContactTileAdapter.getViewTypeCount()+ mContactEntryListAdapter.getViewTypeCount() + 2.
- // (See also this class's getViewTypeCount())
- //
- // We have those values for:
- // - The view types mContactTileAdapter originally has
- // - The view types mContactEntryListAdapter originally has
- // - mAccountFilterHeaderContainer ("all" section's account header), and
- // - mLoadingView
- //
- // Those types should not be mixed, so we have a different range for each kinds of types:
- // - Types for mContactTileAdapter ("tile" and "frequent" sections)
- // They should have the index, >=0 and <mContactTileAdapter.getViewTypeCount()
- //
- // - Types for mContactEntryListAdapter ("all" sections)
- // They should have the index, >=mContactTileAdapter.getViewTypeCount() and
- // <(mContactTileAdapter.getViewTypeCount() + mContactEntryListAdapter.getViewTypeCount())
- //
- // - Type for "all" section's account header
- // It should have the exact index
- // mContactTileAdapter.getViewTypeCount()+ mContactEntryListAdapter.getViewTypeCount()
- //
- // - Type for "loading" view used during "all" section is being loaded.
- // It should have the exact index
- // mContactTileAdapter.getViewTypeCount()+ mContactEntryListAdapter.getViewTypeCount() + 1
- //
- // As an exception, IGNORE_ITEM_VIEW_TYPE (-1) will be remained as is, which will be used
- // by framework's Adapter implementation and thus should be left as is.
- if (position < contactTileAdapterCount) { // For "tile" and "frequent" sections
- return mContactTileAdapter.getItemViewType(position);
- } else if (position == contactTileAdapterCount) { // For "all" section's account header
- return mContactTileAdapter.getViewTypeCount()
- + mContactEntryListAdapter.getViewTypeCount();
- } else { // For "all" section
- if (mContactEntryListAdapter.isLoading()) { // "All" section is being loaded.
- return mContactTileAdapter.getViewTypeCount()
- + mContactEntryListAdapter.getViewTypeCount() + 1;
- } else {
- // "-1" for mAccountFilterHeaderContainer
- final int localPosition = position - contactTileAdapterCount - 1;
- final int type = mContactEntryListAdapter.getItemViewType(localPosition);
- // IGNORE_ITEM_VIEW_TYPE must be handled differently.
- return (type < 0) ? type : type + mContactTileAdapter.getViewTypeCount();
- }
- }
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- final int contactTileAdapterCount = mContactTileAdapter.getCount();
- final int contactEntryListAdapterCount = mContactEntryListAdapter.getCount();
-
- // Obtain a View relevant for that position, and adjust its horizontal padding. Each
- // View has different implementation, so we use different way to control those padding.
- if (position < contactTileAdapterCount) { // For "tile" and "frequent" sections
- final View view = mContactTileAdapter.getView(position, convertView, parent);
- final int frequentHeaderPosition = mContactTileAdapter.getFrequentHeaderPosition();
- if (position < frequentHeaderPosition) { // "starred" contacts
- // No padding adjustment.
- } else if (position == frequentHeaderPosition) {
- view.setPadding(mItemPaddingLeft, mFrequentHeaderPaddingTop,
- mItemPaddingRight, view.getPaddingBottom());
- } else {
- // Views for "frequent" contacts use FrameLayout's margins instead of padding.
- final FrameLayout frameLayout = (FrameLayout) view;
- final View child = frameLayout.getChildAt(0);
- FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
- FrameLayout.LayoutParams.WRAP_CONTENT,
- FrameLayout.LayoutParams.WRAP_CONTENT);
- params.setMargins(mItemPaddingLeft, 0, mItemPaddingRight, 0);
- child.setLayoutParams(params);
- }
- return view;
- } else if (position == contactTileAdapterCount) { // For "all" section's account header
- mAccountFilterHeaderContainer.setPadding(mItemPaddingLeft,
- mAccountFilterHeaderContainer.getPaddingTop(),
- mItemPaddingRight,
- mAccountFilterHeaderContainer.getPaddingBottom());
- return mAccountFilterHeaderContainer;
- } else { // For "all" section
- if (mContactEntryListAdapter.isLoading()) { // "All" section is being loaded.
- mLoadingView.setPadding(mItemPaddingLeft,
- mLoadingView.getPaddingTop(),
- mItemPaddingRight,
- mLoadingView.getPaddingBottom());
- return mLoadingView;
- } else {
- // "-1" for mAccountFilterHeaderContainer
- final int localPosition = position - contactTileAdapterCount - 1;
- final ContactListItemView itemView = (ContactListItemView)
- mContactEntryListAdapter.getView(localPosition, convertView, null);
- itemView.setPadding(mItemPaddingLeft, itemView.getPaddingTop(),
- mItemPaddingRight, itemView.getPaddingBottom());
- itemView.setSelectionBoundsHorizontalMargin(mItemPaddingLeft, mItemPaddingRight);
- return itemView;
- }
- }
- }
-
- @Override
- public boolean areAllItemsEnabled() {
- // If "all" section is being loaded we'll show mLoadingView, which is not enabled.
- // Otherwise check the all the other components in the ListView and return appropriate
- // result.
- return !mContactEntryListAdapter.isLoading()
- && (mContactTileAdapter.areAllItemsEnabled()
- && mAccountFilterHeaderContainer.isEnabled()
- && mContactEntryListAdapter.areAllItemsEnabled());
- }
-
- @Override
- public boolean isEnabled(int position) {
- final int contactTileAdapterCount = mContactTileAdapter.getCount();
- final int contactEntryListAdapterCount = mContactEntryListAdapter.getCount();
- if (position < contactTileAdapterCount) { // For "tile" and "frequent" sections
- return mContactTileAdapter.isEnabled(position);
- } else if (position == contactTileAdapterCount) { // For "all" section's account header
- // This will be handled by View's onClick event instead of ListView's onItemClick event.
- return false;
- } else { // For "all" section
- if (mContactEntryListAdapter.isLoading()) { // "All" section is being loaded.
- return false;
- } else {
- // "-1" for mAccountFilterHeaderContainer
- final int localPosition = position - contactTileAdapterCount - 1;
- return mContactEntryListAdapter.isEnabled(localPosition);
- }
- }
- }
-
- @Override
- public int getPositionForSection(int sectionIndex) {
- final int contactTileAdapterCount = mContactTileAdapter.getCount();
- final int localPosition = mContactEntryListAdapter.getPositionForSection(sectionIndex);
- return contactTileAdapterCount + 1 + localPosition;
- }
-
- @Override
- public int getSectionForPosition(int position) {
- final int contactTileAdapterCount = mContactTileAdapter.getCount();
- if (position <= contactTileAdapterCount) {
- return 0;
- } else {
- // "-1" for mAccountFilterHeaderContainer
- final int localPosition = position - contactTileAdapterCount - 1;
- return mContactEntryListAdapter.getSectionForPosition(localPosition);
- }
- }
-
- @Override
- public Object[] getSections() {
- return mContactEntryListAdapter.getSections();
- }
-
- public boolean shouldShowFirstScroller(int firstVisibleItem) {
- final int contactTileAdapterCount = mContactTileAdapter.getCount();
- return firstVisibleItem > contactTileAdapterCount;
- }
-}
diff --git a/src/com/android/contacts/list/ShortcutIntentBuilder.java b/src/com/android/contacts/list/ShortcutIntentBuilder.java
index 1578524..447328b 100644
--- a/src/com/android/contacts/list/ShortcutIntentBuilder.java
+++ b/src/com/android/contacts/list/ShortcutIntentBuilder.java
@@ -40,8 +40,8 @@
import android.text.TextUtils;
import android.text.TextUtils.TruncateAt;
+import com.android.contacts.common.CallUtil;
import com.android.contacts.R;
-import com.android.contacts.util.Constants;
/**
* Constructs shortcut intents.
@@ -293,11 +293,11 @@
Uri phoneUri;
if (Intent.ACTION_CALL.equals(shortcutAction)) {
// Make the URI a direct tel: URI so that it will always continue to work
- phoneUri = Uri.fromParts(Constants.SCHEME_TEL, phoneNumber, null);
+ phoneUri = Uri.fromParts(CallUtil.SCHEME_TEL, phoneNumber, null);
bitmap = generatePhoneNumberIcon(bitmap, phoneType, phoneLabel,
R.drawable.badge_action_call);
} else {
- phoneUri = Uri.fromParts(Constants.SCHEME_SMSTO, phoneNumber, null);
+ phoneUri = Uri.fromParts(CallUtil.SCHEME_SMSTO, phoneNumber, null);
bitmap = generatePhoneNumberIcon(bitmap, phoneType, phoneLabel,
R.drawable.badge_action_sms);
}
diff --git a/src/com/android/contacts/model/AccountTypeManager.java b/src/com/android/contacts/model/AccountTypeManager.java
index b4a3e2b..6850e4f 100644
--- a/src/com/android/contacts/model/AccountTypeManager.java
+++ b/src/com/android/contacts/model/AccountTypeManager.java
@@ -140,8 +140,7 @@
* {@link AccountType#accountType}, {@link AccountType#dataSet}, and {@link DataKind#mimeType}.
* If no direct match found, we try searching {@link FallbackAccountType}.
*/
- public DataKind getKindOrFallback(String accountType, String dataSet, String mimeType) {
- final AccountType type = getAccountType(accountType, dataSet);
+ public DataKind getKindOrFallback(AccountType type, String mimeType) {
return type == null ? null : type.getKindForMimetype(mimeType);
}
@@ -588,13 +587,11 @@
* If no direct match found, we try searching {@link FallbackAccountType}.
*/
@Override
- public DataKind getKindOrFallback(String accountType, String dataSet, String mimeType) {
+ public DataKind getKindOrFallback(AccountType type, String mimeType) {
ensureAccountsLoaded();
DataKind kind = null;
// Try finding account type and kind matching request
- final AccountType type = mAccountTypesWithDataSets.get(
- AccountTypeWithDataSet.get(accountType, dataSet));
if (type != null) {
kind = type.getKindForMimetype(mimeType);
}
@@ -605,7 +602,7 @@
}
if (kind == null) {
- Log.w(TAG, "Unknown type=" + accountType + ", mime=" + mimeType);
+ Log.w(TAG, "Unknown type=" + type + ", mime=" + mimeType);
}
return kind;
diff --git a/src/com/android/contacts/model/Contact.java b/src/com/android/contacts/model/Contact.java
index ede2101..a097a25 100644
--- a/src/com/android/contacts/model/Contact.java
+++ b/src/com/android/contacts/model/Contact.java
@@ -26,7 +26,6 @@
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;
@@ -389,7 +388,7 @@
// Iterate through raw-contacts; if we find a writable on, return its ID.
for (RawContact rawContact : getRawContacts()) {
- AccountType accountType = rawContact.getAccountType();
+ AccountType accountType = rawContact.getAccountType(context);
if (accountType != null && accountType.areContactsWritable()) {
return rawContact.getId();
}
@@ -429,10 +428,7 @@
}
RawContact rawContact = mRawContacts.get(0);
- ArrayList<ContentValues> result = new ArrayList<ContentValues>();
- for (DataItem dataItem : rawContact.getDataItems()) {
- result.add(dataItem.getContentValues());
- }
+ ArrayList<ContentValues> result = rawContact.getContentValues();
// If the photo was loaded using the URI, create an entry for the photo
// binary data.
diff --git a/src/com/android/contacts/model/ContactLoader.java b/src/com/android/contacts/model/ContactLoader.java
index f9f630d..bbab0f5 100644
--- a/src/com/android/contacts/model/ContactLoader.java
+++ b/src/com/android/contacts/model/ContactLoader.java
@@ -41,8 +41,8 @@
import android.util.Log;
import android.util.LongSparseArray;
-import com.android.contacts.ContactsUtils;
import com.android.contacts.GroupMetaData;
+import com.android.contacts.common.GeoUtil;
import com.android.contacts.model.account.AccountType;
import com.android.contacts.model.account.AccountTypeWithDataSet;
import com.android.contacts.model.dataitem.DataItem;
@@ -52,7 +52,7 @@
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.android.contacts.common.util.UriUtils;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
@@ -382,12 +382,12 @@
// 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));
+ rawContact = new RawContact(loadRawContactValues(cursor));
rawContactsBuilder.add(rawContact);
}
if (!cursor.isNull(ContactQuery.DATA_ID)) {
ContentValues data = loadDataValues(cursor);
- final DataItem item = rawContact.addDataItemValues(data);
+ rawContact.addDataItemValues(data);
if (!cursor.isNull(ContactQuery.PRESENCE)
|| !cursor.isNull(ContactQuery.STATUS)) {
@@ -804,7 +804,7 @@
* overwritten
*/
private void computeFormattedPhoneNumbers(Contact contactData) {
- final String countryIso = ContactsUtils.getCurrentCountryIso(getContext());
+ final String countryIso = GeoUtil.getCurrentCountryIso(getContext());
final ImmutableList<RawContact> rawContacts = contactData.getRawContacts();
final int rawContactCount = rawContacts.size();
for (int rawContactIndex = 0; rawContactIndex < rawContactCount; rawContactIndex++) {
@@ -865,7 +865,7 @@
continue; // Already notified for this raw contact.
}
mNotifiedRawContactIds.add(rawContactId);
- final AccountType accountType = rawContact.getAccountType();
+ final AccountType accountType = rawContact.getAccountType(context);
final String serviceName = accountType.getViewContactNotifyServiceClassName();
final String servicePackageName = accountType.getViewContactNotifyServicePackageName();
if (!TextUtils.isEmpty(serviceName) && !TextUtils.isEmpty(servicePackageName)) {
diff --git a/src/com/android/contacts/model/RawContact.java b/src/com/android/contacts/model/RawContact.java
index 6d4a881..823a853 100644
--- a/src/com/android/contacts/model/RawContact.java
+++ b/src/com/android/contacts/model/RawContact.java
@@ -20,6 +20,8 @@
import android.content.Context;
import android.content.Entity;
import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
@@ -27,6 +29,8 @@
import com.android.contacts.model.account.AccountType;
import com.android.contacts.model.account.AccountWithDataSet;
import com.android.contacts.model.dataitem.DataItem;
+import com.google.common.base.Objects;
+import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.List;
@@ -42,20 +46,76 @@
* DataItem objects that represent contact information elements (like phone
* numbers, email, address, etc.).
*/
-public class RawContact {
+final public class RawContact implements Parcelable {
- 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;
+ final public static class NamedDataItem implements Parcelable {
+ public final Uri mUri;
- public NamedDataItem(Uri uri, DataItem dataItem) {
- this.uri = uri;
- this.dataItem = dataItem;
+ // This use to be a DataItem. DataItem creation is now delayed until the point of request
+ // since there is no benefit to storing them here due to the multiple inheritance.
+ // Eventually instanceof still has to be used anyways to determine which sub-class of
+ // DataItem it is. And having parent DataItem's here makes it very difficult to serialize or
+ // parcelable.
+ //
+ // Instead of having a common DataItem super class, we should refactor this to be a generic
+ // Object where the object is a concrete class that no longer relies on ContentValues.
+ // (this will also make the classes easier to use).
+ // Since instanceof is used later anyways, having a list of Objects won't hurt and is no
+ // worse than having a DataItem.
+ public final ContentValues mContentValues;
+
+ public NamedDataItem(Uri uri, ContentValues values) {
+ this.mUri = uri;
+ this.mContentValues = values;
+ }
+
+ public NamedDataItem(Parcel parcel) {
+ this.mUri = parcel.readParcelable(Uri.class.getClassLoader());
+ this.mContentValues = parcel.readParcelable(ContentValues.class.getClassLoader());
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int i) {
+ parcel.writeParcelable(mUri, i);
+ parcel.writeParcelable(mContentValues, i);
+ }
+
+ public static final Parcelable.Creator<NamedDataItem> CREATOR
+ = new Parcelable.Creator<NamedDataItem>() {
+
+ @Override
+ public NamedDataItem createFromParcel(Parcel parcel) {
+ return new NamedDataItem(parcel);
+ }
+
+ @Override
+ public NamedDataItem[] newArray(int i) {
+ return new NamedDataItem[i];
+ }
+ };
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(mUri, mContentValues);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) return false;
+ if (getClass() != obj.getClass()) return false;
+
+ final NamedDataItem other = (NamedDataItem) obj;
+ return Objects.equal(mUri, other.mUri) &&
+ Objects.equal(mContentValues, other.mContentValues);
}
}
@@ -63,7 +123,7 @@
final ContentValues values = entity.getEntityValues();
final ArrayList<Entity.NamedContentValues> subValues = entity.getSubValues();
- RawContact rawContact = new RawContact(null, values);
+ RawContact rawContact = new RawContact(values);
for (Entity.NamedContentValues subValue : subValues) {
rawContact.addNamedDataItemValues(subValue.uri, subValue.values);
}
@@ -72,31 +132,60 @@
/**
* 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() {
+ this(new ContentValues());
}
- public RawContact(Context context, ContentValues values) {
- mContext = context;
+ public RawContact(ContentValues values) {
mValues = values;
mDataItems = new ArrayList<NamedDataItem>();
}
- public AccountTypeManager getAccountTypeManager() {
- if (mAccountTypeManager == null) {
- mAccountTypeManager = AccountTypeManager.getInstance(mContext);
- }
- return mAccountTypeManager;
+ /**
+ * Constructor for the parcelable.
+ *
+ * @param parcel The parcel to de-serialize from.
+ */
+ private RawContact(Parcel parcel) {
+ mValues = parcel.readParcelable(ContentValues.class.getClassLoader());
+ mDataItems = Lists.newArrayList();
+ parcel.readTypedList(mDataItems, NamedDataItem.CREATOR);
}
- public Context getContext() {
- return mContext;
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int i) {
+ parcel.writeParcelable(mValues, i);
+ parcel.writeTypedList(mDataItems);
+ }
+
+ /**
+ * Create for building the parcelable.
+ */
+ public static final Parcelable.Creator<RawContact> CREATOR
+ = new Parcelable.Creator<RawContact>() {
+
+ @Override
+ public RawContact createFromParcel(Parcel parcel) {
+ return new RawContact(parcel);
+ }
+
+ @Override
+ public RawContact[] newArray(int i) {
+ return new RawContact[i];
+ }
+ };
+
+ public AccountTypeManager getAccountTypeManager(Context context) {
+ if (mAccountTypeManager == null) {
+ mAccountTypeManager = AccountTypeManager.getInstance(context);
+ }
+ return mAccountTypeManager;
}
public ContentValues getValues() {
@@ -182,8 +271,8 @@
return getValues().getAsBoolean(Contacts.STARRED);
}
- public AccountType getAccountType() {
- return getAccountTypeManager().getAccountType(getAccountTypeString(), getDataSet());
+ public AccountType getAccountType(Context context) {
+ return getAccountTypeManager(context).getAccountType(getAccountTypeString(), getDataSet());
}
/**
@@ -231,38 +320,58 @@
/**
* Creates and inserts a DataItem object that wraps the content values, and returns it.
*/
- public DataItem addDataItemValues(ContentValues values) {
- final NamedDataItem namedItem = addNamedDataItemValues(Data.CONTENT_URI, values);
- return namedItem.dataItem;
+ public void addDataItemValues(ContentValues values) {
+ addNamedDataItemValues(Data.CONTENT_URI, values);
}
public NamedDataItem addNamedDataItemValues(Uri uri, ContentValues values) {
- final NamedDataItem namedItem = new NamedDataItem(uri, DataItem.createFrom(this, values));
+ final NamedDataItem namedItem = new NamedDataItem(uri, values);
mDataItems.add(namedItem);
return namedItem;
}
- public List<DataItem> getDataItems() {
- final ArrayList<DataItem> list = new ArrayList<DataItem>();
+ public ArrayList<ContentValues> getContentValues() {
+ final ArrayList<ContentValues> list = Lists.newArrayListWithCapacity(mDataItems.size());
for (NamedDataItem dataItem : mDataItems) {
- if (Data.CONTENT_URI.equals(dataItem.uri)) {
- list.add(dataItem.dataItem);
+ if (Data.CONTENT_URI.equals(dataItem.mUri)) {
+ list.add(dataItem.mContentValues);
}
}
return list;
}
- public List<NamedDataItem> getNamedDataItems() {
- return mDataItems;
+ public List<DataItem> getDataItems() {
+ final ArrayList<DataItem> list = Lists.newArrayListWithCapacity(mDataItems.size());
+ for (NamedDataItem dataItem : mDataItems) {
+ if (Data.CONTENT_URI.equals(dataItem.mUri)) {
+ list.add(DataItem.createFrom(dataItem.mContentValues));
+ }
+ }
+ return list;
}
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());
+ sb.append("\n ").append(namedDataItem.mUri);
+ sb.append("\n -> ").append(namedDataItem.mContentValues);
}
return sb.toString();
}
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(mValues, mDataItems);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) return false;
+ if (getClass() != obj.getClass()) return false;
+
+ RawContact other = (RawContact) obj;
+ return Objects.equal(mValues, other.mValues) &&
+ Objects.equal(mDataItems, other.mDataItems);
+ }
}
diff --git a/src/com/android/contacts/model/RawContactDelta.java b/src/com/android/contacts/model/RawContactDelta.java
index 2ee9d5c..b381174 100644
--- a/src/com/android/contacts/model/RawContactDelta.java
+++ b/src/com/android/contacts/model/RawContactDelta.java
@@ -35,7 +35,6 @@
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;
@@ -97,8 +96,8 @@
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()));
+ for (final ContentValues values : before.getContentValues()) {
+ rawContactDelta.addEntry(ValuesDelta.fromBefore(values));
}
return rawContactDelta;
}
diff --git a/src/com/android/contacts/model/account/AccountType.java b/src/com/android/contacts/model/account/AccountType.java
index edd17a0..ca3dc68 100644
--- a/src/com/android/contacts/model/account/AccountType.java
+++ b/src/com/android/contacts/model/account/AccountType.java
@@ -28,7 +28,6 @@
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;
@@ -325,8 +324,7 @@
/**
* Find the {@link DataKind} for a specific MIME-type, if it's handled by
- * this data source. If you may need a fallback {@link DataKind}, use
- * {@link AccountTypeManager#getKindOrFallback(String, String, String)}.
+ * this data source.
*/
public DataKind getKindForMimetype(String mimeType) {
return this.mMimeKinds.get(mimeType);
diff --git a/src/com/android/contacts/model/account/BaseAccountType.java b/src/com/android/contacts/model/account/BaseAccountType.java
index 7f9e1ef..6b4d623 100644
--- a/src/com/android/contacts/model/account/BaseAccountType.java
+++ b/src/com/android/contacts/model/account/BaseAccountType.java
@@ -39,6 +39,7 @@
import android.view.inputmethod.EditorInfo;
import com.android.contacts.R;
+import com.android.contacts.common.util.ContactDisplayUtils;
import com.android.contacts.model.dataitem.DataKind;
import com.android.contacts.test.NeededForTesting;
import com.android.contacts.util.DateUtils;
@@ -540,70 +541,24 @@
public static class PhoneActionInflater extends CommonInflater {
@Override
protected boolean isCustom(Integer type) {
- return type == Phone.TYPE_CUSTOM || type == Phone.TYPE_ASSISTANT;
+ return ContactDisplayUtils.isCustomPhoneType(type);
}
@Override
protected int getTypeLabelResource(Integer type) {
- if (type == null) return R.string.call_other;
- switch (type) {
- case Phone.TYPE_HOME: return R.string.call_home;
- case Phone.TYPE_MOBILE: return R.string.call_mobile;
- case Phone.TYPE_WORK: return R.string.call_work;
- case Phone.TYPE_FAX_WORK: return R.string.call_fax_work;
- case Phone.TYPE_FAX_HOME: return R.string.call_fax_home;
- case Phone.TYPE_PAGER: return R.string.call_pager;
- case Phone.TYPE_OTHER: return R.string.call_other;
- case Phone.TYPE_CALLBACK: return R.string.call_callback;
- case Phone.TYPE_CAR: return R.string.call_car;
- case Phone.TYPE_COMPANY_MAIN: return R.string.call_company_main;
- case Phone.TYPE_ISDN: return R.string.call_isdn;
- case Phone.TYPE_MAIN: return R.string.call_main;
- case Phone.TYPE_OTHER_FAX: return R.string.call_other_fax;
- case Phone.TYPE_RADIO: return R.string.call_radio;
- case Phone.TYPE_TELEX: return R.string.call_telex;
- case Phone.TYPE_TTY_TDD: return R.string.call_tty_tdd;
- case Phone.TYPE_WORK_MOBILE: return R.string.call_work_mobile;
- case Phone.TYPE_WORK_PAGER: return R.string.call_work_pager;
- case Phone.TYPE_ASSISTANT: return R.string.call_assistant;
- case Phone.TYPE_MMS: return R.string.call_mms;
- default: return R.string.call_custom;
- }
+ return ContactDisplayUtils.getPhoneLabelResourceId(type);
}
}
public static class PhoneActionAltInflater extends CommonInflater {
@Override
protected boolean isCustom(Integer type) {
- return (type == Phone.TYPE_CUSTOM || type == Phone.TYPE_ASSISTANT);
+ return ContactDisplayUtils.isCustomPhoneType(type);
}
@Override
protected int getTypeLabelResource(Integer type) {
- if (type == null) return R.string.sms_other;
- switch (type) {
- case Phone.TYPE_HOME: return R.string.sms_home;
- case Phone.TYPE_MOBILE: return R.string.sms_mobile;
- case Phone.TYPE_WORK: return R.string.sms_work;
- case Phone.TYPE_FAX_WORK: return R.string.sms_fax_work;
- case Phone.TYPE_FAX_HOME: return R.string.sms_fax_home;
- case Phone.TYPE_PAGER: return R.string.sms_pager;
- case Phone.TYPE_OTHER: return R.string.sms_other;
- case Phone.TYPE_CALLBACK: return R.string.sms_callback;
- case Phone.TYPE_CAR: return R.string.sms_car;
- case Phone.TYPE_COMPANY_MAIN: return R.string.sms_company_main;
- case Phone.TYPE_ISDN: return R.string.sms_isdn;
- case Phone.TYPE_MAIN: return R.string.sms_main;
- case Phone.TYPE_OTHER_FAX: return R.string.sms_other_fax;
- case Phone.TYPE_RADIO: return R.string.sms_radio;
- case Phone.TYPE_TELEX: return R.string.sms_telex;
- case Phone.TYPE_TTY_TDD: return R.string.sms_tty_tdd;
- case Phone.TYPE_WORK_MOBILE: return R.string.sms_work_mobile;
- case Phone.TYPE_WORK_PAGER: return R.string.sms_work_pager;
- case Phone.TYPE_ASSISTANT: return R.string.sms_assistant;
- case Phone.TYPE_MMS: return R.string.sms_mms;
- default: return R.string.sms_custom;
- }
+ return ContactDisplayUtils.getSmsLabelResourceId(type);
}
}
diff --git a/src/com/android/contacts/model/dataitem/DataItem.java b/src/com/android/contacts/model/dataitem/DataItem.java
index 25c44cb..9c618de 100644
--- a/src/com/android/contacts/model/dataitem/DataItem.java
+++ b/src/com/android/contacts/model/dataitem/DataItem.java
@@ -17,6 +17,7 @@
package com.android.contacts.model.dataitem;
import android.content.ContentValues;
+import android.content.Context;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Event;
import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
@@ -34,10 +35,6 @@
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.
*/
@@ -45,67 +42,56 @@
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) {
+ protected DataItem(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) {
+ public static DataItem createFrom(ContentValues values) {
final String mimeType = values.getAsString(Data.MIMETYPE);
if (GroupMembership.CONTENT_ITEM_TYPE.equals(mimeType)) {
- return new GroupMembershipDataItem(rawContact, values);
+ return new GroupMembershipDataItem(values);
} else if (StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)) {
- return new StructuredNameDataItem(rawContact, values);
+ return new StructuredNameDataItem(values);
} else if (Phone.CONTENT_ITEM_TYPE.equals(mimeType)) {
- return new PhoneDataItem(rawContact, values);
+ return new PhoneDataItem(values);
} else if (Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
- return new EmailDataItem(rawContact, values);
+ return new EmailDataItem(values);
} else if (StructuredPostal.CONTENT_ITEM_TYPE.equals(mimeType)) {
- return new StructuredPostalDataItem(rawContact, values);
+ return new StructuredPostalDataItem(values);
} else if (Im.CONTENT_ITEM_TYPE.equals(mimeType)) {
- return new ImDataItem(rawContact, values);
+ return new ImDataItem(values);
} else if (Organization.CONTENT_ITEM_TYPE.equals(mimeType)) {
- return new OrganizationDataItem(rawContact, values);
+ return new OrganizationDataItem(values);
} else if (Nickname.CONTENT_ITEM_TYPE.equals(mimeType)) {
- return new NicknameDataItem(rawContact, values);
+ return new NicknameDataItem(values);
} else if (Note.CONTENT_ITEM_TYPE.equals(mimeType)) {
- return new NoteDataItem(rawContact, values);
+ return new NoteDataItem(values);
} else if (Website.CONTENT_ITEM_TYPE.equals(mimeType)) {
- return new WebsiteDataItem(rawContact, values);
+ return new WebsiteDataItem(values);
} else if (SipAddress.CONTENT_ITEM_TYPE.equals(mimeType)) {
- return new SipAddressDataItem(rawContact, values);
+ return new SipAddressDataItem(values);
} else if (Event.CONTENT_ITEM_TYPE.equals(mimeType)) {
- return new EventDataItem(rawContact, values);
+ return new EventDataItem(values);
} else if (Relation.CONTENT_ITEM_TYPE.equals(mimeType)) {
- return new RelationDataItem(rawContact, values);
+ return new RelationDataItem(values);
} else if (Identity.CONTENT_ITEM_TYPE.equals(mimeType)) {
- return new IdentityDataItem(rawContact, values);
+ return new IdentityDataItem(values);
} else if (Photo.CONTENT_ITEM_TYPE.equals(mimeType)) {
- return new PhotoDataItem(rawContact, values);
+ return new PhotoDataItem(values);
}
// generic
- return new DataItem(rawContact, values);
+ return new DataItem(values);
}
public ContentValues getContentValues() {
return mContentValues;
}
- protected RawContact getRawContact() {
- return mRawContact;
- }
-
public void setRawContactId(long rawContactId) {
mContentValues.put(Data.RAW_CONTACT_ID, rawContactId);
}
@@ -145,70 +131,25 @@
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;
+ public boolean hasKindTypeColumn(DataKind kind) {
+ final String key = kind.typeColumn;
return key != null && mContentValues.containsKey(key);
}
- public int getKindTypeColumn() {
- final String key = getDataKind().typeColumn;
+ public int getKindTypeColumn(DataKind kind) {
+ final String key = kind.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.
+ * DataKind object underneath.
*/
- public String buildDataString() {
- if (mRawContact == null) {
- throw new IllegalStateException("mRawContact must be non-null to call getDataKind()");
- }
- final DataKind kind = getDataKind();
-
+ public String buildDataString(Context context, DataKind kind) {
if (kind.actionBody == null) {
return null;
}
- CharSequence actionBody = kind.actionBody.inflateUsing(mRawContact.getContext(),
- mContentValues);
+ CharSequence actionBody = kind.actionBody.inflateUsing(context, 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/dataitem/DataKind.java b/src/com/android/contacts/model/dataitem/DataKind.java
index 8707012..204b784 100644
--- a/src/com/android/contacts/model/dataitem/DataKind.java
+++ b/src/com/android/contacts/model/dataitem/DataKind.java
@@ -17,6 +17,7 @@
package com.android.contacts.model.dataitem;
import android.content.ContentValues;
+import android.content.Context;
import android.provider.ContactsContract.Data;
import com.android.contacts.R;
@@ -106,6 +107,10 @@
maxLinesForDisplay = 1;
}
+ public String getKindString(Context context) {
+ return (titleRes == -1 || titleRes == 0) ? "" : context.getString(titleRes);
+ }
+
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
diff --git a/src/com/android/contacts/model/dataitem/EmailDataItem.java b/src/com/android/contacts/model/dataitem/EmailDataItem.java
index a535c73..cb93395 100644
--- a/src/com/android/contacts/model/dataitem/EmailDataItem.java
+++ b/src/com/android/contacts/model/dataitem/EmailDataItem.java
@@ -20,16 +20,14 @@
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);
+ /* package */ EmailDataItem(ContentValues values) {
+ super(values);
}
public String getAddress() {
diff --git a/src/com/android/contacts/model/dataitem/EventDataItem.java b/src/com/android/contacts/model/dataitem/EventDataItem.java
index 2114279..1b34a17 100644
--- a/src/com/android/contacts/model/dataitem/EventDataItem.java
+++ b/src/com/android/contacts/model/dataitem/EventDataItem.java
@@ -20,16 +20,14 @@
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);
+ /* package */ EventDataItem(ContentValues values) {
+ super(values);
}
public String getStartDate() {
diff --git a/src/com/android/contacts/model/dataitem/GroupMembershipDataItem.java b/src/com/android/contacts/model/dataitem/GroupMembershipDataItem.java
index aea9bca..a3db7f9 100644
--- a/src/com/android/contacts/model/dataitem/GroupMembershipDataItem.java
+++ b/src/com/android/contacts/model/dataitem/GroupMembershipDataItem.java
@@ -20,16 +20,14 @@
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);
+ /* package */ GroupMembershipDataItem(ContentValues values) {
+ super(values);
}
public long getGroupRowId() {
diff --git a/src/com/android/contacts/model/dataitem/IdentityDataItem.java b/src/com/android/contacts/model/dataitem/IdentityDataItem.java
index fd4b836..045867a 100644
--- a/src/com/android/contacts/model/dataitem/IdentityDataItem.java
+++ b/src/com/android/contacts/model/dataitem/IdentityDataItem.java
@@ -20,16 +20,14 @@
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);
+ /* package */ IdentityDataItem(ContentValues values) {
+ super(values);
}
public String getIdentity() {
diff --git a/src/com/android/contacts/model/dataitem/ImDataItem.java b/src/com/android/contacts/model/dataitem/ImDataItem.java
index 3a08325..00473e5 100644
--- a/src/com/android/contacts/model/dataitem/ImDataItem.java
+++ b/src/com/android/contacts/model/dataitem/ImDataItem.java
@@ -21,8 +21,6 @@
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}.
@@ -31,20 +29,18 @@
private final boolean mCreatedFromEmail;
- /* package */ ImDataItem(RawContact rawContact, ContentValues values) {
- super(rawContact, values);
+ /* package */ ImDataItem(ContentValues values) {
+ super(values);
mCreatedFromEmail = false;
}
- private ImDataItem(RawContact rawContact, ContentValues values,
- boolean createdFromEmail) {
- super(rawContact, values);
+ private ImDataItem(ContentValues values, boolean createdFromEmail) {
+ super(values);
mCreatedFromEmail = createdFromEmail;
}
public static ImDataItem createFromEmail(EmailDataItem item) {
- ImDataItem im = new ImDataItem(item.getRawContact(),
- new ContentValues(item.getContentValues()), true);
+ ImDataItem im = new ImDataItem(new ContentValues(item.getContentValues()), true);
im.setMimeType(Im.CONTENT_ITEM_TYPE);
return im;
}
diff --git a/src/com/android/contacts/model/dataitem/NicknameDataItem.java b/src/com/android/contacts/model/dataitem/NicknameDataItem.java
index 7b52510..79c2c50 100644
--- a/src/com/android/contacts/model/dataitem/NicknameDataItem.java
+++ b/src/com/android/contacts/model/dataitem/NicknameDataItem.java
@@ -20,16 +20,14 @@
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 NicknameDataItem(ContentValues values) {
+ super(values);
}
public String getName() {
diff --git a/src/com/android/contacts/model/dataitem/NoteDataItem.java b/src/com/android/contacts/model/dataitem/NoteDataItem.java
index 0d0fa24..9a572cb 100644
--- a/src/com/android/contacts/model/dataitem/NoteDataItem.java
+++ b/src/com/android/contacts/model/dataitem/NoteDataItem.java
@@ -20,16 +20,14 @@
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);
+ /* package */ NoteDataItem(ContentValues values) {
+ super(values);
}
public String getNote() {
diff --git a/src/com/android/contacts/model/dataitem/OrganizationDataItem.java b/src/com/android/contacts/model/dataitem/OrganizationDataItem.java
index 1326bdb..0fbcd01 100644
--- a/src/com/android/contacts/model/dataitem/OrganizationDataItem.java
+++ b/src/com/android/contacts/model/dataitem/OrganizationDataItem.java
@@ -20,16 +20,14 @@
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);
+ /* package */ OrganizationDataItem(ContentValues values) {
+ super(values);
}
public String getCompany() {
diff --git a/src/com/android/contacts/model/dataitem/PhoneDataItem.java b/src/com/android/contacts/model/dataitem/PhoneDataItem.java
index 61d62c1..66b9018 100644
--- a/src/com/android/contacts/model/dataitem/PhoneDataItem.java
+++ b/src/com/android/contacts/model/dataitem/PhoneDataItem.java
@@ -21,8 +21,6 @@
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.telephony.PhoneNumberUtils;
-import com.android.contacts.model.RawContact;
-
/**
* Represents a phone data item, wrapping the columns in
* {@link ContactsContract.CommonDataKinds.Phone}.
@@ -31,8 +29,8 @@
public static final String KEY_FORMATTED_PHONE_NUMBER = "formattedPhoneNumber";
- /* package */ PhoneDataItem(RawContact rawContact, ContentValues values) {
- super(rawContact, values);
+ /* package */ PhoneDataItem(ContentValues values) {
+ super(values);
}
public String getNumber() {
diff --git a/src/com/android/contacts/model/dataitem/PhotoDataItem.java b/src/com/android/contacts/model/dataitem/PhotoDataItem.java
index 5e355fa..62eab8f 100644
--- a/src/com/android/contacts/model/dataitem/PhotoDataItem.java
+++ b/src/com/android/contacts/model/dataitem/PhotoDataItem.java
@@ -20,16 +20,14 @@
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);
+ /* package */ PhotoDataItem(ContentValues values) {
+ super(values);
}
public long getPhotoFileId() {
diff --git a/src/com/android/contacts/model/dataitem/RelationDataItem.java b/src/com/android/contacts/model/dataitem/RelationDataItem.java
index 7c22cf5..86967f5 100644
--- a/src/com/android/contacts/model/dataitem/RelationDataItem.java
+++ b/src/com/android/contacts/model/dataitem/RelationDataItem.java
@@ -20,16 +20,14 @@
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);
+ /* package */ RelationDataItem(ContentValues values) {
+ super(values);
}
public String getName() {
diff --git a/src/com/android/contacts/model/dataitem/SipAddressDataItem.java b/src/com/android/contacts/model/dataitem/SipAddressDataItem.java
index 6b8e93d..3457fb2 100644
--- a/src/com/android/contacts/model/dataitem/SipAddressDataItem.java
+++ b/src/com/android/contacts/model/dataitem/SipAddressDataItem.java
@@ -20,16 +20,14 @@
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);
+ /* package */ SipAddressDataItem(ContentValues values) {
+ super(values);
}
public String getSipAddress() {
diff --git a/src/com/android/contacts/model/dataitem/StructuredNameDataItem.java b/src/com/android/contacts/model/dataitem/StructuredNameDataItem.java
index 4654a6f..7d1a44d 100644
--- a/src/com/android/contacts/model/dataitem/StructuredNameDataItem.java
+++ b/src/com/android/contacts/model/dataitem/StructuredNameDataItem.java
@@ -21,8 +21,6 @@
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}.
@@ -30,12 +28,12 @@
public class StructuredNameDataItem extends DataItem {
public StructuredNameDataItem() {
- super(null, new ContentValues());
+ super(new ContentValues());
getContentValues().put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
}
- /* package */ StructuredNameDataItem(RawContact rawContact, ContentValues values) {
- super(rawContact, values);
+ /* package */ StructuredNameDataItem(ContentValues values) {
+ super(values);
}
public String getDisplayName() {
diff --git a/src/com/android/contacts/model/dataitem/StructuredPostalDataItem.java b/src/com/android/contacts/model/dataitem/StructuredPostalDataItem.java
index cc2cf56..b571bd3 100644
--- a/src/com/android/contacts/model/dataitem/StructuredPostalDataItem.java
+++ b/src/com/android/contacts/model/dataitem/StructuredPostalDataItem.java
@@ -20,16 +20,14 @@
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);
+ /* package */ StructuredPostalDataItem(ContentValues values) {
+ super(values);
}
public String getFormattedAddress() {
diff --git a/src/com/android/contacts/model/dataitem/WebsiteDataItem.java b/src/com/android/contacts/model/dataitem/WebsiteDataItem.java
index c3aadf3..33935fb 100644
--- a/src/com/android/contacts/model/dataitem/WebsiteDataItem.java
+++ b/src/com/android/contacts/model/dataitem/WebsiteDataItem.java
@@ -20,16 +20,14 @@
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);
+ /* package */ WebsiteDataItem(ContentValues values) {
+ super(values);
}
public String getUrl() {
diff --git a/src/com/android/contacts/quickcontact/Action.java b/src/com/android/contacts/quickcontact/Action.java
index 08fbce4..fa23286 100644
--- a/src/com/android/contacts/quickcontact/Action.java
+++ b/src/com/android/contacts/quickcontact/Action.java
@@ -20,7 +20,7 @@
import android.graphics.drawable.Drawable;
import android.net.Uri;
-import com.android.contacts.Collapser;
+import com.android.contacts.common.Collapser;
/**
* Abstract definition of an action that could be performed, along with
diff --git a/src/com/android/contacts/quickcontact/DataAction.java b/src/com/android/contacts/quickcontact/DataAction.java
index c10c338..3cf3adf 100644
--- a/src/com/android/contacts/quickcontact/DataAction.java
+++ b/src/com/android/contacts/quickcontact/DataAction.java
@@ -28,8 +28,10 @@
import android.text.TextUtils;
import android.util.Log;
+import com.android.contacts.common.CallUtil;
import com.android.contacts.ContactsUtils;
import com.android.contacts.R;
+import com.android.contacts.common.MoreContactUtils;
import com.android.contacts.model.account.AccountType.EditType;
import com.android.contacts.model.dataitem.DataItem;
import com.android.contacts.model.dataitem.DataKind;
@@ -39,7 +41,6 @@
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;
@@ -69,18 +70,18 @@
/**
* Create an action from common {@link Data} elements.
*/
- public DataAction(Context context, DataItem item) {
+ public DataAction(Context context, DataItem item, DataKind kind) {
mContext = context;
- mKind = item.getDataKind();
+ mKind = kind;
mMimeType = item.getMimeType();
// Determine type for subtitle
mSubtitle = "";
- if (item.hasKindTypeColumn()) {
- final int typeValue = item.getKindTypeColumn();
+ if (item.hasKindTypeColumn(kind)) {
+ final int typeValue = item.getKindTypeColumn(kind);
// get type string
- for (EditType type : item.getDataKind().typeList) {
+ for (EditType type : kind.typeList) {
if (type.rawValue == typeValue) {
if (type.customColumn == null) {
// Non-custom type. Get its description from the resource
@@ -95,7 +96,7 @@
}
mIsPrimary = item.isSuperPrimary();
- mBody = item.buildDataString();
+ mBody = item.buildDataString(context, kind);
mDataId = item.getId();
mDataUri = ContentUris.withAppendedId(Data.CONTENT_URI, mDataId);
@@ -110,17 +111,17 @@
final String number = phone.getNumber();
if (!TextUtils.isEmpty(number)) {
- final Intent phoneIntent = hasPhone ? ContactsUtils.getCallIntent(number)
+ final Intent phoneIntent = hasPhone ? CallUtil.getCallIntent(number)
: null;
final Intent smsIntent = hasSms ? new Intent(Intent.ACTION_SENDTO,
- Uri.fromParts(Constants.SCHEME_SMSTO, number, null)) : null;
+ Uri.fromParts(CallUtil.SCHEME_SMSTO, number, null)) : null;
// Configure Icons and Intents. Notice actionIcon is already set to the phone
if (hasPhone && hasSms) {
mIntent = phoneIntent;
mAlternateIntent = smsIntent;
- mAlternateIconRes = phone.getDataKind().iconAltRes;
- mAlternateIconDescriptionRes = phone.getDataKind().iconAltDescriptionRes;
+ mAlternateIconRes = kind.iconAltRes;
+ mAlternateIconDescriptionRes = kind.iconAltDescriptionRes;
} else if (hasPhone) {
mIntent = phoneIntent;
} else if (hasSms) {
@@ -133,8 +134,8 @@
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);
+ final Uri callUri = Uri.fromParts(CallUtil.SCHEME_SIP, address, null);
+ mIntent = CallUtil.getCallIntent(callUri);
// Note that this item will get a SIP-specific variant
// of the "call phone" icon, rather than the standard
// app icon for the Phone app (which we show for
@@ -147,7 +148,7 @@
final EmailDataItem email = (EmailDataItem) item;
final String address = email.getData();
if (!TextUtils.isEmpty(address)) {
- final Uri mailUri = Uri.fromParts(Constants.SCHEME_MAILTO, address, null);
+ final Uri mailUri = Uri.fromParts(CallUtil.SCHEME_MAILTO, address, null);
mIntent = new Intent(Intent.ACTION_SENDTO, mailUri);
}
@@ -182,7 +183,7 @@
if (!TextUtils.isEmpty(host) && !TextUtils.isEmpty(data)) {
final String authority = host.toLowerCase();
- final Uri imUri = new Uri.Builder().scheme(Constants.SCHEME_IMTO).authority(
+ final Uri imUri = new Uri.Builder().scheme(CallUtil.SCHEME_IMTO).authority(
authority).appendPath(data).build();
mIntent = new Intent(Intent.ACTION_SENDTO, imUri);
@@ -309,7 +310,7 @@
return false;
}
DataAction that = (DataAction)t;
- if (!ContactsUtils.shouldCollapse(mMimeType, mBody, that.mMimeType, that.mBody)) {
+ if (!MoreContactUtils.shouldCollapse(mMimeType, mBody, that.mMimeType, that.mBody)) {
return false;
}
if (!TextUtils.equals(mMimeType, that.mMimeType)
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index 25fb3f4..8eb14c2 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -56,11 +56,13 @@
import android.widget.TextView;
import android.widget.Toast;
-import com.android.contacts.Collapser;
+import com.android.contacts.common.Collapser;
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.RawContact;
+import com.android.contacts.model.account.AccountType;
import com.android.contacts.model.dataitem.DataItem;
import com.android.contacts.model.dataitem.DataKind;
import com.android.contacts.model.dataitem.EmailDataItem;
@@ -69,7 +71,7 @@
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.android.contacts.common.util.StopWatch;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
@@ -348,6 +350,9 @@
for (RawContact rawContact : data.getRawContacts()) {
for (DataItem dataItem : rawContact.getDataItems()) {
final String mimeType = dataItem.getMimeType();
+ final AccountType accountType = rawContact.getAccountType(this);
+ final DataKind dataKind = AccountTypeManager.getInstance(this)
+ .getKindOrFallback(accountType, mimeType);
// Skip this data item if MIME-type excluded
if (isMimeExcluded(mimeType)) continue;
@@ -356,11 +361,11 @@
final boolean isPrimary = dataItem.isPrimary();
final boolean isSuperPrimary = dataItem.isSuperPrimary();
- if (dataItem.getDataKind() != null) {
+ if (dataKind != 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, dataItem);
+ final Action action = new DataAction(context, dataItem, dataKind);
final boolean wasAdded = considerAdd(action, cache, isSuperPrimary);
if (wasAdded) {
// Remember the default
@@ -375,8 +380,8 @@
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);
+ if (dataKind != null) {
+ final DataAction action = new DataAction(context, im, dataKind);
action.setPresence(status.getPresence());
considerAdd(action, cache, isSuperPrimary);
}
diff --git a/src/com/android/contacts/test/FragmentTestActivity.java b/src/com/android/contacts/test/FragmentTestActivity.java
deleted file mode 100644
index 80c6731..0000000
--- a/src/com/android/contacts/test/FragmentTestActivity.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.test;
-
-import android.os.Bundle;
-import android.view.Window;
-import android.view.WindowManager;
-
-import com.android.contacts.ContactsActivity;
-import com.android.contacts.R;
-
-/**
- * An activity that is used for testing fragments. A unit test starts this
- * activity, adds a fragment and then tests the fragment.
- */
-public class FragmentTestActivity extends ContactsActivity {
-
- @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/util/AsyncTaskExecutor.java b/src/com/android/contacts/util/AsyncTaskExecutor.java
deleted file mode 100644
index f202949..0000000
--- a/src/com/android/contacts/util/AsyncTaskExecutor.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.util;
-
-import android.os.AsyncTask;
-
-import java.util.concurrent.Executor;
-
-/**
- * Interface used to submit {@link AsyncTask} objects to run in the background.
- * <p>
- * This interface has a direct parallel with the {@link Executor} interface. It exists to decouple
- * the mechanics of AsyncTask submission from the description of how that AsyncTask will execute.
- * <p>
- * One immediate benefit of this approach is that testing becomes much easier, since it is easy to
- * introduce a mock or fake AsyncTaskExecutor in unit/integration tests, and thus inspect which
- * tasks have been submitted and control their execution in an orderly manner.
- * <p>
- * Another benefit in due course will be the management of the submitted tasks. An extension to this
- * interface is planned to allow Activities to easily cancel all the submitted tasks that are still
- * pending in the onDestroy() method of the Activity.
- */
-public interface AsyncTaskExecutor {
- /**
- * Executes the given AsyncTask with the default Executor.
- * <p>
- * This method <b>must only be called from the ui thread</b>.
- * <p>
- * The identifier supplied is any Object that can be used to identify the task later. Most
- * commonly this will be an enum which the tests can also refer to. {@code null} is also
- * accepted, though of course this won't help in identifying the task later.
- */
- <T> AsyncTask<T, ?, ?> submit(Object identifier, AsyncTask<T, ?, ?> task, T... params);
-}
diff --git a/src/com/android/contacts/util/AsyncTaskExecutors.java b/src/com/android/contacts/util/AsyncTaskExecutors.java
deleted file mode 100644
index 36b05c7..0000000
--- a/src/com/android/contacts/util/AsyncTaskExecutors.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.util;
-
-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;
-
-/**
- * Factory methods for creating AsyncTaskExecutors.
- * <p>
- * All of the factory methods on this class check first to see if you have set a static
- * {@link AsyncTaskExecutorFactory} set through the
- * {@link #setFactoryForTest(AsyncTaskExecutorFactory)} method, and if so delegate to that instead,
- * which is one way of injecting dependencies for testing classes whose construction cannot be
- * controlled such as {@link android.app.Activity}.
- */
-public final class AsyncTaskExecutors {
- /**
- * A single instance of the {@link AsyncTaskExecutorFactory}, to which we delegate if it is
- * non-null, for injecting when testing.
- */
- private static AsyncTaskExecutorFactory mInjectedAsyncTaskExecutorFactory = null;
-
- /**
- * Creates an AsyncTaskExecutor that submits tasks to run with
- * {@link AsyncTask#SERIAL_EXECUTOR}.
- */
- public static AsyncTaskExecutor createAsyncTaskExecutor() {
- synchronized (AsyncTaskExecutors.class) {
- if (mInjectedAsyncTaskExecutorFactory != null) {
- return mInjectedAsyncTaskExecutorFactory.createAsyncTaskExeuctor();
- }
- return new SimpleAsyncTaskExecutor(AsyncTask.SERIAL_EXECUTOR);
- }
- }
-
- /**
- * Creates an AsyncTaskExecutor that submits tasks to run with
- * {@link AsyncTask#THREAD_POOL_EXECUTOR}.
- */
- public static AsyncTaskExecutor createThreadPoolExecutor() {
- synchronized (AsyncTaskExecutors.class) {
- if (mInjectedAsyncTaskExecutorFactory != null) {
- return mInjectedAsyncTaskExecutorFactory.createAsyncTaskExeuctor();
- }
- return new SimpleAsyncTaskExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- }
-
- /** Interface for creating AsyncTaskExecutor objects. */
- public interface AsyncTaskExecutorFactory {
- AsyncTaskExecutor createAsyncTaskExeuctor();
- }
-
- @NeededForTesting
- public static void setFactoryForTest(AsyncTaskExecutorFactory factory) {
- synchronized (AsyncTaskExecutors.class) {
- mInjectedAsyncTaskExecutorFactory = factory;
- }
- }
-
- public static void checkCalledFromUiThread() {
- Preconditions.checkState(Thread.currentThread() == Looper.getMainLooper().getThread(),
- "submit method must be called from ui thread, was: " + Thread.currentThread());
- }
-
- private static class SimpleAsyncTaskExecutor implements AsyncTaskExecutor {
- private final Executor mExecutor;
-
- public SimpleAsyncTaskExecutor(Executor executor) {
- mExecutor = executor;
- }
-
- @Override
- public <T> AsyncTask<T, ?, ?> submit(Object identifer, AsyncTask<T, ?, ?> task,
- T... params) {
- checkCalledFromUiThread();
- return task.executeOnExecutor(mExecutor, params);
- }
- }
-}
diff --git a/src/com/android/contacts/util/BitmapUtil.java b/src/com/android/contacts/util/BitmapUtil.java
deleted file mode 100644
index 87eeb3c..0000000
--- a/src/com/android/contacts/util/BitmapUtil.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.util;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-
-/**
- * Provides static functions to decode bitmaps at the optimal size
- */
-public class BitmapUtil {
- private BitmapUtil() {}
-
- /**
- * Returns Width or Height of the picture, depending on which size is smaller. Doesn't actually
- * decode the picture, so it is pretty efficient to run.
- */
- public static int getSmallerExtentFromBytes(byte[] bytes) {
- final BitmapFactory.Options options = new BitmapFactory.Options();
-
- // don't actually decode the picture, just return its bounds
- options.inJustDecodeBounds = true;
- BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
-
- // test what the best sample size is
- return Math.min(options.outWidth, options.outHeight);
- }
-
- /**
- * Finds the optimal sampleSize for loading the picture
- * @param originalSmallerExtent Width or height of the picture, whichever is smaller
- * @param targetExtent Width or height of the target view, whichever is bigger.
- *
- * If either one of the parameters is 0 or smaller, no sampling is applied
- */
- public static int findOptimalSampleSize(int originalSmallerExtent, int targetExtent) {
- // If we don't know sizes, we can't do sampling.
- if (targetExtent < 1) return 1;
- if (originalSmallerExtent < 1) return 1;
-
- // Test what the best sample size is. To do that, we find the sample size that gives us
- // the best trade-off between resulting image size and memory requirement. We allow
- // the down-sampled image to be 20% smaller than the target size. That way we can get around
- // unfortunate cases where e.g. a 720 picture is requested for 362 and not down-sampled at
- // all. Why 20%? Why not. Prove me wrong.
- int extent = originalSmallerExtent;
- int sampleSize = 1;
- while ((extent >> 1) >= targetExtent * 0.8f) {
- sampleSize <<= 1;
- extent >>= 1;
- }
-
- return sampleSize;
- }
-
- /**
- * Decodes the bitmap with the given sample size
- */
- public static Bitmap decodeBitmapFromBytes(byte[] bytes, int sampleSize) {
- final BitmapFactory.Options options;
- if (sampleSize <= 1) {
- options = null;
- } else {
- options = new BitmapFactory.Options();
- options.inSampleSize = sampleSize;
- }
- return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
- }
-}
diff --git a/src/com/android/contacts/util/ClipboardUtils.java b/src/com/android/contacts/util/ClipboardUtils.java
deleted file mode 100644
index 1d0a3c1..0000000
--- a/src/com/android/contacts/util/ClipboardUtils.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.contacts.util;
-
-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";
-
- private ClipboardUtils() { }
-
- /**
- * Copy a text to clipboard.
- *
- * @param context Context
- * @param label Label to show to the user describing this clip.
- * @param text Text to copy.
- * @param showToast If {@code true}, a toast is shown to the user.
- */
- public static void copyText(Context context, CharSequence label, CharSequence text,
- boolean showToast) {
- if (TextUtils.isEmpty(text)) return;
-
- ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(
- Context.CLIPBOARD_SERVICE);
- ClipData clipData = ClipData.newPlainText(label == null ? "" : label, text);
- clipboardManager.setPrimaryClip(clipData);
-
- if (showToast) {
- String toastText = context.getString(R.string.toast_text_copied);
- Toast.makeText(context, toastText, Toast.LENGTH_SHORT).show();
- }
- }
-}
diff --git a/src/com/android/contacts/util/Constants.java b/src/com/android/contacts/util/Constants.java
index eb68f5a..17e9c0c 100644
--- a/src/com/android/contacts/util/Constants.java
+++ b/src/com/android/contacts/util/Constants.java
@@ -19,12 +19,6 @@
public class Constants {
public static final String MIME_TYPE_VIDEO_CHAT = "vnd.android.cursor.item/video-chat-address";
- public static final String SCHEME_TEL = "tel";
- public static final String SCHEME_SMSTO = "smsto";
- public static final String SCHEME_MAILTO = "mailto";
- public static final String SCHEME_IMTO = "imto";
- public static final String SCHEME_SIP = "sip";
-
/**
* Log tag for performance measurement.
* To enable: adb shell setprop log.tag.ContactsPerf VERBOSE
diff --git a/src/com/android/contacts/util/ContactBadgeUtil.java b/src/com/android/contacts/util/ContactBadgeUtil.java
index 5c2cc65..fa1a60c 100644
--- a/src/com/android/contacts/util/ContactBadgeUtil.java
+++ b/src/com/android/contacts/util/ContactBadgeUtil.java
@@ -26,7 +26,7 @@
import android.text.format.DateUtils;
import android.util.Log;
-import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.R;
/**
diff --git a/src/com/android/contacts/util/EmptyLoader.java b/src/com/android/contacts/util/EmptyLoader.java
deleted file mode 100644
index 97478bd..0000000
--- a/src/com/android/contacts/util/EmptyLoader.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.contacts.util;
-
-import android.app.LoaderManager.LoaderCallbacks;
-import android.content.Context;
-import android.content.Loader;
-import android.os.Bundle;
-
-/**
- * A {@link Loader} only used to make use of the {@link android.app.Fragment#setStartDeferred}
- * feature from an old-style fragment which doesn't use {@link Loader}s to load data.
- *
- * This loader never delivers results. A caller fragment must destroy it when deferred fragments
- * should be started.
- */
-public class EmptyLoader extends Loader<Object> {
- public EmptyLoader(Context context) {
- super(context);
- }
-
- /**
- * {@link LoaderCallbacks} which just generates {@link EmptyLoader}. {@link #onLoadFinished}
- * and {@link #onLoaderReset} are no-op.
- */
- public static class Callback implements LoaderCallbacks<Object> {
- private final Context mContext;
-
- public Callback(Context context) {
- mContext = context.getApplicationContext();
- }
-
- @Override
- public Loader<Object> onCreateLoader(int id, Bundle args) {
- return new EmptyLoader(mContext);
- }
-
- @Override
- public void onLoadFinished(Loader<Object> loader, Object data) {
- }
-
- @Override
- public void onLoaderReset(Loader<Object> loader) {
- }
- }
-}
diff --git a/src/com/android/contacts/util/ExpirableCache.java b/src/com/android/contacts/util/ExpirableCache.java
deleted file mode 100644
index 3f19a26..0000000
--- a/src/com/android/contacts/util/ExpirableCache.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.util;
-
-import android.util.LruCache;
-
-import com.android.contacts.test.NeededForTesting;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.annotation.concurrent.Immutable;
-import javax.annotation.concurrent.ThreadSafe;
-
-/**
- * An LRU cache in which all items can be marked as expired at a given time and it is possible to
- * query whether a particular cached value is expired or not.
- * <p>
- * A typical use case for this is caching of values which are expensive to compute but which are
- * still useful when out of date.
- * <p>
- * Consider a cache for contact information:
- * <pre>{@code
- * private ExpirableCache<String, Contact> mContactCache;}</pre>
- * which stores the contact information for a given phone number.
- * <p>
- * When we need to store contact information for a given phone number, we can look up the info in
- * the cache:
- * <pre>{@code
- * CachedValue<Contact> cachedContact = mContactCache.getCachedValue(phoneNumber);
- * }</pre>
- * We might also want to fetch the contact information again if the item is expired.
- * <pre>
- * if (cachedContact.isExpired()) {
- * fetchContactForNumber(phoneNumber,
- * new FetchListener() {
- * @Override
- * public void onFetched(Contact contact) {
- * mContactCache.put(phoneNumber, contact);
- * }
- * });
- * }</pre>
- * and insert it back into the cache when the fetch completes.
- * <p>
- * At a certain point we want to expire the content of the cache because we know the content may
- * no longer be up-to-date, for instance, when resuming the activity this is shown into:
- * <pre>
- * @Override
- * protected onResume() {
- * // We were paused for some time, the cached value might no longer be up to date.
- * mContactCache.expireAll();
- * super.onResume();
- * }
- * </pre>
- * The values will be still available from the cache, but they will be expired.
- * <p>
- * If interested only in the value itself, not whether it is expired or not, one should use the
- * {@link #getPossiblyExpired(Object)} method. If interested only in non-expired values, one should
- * use the {@link #get(Object)} method instead.
- * <p>
- * This class wraps around an {@link LruCache} instance: it follows the {@link LruCache} behavior
- * for evicting items when the cache is full. It is possible to supply your own subclass of LruCache
- * by using the {@link #create(LruCache)} method, which can define a custom expiration policy.
- * Since the underlying cache maps keys to cached values it can determine which items are expired
- * and which are not, allowing for an implementation that evicts expired items before non expired
- * ones.
- * <p>
- * This class is thread-safe.
- *
- * @param <K> the type of the keys
- * @param <V> the type of the values
- */
-@ThreadSafe
-public class ExpirableCache<K, V> {
- /**
- * A cached value stored inside the cache.
- * <p>
- * It provides access to the value stored in the cache but also allows to check whether the
- * value is expired.
- *
- * @param <V> the type of value stored in the cache
- */
- public interface CachedValue<V> {
- /** Returns the value stored in the cache for a given key. */
- public V getValue();
-
- /**
- * Checks whether the value, while still being present in the cache, is expired.
- *
- * @return true if the value is expired
- */
- public boolean isExpired();
- }
-
- /**
- * Cached values storing the generation at which they were added.
- */
- @Immutable
- private static class GenerationalCachedValue<V> implements ExpirableCache.CachedValue<V> {
- /** The value stored in the cache. */
- public final V mValue;
- /** The generation at which the value was added to the cache. */
- private final int mGeneration;
- /** The atomic integer storing the current generation of the cache it belongs to. */
- private final AtomicInteger mCacheGeneration;
-
- /**
- * @param cacheGeneration the atomic integer storing the generation of the cache in which
- * this value will be stored
- */
- public GenerationalCachedValue(V value, AtomicInteger cacheGeneration) {
- mValue = value;
- mCacheGeneration = cacheGeneration;
- // Snapshot the current generation.
- mGeneration = mCacheGeneration.get();
- }
-
- @Override
- public V getValue() {
- return mValue;
- }
-
- @Override
- public boolean isExpired() {
- return mGeneration != mCacheGeneration.get();
- }
- }
-
- /** The underlying cache used to stored the cached values. */
- private LruCache<K, CachedValue<V>> mCache;
-
- /**
- * The current generation of items added to the cache.
- * <p>
- * Items in the cache can belong to a previous generation, but in that case they would be
- * expired.
- *
- * @see ExpirableCache.CachedValue#isExpired()
- */
- private final AtomicInteger mGeneration;
-
- private ExpirableCache(LruCache<K, CachedValue<V>> cache) {
- mCache = cache;
- mGeneration = new AtomicInteger(0);
- }
-
- /**
- * Returns the cached value for the given key, or null if no value exists.
- * <p>
- * The cached value gives access both to the value associated with the key and whether it is
- * expired or not.
- * <p>
- * If not interested in whether the value is expired, use {@link #getPossiblyExpired(Object)}
- * instead.
- * <p>
- * If only wants values that are not expired, use {@link #get(Object)} instead.
- *
- * @param key the key to look up
- */
- public CachedValue<V> getCachedValue(K key) {
- return mCache.get(key);
- }
-
- /**
- * Returns the value for the given key, or null if no value exists.
- * <p>
- * When using this method, it is not possible to determine whether the value is expired or not.
- * Use {@link #getCachedValue(Object)} to achieve that instead. However, if using
- * {@link #getCachedValue(Object)} to determine if an item is expired, one should use the item
- * within the {@link CachedValue} and not call {@link #getPossiblyExpired(Object)} to get the
- * value afterwards, since that is not guaranteed to return the same value or that the newly
- * returned value is in the same state.
- *
- * @param key the key to look up
- */
- public V getPossiblyExpired(K key) {
- CachedValue<V> cachedValue = getCachedValue(key);
- return cachedValue == null ? null : cachedValue.getValue();
- }
-
- /**
- * Returns the value for the given key only if it is not expired, or null if no value exists or
- * is expired.
- * <p>
- * This method will return null if either there is no value associated with this key or if the
- * associated value is expired.
- *
- * @param key the key to look up
- */
- @NeededForTesting
- public V get(K key) {
- CachedValue<V> cachedValue = getCachedValue(key);
- return cachedValue == null || cachedValue.isExpired() ? null : cachedValue.getValue();
- }
-
- /**
- * Puts an item in the cache.
- * <p>
- * Newly added item will not be expired until {@link #expireAll()} is next called.
- *
- * @param key the key to look up
- * @param value the value to associate with the key
- */
- public void put(K key, V value) {
- mCache.put(key, newCachedValue(value));
- }
-
- /**
- * Mark all items currently in the cache as expired.
- * <p>
- * Newly added items after this call will be marked as not expired.
- * <p>
- * Expiring the items in the cache does not imply they will be evicted.
- */
- public void expireAll() {
- mGeneration.incrementAndGet();
- }
-
- /**
- * Creates a new {@link CachedValue} instance to be stored in this cache.
- * <p>
- * Implementation of {@link LruCache#create(K)} can use this method to create a new entry.
- */
- public CachedValue<V> newCachedValue(V value) {
- return new GenerationalCachedValue<V>(value, mGeneration);
- }
-
- /**
- * Creates a new {@link ExpirableCache} that wraps the given {@link LruCache}.
- * <p>
- * The created cache takes ownership of the cache passed in as an argument.
- *
- * @param <K> the type of the keys
- * @param <V> the type of the values
- * @param cache the cache to store the value in
- * @return the newly created expirable cache
- * @throws IllegalArgumentException if the cache is not empty
- */
- public static <K, V> ExpirableCache<K, V> create(LruCache<K, CachedValue<V>> cache) {
- return new ExpirableCache<K, V>(cache);
- }
-
- /**
- * Creates a new {@link ExpirableCache} with the given maximum size.
- *
- * @param <K> the type of the keys
- * @param <V> the type of the values
- * @return the newly created expirable cache
- */
- public static <K, V> ExpirableCache<K, V> create(int maxSize) {
- return create(new LruCache<K, CachedValue<V>>(maxSize));
- }
-}
diff --git a/src/com/android/contacts/util/ImageViewDrawableSetter.java b/src/com/android/contacts/util/ImageViewDrawableSetter.java
index b231572..91ecd61 100644
--- a/src/com/android/contacts/util/ImageViewDrawableSetter.java
+++ b/src/com/android/contacts/util/ImageViewDrawableSetter.java
@@ -26,7 +26,7 @@
import android.util.Log;
import android.widget.ImageView;
-import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.model.Contact;
import java.util.Arrays;
diff --git a/src/com/android/contacts/util/MemoryUtils.java b/src/com/android/contacts/util/MemoryUtils.java
deleted file mode 100644
index f634151..0000000
--- a/src/com/android/contacts/util/MemoryUtils.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.util;
-
-import com.android.internal.util.MemInfoReader;
-
-public final class MemoryUtils {
- private MemoryUtils() {
- }
-
- private static long sTotalMemorySize = -1;
-
- public static long getTotalMemorySize() {
- if (sTotalMemorySize < 0) {
- MemInfoReader reader = new MemInfoReader();
- reader.readMemInfo();
-
- // getTotalSize() returns the "MemTotal" value from /proc/meminfo.
- // Because the linux kernel doesn't see all the RAM on the system (e.g. GPU takes some),
- // this is usually smaller than the actual RAM size.
- sTotalMemorySize = reader.getTotalSize();
- }
- return sTotalMemorySize;
- }
-}
diff --git a/src/com/android/contacts/util/PhoneCapabilityTester.java b/src/com/android/contacts/util/PhoneCapabilityTester.java
index 421341c..13259f9 100644
--- a/src/com/android/contacts/util/PhoneCapabilityTester.java
+++ b/src/com/android/contacts/util/PhoneCapabilityTester.java
@@ -24,6 +24,7 @@
import android.net.sip.SipManager;
import android.telephony.TelephonyManager;
+import com.android.contacts.common.CallUtil;
import com.android.contacts.R;
import java.util.List;
@@ -78,7 +79,7 @@
public static boolean isSmsIntentRegistered(Context context) {
// Don't cache the result as the user might install third party apps to send SMS
final Intent intent = new Intent(Intent.ACTION_SENDTO,
- Uri.fromParts(Constants.SCHEME_SMSTO, "", null));
+ Uri.fromParts(CallUtil.SCHEME_SMSTO, "", null));
return isIntentRegistered(context, intent);
}
diff --git a/src/com/android/contacts/util/PhoneNumberFormatter.java b/src/com/android/contacts/util/PhoneNumberFormatter.java
deleted file mode 100644
index 7ae28db..0000000
--- a/src/com/android/contacts/util/PhoneNumberFormatter.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.util;
-
-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() {}
-
- /**
- * Load {@link TextWatcherLoadAsyncTask} in a worker thread and set it to a {@link TextView}.
- */
- private static class TextWatcherLoadAsyncTask extends
- AsyncTask<Void, Void, PhoneNumberFormattingTextWatcher> {
- private final String mCountryCode;
- private final TextView mTextView;
-
- public TextWatcherLoadAsyncTask(String countryCode, TextView textView) {
- mCountryCode = countryCode;
- mTextView = textView;
- }
-
- @Override
- protected PhoneNumberFormattingTextWatcher doInBackground(Void... params) {
- return new PhoneNumberFormattingTextWatcher(mCountryCode);
- }
-
- @Override
- protected void onPostExecute(PhoneNumberFormattingTextWatcher watcher) {
- if (watcher == null || isCancelled()) {
- return; // May happen if we cancel the task.
- }
- // Setting a text changed listener is safe even after the view is detached.
- mTextView.addTextChangedListener(watcher);
-
- // Note changes the user made before onPostExecute() will not be formatted, but
- // once they type the next letter we format the entire text, so it's not a big deal.
- // (And loading PhoneNumberFormattingTextWatcher is usually fast enough.)
- // We could use watcher.afterTextChanged(mTextView.getEditableText()) to force format
- // the existing content here, but that could cause unwanted results.
- // (e.g. the contact editor thinks the user changed the content, and would save
- // when closed even when the user didn't make other changes.)
- }
- }
-
- /**
- * Delay-set {@link PhoneNumberFormattingTextWatcher} to a {@link TextView}.
- */
- public static final void setPhoneNumberFormattingTextWatcher(Context context,
- TextView textView) {
- new TextWatcherLoadAsyncTask(ContactsUtils.getCurrentCountryIso(context), textView)
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
- }
-}
diff --git a/src/com/android/contacts/util/StopWatch.java b/src/com/android/contacts/util/StopWatch.java
deleted file mode 100644
index c53f346..0000000
--- a/src/com/android/contacts/util/StopWatch.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.util;
-
-import android.util.Log;
-
-import com.google.common.collect.Lists;
-
-import java.util.ArrayList;
-
-/**
- * A {@link StopWatch} records start, laps and stop, and print them to logcat.
- */
-public class StopWatch {
-
- private final String mLabel;
-
- private final ArrayList<Long> mTimes = Lists.newArrayList();
- private final ArrayList<String> mLapLabels = Lists.newArrayList();
-
- private StopWatch(String label) {
- mLabel = label;
- lap("");
- }
-
- /**
- * Create a new instance and start it.
- */
- public static StopWatch start(String label) {
- return new StopWatch(label);
- }
-
- /**
- * Record a lap.
- */
- public void lap(String lapLabel) {
- mTimes.add(System.currentTimeMillis());
- mLapLabels.add(lapLabel);
- }
-
- /**
- * Stop it and log the result, if the total time >= {@code timeThresholdToLog}.
- */
- public void stopAndLog(String TAG, int timeThresholdToLog) {
-
- lap("");
-
- final long start = mTimes.get(0);
- final long stop = mTimes.get(mTimes.size() - 1);
-
- final long total = stop - start;
- if (total < timeThresholdToLog) return;
-
- final StringBuilder sb = new StringBuilder();
- sb.append(mLabel);
- sb.append(",");
- sb.append(total);
- sb.append(": ");
-
- long last = start;
- for (int i = 1; i < mTimes.size(); i++) {
- final long current = mTimes.get(i);
- sb.append(mLapLabels.get(i));
- sb.append(",");
- sb.append((current - last));
- sb.append(" ");
- last = current;
- }
- Log.v(TAG, sb.toString());
- }
-
- /**
- * Return a dummy instance that does no operations.
- */
- public static StopWatch getNullStopWatch() {
- return NullStopWatch.INSTANCE;
- }
-
- private static class NullStopWatch extends StopWatch {
- public static final NullStopWatch INSTANCE = new NullStopWatch();
-
- public NullStopWatch() {
- super(null);
- }
-
- @Override
- public void lap(String lapLabel) {
- // noop
- }
-
- @Override
- public void stopAndLog(String TAG, int timeThresholdToLog) {
- // noop
- }
- }
-}
diff --git a/src/com/android/contacts/util/UriUtils.java b/src/com/android/contacts/util/UriUtils.java
deleted file mode 100644
index c70d923..0000000
--- a/src/com/android/contacts/util/UriUtils.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.util;
-
-import android.net.Uri;
-
-/**
- * Utility methods for dealing with URIs.
- */
-public class UriUtils {
- /** Static helper, not instantiable. */
- private UriUtils() {}
-
- /** Checks whether two URI are equal, taking care of the case where either is null. */
- public static boolean areEqual(Uri uri1, Uri uri2) {
- if (uri1 == null && uri2 == null) {
- return true;
- }
- if (uri1 == null || uri2 == null) {
- return false;
- }
- return uri1.equals(uri2);
- }
-
- /** Parses a string into a URI and returns null if the given string is null. */
- public static Uri parseUriOrNull(String uriString) {
- if (uriString == null) {
- return null;
- }
- return Uri.parse(uriString);
- }
-
- /** Converts a URI into a string, returns null if the given URI is null. */
- public static String uriToString(Uri uri) {
- return uri == null ? null : uri.toString();
- }
-}
diff --git a/src/com/android/contacts/vcard/ThreadStarter.java b/src/com/android/contacts/vcard/ThreadStarter.java
deleted file mode 100644
index d7adad6..0000000
--- a/src/com/android/contacts/vcard/ThreadStarter.java
+++ /dev/null
@@ -1,20 +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.vcard;
-
-public interface ThreadStarter {
- public void start();
-}
\ No newline at end of file
diff --git a/src/com/android/contacts/voicemail/VoicemailPlaybackFragment.java b/src/com/android/contacts/voicemail/VoicemailPlaybackFragment.java
deleted file mode 100644
index 5973387..0000000
--- a/src/com/android/contacts/voicemail/VoicemailPlaybackFragment.java
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.voicemail;
-
-import static com.android.contacts.CallDetailActivity.EXTRA_VOICEMAIL_START_PLAYBACK;
-import static com.android.contacts.CallDetailActivity.EXTRA_VOICEMAIL_URI;
-
-import android.app.Activity;
-import android.app.Fragment;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.media.AudioManager;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.PowerManager;
-import android.provider.VoicemailContract;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageButton;
-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;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.NotThreadSafe;
-
-/**
- * Displays and plays back a single voicemail.
- * <p>
- * When the Activity containing this Fragment is created, voicemail playback
- * will begin immediately. The Activity is expected to be started via an intent
- * containing a suitable voicemail uri to playback.
- * <p>
- * This class is not thread-safe, it is thread-confined. All calls to all public
- * methods on this class are expected to come from the main ui thread.
- */
-@NotThreadSafe
-public class VoicemailPlaybackFragment extends Fragment {
- private static final String TAG = "VoicemailPlayback";
- private static final int NUMBER_OF_THREADS_IN_POOL = 2;
- private static final String[] HAS_CONTENT_PROJECTION = new String[] {
- VoicemailContract.Voicemails.HAS_CONTENT,
- };
-
- private VoicemailPlaybackPresenter mPresenter;
- private ScheduledExecutorService mScheduledExecutorService;
- private View mPlaybackLayout;
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- mPlaybackLayout = inflater.inflate(R.layout.playback_layout, null);
- return mPlaybackLayout;
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- mScheduledExecutorService = createScheduledExecutorService();
- Bundle arguments = getArguments();
- Preconditions.checkNotNull(arguments, "fragment must be started with arguments");
- Uri voicemailUri = arguments.getParcelable(EXTRA_VOICEMAIL_URI);
- Preconditions.checkNotNull(voicemailUri, "fragment must contain EXTRA_VOICEMAIL_URI");
- boolean startPlayback = arguments.getBoolean(EXTRA_VOICEMAIL_START_PLAYBACK, false);
- PowerManager powerManager =
- (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE);
- PowerManager.WakeLock wakeLock =
- powerManager.newWakeLock(
- PowerManager.SCREEN_DIM_WAKE_LOCK, getClass().getSimpleName());
- mPresenter = new VoicemailPlaybackPresenter(createPlaybackViewImpl(),
- createMediaPlayer(mScheduledExecutorService), voicemailUri,
- mScheduledExecutorService, startPlayback,
- AsyncTaskExecutors.createAsyncTaskExecutor(), wakeLock);
- mPresenter.onCreate(savedInstanceState);
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- mPresenter.onSaveInstanceState(outState);
- super.onSaveInstanceState(outState);
- }
-
- @Override
- public void onDestroy() {
- mPresenter.onDestroy();
- mScheduledExecutorService.shutdown();
- super.onDestroy();
- }
-
- @Override
- public void onPause() {
- mPresenter.onPause();
- super.onPause();
- }
-
- private PlaybackViewImpl createPlaybackViewImpl() {
- return new PlaybackViewImpl(new ActivityReference(), getActivity().getApplicationContext(),
- mPlaybackLayout);
- }
-
- private MediaPlayerProxy createMediaPlayer(ExecutorService executorService) {
- return VariableSpeed.createVariableSpeed(executorService);
- }
-
- private ScheduledExecutorService createScheduledExecutorService() {
- return Executors.newScheduledThreadPool(NUMBER_OF_THREADS_IN_POOL);
- }
-
- /**
- * Formats a number of milliseconds as something that looks like {@code 00:05}.
- * <p>
- * We always use four digits, two for minutes two for seconds. In the very unlikely event
- * that the voicemail duration exceeds 99 minutes, the display is capped at 99 minutes.
- */
- private static String formatAsMinutesAndSeconds(int millis) {
- int seconds = millis / 1000;
- int minutes = seconds / 60;
- seconds -= minutes * 60;
- if (minutes > 99) {
- minutes = 99;
- }
- return String.format("%02d:%02d", minutes, seconds);
- }
-
- /**
- * An object that can provide us with an Activity.
- * <p>
- * Fragments suffer the drawback that the Activity they belong to may sometimes be null. This
- * can happen if the Fragment is detached, for example. In that situation a call to
- * {@link Fragment#getString(int)} will throw and {@link IllegalStateException}. Also, calling
- * {@link Fragment#getActivity()} is dangerous - it may sometimes return null. And thus blindly
- * calling a method on the result of getActivity() is dangerous too.
- * <p>
- * To work around this, I have made the {@link PlaybackViewImpl} class static, so that it does
- * not have access to any Fragment methods directly. Instead it uses an application Context for
- * things like accessing strings, accessing system services. It only uses the Activity when it
- * absolutely needs it - and does so through this class. This makes it easy to see where we have
- * to check for null properly.
- */
- private final class ActivityReference {
- /** Gets this Fragment's Activity: <b>may be null</b>. */
- public final Activity get() {
- return getActivity();
- }
- }
-
- /** Methods required by the PlaybackView for the VoicemailPlaybackPresenter. */
- private static final class PlaybackViewImpl implements VoicemailPlaybackPresenter.PlaybackView {
- private final ActivityReference mActivityReference;
- private final Context mApplicationContext;
- private final SeekBar mPlaybackSeek;
- private final ImageButton mStartStopButton;
- private final ImageButton mPlaybackSpeakerphone;
- private final ImageButton mRateDecreaseButton;
- private final ImageButton mRateIncreaseButton;
- private final TextViewWithMessagesController mTextController;
-
- public PlaybackViewImpl(ActivityReference activityReference, Context applicationContext,
- View playbackLayout) {
- Preconditions.checkNotNull(activityReference);
- Preconditions.checkNotNull(applicationContext);
- Preconditions.checkNotNull(playbackLayout);
- mActivityReference = activityReference;
- mApplicationContext = applicationContext;
- mPlaybackSeek = (SeekBar) playbackLayout.findViewById(R.id.playback_seek);
- mStartStopButton = (ImageButton) playbackLayout.findViewById(
- R.id.playback_start_stop);
- mPlaybackSpeakerphone = (ImageButton) playbackLayout.findViewById(
- R.id.playback_speakerphone);
- mRateDecreaseButton = (ImageButton) playbackLayout.findViewById(
- R.id.rate_decrease_button);
- mRateIncreaseButton = (ImageButton) playbackLayout.findViewById(
- R.id.rate_increase_button);
- mTextController = new TextViewWithMessagesController(
- (TextView) playbackLayout.findViewById(R.id.playback_position_text),
- (TextView) playbackLayout.findViewById(R.id.playback_speed_text));
- }
-
- @Override
- public void finish() {
- Activity activity = mActivityReference.get();
- if (activity != null) {
- activity.finish();
- }
- }
-
- @Override
- public void runOnUiThread(Runnable runnable) {
- Activity activity = mActivityReference.get();
- if (activity != null) {
- activity.runOnUiThread(runnable);
- }
- }
-
- @Override
- public Context getDataSourceContext() {
- return mApplicationContext;
- }
-
- @Override
- public void setRateDecreaseButtonListener(View.OnClickListener listener) {
- mRateDecreaseButton.setOnClickListener(listener);
- }
-
- @Override
- public void setRateIncreaseButtonListener(View.OnClickListener listener) {
- mRateIncreaseButton.setOnClickListener(listener);
- }
-
- @Override
- public void setStartStopListener(View.OnClickListener listener) {
- mStartStopButton.setOnClickListener(listener);
- }
-
- @Override
- public void setSpeakerphoneListener(View.OnClickListener listener) {
- mPlaybackSpeakerphone.setOnClickListener(listener);
- }
-
- @Override
- public void setRateDisplay(float rate, int stringResourceId) {
- mTextController.setTemporaryText(
- mApplicationContext.getString(stringResourceId), 1, TimeUnit.SECONDS);
- }
-
- @Override
- public void setPositionSeekListener(SeekBar.OnSeekBarChangeListener listener) {
- mPlaybackSeek.setOnSeekBarChangeListener(listener);
- }
-
- @Override
- public void playbackStarted() {
- mStartStopButton.setImageResource(R.drawable.ic_hold_pause_holo_dark);
- }
-
- @Override
- public void playbackStopped() {
- mStartStopButton.setImageResource(R.drawable.ic_play);
- }
-
- @Override
- public void enableProximitySensor() {
- // Only change the state if the activity is still around.
- Activity activity = mActivityReference.get();
- if (activity != null && activity instanceof ProximitySensorAware) {
- ((ProximitySensorAware) activity).enableProximitySensor();
- }
- }
-
- @Override
- public void disableProximitySensor() {
- // Only change the state if the activity is still around.
- Activity activity = mActivityReference.get();
- if (activity != null && activity instanceof ProximitySensorAware) {
- ((ProximitySensorAware) activity).disableProximitySensor(true);
- }
- }
-
- @Override
- public void registerContentObserver(Uri uri, ContentObserver observer) {
- mApplicationContext.getContentResolver().registerContentObserver(uri, false, observer);
- }
-
- @Override
- public void unregisterContentObserver(ContentObserver observer) {
- mApplicationContext.getContentResolver().unregisterContentObserver(observer);
- }
-
- @Override
- public void setClipPosition(int clipPositionInMillis, int clipLengthInMillis) {
- int seekBarPosition = Math.max(0, clipPositionInMillis);
- int seekBarMax = Math.max(seekBarPosition, clipLengthInMillis);
- if (mPlaybackSeek.getMax() != seekBarMax) {
- mPlaybackSeek.setMax(seekBarMax);
- }
- mPlaybackSeek.setProgress(seekBarPosition);
- mTextController.setPermanentText(
- formatAsMinutesAndSeconds(seekBarMax - seekBarPosition));
- }
-
- private String getString(int resId) {
- return mApplicationContext.getString(resId);
- }
-
- @Override
- public void setIsBuffering() {
- disableUiElements();
- mTextController.setPermanentText(getString(R.string.voicemail_buffering));
- }
-
- @Override
- public void setIsFetchingContent() {
- disableUiElements();
- mTextController.setPermanentText(getString(R.string.voicemail_fetching_content));
- }
-
- @Override
- public void setFetchContentTimeout() {
- disableUiElements();
- mTextController.setPermanentText(getString(R.string.voicemail_fetching_timout));
- }
-
- @Override
- public int getDesiredClipPosition() {
- return mPlaybackSeek.getProgress();
- }
-
- @Override
- public void disableUiElements() {
- mRateIncreaseButton.setEnabled(false);
- mRateDecreaseButton.setEnabled(false);
- mStartStopButton.setEnabled(false);
- mPlaybackSpeakerphone.setEnabled(false);
- mPlaybackSeek.setProgress(0);
- mPlaybackSeek.setEnabled(false);
- }
-
- @Override
- public void playbackError(Exception e) {
- disableUiElements();
- mTextController.setPermanentText(getString(R.string.voicemail_playback_error));
- Log.e(TAG, "Could not play voicemail", e);
- }
-
- @Override
- public void enableUiElements() {
- mRateIncreaseButton.setEnabled(true);
- mRateDecreaseButton.setEnabled(true);
- mStartStopButton.setEnabled(true);
- mPlaybackSpeakerphone.setEnabled(true);
- mPlaybackSeek.setEnabled(true);
- }
-
- @Override
- public void sendFetchVoicemailRequest(Uri voicemailUri) {
- Intent intent = new Intent(VoicemailContract.ACTION_FETCH_VOICEMAIL, voicemailUri);
- mApplicationContext.sendBroadcast(intent);
- }
-
- @Override
- public boolean queryHasContent(Uri voicemailUri) {
- ContentResolver contentResolver = mApplicationContext.getContentResolver();
- Cursor cursor = contentResolver.query(
- voicemailUri, HAS_CONTENT_PROJECTION, null, null, null);
- try {
- if (cursor != null && cursor.moveToNext()) {
- return cursor.getInt(cursor.getColumnIndexOrThrow(
- VoicemailContract.Voicemails.HAS_CONTENT)) == 1;
- }
- } finally {
- MoreCloseables.closeQuietly(cursor);
- }
- return false;
- }
-
- private AudioManager getAudioManager() {
- return (AudioManager) mApplicationContext.getSystemService(Context.AUDIO_SERVICE);
- }
-
- @Override
- public boolean isSpeakerPhoneOn() {
- return getAudioManager().isSpeakerphoneOn();
- }
-
- @Override
- public void setSpeakerPhoneOn(boolean on) {
- getAudioManager().setSpeakerphoneOn(on);
- if (on) {
- mPlaybackSpeakerphone.setImageResource(R.drawable.ic_speakerphone_on);
- } else {
- mPlaybackSpeakerphone.setImageResource(R.drawable.ic_speakerphone_off);
- }
- }
-
- @Override
- public void setVolumeControlStream(int streamType) {
- Activity activity = mActivityReference.get();
- if (activity != null) {
- activity.setVolumeControlStream(streamType);
- }
- }
- }
-
- /**
- * Controls a TextView with dynamically changing text.
- * <p>
- * There are two methods here of interest,
- * {@link TextViewWithMessagesController#setPermanentText(String)} and
- * {@link TextViewWithMessagesController#setTemporaryText(String, long, TimeUnit)}. The
- * former is used to set the text on the text view immediately, and is used in our case for
- * the countdown of duration remaining during voicemail playback. The second is used to
- * temporarily replace this countdown with a message, in our case faster voicemail speed or
- * slower voicemail speed, before returning to the countdown display.
- * <p>
- * All the methods on this class must be called from the ui thread.
- */
- private static final class TextViewWithMessagesController {
- private static final float VISIBLE = 1;
- private static final float INVISIBLE = 0;
- private static final long SHORT_ANIMATION_MS = 200;
- private static final long LONG_ANIMATION_MS = 400;
- private final Object mLock = new Object();
- private final TextView mPermanentTextView;
- private final TextView mTemporaryTextView;
- @GuardedBy("mLock") private Runnable mRunnable;
-
- public TextViewWithMessagesController(TextView permanentTextView,
- TextView temporaryTextView) {
- mPermanentTextView = permanentTextView;
- mTemporaryTextView = temporaryTextView;
- }
-
- public void setPermanentText(String text) {
- mPermanentTextView.setText(text);
- }
-
- public void setTemporaryText(String text, long duration, TimeUnit units) {
- synchronized (mLock) {
- mTemporaryTextView.setText(text);
- mTemporaryTextView.animate().alpha(VISIBLE).setDuration(SHORT_ANIMATION_MS);
- mPermanentTextView.animate().alpha(INVISIBLE).setDuration(SHORT_ANIMATION_MS);
- mRunnable = new Runnable() {
- @Override
- public void run() {
- synchronized (mLock) {
- // We check for (mRunnable == this) becuase if not true, then another
- // setTemporaryText call has taken place in the meantime, and this
- // one is now defunct and needs to take no action.
- if (mRunnable == this) {
- mRunnable = null;
- mTemporaryTextView.animate()
- .alpha(INVISIBLE).setDuration(LONG_ANIMATION_MS);
- mPermanentTextView.animate()
- .alpha(VISIBLE).setDuration(LONG_ANIMATION_MS);
- }
- }
- }
- };
- mTemporaryTextView.postDelayed(mRunnable, units.toMillis(duration));
- }
- }
- }
-}
diff --git a/src/com/android/contacts/voicemail/VoicemailPlaybackPresenter.java b/src/com/android/contacts/voicemail/VoicemailPlaybackPresenter.java
deleted file mode 100644
index 2c7ba52..0000000
--- a/src/com/android/contacts/voicemail/VoicemailPlaybackPresenter.java
+++ /dev/null
@@ -1,630 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.voicemail;
-
-import static android.util.MathUtils.constrain;
-
-import android.content.Context;
-import android.database.ContentObserver;
-import android.media.AudioManager;
-import android.media.MediaPlayer;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.PowerManager;
-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;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.NotThreadSafe;
-import javax.annotation.concurrent.ThreadSafe;
-
-/**
- * Contains the controlling logic for a voicemail playback ui.
- * <p>
- * Specifically right now this class is used to control the
- * {@link com.android.contacts.voicemail.VoicemailPlaybackFragment}.
- * <p>
- * This class is not thread safe. The thread policy for this class is
- * thread-confinement, all calls into this class from outside must be done from
- * the main ui thread.
- */
-@NotThreadSafe
-@VisibleForTesting
-public class VoicemailPlaybackPresenter {
- /** The stream used to playback voicemail. */
- private static final int PLAYBACK_STREAM = AudioManager.STREAM_VOICE_CALL;
-
- /** Contract describing the behaviour we need from the ui we are controlling. */
- public interface PlaybackView {
- Context getDataSourceContext();
- void runOnUiThread(Runnable runnable);
- void setStartStopListener(View.OnClickListener listener);
- void setPositionSeekListener(SeekBar.OnSeekBarChangeListener listener);
- void setSpeakerphoneListener(View.OnClickListener listener);
- void setIsBuffering();
- void setClipPosition(int clipPositionInMillis, int clipLengthInMillis);
- int getDesiredClipPosition();
- void playbackStarted();
- void playbackStopped();
- void playbackError(Exception e);
- boolean isSpeakerPhoneOn();
- void setSpeakerPhoneOn(boolean on);
- void finish();
- void setRateDisplay(float rate, int stringResourceId);
- void setRateIncreaseButtonListener(View.OnClickListener listener);
- void setRateDecreaseButtonListener(View.OnClickListener listener);
- void setIsFetchingContent();
- void disableUiElements();
- void enableUiElements();
- void sendFetchVoicemailRequest(Uri voicemailUri);
- boolean queryHasContent(Uri voicemailUri);
- void setFetchContentTimeout();
- void registerContentObserver(Uri uri, ContentObserver observer);
- void unregisterContentObserver(ContentObserver observer);
- void enableProximitySensor();
- void disableProximitySensor();
- void setVolumeControlStream(int streamType);
- }
-
- /** The enumeration of {@link AsyncTask} objects we use in this class. */
- public enum Tasks {
- CHECK_FOR_CONTENT,
- CHECK_CONTENT_AFTER_CHANGE,
- PREPARE_MEDIA_PLAYER,
- RESET_PREPARE_START_MEDIA_PLAYER,
- }
-
- /** Update rate for the slider, 30fps. */
- private static final int SLIDER_UPDATE_PERIOD_MILLIS = 1000 / 30;
- /** Time our ui will wait for content to be fetched before reporting not available. */
- private static final long FETCH_CONTENT_TIMEOUT_MS = 20000;
- /**
- * If present in the saved instance bundle, we should not resume playback on
- * create.
- */
- private static final String PAUSED_STATE_KEY = VoicemailPlaybackPresenter.class.getName()
- + ".PAUSED_STATE_KEY";
- /**
- * If present in the saved instance bundle, indicates where to set the
- * playback slider.
- */
- private static final String CLIP_POSITION_KEY = VoicemailPlaybackPresenter.class.getName()
- + ".CLIP_POSITION_KEY";
-
- /** The preset variable-speed rates. Each is greater than the previous by 25%. */
- private static final float[] PRESET_RATES = new float[] {
- 0.64f, 0.8f, 1.0f, 1.25f, 1.5625f
- };
- /** The string resource ids corresponding to the names given to the above preset rates. */
- private static final int[] PRESET_NAMES = new int[] {
- R.string.voicemail_speed_slowest,
- R.string.voicemail_speed_slower,
- R.string.voicemail_speed_normal,
- R.string.voicemail_speed_faster,
- R.string.voicemail_speed_fastest,
- };
-
- /**
- * Pointer into the {@link VoicemailPlaybackPresenter#PRESET_RATES} array.
- * <p>
- * This doesn't need to be synchronized, it's used only by the {@link RateChangeListener}
- * which in turn is only executed on the ui thread. This can't be encapsulated inside the
- * rate change listener since multiple rate change listeners must share the same value.
- */
- private int mRateIndex = 2;
-
- /**
- * The most recently calculated duration.
- * <p>
- * We cache this in a field since we don't want to keep requesting it from the player, as
- * this can easily lead to throwing {@link IllegalStateException} (any time the player is
- * released, it's illegal to ask for the duration).
- */
- private final AtomicInteger mDuration = new AtomicInteger(0);
-
- private final PlaybackView mView;
- private final MediaPlayerProxy mPlayer;
- private final PositionUpdater mPositionUpdater;
-
- /** Voicemail uri to play. */
- private final Uri mVoicemailUri;
- /** Start playing in onCreate iff this is true. */
- private final boolean mStartPlayingImmediately;
- /** Used to run async tasks that need to interact with the ui. */
- private final AsyncTaskExecutor mAsyncTaskExecutor;
-
- /**
- * Used to handle the result of a successful or time-out fetch result.
- * <p>
- * This variable is thread-contained, accessed only on the ui thread.
- */
- private FetchResultHandler mFetchResultHandler;
- private PowerManager.WakeLock mWakeLock;
- private AsyncTask<Void, ?, ?> mPrepareTask;
-
- public VoicemailPlaybackPresenter(PlaybackView view, MediaPlayerProxy player,
- Uri voicemailUri, ScheduledExecutorService executorService,
- boolean startPlayingImmediately, AsyncTaskExecutor asyncTaskExecutor,
- PowerManager.WakeLock wakeLock) {
- mView = view;
- mPlayer = player;
- mVoicemailUri = voicemailUri;
- mStartPlayingImmediately = startPlayingImmediately;
- mAsyncTaskExecutor = asyncTaskExecutor;
- mPositionUpdater = new PositionUpdater(executorService, SLIDER_UPDATE_PERIOD_MILLIS);
- mWakeLock = wakeLock;
- }
-
- public void onCreate(Bundle bundle) {
- mView.setVolumeControlStream(PLAYBACK_STREAM);
- checkThatWeHaveContent();
- }
-
- /**
- * Checks to see if we have content available for this voicemail.
- * <p>
- * This method will be called once, after the fragment has been created, before we know if the
- * voicemail we've been asked to play has any content available.
- * <p>
- * This method will notify the user through the ui that we are fetching the content, then check
- * to see if the content field in the db is set. If set, we proceed to
- * {@link #postSuccessfullyFetchedContent()} method. If not set, we will make a request to fetch
- * the content asynchronously via {@link #makeRequestForContent()}.
- */
- private void checkThatWeHaveContent() {
- mView.setIsFetchingContent();
- mAsyncTaskExecutor.submit(Tasks.CHECK_FOR_CONTENT, new AsyncTask<Void, Void, Boolean>() {
- @Override
- public Boolean doInBackground(Void... params) {
- return mView.queryHasContent(mVoicemailUri);
- }
-
- @Override
- public void onPostExecute(Boolean hasContent) {
- if (hasContent) {
- postSuccessfullyFetchedContent();
- } else {
- makeRequestForContent();
- }
- }
- });
- }
-
- /**
- * Makes a broadcast request to ask that a voicemail source fetch this content.
- * <p>
- * This method <b>must be called on the ui thread</b>.
- * <p>
- * This method will be called when we realise that we don't have content for this voicemail. It
- * will trigger a broadcast to request that the content be downloaded. It will add a listener to
- * the content resolver so that it will be notified when the has_content field changes. It will
- * also set a timer. If the has_content field changes to true within the allowed time, we will
- * proceed to {@link #postSuccessfullyFetchedContent()}. If the has_content field does not
- * become true within the allowed time, we will update the ui to reflect the fact that content
- * was not available.
- */
- private void makeRequestForContent() {
- Handler handler = new Handler();
- Preconditions.checkState(mFetchResultHandler == null, "mFetchResultHandler should be null");
- mFetchResultHandler = new FetchResultHandler(handler);
- mView.registerContentObserver(mVoicemailUri, mFetchResultHandler);
- handler.postDelayed(mFetchResultHandler.getTimeoutRunnable(), FETCH_CONTENT_TIMEOUT_MS);
- mView.sendFetchVoicemailRequest(mVoicemailUri);
- }
-
- @ThreadSafe
- private class FetchResultHandler extends ContentObserver implements Runnable {
- private AtomicBoolean mResultStillPending = new AtomicBoolean(true);
- private final Handler mHandler;
-
- public FetchResultHandler(Handler handler) {
- super(handler);
- mHandler = handler;
- }
-
- public Runnable getTimeoutRunnable() {
- return this;
- }
-
- @Override
- public void run() {
- if (mResultStillPending.getAndSet(false)) {
- mView.unregisterContentObserver(FetchResultHandler.this);
- mView.setFetchContentTimeout();
- }
- }
-
- public void destroy() {
- if (mResultStillPending.getAndSet(false)) {
- mView.unregisterContentObserver(FetchResultHandler.this);
- mHandler.removeCallbacks(this);
- }
- }
-
- @Override
- public void onChange(boolean selfChange) {
- mAsyncTaskExecutor.submit(Tasks.CHECK_CONTENT_AFTER_CHANGE,
- new AsyncTask<Void, Void, Boolean>() {
- @Override
- public Boolean doInBackground(Void... params) {
- return mView.queryHasContent(mVoicemailUri);
- }
-
- @Override
- public void onPostExecute(Boolean hasContent) {
- if (hasContent) {
- if (mResultStillPending.getAndSet(false)) {
- mView.unregisterContentObserver(FetchResultHandler.this);
- postSuccessfullyFetchedContent();
- }
- }
- }
- });
- }
- }
-
- /**
- * Prepares the voicemail content for playback.
- * <p>
- * This method will be called once we know that our voicemail has content (according to the
- * content provider). This method will try to prepare the data source through the media player.
- * If preparing the media player works, we will call through to
- * {@link #postSuccessfulPrepareActions()}. If preparing the media player fails (perhaps the
- * file the content provider points to is actually missing, perhaps it is of an unknown file
- * format that we can't play, who knows) then we will show an error on the ui.
- */
- private void postSuccessfullyFetchedContent() {
- mView.setIsBuffering();
- mAsyncTaskExecutor.submit(Tasks.PREPARE_MEDIA_PLAYER,
- new AsyncTask<Void, Void, Exception>() {
- @Override
- public Exception doInBackground(Void... params) {
- try {
- mPlayer.reset();
- mPlayer.setDataSource(mView.getDataSourceContext(), mVoicemailUri);
- mPlayer.setAudioStreamType(PLAYBACK_STREAM);
- mPlayer.prepare();
- return null;
- } catch (Exception e) {
- return e;
- }
- }
-
- @Override
- public void onPostExecute(Exception exception) {
- if (exception == null) {
- postSuccessfulPrepareActions();
- } else {
- mView.playbackError(exception);
- }
- }
- });
- }
-
- /**
- * Enables the ui, and optionally starts playback immediately.
- * <p>
- * This will be called once we have successfully prepared the media player, and will optionally
- * playback immediately.
- */
- private void postSuccessfulPrepareActions() {
- mView.enableUiElements();
- mView.setPositionSeekListener(new PlaybackPositionListener());
- mView.setStartStopListener(new StartStopButtonListener());
- mView.setSpeakerphoneListener(new SpeakerphoneListener());
- mPlayer.setOnErrorListener(new MediaPlayerErrorListener());
- mPlayer.setOnCompletionListener(new MediaPlayerCompletionListener());
- mView.setSpeakerPhoneOn(mView.isSpeakerPhoneOn());
- mView.setRateDecreaseButtonListener(createRateDecreaseListener());
- mView.setRateIncreaseButtonListener(createRateIncreaseListener());
- mView.setClipPosition(0, mPlayer.getDuration());
- mView.playbackStopped();
- // Always disable on stop.
- mView.disableProximitySensor();
- if (mStartPlayingImmediately) {
- resetPrepareStartPlaying(0);
- }
- // TODO: Now I'm ignoring the bundle, when previously I was checking for contains against
- // the PAUSED_STATE_KEY, and CLIP_POSITION_KEY.
- }
-
- public void onSaveInstanceState(Bundle outState) {
- outState.putInt(CLIP_POSITION_KEY, mView.getDesiredClipPosition());
- if (!mPlayer.isPlaying()) {
- outState.putBoolean(PAUSED_STATE_KEY, true);
- }
- }
-
- public void onDestroy() {
- mPlayer.release();
- if (mFetchResultHandler != null) {
- mFetchResultHandler.destroy();
- mFetchResultHandler = null;
- }
- mPositionUpdater.stopUpdating();
- if (mWakeLock.isHeld()) {
- mWakeLock.release();
- }
- }
-
- private class MediaPlayerErrorListener implements MediaPlayer.OnErrorListener {
- @Override
- public boolean onError(MediaPlayer mp, int what, int extra) {
- mView.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- handleError(new IllegalStateException("MediaPlayer error listener invoked"));
- }
- });
- return true;
- }
- }
-
- private class MediaPlayerCompletionListener implements MediaPlayer.OnCompletionListener {
- @Override
- public void onCompletion(final MediaPlayer mp) {
- mView.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- handleCompletion(mp);
- }
- });
- }
- }
-
- public View.OnClickListener createRateDecreaseListener() {
- return new RateChangeListener(false);
- }
-
- public View.OnClickListener createRateIncreaseListener() {
- return new RateChangeListener(true);
- }
-
- /**
- * Listens to clicks on the rate increase and decrease buttons.
- * <p>
- * This class is not thread-safe, but all interactions with it will happen on the ui thread.
- */
- private class RateChangeListener implements View.OnClickListener {
- private final boolean mIncrease;
-
- public RateChangeListener(boolean increase) {
- mIncrease = increase;
- }
-
- @Override
- public void onClick(View v) {
- // Adjust the current rate, then clamp it to the allowed values.
- mRateIndex = constrain(mRateIndex + (mIncrease ? 1 : -1), 0, PRESET_RATES.length - 1);
- // Whether or not we have actually changed the index, call changeRate().
- // This will ensure that we show the "fastest" or "slowest" text on the ui to indicate
- // to the user that it doesn't get any faster or slower.
- changeRate(PRESET_RATES[mRateIndex], PRESET_NAMES[mRateIndex]);
- }
- }
-
- private void resetPrepareStartPlaying(final int clipPositionInMillis) {
- if (mPrepareTask != null) {
- mPrepareTask.cancel(false);
- }
- mPrepareTask = mAsyncTaskExecutor.submit(Tasks.RESET_PREPARE_START_MEDIA_PLAYER,
- new AsyncTask<Void, Void, Exception>() {
- @Override
- public Exception doInBackground(Void... params) {
- try {
- mPlayer.reset();
- mPlayer.setDataSource(mView.getDataSourceContext(), mVoicemailUri);
- mPlayer.setAudioStreamType(PLAYBACK_STREAM);
- mPlayer.prepare();
- return null;
- } catch (Exception e) {
- return e;
- }
- }
-
- @Override
- public void onPostExecute(Exception exception) {
- mPrepareTask = null;
- if (exception == null) {
- mDuration.set(mPlayer.getDuration());
- int startPosition =
- constrain(clipPositionInMillis, 0, mDuration.get());
- mView.setClipPosition(startPosition, mDuration.get());
- mPlayer.seekTo(startPosition);
- mPlayer.start();
- mView.playbackStarted();
- if (!mWakeLock.isHeld()) {
- mWakeLock.acquire();
- }
- // Only enable if we are not currently using the speaker phone.
- if (!mView.isSpeakerPhoneOn()) {
- mView.enableProximitySensor();
- }
- mPositionUpdater.startUpdating(startPosition, mDuration.get());
- } else {
- handleError(exception);
- }
- }
- });
- }
-
- private void handleError(Exception e) {
- mView.playbackError(e);
- mPositionUpdater.stopUpdating();
- mPlayer.release();
- }
-
- public void handleCompletion(MediaPlayer mediaPlayer) {
- stopPlaybackAtPosition(0, mDuration.get());
- }
-
- private void stopPlaybackAtPosition(int clipPosition, int duration) {
- mPositionUpdater.stopUpdating();
- mView.playbackStopped();
- if (mWakeLock.isHeld()) {
- mWakeLock.release();
- }
- // Always disable on stop.
- mView.disableProximitySensor();
- mView.setClipPosition(clipPosition, duration);
- if (mPlayer.isPlaying()) {
- mPlayer.pause();
- }
- }
-
- private class PlaybackPositionListener implements SeekBar.OnSeekBarChangeListener {
- private boolean mShouldResumePlaybackAfterSeeking;
-
- @Override
- public void onStartTrackingTouch(SeekBar arg0) {
- if (mPlayer.isPlaying()) {
- mShouldResumePlaybackAfterSeeking = true;
- stopPlaybackAtPosition(mPlayer.getCurrentPosition(), mDuration.get());
- } else {
- mShouldResumePlaybackAfterSeeking = false;
- }
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar arg0) {
- if (mPlayer.isPlaying()) {
- stopPlaybackAtPosition(mPlayer.getCurrentPosition(), mDuration.get());
- }
- if (mShouldResumePlaybackAfterSeeking) {
- resetPrepareStartPlaying(mView.getDesiredClipPosition());
- }
- }
-
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- mView.setClipPosition(seekBar.getProgress(), seekBar.getMax());
- }
- }
-
- private void changeRate(float rate, int stringResourceId) {
- ((SingleThreadedMediaPlayerProxy) mPlayer).setVariableSpeed(rate);
- mView.setRateDisplay(rate, stringResourceId);
- }
-
- private class SpeakerphoneListener implements View.OnClickListener {
- @Override
- public void onClick(View v) {
- boolean previousState = mView.isSpeakerPhoneOn();
- mView.setSpeakerPhoneOn(!previousState);
- if (mPlayer.isPlaying() && previousState) {
- // If we are currently playing and we are disabling the speaker phone, enable the
- // sensor.
- mView.enableProximitySensor();
- } else {
- // If we are not currently playing, disable the sensor.
- mView.disableProximitySensor();
- }
- }
- }
-
- private class StartStopButtonListener implements View.OnClickListener {
- @Override
- public void onClick(View arg0) {
- if (mPlayer.isPlaying()) {
- stopPlaybackAtPosition(mPlayer.getCurrentPosition(), mDuration.get());
- } else {
- resetPrepareStartPlaying(mView.getDesiredClipPosition());
- }
- }
- }
-
- /**
- * Controls the animation of the playback slider.
- */
- @ThreadSafe
- private final class PositionUpdater implements Runnable {
- private final ScheduledExecutorService mExecutorService;
- private final int mPeriodMillis;
- private final Object mLock = new Object();
- @GuardedBy("mLock") private ScheduledFuture<?> mScheduledFuture;
- private final Runnable mSetClipPostitionRunnable = new Runnable() {
- @Override
- public void run() {
- int currentPosition = 0;
- synchronized (mLock) {
- if (mScheduledFuture == null) {
- // This task has been canceled. Just stop now.
- return;
- }
- currentPosition = mPlayer.getCurrentPosition();
- }
- mView.setClipPosition(currentPosition, mDuration.get());
- }
- };
-
- public PositionUpdater(ScheduledExecutorService executorService, int periodMillis) {
- mExecutorService = executorService;
- mPeriodMillis = periodMillis;
- }
-
- @Override
- public void run() {
- mView.runOnUiThread(mSetClipPostitionRunnable);
- }
-
- public void startUpdating(int beginPosition, int endPosition) {
- synchronized (mLock) {
- if (mScheduledFuture != null) {
- mScheduledFuture.cancel(false);
- }
- mScheduledFuture = mExecutorService.scheduleAtFixedRate(this, 0, mPeriodMillis,
- TimeUnit.MILLISECONDS);
- }
- }
-
- public void stopUpdating() {
- synchronized (mLock) {
- if (mScheduledFuture != null) {
- mScheduledFuture.cancel(false);
- mScheduledFuture = null;
- }
- }
- }
- }
-
- public void onPause() {
- if (mPlayer.isPlaying()) {
- stopPlaybackAtPosition(mPlayer.getCurrentPosition(), mDuration.get());
- }
- if (mPrepareTask != null) {
- mPrepareTask.cancel(false);
- }
- if (mWakeLock.isHeld()) {
- mWakeLock.release();
- }
- }
-}
diff --git a/src/com/android/contacts/voicemail/VoicemailStatusHelper.java b/src/com/android/contacts/voicemail/VoicemailStatusHelper.java
deleted file mode 100644
index 6664b88..0000000
--- a/src/com/android/contacts/voicemail/VoicemailStatusHelper.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.contacts.voicemail;
-
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.VoicemailContract.Status;
-
-import java.util.List;
-
-/**
- * Interface used by the call log UI to determine what user message, if any, related to voicemail
- * source status needs to be shown. The messages are returned in the order of importance.
- * <p>
- * The implementation of this interface interacts with the voicemail content provider to fetch
- * statuses of all the registered voicemail sources and determines if any status message needs to
- * be shown. The user of this interface must observe/listen to provider changes and invoke
- * this class to check if any message needs to be shown.
- */
-public interface VoicemailStatusHelper {
- public class StatusMessage {
- /** Package of the source on behalf of which this message has to be shown.*/
- public final String sourcePackage;
- /**
- * The string resource id of the status message that should be shown in the call log
- * page. Set to -1, if this message is not to be shown in call log.
- */
- public final int callLogMessageId;
- /**
- * The string resource id of the status message that should be shown in the call details
- * page. Set to -1, if this message is not to be shown in call details page.
- */
- public final int callDetailsMessageId;
- /** The string resource id of the action message that should be shown. */
- public final int actionMessageId;
- /** URI for the corrective action, where applicable. Null if no action URI is available. */
- public final Uri actionUri;
- public StatusMessage(String sourcePackage, int callLogMessageId, int callDetailsMessageId,
- int actionMessageId, Uri actionUri) {
- this.sourcePackage = sourcePackage;
- this.callLogMessageId = callLogMessageId;
- this.callDetailsMessageId = callDetailsMessageId;
- this.actionMessageId = actionMessageId;
- this.actionUri = actionUri;
- }
-
- /** Whether this message should be shown in the call log page. */
- public boolean showInCallLog() {
- return callLogMessageId != -1;
- }
-
- /** Whether this message should be shown in the call details page. */
- public boolean showInCallDetails() {
- return callDetailsMessageId != -1;
- }
- }
-
- /**
- * Returns a list of messages, in the order or priority that should be shown to the user. An
- * empty list is returned if no message needs to be shown.
- * @param cursor The cursor pointing to the query on {@link Status#CONTENT_URI}. The projection
- * to be used is defined by the implementation class of this interface.
- */
- public List<StatusMessage> getStatusMessages(Cursor cursor);
-
- /**
- * Returns the number of active voicemail sources installed.
- * <p>
- * The number of sources is counted by querying the voicemail status table.
- */
- public int getNumberActivityVoicemailSources(Cursor cursor);
-}
diff --git a/src/com/android/contacts/voicemail/VoicemailStatusHelperImpl.java b/src/com/android/contacts/voicemail/VoicemailStatusHelperImpl.java
deleted file mode 100644
index c7f9c8f..0000000
--- a/src/com/android/contacts/voicemail/VoicemailStatusHelperImpl.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.contacts.voicemail;
-
-import static android.provider.VoicemailContract.Status.CONFIGURATION_STATE_CAN_BE_CONFIGURED;
-import static android.provider.VoicemailContract.Status.CONFIGURATION_STATE_OK;
-import static android.provider.VoicemailContract.Status.DATA_CHANNEL_STATE_NO_CONNECTION;
-import static android.provider.VoicemailContract.Status.DATA_CHANNEL_STATE_OK;
-import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING;
-import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION;
-import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_OK;
-
-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;
-import java.util.List;
-
-/** Implementation of {@link VoicemailStatusHelper}. */
-public class VoicemailStatusHelperImpl implements VoicemailStatusHelper {
- private static final int SOURCE_PACKAGE_INDEX = 0;
- private static final int CONFIGURATION_STATE_INDEX = 1;
- private static final int DATA_CHANNEL_STATE_INDEX = 2;
- private static final int NOTIFICATION_CHANNEL_STATE_INDEX = 3;
- private static final int SETTINGS_URI_INDEX = 4;
- private static final int VOICEMAIL_ACCESS_URI_INDEX = 5;
- private static final int NUM_COLUMNS = 6;
- /** Projection on the voicemail_status table used by this class. */
- public static final String[] PROJECTION = new String[NUM_COLUMNS];
- static {
- PROJECTION[SOURCE_PACKAGE_INDEX] = Status.SOURCE_PACKAGE;
- PROJECTION[CONFIGURATION_STATE_INDEX] = Status.CONFIGURATION_STATE;
- PROJECTION[DATA_CHANNEL_STATE_INDEX] = Status.DATA_CHANNEL_STATE;
- PROJECTION[NOTIFICATION_CHANNEL_STATE_INDEX] = Status.NOTIFICATION_CHANNEL_STATE;
- PROJECTION[SETTINGS_URI_INDEX] = Status.SETTINGS_URI;
- PROJECTION[VOICEMAIL_ACCESS_URI_INDEX] = Status.VOICEMAIL_ACCESS_URI;
- }
-
- /** Possible user actions. */
- public static enum Action {
- NONE(-1),
- CALL_VOICEMAIL(R.string.voicemail_status_action_call_server),
- CONFIGURE_VOICEMAIL(R.string.voicemail_status_action_configure);
-
- private final int mMessageId;
- private Action(int messageId) {
- mMessageId = messageId;
- }
-
- public int getMessageId() {
- return mMessageId;
- }
- }
-
- /**
- * Overall state of the source status. Each state is associated with the corresponding display
- * string and the corrective action. The states are also assigned a relative priority which is
- * used to order the messages from different sources.
- */
- private static enum OverallState {
- // TODO: Add separate string for call details and call log pages for the states that needs
- // to be shown in both.
- /** Both notification and data channel are not working. */
- NO_CONNECTION(0, Action.CALL_VOICEMAIL, R.string.voicemail_status_voicemail_not_available,
- R.string.voicemail_status_audio_not_available),
- /** Notifications working, but data channel is not working. Audio cannot be downloaded. */
- NO_DATA(1, Action.CALL_VOICEMAIL, R.string.voicemail_status_voicemail_not_available,
- R.string.voicemail_status_audio_not_available),
- /** Messages are known to be waiting but data channel is not working. */
- MESSAGE_WAITING(2, Action.CALL_VOICEMAIL, R.string.voicemail_status_messages_waiting,
- R.string.voicemail_status_audio_not_available),
- /** Notification channel not working, but data channel is. */
- NO_NOTIFICATIONS(3, Action.CALL_VOICEMAIL,
- R.string.voicemail_status_voicemail_not_available),
- /** Invite user to set up voicemail. */
- INVITE_FOR_CONFIGURATION(4, Action.CONFIGURE_VOICEMAIL,
- R.string.voicemail_status_configure_voicemail),
- /**
- * No detailed notifications, but data channel is working.
- * This is normal mode of operation for certain sources. No action needed.
- */
- NO_DETAILED_NOTIFICATION(5, Action.NONE, -1),
- /** Visual voicemail not yet set up. No local action needed. */
- NOT_CONFIGURED(6, Action.NONE, -1),
- /** Everything is OK. */
- OK(7, Action.NONE, -1),
- /** If one or more state value set by the source is not valid. */
- INVALID(8, Action.NONE, -1);
-
- private final int mPriority;
- private final Action mAction;
- private final int mCallLogMessageId;
- private final int mCallDetailsMessageId;
-
- private OverallState(int priority, Action action, int callLogMessageId) {
- this(priority, action, callLogMessageId, -1);
- }
-
- private OverallState(int priority, Action action, int callLogMessageId,
- int callDetailsMessageId) {
- mPriority = priority;
- mAction = action;
- mCallLogMessageId = callLogMessageId;
- mCallDetailsMessageId = callDetailsMessageId;
- }
-
- public Action getAction() {
- return mAction;
- }
-
- public int getPriority() {
- return mPriority;
- }
-
- public int getCallLogMessageId() {
- return mCallLogMessageId;
- }
-
- public int getCallDetailsMessageId() {
- return mCallDetailsMessageId;
- }
- }
-
- /** A wrapper on {@link StatusMessage} which additionally stores the priority of the message. */
- private static class MessageStatusWithPriority {
- private final StatusMessage mMessage;
- private final int mPriority;
-
- public MessageStatusWithPriority(StatusMessage message, int priority) {
- mMessage = message;
- mPriority = priority;
- }
- }
-
- @Override
- public List<StatusMessage> getStatusMessages(Cursor cursor) {
- List<MessageStatusWithPriority> messages =
- new ArrayList<VoicemailStatusHelperImpl.MessageStatusWithPriority>();
- cursor.moveToPosition(-1);
- while(cursor.moveToNext()) {
- MessageStatusWithPriority message = getMessageForStatusEntry(cursor);
- if (message != null) {
- messages.add(message);
- }
- }
- // Finally reorder the messages by their priority.
- return reorderMessages(messages);
- }
-
- @Override
- public int getNumberActivityVoicemailSources(Cursor cursor) {
- int count = 0;
- cursor.moveToPosition(-1);
- while(cursor.moveToNext()) {
- if (isVoicemailSourceActive(cursor)) {
- ++count;
- }
- }
- return count;
- }
-
- /** Returns whether the source status in the cursor corresponds to an active source. */
- private boolean isVoicemailSourceActive(Cursor cursor) {
- return cursor.getString(SOURCE_PACKAGE_INDEX) != null
- && cursor.getInt(CONFIGURATION_STATE_INDEX) == Status.CONFIGURATION_STATE_OK;
- }
-
- private List<StatusMessage> reorderMessages(List<MessageStatusWithPriority> messageWrappers) {
- Collections.sort(messageWrappers, new Comparator<MessageStatusWithPriority>() {
- @Override
- public int compare(MessageStatusWithPriority msg1, MessageStatusWithPriority msg2) {
- return msg1.mPriority - msg2.mPriority;
- }
- });
- List<StatusMessage> reorderMessages = new ArrayList<VoicemailStatusHelper.StatusMessage>();
- // Copy the ordered message objects into the final list.
- for (MessageStatusWithPriority messageWrapper : messageWrappers) {
- reorderMessages.add(messageWrapper.mMessage);
- }
- return reorderMessages;
- }
-
- /**
- * Returns the message for the status entry pointed to by the cursor.
- */
- private MessageStatusWithPriority getMessageForStatusEntry(Cursor cursor) {
- final String sourcePackage = cursor.getString(SOURCE_PACKAGE_INDEX);
- if (sourcePackage == null) {
- return null;
- }
- final OverallState overallState = getOverallState(cursor.getInt(CONFIGURATION_STATE_INDEX),
- cursor.getInt(DATA_CHANNEL_STATE_INDEX),
- cursor.getInt(NOTIFICATION_CHANNEL_STATE_INDEX));
- final Action action = overallState.getAction();
-
- // No source package or no action, means no message shown.
- if (action == Action.NONE) {
- return null;
- }
-
- Uri actionUri = null;
- if (action == Action.CALL_VOICEMAIL) {
- actionUri = UriUtils.parseUriOrNull(cursor.getString(VOICEMAIL_ACCESS_URI_INDEX));
- // Even if actionUri is null, it is still be useful to show the notification.
- } else if (action == Action.CONFIGURE_VOICEMAIL) {
- actionUri = UriUtils.parseUriOrNull(cursor.getString(SETTINGS_URI_INDEX));
- // If there is no settings URI, there is no point in showing the notification.
- if (actionUri == null) {
- return null;
- }
- }
- return new MessageStatusWithPriority(
- new StatusMessage(sourcePackage, overallState.getCallLogMessageId(),
- overallState.getCallDetailsMessageId(), action.getMessageId(),
- actionUri),
- overallState.getPriority());
- }
-
- private OverallState getOverallState(int configurationState, int dataChannelState,
- int notificationChannelState) {
- if (configurationState == CONFIGURATION_STATE_OK) {
- // Voicemail is configured. Let's see how is the data channel.
- if (dataChannelState == DATA_CHANNEL_STATE_OK) {
- // Data channel is fine. What about notification channel?
- if (notificationChannelState == NOTIFICATION_CHANNEL_STATE_OK) {
- return OverallState.OK;
- } else if (notificationChannelState == NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING) {
- return OverallState.NO_DETAILED_NOTIFICATION;
- } else if (notificationChannelState == NOTIFICATION_CHANNEL_STATE_NO_CONNECTION) {
- return OverallState.NO_NOTIFICATIONS;
- }
- } else if (dataChannelState == DATA_CHANNEL_STATE_NO_CONNECTION) {
- // Data channel is not working. What about notification channel?
- if (notificationChannelState == NOTIFICATION_CHANNEL_STATE_OK) {
- return OverallState.NO_DATA;
- } else if (notificationChannelState == NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING) {
- return OverallState.MESSAGE_WAITING;
- } else if (notificationChannelState == NOTIFICATION_CHANNEL_STATE_NO_CONNECTION) {
- return OverallState.NO_CONNECTION;
- }
- }
- } else if (configurationState == CONFIGURATION_STATE_CAN_BE_CONFIGURED) {
- // Voicemail not configured. data/notification channel states are irrelevant.
- return OverallState.INVITE_FOR_CONFIGURATION;
- } else if (configurationState == Status.CONFIGURATION_STATE_NOT_CONFIGURED) {
- // Voicemail not configured. data/notification channel states are irrelevant.
- return OverallState.NOT_CONFIGURED;
- }
- // Will reach here only if the source has set an invalid value.
- return OverallState.INVALID;
- }
-}
diff --git a/tests/Android.mk b/tests/Android.mk
index ef11c5e..241ff5e 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -6,6 +6,7 @@
LOCAL_CERTIFICATE := shared
LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_STATIC_JAVA_LIBRARIES := com.android.contacts.common.test
# Include all test java files.
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index d80a35d..a3dacbe 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -76,16 +76,6 @@
</intent-filter>
</activity>
- <activity android:name=".calllog.FillCallLogTestActivity"
- android:label="@string/fillCallLogTest"
- >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
-
<activity android:name=".streamitems.StreamItemPopulatorActivity"
android:label="@string/streamItemPopulator"
>
@@ -139,9 +129,4 @@
android:label="Contacts launch performance">
</instrumentation>
- <instrumentation android:name="com.android.contacts.DialerLaunchPerformance"
- android:targetPackage="com.android.contacts"
- android:label="Dialer launch performance">
- </instrumentation>
-
</manifest>
diff --git a/tests/src/com/android/contacts/CallDetailActivityTest.java b/tests/src/com/android/contacts/CallDetailActivityTest.java
deleted file mode 100644
index ae28929..0000000
--- a/tests/src/com/android/contacts/CallDetailActivityTest.java
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-import static com.android.contacts.CallDetailActivity.Tasks.UPDATE_PHONE_CALL_DETAILS;
-import static com.android.contacts.voicemail.VoicemailPlaybackPresenter.Tasks.CHECK_FOR_CONTENT;
-import static com.android.contacts.voicemail.VoicemailPlaybackPresenter.Tasks.PREPARE_MEDIA_PLAYER;
-
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Intent;
-import android.content.res.AssetManager;
-import android.net.Uri;
-import android.provider.CallLog;
-import android.provider.VoicemailContract;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.Suppress;
-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;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * Unit tests for the {@link CallDetailActivity}.
- */
-@LargeTest
-public class CallDetailActivityTest extends ActivityInstrumentationTestCase2<CallDetailActivity> {
- private static final String TEST_ASSET_NAME = "quick_test_recording.mp3";
- private static final String MIME_TYPE = "audio/mp3";
- private static final String CONTACT_NUMBER = "+1412555555";
- private static final String VOICEMAIL_FILE_LOCATION = "/sdcard/sadlfj893w4j23o9sfu.mp3";
-
- private Uri mCallLogUri;
- private Uri mVoicemailUri;
- private IntegrationTestUtils mTestUtils;
- private LocaleTestUtils mLocaleTestUtils;
- private FakeAsyncTaskExecutor mFakeAsyncTaskExecutor;
- private CallDetailActivity mActivityUnderTest;
-
- public CallDetailActivityTest() {
- super(CallDetailActivity.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mFakeAsyncTaskExecutor = new FakeAsyncTaskExecutor(getInstrumentation());
- AsyncTaskExecutors.setFactoryForTest(mFakeAsyncTaskExecutor.getFactory());
- // I don't like the default of focus-mode for tests, the green focus border makes the
- // screenshots look weak.
- setActivityInitialTouchMode(true);
- mTestUtils = new IntegrationTestUtils(getInstrumentation());
- // Some of the tests rely on the text that appears on screen - safest to force a
- // specific locale.
- mLocaleTestUtils = new LocaleTestUtils(getInstrumentation().getTargetContext());
- mLocaleTestUtils.setLocale(Locale.US);
- }
-
- @Override
- protected void tearDown() throws Exception {
- mLocaleTestUtils.restoreLocale();
- mLocaleTestUtils = null;
- cleanUpUri();
- mTestUtils = null;
- AsyncTaskExecutors.setFactoryForTest(null);
- super.tearDown();
- }
-
- public void testInitialActivityStartsWithFetchingVoicemail() throws Throwable {
- setActivityIntentForTestVoicemailEntry();
- startActivityUnderTest();
- // When the activity first starts, we will show "Fetching voicemail" on the screen.
- // The duration should not be visible.
- assertHasOneTextViewContaining("Fetching voicemail");
- assertZeroTextViewsContaining("00:00");
- }
-
- public void testWhenCheckForContentCompletes_UiShowsBuffering() throws Throwable {
- setActivityIntentForTestVoicemailEntry();
- startActivityUnderTest();
- // There is a background check that is testing to see if we have the content available.
- // Once that task completes, we shouldn't be showing the fetching message, we should
- // be showing "Buffering".
- mFakeAsyncTaskExecutor.runTask(CHECK_FOR_CONTENT);
- assertHasOneTextViewContaining("Buffering");
- assertZeroTextViewsContaining("Fetching voicemail");
- }
-
- public void testInvalidVoicemailShowsErrorMessage() throws Throwable {
- setActivityIntentForTestVoicemailEntry();
- startActivityUnderTest();
- mFakeAsyncTaskExecutor.runTask(CHECK_FOR_CONTENT);
- // There should be exactly one background task ready to prepare the media player.
- // Preparing the media player will have thrown an IOException since the file doesn't exist.
- // This should have put a failed to play message on screen, buffering is gone.
- mFakeAsyncTaskExecutor.runTask(PREPARE_MEDIA_PLAYER);
- assertHasOneTextViewContaining("Couldn't play voicemail");
- assertZeroTextViewsContaining("Buffering");
- }
-
- public void testOnResumeDoesNotCreateManyFragments() throws Throwable {
- // There was a bug where every time the activity was resumed, a new fragment was created.
- // Before the fix, this was failing reproducibly with at least 3 "Buffering" views.
- setActivityIntentForTestVoicemailEntry();
- startActivityUnderTest();
- mFakeAsyncTaskExecutor.runTask(CHECK_FOR_CONTENT);
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- getInstrumentation().callActivityOnPause(mActivityUnderTest);
- getInstrumentation().callActivityOnResume(mActivityUnderTest);
- getInstrumentation().callActivityOnPause(mActivityUnderTest);
- getInstrumentation().callActivityOnResume(mActivityUnderTest);
- }
- });
- assertHasOneTextViewContaining("Buffering");
- }
-
- /**
- * Test for bug where increase rate button with invalid voicemail causes a crash.
- * <p>
- * The repro steps for this crash were to open a voicemail that does not have an attachment,
- * then click the play button (which just reported an error), then after that try to adjust the
- * rate. See http://b/5047879.
- */
- public void testClickIncreaseRateButtonWithInvalidVoicemailDoesNotCrash() throws Throwable {
- setActivityIntentForTestVoicemailEntry();
- startActivityUnderTest();
- mTestUtils.clickButton(mActivityUnderTest, R.id.playback_start_stop);
- mTestUtils.clickButton(mActivityUnderTest, R.id.rate_increase_button);
- }
-
- /** Test for bug where missing Extras on intent used to start Activity causes NPE. */
- public void testCallLogUriWithMissingExtrasShouldNotCauseNPE() throws Throwable {
- setActivityIntentForTestCallEntry();
- startActivityUnderTest();
- }
-
- /**
- * Test for bug where voicemails should not have remove-from-call-log entry.
- * <p>
- * See http://b/5054103.
- */
- public void testVoicemailDoesNotHaveRemoveFromCallLog() throws Throwable {
- setActivityIntentForTestVoicemailEntry();
- startActivityUnderTest();
- Menu menu = new ContextMenuBuilder(mActivityUnderTest);
- mActivityUnderTest.onCreateOptionsMenu(menu);
- mActivityUnderTest.onPrepareOptionsMenu(menu);
- assertFalse(menu.findItem(R.id.menu_remove_from_call_log).isVisible());
- }
-
- /** Test to check that I haven't broken the remove-from-call-log entry from regular calls. */
- public void testRegularCallDoesHaveRemoveFromCallLog() throws Throwable {
- setActivityIntentForTestCallEntry();
- startActivityUnderTest();
- Menu menu = new ContextMenuBuilder(mActivityUnderTest);
- mActivityUnderTest.onCreateOptionsMenu(menu);
- mActivityUnderTest.onPrepareOptionsMenu(menu);
- assertTrue(menu.findItem(R.id.menu_remove_from_call_log).isVisible());
- }
-
- /**
- * Test to show that we are correctly displaying playback rate on the ui.
- * <p>
- * See bug http://b/5044075.
- */
- @Suppress
- public void testVoicemailPlaybackRateDisplayedOnUi() throws Throwable {
- setActivityIntentForTestVoicemailEntry();
- startActivityUnderTest();
- // Find the TextView containing the duration. It should be initially displaying "00:00".
- List<TextView> views = mTestUtils.getTextViewsWithString(mActivityUnderTest, "00:00");
- assertEquals(1, views.size());
- TextView timeDisplay = views.get(0);
- // Hit the plus button. At this point we should be displaying "fast speed".
- mTestUtils.clickButton(mActivityUnderTest, R.id.rate_increase_button);
- assertEquals("fast speed", mTestUtils.getText(timeDisplay));
- // Hit the minus button. We should be back to "normal" speed.
- mTestUtils.clickButton(mActivityUnderTest, R.id.rate_decrease_button);
- assertEquals("normal speed", mTestUtils.getText(timeDisplay));
- // Wait for one and a half seconds. The timer will be back.
- Thread.sleep(1500);
- assertEquals("00:00", mTestUtils.getText(timeDisplay));
- }
-
- @Suppress
- public void testClickingCallStopsPlayback() throws Throwable {
- setActivityIntentForRealFileVoicemailEntry();
- startActivityUnderTest();
- mFakeAsyncTaskExecutor.runTask(CHECK_FOR_CONTENT);
- mFakeAsyncTaskExecutor.runTask(PREPARE_MEDIA_PLAYER);
- mTestUtils.clickButton(mActivityUnderTest, R.id.playback_speakerphone);
- mTestUtils.clickButton(mActivityUnderTest, R.id.playback_start_stop);
- mTestUtils.clickButton(mActivityUnderTest, R.id.call_and_sms_main_action);
- Thread.sleep(2000);
- // TODO: Suppressed the test for now, because I'm looking for an easy way to say "the audio
- // is not playing at this point", and I can't find it without doing dirty things.
- }
-
- private void setActivityIntentForTestCallEntry() {
- assertNull(mCallLogUri);
- ContentResolver contentResolver = getContentResolver();
- ContentValues values = new ContentValues();
- values.put(CallLog.Calls.NUMBER, CONTACT_NUMBER);
- values.put(CallLog.Calls.TYPE, CallLog.Calls.INCOMING_TYPE);
- mCallLogUri = contentResolver.insert(CallLog.Calls.CONTENT_URI, values);
- setActivityIntent(new Intent(Intent.ACTION_VIEW, mCallLogUri));
- }
-
- private void setActivityIntentForTestVoicemailEntry() {
- assertNull(mVoicemailUri);
- ContentResolver contentResolver = getContentResolver();
- ContentValues values = new ContentValues();
- values.put(VoicemailContract.Voicemails.NUMBER, CONTACT_NUMBER);
- values.put(VoicemailContract.Voicemails.HAS_CONTENT, 1);
- values.put(VoicemailContract.Voicemails._DATA, VOICEMAIL_FILE_LOCATION);
- mVoicemailUri = contentResolver.insert(VoicemailContract.Voicemails.CONTENT_URI, values);
- Uri callLogUri = ContentUris.withAppendedId(CallLog.Calls.CONTENT_URI_WITH_VOICEMAIL,
- ContentUris.parseId(mVoicemailUri));
- Intent intent = new Intent(Intent.ACTION_VIEW, callLogUri);
- intent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI, mVoicemailUri);
- setActivityIntent(intent);
- }
-
- private void setActivityIntentForRealFileVoicemailEntry() throws IOException {
- assertNull(mVoicemailUri);
- ContentValues values = new ContentValues();
- values.put(VoicemailContract.Voicemails.DATE, String.valueOf(System.currentTimeMillis()));
- values.put(VoicemailContract.Voicemails.NUMBER, CONTACT_NUMBER);
- values.put(VoicemailContract.Voicemails.MIME_TYPE, MIME_TYPE);
- values.put(VoicemailContract.Voicemails.HAS_CONTENT, 1);
- String packageName = getInstrumentation().getTargetContext().getPackageName();
- mVoicemailUri = getContentResolver().insert(
- VoicemailContract.Voicemails.buildSourceUri(packageName), values);
- AssetManager assets = getAssets();
- OutputStream outputStream = null;
- InputStream inputStream = null;
- try {
- inputStream = assets.open(TEST_ASSET_NAME);
- outputStream = getContentResolver().openOutputStream(mVoicemailUri);
- copyBetweenStreams(inputStream, outputStream);
- } finally {
- Closeables.closeQuietly(outputStream);
- Closeables.closeQuietly(inputStream);
- }
- Uri callLogUri = ContentUris.withAppendedId(CallLog.Calls.CONTENT_URI_WITH_VOICEMAIL,
- ContentUris.parseId(mVoicemailUri));
- Intent intent = new Intent(Intent.ACTION_VIEW, callLogUri);
- intent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI, mVoicemailUri);
- setActivityIntent(intent);
- }
-
- public void copyBetweenStreams(InputStream in, OutputStream out) throws IOException {
- byte[] buffer = new byte[1024];
- int bytesRead;
- int total = 0;
- while ((bytesRead = in.read(buffer)) != -1) {
- total += bytesRead;
- out.write(buffer, 0, bytesRead);
- }
- }
-
- private void cleanUpUri() {
- if (mVoicemailUri != null) {
- getContentResolver().delete(VoicemailContract.Voicemails.CONTENT_URI,
- "_ID = ?", new String[] { String.valueOf(ContentUris.parseId(mVoicemailUri)) });
- mVoicemailUri = null;
- }
- if (mCallLogUri != null) {
- getContentResolver().delete(CallLog.Calls.CONTENT_URI_WITH_VOICEMAIL,
- "_ID = ?", new String[] { String.valueOf(ContentUris.parseId(mCallLogUri)) });
- mCallLogUri = null;
- }
- }
-
- private ContentResolver getContentResolver() {
- return getInstrumentation().getTargetContext().getContentResolver();
- }
-
- private TextView assertHasOneTextViewContaining(String text) throws Throwable {
- assertNotNull(mActivityUnderTest);
- List<TextView> views = mTestUtils.getTextViewsWithString(mActivityUnderTest, text);
- assertEquals("There should have been one TextView with text '" + text + "' but found "
- + views, 1, views.size());
- return views.get(0);
- }
-
- private void assertZeroTextViewsContaining(String text) throws Throwable {
- assertNotNull(mActivityUnderTest);
- List<TextView> views = mTestUtils.getTextViewsWithString(mActivityUnderTest, text);
- assertEquals("There should have been no TextViews with text '" + text + "' but found "
- + views, 0, views.size());
- }
-
- private void startActivityUnderTest() throws Throwable {
- assertNull(mActivityUnderTest);
- mActivityUnderTest = getActivity();
- assertNotNull("activity should not be null", mActivityUnderTest);
- // We have to run all tasks, not just one.
- // This is because it seems that we can have onResume, onPause, onResume during the course
- // of a single unit test.
- mFakeAsyncTaskExecutor.runAllTasks(UPDATE_PHONE_CALL_DETAILS);
- }
-
- private AssetManager getAssets() {
- return getInstrumentation().getContext().getAssets();
- }
-}
diff --git a/tests/src/com/android/contacts/ContactsUtilsTests.java b/tests/src/com/android/contacts/ContactsUtilsTests.java
index d2d5bbb..49e9ddd 100644
--- a/tests/src/com/android/contacts/ContactsUtilsTests.java
+++ b/tests/src/com/android/contacts/ContactsUtilsTests.java
@@ -21,6 +21,8 @@
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.contacts.common.MoreContactUtils;
+
/**
* Tests for {@link ContactsUtils}.
*/
@@ -183,9 +185,9 @@
private void assertCollapses(String message, boolean expected, CharSequence mimetype1,
CharSequence data1, CharSequence mimetype2, CharSequence data2) {
assertEquals(message, expected,
- ContactsUtils.shouldCollapse(mimetype1, data1, mimetype2, data2));
+ MoreContactUtils.shouldCollapse(mimetype1, data1, mimetype2, data2));
assertEquals(message, expected,
- ContactsUtils.shouldCollapse(mimetype2, data2, mimetype1, data1));
+ MoreContactUtils.shouldCollapse(mimetype2, data2, mimetype1, data1));
// If data1 and data2 are the same instance, make sure the same test passes with different
// instances.
@@ -201,11 +203,11 @@
// we have two different instances, now make sure we get the same result as before
assertEquals(message, expected,
- ContactsUtils.shouldCollapse(mimetype1, data1, mimetype2,
- data2_newref));
+ MoreContactUtils.shouldCollapse(mimetype1, data1, mimetype2,
+ data2_newref));
assertEquals(message, expected,
- ContactsUtils.shouldCollapse(mimetype2, data2_newref, mimetype1,
- data1));
+ MoreContactUtils.shouldCollapse(mimetype2, data2_newref, mimetype1,
+ data1));
}
}
diff --git a/tests/src/com/android/contacts/DialerLaunchPerformance.java b/tests/src/com/android/contacts/DialerLaunchPerformance.java
deleted file mode 100644
index 0803c6b..0000000
--- a/tests/src/com/android/contacts/DialerLaunchPerformance.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.app.Activity;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.os.Bundle;
-import android.test.LaunchPerformanceBase;
-
-/**
- * Instrumentation class for Address Book launch performance testing.
- */
-public class DialerLaunchPerformance extends LaunchPerformanceBase {
-
- @Override
- public void onCreate(Bundle arguments) {
- mIntent.setAction(Intent.ACTION_MAIN);
- mIntent.addCategory(Intent.CATEGORY_LAUNCHER);
- mIntent.setComponent(new ComponentName("com.android.contacts",
- "com.android.contacts.activities.DialtactsActivity"));
-
- start();
- }
-
- /**
- * Calls LaunchApp and finish.
- */
- @Override
- public void onStart() {
- super.onStart();
- LaunchApp();
- finish(Activity.RESULT_OK, mResults);
- }
-}
diff --git a/tests/src/com/android/contacts/PhoneCallDetailsHelperTest.java b/tests/src/com/android/contacts/PhoneCallDetailsHelperTest.java
deleted file mode 100644
index b852b58..0000000
--- a/tests/src/com/android/contacts/PhoneCallDetailsHelperTest.java
+++ /dev/null
@@ -1,328 +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 android.content.Context;
-import android.content.res.Resources;
-import android.provider.CallLog.Calls;
-import android.test.AndroidTestCase;
-import android.text.Html;
-import android.text.Spanned;
-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;
-
-/**
- * Unit tests for {@link PhoneCallDetailsHelper}.
- */
-public class PhoneCallDetailsHelperTest extends AndroidTestCase {
- /** The number to be used to access the voicemail. */
- private static final String TEST_VOICEMAIL_NUMBER = "125";
- /** The date of the call log entry. */
- private static final long TEST_DATE =
- new GregorianCalendar(2011, 5, 3, 13, 0, 0).getTimeInMillis();
- /** A test duration value for phone calls. */
- private static final long TEST_DURATION = 62300;
- /** The number of the caller/callee in the log entry. */
- private static final String TEST_NUMBER = "14125555555";
- /** The formatted version of {@link #TEST_NUMBER}. */
- private static final String TEST_FORMATTED_NUMBER = "1-412-255-5555";
- /** The country ISO name used in the tests. */
- private static final String TEST_COUNTRY_ISO = "US";
- /** The geocoded location used in the tests. */
- private static final String TEST_GEOCODE = "United States";
-
- /** The object under test. */
- private PhoneCallDetailsHelper mHelper;
- /** The views to fill. */
- private PhoneCallDetailsViews mViews;
- private TextView mNameView;
- private PhoneNumberHelper mPhoneNumberHelper;
- private LocaleTestUtils mLocaleTestUtils;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- Context context = getContext();
- Resources resources = context.getResources();
- CallTypeHelper callTypeHelper = new CallTypeHelper(resources);
- mPhoneNumberHelper = new TestPhoneNumberHelper(resources, TEST_VOICEMAIL_NUMBER);
- mHelper = new PhoneCallDetailsHelper(resources, callTypeHelper, mPhoneNumberHelper);
- mHelper.setCurrentTimeForTest(
- new GregorianCalendar(2011, 5, 4, 13, 0, 0).getTimeInMillis());
- mViews = PhoneCallDetailsViews.createForTest(context);
- mNameView = new TextView(context);
- mLocaleTestUtils = new LocaleTestUtils(getContext());
- mLocaleTestUtils.setLocale(Locale.US);
- }
-
- @Override
- protected void tearDown() throws Exception {
- mLocaleTestUtils.restoreLocale();
- mNameView = null;
- mViews = null;
- mHelper = null;
- mPhoneNumberHelper = null;
- super.tearDown();
- }
-
- public void testSetPhoneCallDetails_Unknown() {
- setPhoneCallDetailsWithNumber(CallerInfo.UNKNOWN_NUMBER, CallerInfo.UNKNOWN_NUMBER);
- assertNameEqualsResource(R.string.unknown);
- }
-
- public void testSetPhoneCallDetails_Private() {
- setPhoneCallDetailsWithNumber(CallerInfo.PRIVATE_NUMBER, CallerInfo.PRIVATE_NUMBER);
- assertNameEqualsResource(R.string.private_num);
- }
-
- public void testSetPhoneCallDetails_Payphone() {
- setPhoneCallDetailsWithNumber(CallerInfo.PAYPHONE_NUMBER, CallerInfo.PAYPHONE_NUMBER);
- assertNameEqualsResource(R.string.payphone);
- }
-
- public void testSetPhoneCallDetails_Voicemail() {
- setPhoneCallDetailsWithNumber(TEST_VOICEMAIL_NUMBER, TEST_VOICEMAIL_NUMBER);
- assertNameEqualsResource(R.string.voicemail);
- }
-
- public void testSetPhoneCallDetails_Normal() {
- setPhoneCallDetailsWithNumber("14125551212", "1-412-555-1212");
- assertEquals("yesterday", mViews.callTypeAndDate.getText().toString());
- assertEqualsHtml("<font color='#33b5e5'><b>yesterday</b></font>",
- mViews.callTypeAndDate.getText());
- }
-
- /** Asserts that a char sequence is actually a Spanned corresponding to the expected HTML. */
- private void assertEqualsHtml(String expectedHtml, CharSequence actualText) {
- // In order to contain HTML, the text should actually be a Spanned.
- assertTrue(actualText instanceof Spanned);
- Spanned actualSpanned = (Spanned) actualText;
- // Convert from and to HTML to take care of alternative formatting of HTML.
- assertEquals(Html.toHtml(Html.fromHtml(expectedHtml)), Html.toHtml(actualSpanned));
-
- }
-
- public void testSetPhoneCallDetails_Date() {
- mHelper.setCurrentTimeForTest(
- new GregorianCalendar(2011, 5, 3, 13, 0, 0).getTimeInMillis());
-
- setPhoneCallDetailsWithDate(
- new GregorianCalendar(2011, 5, 3, 13, 0, 0).getTimeInMillis());
- assertDateEquals("0 mins ago");
-
- setPhoneCallDetailsWithDate(
- new GregorianCalendar(2011, 5, 3, 12, 0, 0).getTimeInMillis());
- assertDateEquals("1 hour ago");
-
- setPhoneCallDetailsWithDate(
- new GregorianCalendar(2011, 5, 2, 13, 0, 0).getTimeInMillis());
- assertDateEquals("yesterday");
-
- setPhoneCallDetailsWithDate(
- new GregorianCalendar(2011, 5, 1, 13, 0, 0).getTimeInMillis());
- assertDateEquals("2 days ago");
- }
-
- public void testSetPhoneCallDetails_CallTypeIcons() {
- setPhoneCallDetailsWithCallTypeIcons(Calls.INCOMING_TYPE);
- assertCallTypeIconsEquals(Calls.INCOMING_TYPE);
-
- setPhoneCallDetailsWithCallTypeIcons(Calls.OUTGOING_TYPE);
- assertCallTypeIconsEquals(Calls.OUTGOING_TYPE);
-
- setPhoneCallDetailsWithCallTypeIcons(Calls.MISSED_TYPE);
- assertCallTypeIconsEquals(Calls.MISSED_TYPE);
-
- setPhoneCallDetailsWithCallTypeIcons(Calls.VOICEMAIL_TYPE);
- assertCallTypeIconsEquals(Calls.VOICEMAIL_TYPE);
- }
-
- public void testSetPhoneCallDetails_MultipleCallTypeIcons() {
- setPhoneCallDetailsWithCallTypeIcons(Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE);
- assertCallTypeIconsEquals(Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE);
-
- setPhoneCallDetailsWithCallTypeIcons(Calls.MISSED_TYPE, Calls.MISSED_TYPE);
- assertCallTypeIconsEquals(Calls.MISSED_TYPE, Calls.MISSED_TYPE);
- }
-
- public void testSetPhoneCallDetails_MultipleCallTypeIconsLastOneDropped() {
- setPhoneCallDetailsWithCallTypeIcons(Calls.MISSED_TYPE, Calls.MISSED_TYPE,
- Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE);
- assertCallTypeIconsEqualsPlusOverflow("(4)",
- Calls.MISSED_TYPE, Calls.MISSED_TYPE, Calls.INCOMING_TYPE);
- }
-
- public void testSetPhoneCallDetails_Geocode() {
- setPhoneCallDetailsWithNumberAndGeocode("+14125555555", "1-412-555-5555", "Pennsylvania");
- assertNameEquals("1-412-555-5555"); // The phone number is shown as the name.
- assertNumberEquals("Pennsylvania"); // The geocode is shown as the number.
- }
-
- public void testSetPhoneCallDetails_NoGeocode() {
- setPhoneCallDetailsWithNumberAndGeocode("+14125555555", "1-412-555-5555", null);
- assertNameEquals("1-412-555-5555"); // The phone number is shown as the name.
- assertNumberEquals("-"); // The empty geocode is shown as the number.
- }
-
- public void testSetPhoneCallDetails_EmptyGeocode() {
- setPhoneCallDetailsWithNumberAndGeocode("+14125555555", "1-412-555-5555", "");
- assertNameEquals("1-412-555-5555"); // The phone number is shown as the name.
- assertNumberEquals("-"); // The empty geocode is shown as the number.
- }
-
- public void testSetPhoneCallDetails_NoGeocodeForVoicemail() {
- setPhoneCallDetailsWithNumberAndGeocode(TEST_VOICEMAIL_NUMBER, "", "United States");
- assertNumberEquals("-"); // The empty geocode is shown as the number.
- }
-
- public void testSetPhoneCallDetails_Highlighted() {
- setPhoneCallDetailsWithNumber(TEST_VOICEMAIL_NUMBER, "");
- }
-
- public void testSetCallDetailsHeader_NumberOnly() {
- setCallDetailsHeaderWithNumberOnly(TEST_NUMBER);
- assertEquals(View.VISIBLE, mNameView.getVisibility());
- assertEquals("Add to contacts", mNameView.getText().toString());
- }
-
- public void testSetCallDetailsHeader_UnknownNumber() {
- setCallDetailsHeaderWithNumberOnly(CallerInfo.UNKNOWN_NUMBER);
- assertEquals(View.VISIBLE, mNameView.getVisibility());
- assertEquals("Unknown", mNameView.getText().toString());
- }
-
- public void testSetCallDetailsHeader_PrivateNumber() {
- setCallDetailsHeaderWithNumberOnly(CallerInfo.PRIVATE_NUMBER);
- assertEquals(View.VISIBLE, mNameView.getVisibility());
- assertEquals("Private number", mNameView.getText().toString());
- }
-
- public void testSetCallDetailsHeader_PayphoneNumber() {
- setCallDetailsHeaderWithNumberOnly(CallerInfo.PAYPHONE_NUMBER);
- assertEquals(View.VISIBLE, mNameView.getVisibility());
- assertEquals("Pay phone", mNameView.getText().toString());
- }
-
- public void testSetCallDetailsHeader_VoicemailNumber() {
- setCallDetailsHeaderWithNumberOnly(TEST_VOICEMAIL_NUMBER);
- assertEquals(View.VISIBLE, mNameView.getVisibility());
- assertEquals("Voicemail", mNameView.getText().toString());
- }
-
- public void testSetCallDetailsHeader() {
- setCallDetailsHeader("John Doe");
- assertEquals(View.VISIBLE, mNameView.getVisibility());
- assertEquals("John Doe", mNameView.getText().toString());
- }
-
- /** Asserts that the name text field contains the value of the given string resource. */
- private void assertNameEqualsResource(int resId) {
- assertNameEquals(getContext().getString(resId));
- }
-
- /** Asserts that the name text field contains the given string value. */
- private void assertNameEquals(String text) {
- assertEquals(text, mViews.nameView.getText().toString());
- }
-
- /** Asserts that the number text field contains the given string value. */
- private void assertNumberEquals(String text) {
- assertEquals(text, mViews.numberView.getText().toString());
- }
-
- /** Asserts that the date text field contains the given string value. */
- private void assertDateEquals(String text) {
- assertEquals(text, mViews.callTypeAndDate.getText().toString());
- }
-
- /** Asserts that the call type contains the images with the given drawables. */
- private void assertCallTypeIconsEquals(int... ids) {
- assertEquals(ids.length, mViews.callTypeIcons.getCount());
- for (int index = 0; index < ids.length; ++index) {
- int id = ids[index];
- assertEquals(id, mViews.callTypeIcons.getCallType(index));
- }
- assertEquals(View.VISIBLE, mViews.callTypeIcons.getVisibility());
- assertEquals("yesterday", mViews.callTypeAndDate.getText().toString());
- }
-
- /**
- * Asserts that the call type contains the images with the given drawables and shows the given
- * text next to the icons.
- */
- private void assertCallTypeIconsEqualsPlusOverflow(String overflowText, int... ids) {
- assertEquals(ids.length, mViews.callTypeIcons.getCount());
- for (int index = 0; index < ids.length; ++index) {
- int id = ids[index];
- assertEquals(id, mViews.callTypeIcons.getCallType(index));
- }
- assertEquals(View.VISIBLE, mViews.callTypeIcons.getVisibility());
- assertEquals(overflowText + " yesterday", mViews.callTypeAndDate.getText().toString());
- }
-
- /** Sets the phone call details with default values and the given number. */
- private void setPhoneCallDetailsWithNumber(String number, String formattedNumber) {
- setPhoneCallDetailsWithNumberAndGeocode(number, formattedNumber, TEST_GEOCODE);
- }
-
- /** Sets the phone call details with default values and the given number. */
- private void setPhoneCallDetailsWithNumberAndGeocode(String number, String formattedNumber,
- String geocodedLocation) {
- mHelper.setPhoneCallDetails(mViews,
- new PhoneCallDetails(number, formattedNumber, TEST_COUNTRY_ISO, geocodedLocation,
- new int[]{ Calls.VOICEMAIL_TYPE }, TEST_DATE, TEST_DURATION),
- true);
- }
-
- /** Sets the phone call details with default values and the given date. */
- private void setPhoneCallDetailsWithDate(long date) {
- mHelper.setPhoneCallDetails(mViews,
- new PhoneCallDetails(TEST_NUMBER, TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO,
- TEST_GEOCODE, new int[]{ Calls.INCOMING_TYPE }, date, TEST_DURATION),
- false);
- }
-
- /** Sets the phone call details with default values and the given call types using icons. */
- private void setPhoneCallDetailsWithCallTypeIcons(int... callTypes) {
- mHelper.setPhoneCallDetails(mViews,
- new PhoneCallDetails(TEST_NUMBER, TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO,
- TEST_GEOCODE, callTypes, TEST_DATE, TEST_DURATION),
- false);
- }
-
- private void setCallDetailsHeaderWithNumberOnly(String number) {
- mHelper.setCallDetailsHeader(mNameView,
- new PhoneCallDetails(number, TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO,
- TEST_GEOCODE, new int[]{ Calls.INCOMING_TYPE }, TEST_DATE, TEST_DURATION));
- }
-
- private void setCallDetailsHeader(String name) {
- mHelper.setCallDetailsHeader(mNameView,
- new PhoneCallDetails(TEST_NUMBER, TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO,
- TEST_GEOCODE, new int[]{ Calls.INCOMING_TYPE }, TEST_DATE, TEST_DURATION,
- name, 0, "", null, null));
- }
-}
diff --git a/tests/src/com/android/contacts/RawContactDeltaListTests.java b/tests/src/com/android/contacts/RawContactDeltaListTests.java
index 165e689..07e9dd6 100644
--- a/tests/src/com/android/contacts/RawContactDeltaListTests.java
+++ b/tests/src/com/android/contacts/RawContactDeltaListTests.java
@@ -125,7 +125,7 @@
final ContentValues contact = new ContentValues();
contact.put(RawContacts.VERSION, version);
contact.put(RawContacts._ID, rawContactId);
- final RawContact before = new RawContact(context, contact);
+ final RawContact before = new RawContact(contact);
for (ContentValues entry : entries) {
before.addDataItemValues(entry);
}
diff --git a/tests/src/com/android/contacts/RawContactDeltaTests.java b/tests/src/com/android/contacts/RawContactDeltaTests.java
index 80e4c20..751d41c 100644
--- a/tests/src/com/android/contacts/RawContactDeltaTests.java
+++ b/tests/src/com/android/contacts/RawContactDeltaTests.java
@@ -77,7 +77,7 @@
phone.put(Phone.NUMBER, TEST_PHONE_NUMBER_1);
phone.put(Phone.TYPE, Phone.TYPE_HOME);
- final RawContact before = new RawContact(context, contact);
+ final RawContact before = new RawContact(contact);
before.addDataItemValues(phone);
return before;
}
diff --git a/tests/src/com/android/contacts/RawContactModifierTests.java b/tests/src/com/android/contacts/RawContactModifierTests.java
index 8046ed6..9caaffa 100644
--- a/tests/src/com/android/contacts/RawContactModifierTests.java
+++ b/tests/src/com/android/contacts/RawContactModifierTests.java
@@ -180,7 +180,7 @@
contact.put(RawContacts.ACCOUNT_NAME, TEST_ACCOUNT_NAME);
contact.put(RawContacts.ACCOUNT_TYPE, TEST_ACCOUNT_TYPE);
- final RawContact before = new RawContact(mContext, contact);
+ final RawContact before = new RawContact(contact);
for (ContentValues values : entries) {
before.addDataItemValues(values);
}
diff --git a/tests/src/com/android/contacts/activities/PeopleActivityTest.java b/tests/src/com/android/contacts/activities/PeopleActivityTest.java
index 11fccd1..db7e5c0 100644
--- a/tests/src/com/android/contacts/activities/PeopleActivityTest.java
+++ b/tests/src/com/android/contacts/activities/PeopleActivityTest.java
@@ -32,7 +32,7 @@
import android.test.suitebuilder.annotation.SmallTest;
import android.widget.TextView;
-import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.ContactsApplication;
import com.android.contacts.R;
import com.android.contacts.detail.ContactDetailFragment;
diff --git a/tests/src/com/android/contacts/calllog/CallLogAdapterTest.java b/tests/src/com/android/contacts/calllog/CallLogAdapterTest.java
deleted file mode 100644
index 5bc31f9..0000000
--- a/tests/src/com/android/contacts/calllog/CallLogAdapterTest.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-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;
-
-/**
- * Unit tests for {@link CallLogAdapter}.
- */
-@SmallTest
-public class CallLogAdapterTest extends AndroidTestCase {
- private static final String TEST_NUMBER = "12345678";
- private static final String TEST_NAME = "name";
- private static final String TEST_NUMBER_LABEL = "label";
- private static final int TEST_NUMBER_TYPE = 1;
- private static final String TEST_COUNTRY_ISO = "US";
-
- /** The object under test. */
- private TestCallLogAdapter mAdapter;
-
- private MatrixCursor mCursor;
- private View mView;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- // Use a call fetcher that does not do anything.
- CallLogAdapter.CallFetcher fakeCallFetcher = new CallLogAdapter.CallFetcher() {
- @Override
- public void fetchCalls() {}
- };
-
- ContactInfoHelper fakeContactInfoHelper =
- new ContactInfoHelper(getContext(), TEST_COUNTRY_ISO) {
- @Override
- public ContactInfo lookupNumber(String number, String countryIso) {
- ContactInfo info = new ContactInfo();
- info.number = number;
- info.formattedNumber = number;
- return info;
- }
- };
-
- mAdapter = new TestCallLogAdapter(getContext(), fakeCallFetcher, fakeContactInfoHelper);
- // The cursor used in the tests to store the entries to display.
- mCursor = new MatrixCursor(CallLogQuery.EXTENDED_PROJECTION);
- mCursor.moveToFirst();
- // The views into which to store the data.
- mView = new View(getContext());
- mView.setTag(CallLogListItemViews.createForTest(getContext()));
- }
-
- @Override
- protected void tearDown() throws Exception {
- mAdapter = null;
- mCursor = null;
- mView = null;
- super.tearDown();
- }
-
- public void testBindView_NoCallLogCacheNorMemoryCache_EnqueueRequest() {
- mCursor.addRow(createCallLogEntry());
-
- // Bind the views of a single row.
- mAdapter.bindStandAloneView(mView, getContext(), mCursor);
-
- // There is one request for contact details.
- assertEquals(1, mAdapter.requests.size());
-
- TestCallLogAdapter.Request request = mAdapter.requests.get(0);
- // It is for the number we need to show.
- assertEquals(TEST_NUMBER, request.number);
- // It has the right country.
- assertEquals(TEST_COUNTRY_ISO, request.countryIso);
- // Since there is nothing in the cache, it is an immediate request.
- assertTrue("should be immediate", request.immediate);
- }
-
- public void testBindView_CallLogCacheButNoMemoryCache_EnqueueRequest() {
- mCursor.addRow(createCallLogEntryWithCachedValues());
-
- // Bind the views of a single row.
- mAdapter.bindStandAloneView(mView, getContext(), mCursor);
-
- // There is one request for contact details.
- assertEquals(1, mAdapter.requests.size());
-
- TestCallLogAdapter.Request request = mAdapter.requests.get(0);
- // The values passed to the request, match the ones in the call log cache.
- assertEquals(TEST_NAME, request.callLogInfo.name);
- assertEquals(1, request.callLogInfo.type);
- assertEquals(TEST_NUMBER_LABEL, request.callLogInfo.label);
- }
-
-
- public void testBindView_NoCallLogButMemoryCache_EnqueueRequest() {
- mCursor.addRow(createCallLogEntry());
- mAdapter.injectContactInfoForTest(TEST_NUMBER, TEST_COUNTRY_ISO, createContactInfo());
-
- // Bind the views of a single row.
- mAdapter.bindStandAloneView(mView, getContext(), mCursor);
-
- // There is one request for contact details.
- assertEquals(1, mAdapter.requests.size());
-
- TestCallLogAdapter.Request request = mAdapter.requests.get(0);
- // Since there is something in the cache, it is not an immediate request.
- assertFalse("should not be immediate", request.immediate);
- }
-
- public void testBindView_BothCallLogAndMemoryCache_NoEnqueueRequest() {
- mCursor.addRow(createCallLogEntryWithCachedValues());
- mAdapter.injectContactInfoForTest(TEST_NUMBER, TEST_COUNTRY_ISO, createContactInfo());
-
- // Bind the views of a single row.
- mAdapter.bindStandAloneView(mView, getContext(), mCursor);
-
- // Cache and call log are up-to-date: no need to request update.
- assertEquals(0, mAdapter.requests.size());
- }
-
- public void testBindView_MismatchBetwenCallLogAndMemoryCache_EnqueueRequest() {
- mCursor.addRow(createCallLogEntryWithCachedValues());
-
- // Contact info contains a different name.
- ContactInfo info = createContactInfo();
- info.name = "new name";
- mAdapter.injectContactInfoForTest(TEST_NUMBER, TEST_COUNTRY_ISO, info);
-
- // Bind the views of a single row.
- mAdapter.bindStandAloneView(mView, getContext(), mCursor);
-
- // There is one request for contact details.
- assertEquals(1, mAdapter.requests.size());
-
- TestCallLogAdapter.Request request = mAdapter.requests.get(0);
- // Since there is something in the cache, it is not an immediate request.
- assertFalse("should not be immediate", request.immediate);
- }
-
- /** Returns a contact info with default values. */
- private ContactInfo createContactInfo() {
- ContactInfo info = new ContactInfo();
- info.number = TEST_NUMBER;
- info.name = TEST_NAME;
- info.type = TEST_NUMBER_TYPE;
- info.label = TEST_NUMBER_LABEL;
- return info;
- }
-
- /** Returns a call log entry without cached values. */
- private Object[] createCallLogEntry() {
- Object[] values = CallLogQueryTestUtils.createTestExtendedValues();
- values[CallLogQuery.NUMBER] = TEST_NUMBER;
- values[CallLogQuery.COUNTRY_ISO] = TEST_COUNTRY_ISO;
- return values;
- }
-
- /** Returns a call log entry with a cached values. */
- private Object[] createCallLogEntryWithCachedValues() {
- Object[] values = createCallLogEntry();
- values[CallLogQuery.CACHED_NAME] = TEST_NAME;
- values[CallLogQuery.CACHED_NUMBER_TYPE] = TEST_NUMBER_TYPE;
- values[CallLogQuery.CACHED_NUMBER_LABEL] = TEST_NUMBER_LABEL;
- return values;
- }
-
- /**
- * Subclass of {@link CallLogAdapter} used in tests to intercept certain calls.
- */
- // TODO: This would be better done by splitting the contact lookup into a collaborator class
- // instead.
- private static final class TestCallLogAdapter extends CallLogAdapter {
- public static class Request {
- public final String number;
- public final String countryIso;
- public final ContactInfo callLogInfo;
- public final boolean immediate;
-
- public Request(String number, String countryIso, ContactInfo callLogInfo,
- boolean immediate) {
- this.number = number;
- this.countryIso = countryIso;
- this.callLogInfo = callLogInfo;
- this.immediate = immediate;
- }
- }
-
- public final List<Request> requests = Lists.newArrayList();
-
- public TestCallLogAdapter(Context context, CallFetcher callFetcher,
- ContactInfoHelper contactInfoHelper) {
- super(context, callFetcher, contactInfoHelper);
- }
-
- @Override
- void enqueueRequest(String number, String countryIso, ContactInfo callLogInfo,
- boolean immediate) {
- requests.add(new Request(number, countryIso, callLogInfo, immediate));
- }
- }
-}
diff --git a/tests/src/com/android/contacts/calllog/CallLogFragmentTest.java b/tests/src/com/android/contacts/calllog/CallLogFragmentTest.java
deleted file mode 100644
index 0eaca60..0000000
--- a/tests/src/com/android/contacts/calllog/CallLogFragmentTest.java
+++ /dev/null
@@ -1,632 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
-import android.content.ComponentName;
-import android.content.ContentUris;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.database.MatrixCursor;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.net.Uri;
-import android.provider.CallLog.Calls;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.VoicemailContract;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.TelephonyManager;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-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;
-import java.util.Random;
-
-/**
- * Tests for the contact call list activity.
- *
- * Running all tests:
- *
- * runtest contacts
- * or
- * adb shell am instrument \
- * -w com.android.contacts.tests/android.test.InstrumentationTestRunner
- */
-@LargeTest
-public class CallLogFragmentTest extends ActivityInstrumentationTestCase2<FragmentTestActivity> {
- private static final int RAND_DURATION = -1;
- private static final long NOW = -1L;
-
- /** A test value for the URI of a contact. */
- private static final Uri TEST_LOOKUP_URI = Uri.parse("content://contacts/2");
- /** A test value for the country ISO of the phone number in the call log. */
- private static final String TEST_COUNTRY_ISO = "US";
- /** A phone number to be used in tests. */
- private static final String TEST_NUMBER = "12125551000";
- /** The formatted version of {@link #TEST_NUMBER}. */
- private static final String TEST_FORMATTED_NUMBER = "1 212-555-1000";
-
- /** The activity in which we are hosting the fragment. */
- private FragmentTestActivity mActivity;
- private CallLogFragment mFragment;
- private FrameLayout mParentView;
- /**
- * The adapter used by the fragment to build the rows in the call log. We use it with our own in
- * memory database.
- */
- private CallLogAdapter mAdapter;
- private String mVoicemail;
-
- // In memory array to hold the rows corresponding to the 'calls' table.
- private MatrixCursor mCursor;
- private int mIndex; // Of the next row.
-
- private Random mRnd;
-
- // References to the icons bitmaps used to build the list are stored in a
- // map mIcons. The keys to retrieve the icons are:
- // Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE and Calls.MISSED_TYPE.
- private HashMap<Integer, Bitmap> mCallTypeIcons;
-
- // An item in the call list. All the methods performing checks use it.
- private CallLogListItemViews mItem;
- // The list of views representing the data in the DB. View are in
- // reverse order compare to the DB.
- private View[] mList;
-
- public CallLogFragmentTest() {
- super("com.android.contacts", FragmentTestActivity.class);
- mIndex = 1;
- mRnd = new Random();
- }
-
- @Override
- public void setUp() {
- mActivity = getActivity();
- // Needed by the CallLogFragment.
- mActivity.setTheme(R.style.DialtactsTheme);
-
- // Create the fragment and load it into the activity.
- mFragment = new CallLogFragment();
- FragmentManager fragmentManager = mActivity.getFragmentManager();
- FragmentTransaction transaction = fragmentManager.beginTransaction();
- transaction.add(R.id.fragment, mFragment);
- transaction.commit();
- // Wait for the fragment to be loaded.
- getInstrumentation().waitForIdleSync();
-
- mVoicemail = TelephonyManager.getDefault().getVoiceMailNumber();
- mAdapter = mFragment.getAdapter();
- // Do not process requests for details during tests. This would start a background thread,
- // which makes the tests flaky.
- mAdapter.disableRequestProcessingForTest();
- mAdapter.stopRequestProcessing();
- mParentView = new FrameLayout(mActivity);
- mCursor = new MatrixCursor(CallLogQuery.EXTENDED_PROJECTION);
- buildIconMap();
- }
-
- /**
- * Checks that the call icon is not visible for private and
- * unknown numbers.
- * Use 2 passes, one where new views are created and one where
- * half of the total views are updated and the other half created.
- */
- @MediumTest
- public void testCallViewIsNotVisibleForPrivateAndUnknownNumbers() {
- final int SIZE = 100;
- mList = new View[SIZE];
-
- // Insert the first batch of entries.
- mCursor.moveToFirst();
- insertRandomEntries(SIZE / 2);
- int startOfSecondBatch = mCursor.getPosition();
-
- buildViewListFromDb();
- checkCallStatus();
-
- // Append the rest of the entries. We keep the first set of
- // views around so they get updated and not built from
- // scratch, this exposes some bugs that are not there when the
- // call log is launched for the 1st time but show up when the
- // call log gets updated afterwards.
- mCursor.move(startOfSecondBatch);
- insertRandomEntries(SIZE / 2);
-
- buildViewListFromDb();
- checkCallStatus();
- }
-
- @MediumTest
- public void testCallAndGroupViews_GroupView() {
- mCursor.moveToFirst();
- insert(CallerInfo.PRIVATE_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
- insert(CallerInfo.PRIVATE_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
- insert(CallerInfo.PRIVATE_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
- View view = mAdapter.newGroupView(getActivity(), mParentView);
- mAdapter.bindGroupView(view, getActivity(), mCursor, 3, false);
- assertNotNull(view.findViewById(R.id.secondary_action_icon));
- }
-
- @MediumTest
- public void testCallAndGroupViews_StandAloneView() {
- mCursor.moveToFirst();
- insert(CallerInfo.PRIVATE_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
- View view = mAdapter.newStandAloneView(getActivity(), mParentView);
- mAdapter.bindStandAloneView(view, getActivity(), mCursor);
- assertNotNull(view.findViewById(R.id.secondary_action_icon));
- }
-
- @MediumTest
- public void testCallAndGroupViews_ChildView() {
- mCursor.moveToFirst();
- insert(CallerInfo.PRIVATE_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
- View view = mAdapter.newChildView(getActivity(), mParentView);
- mAdapter.bindChildView(view, getActivity(), mCursor);
- assertNotNull(view.findViewById(R.id.secondary_action_icon));
- }
-
- @MediumTest
- public void testBindView_NumberOnlyNoCache() {
- mCursor.moveToFirst();
- insert(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
- View view = mAdapter.newStandAloneView(getActivity(), mParentView);
- mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
- CallLogListItemViews views = (CallLogListItemViews) view.getTag();
- assertNameIs(views, TEST_NUMBER);
- }
-
- @MediumTest
- public void testBindView_NumberOnlyDbCachedFormattedNumber() {
- mCursor.moveToFirst();
- Object[] values = getValuesToInsert(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
- values[CallLogQuery.CACHED_FORMATTED_NUMBER] = TEST_FORMATTED_NUMBER;
- insertValues(values);
- View view = mAdapter.newStandAloneView(getActivity(), mParentView);
- mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
- CallLogListItemViews views = (CallLogListItemViews) view.getTag();
- assertNameIs(views, TEST_FORMATTED_NUMBER);
- }
-
- @MediumTest
- public void testBindView_WithCachedName() {
- mCursor.moveToFirst();
- insertWithCachedValues(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE,
- "John Doe", Phone.TYPE_HOME, "");
- View view = mAdapter.newStandAloneView(getActivity(), mParentView);
- mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
- CallLogListItemViews views = (CallLogListItemViews) view.getTag();
- assertNameIs(views, "John Doe");
- assertNumberAndLabelAre(views, TEST_FORMATTED_NUMBER, getTypeLabel(Phone.TYPE_HOME));
- }
-
- @MediumTest
- public void testBindView_UriNumber() {
- mCursor.moveToFirst();
- insertWithCachedValues("sip:johndoe@gmail.com", NOW, 0, Calls.INCOMING_TYPE,
- "John Doe", Phone.TYPE_HOME, "");
- View view = mAdapter.newStandAloneView(getActivity(), mParentView);
- mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
- CallLogListItemViews views = (CallLogListItemViews) view.getTag();
- assertNameIs(views, "John Doe");
- assertNumberAndLabelAre(views, "sip:johndoe@gmail.com", null);
- }
-
- @MediumTest
- public void testBindView_HomeLabel() {
- mCursor.moveToFirst();
- insertWithCachedValues(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE,
- "John Doe", Phone.TYPE_HOME, "");
- View view = mAdapter.newStandAloneView(getActivity(), mParentView);
- mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
- CallLogListItemViews views = (CallLogListItemViews) view.getTag();
- assertNameIs(views, "John Doe");
- assertNumberAndLabelAre(views, TEST_FORMATTED_NUMBER, getTypeLabel(Phone.TYPE_HOME));
- }
-
- @MediumTest
- public void testBindView_WorkLabel() {
- mCursor.moveToFirst();
- insertWithCachedValues(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE,
- "John Doe", Phone.TYPE_WORK, "");
- View view = mAdapter.newStandAloneView(getActivity(), mParentView);
- mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
- CallLogListItemViews views = (CallLogListItemViews) view.getTag();
- assertNameIs(views, "John Doe");
- assertNumberAndLabelAre(views, TEST_FORMATTED_NUMBER, getTypeLabel(Phone.TYPE_WORK));
- }
-
- @MediumTest
- public void testBindView_CustomLabel() {
- mCursor.moveToFirst();
- String numberLabel = "My label";
- insertWithCachedValues(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE,
- "John Doe", Phone.TYPE_CUSTOM, numberLabel);
- View view = mAdapter.newStandAloneView(getActivity(), mParentView);
- mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
- CallLogListItemViews views = (CallLogListItemViews) view.getTag();
- assertNameIs(views, "John Doe");
- assertNumberAndLabelAre(views, TEST_FORMATTED_NUMBER, numberLabel);
- }
-
- @MediumTest
- public void testBindView_WithQuickContactBadge() {
- mCursor.moveToFirst();
- insertWithCachedValues(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE,
- "John Doe", Phone.TYPE_HOME, "");
- View view = mAdapter.newStandAloneView(getActivity(), mParentView);
- mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
- CallLogListItemViews views = (CallLogListItemViews) view.getTag();
- assertTrue(views.quickContactView.isEnabled());
- }
-
- @MediumTest
- public void testBindView_WithoutQuickContactBadge() {
- mCursor.moveToFirst();
- insert(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
- View view = mAdapter.newStandAloneView(getActivity(), mParentView);
- mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
- CallLogListItemViews views = (CallLogListItemViews) view.getTag();
- assertFalse(views.quickContactView.isEnabled());
- }
-
- @MediumTest
- public void testBindView_CallButton() {
- mCursor.moveToFirst();
- insert(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
- View view = mAdapter.newStandAloneView(getActivity(), mParentView);
- mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
- CallLogListItemViews views = (CallLogListItemViews) view.getTag();
- IntentProvider intentProvider = (IntentProvider) views.secondaryActionView.getTag();
- Intent intent = intentProvider.getIntent(mActivity);
- // Starts a call.
- assertEquals(Intent.ACTION_CALL_PRIVILEGED, intent.getAction());
- // To the entry's number.
- assertEquals(Uri.parse("tel:" + TEST_NUMBER), intent.getData());
- }
-
- @MediumTest
- public void testBindView_PlayButton() {
- mCursor.moveToFirst();
- insertVoicemail(TEST_NUMBER, NOW, 0);
- View view = mAdapter.newStandAloneView(getActivity(), mParentView);
- mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
- CallLogListItemViews views = (CallLogListItemViews) view.getTag();
- IntentProvider intentProvider = (IntentProvider) views.secondaryActionView.getTag();
- Intent intent = intentProvider.getIntent(mActivity);
- // Starts the call detail activity.
- assertEquals(new ComponentName(mActivity, CallDetailActivity.class),
- intent.getComponent());
- // With the given entry.
- assertEquals(ContentUris.withAppendedId(Calls.CONTENT_URI_WITH_VOICEMAIL, 1),
- intent.getData());
- // With the URI of the voicemail.
- assertEquals(
- ContentUris.withAppendedId(VoicemailContract.Voicemails.CONTENT_URI, 1),
- intent.getParcelableExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI));
- // And starts playback.
- assertTrue(
- intent.getBooleanExtra(CallDetailActivity.EXTRA_VOICEMAIL_START_PLAYBACK, false));
- }
-
- /** Returns the label associated with a given phone type. */
- private CharSequence getTypeLabel(int phoneType) {
- return Phone.getTypeLabel(getActivity().getResources(), phoneType, "");
- }
-
- //
- // HELPERS to check conditions on the DB/views
- //
- /**
- * Go over all the views in the list and check that the Call
- * icon's visibility matches the nature of the number.
- */
- private void checkCallStatus() {
- for (int i = 0; i < mList.length; i++) {
- if (null == mList[i]) {
- break;
- }
- mItem = (CallLogListItemViews) mList[i].getTag();
- String number = getPhoneNumberForListEntry(i);
- if (CallerInfo.PRIVATE_NUMBER.equals(number) ||
- CallerInfo.UNKNOWN_NUMBER.equals(number)) {
- assertFalse(View.VISIBLE == mItem.secondaryActionView.getVisibility());
- } else {
- assertEquals(View.VISIBLE, mItem.secondaryActionView.getVisibility());
- }
- }
- }
-
-
- //
- // HELPERS to setup the tests.
- //
-
- /**
- * Get the Bitmap from the icons in the contacts package.
- */
- private Bitmap getBitmap(String resName) {
- Resources r = mActivity.getResources();
- int resid = r.getIdentifier(resName, "drawable", "com.android.contacts");
- BitmapDrawable d = (BitmapDrawable) r.getDrawable(resid);
- assertNotNull(d);
- return d.getBitmap();
- }
-
- /**
- * Fetch all the icons we need in tests from the contacts app and store them in a map.
- */
- private void buildIconMap() {
- mCallTypeIcons = new HashMap<Integer, Bitmap>(3);
-
- mCallTypeIcons.put(Calls.INCOMING_TYPE, getBitmap("ic_call_incoming_holo_dark"));
- mCallTypeIcons.put(Calls.MISSED_TYPE, getBitmap("ic_call_missed_holo_dark"));
- mCallTypeIcons.put(Calls.OUTGOING_TYPE, getBitmap("ic_call_outgoing_holo_dark"));
- }
-
- //
- // HELPERS to build/update the call entries (views) from the DB.
- //
-
- /**
- * Read the DB and foreach call either update the existing view if
- * one exists already otherwise create one.
- * The list is build from a DESC view of the DB (last inserted entry is first).
- */
- private void buildViewListFromDb() {
- int i = 0;
- mCursor.moveToLast();
- while(!mCursor.isBeforeFirst()) {
- if (null == mList[i]) {
- mList[i] = mAdapter.newStandAloneView(mActivity, mParentView);
- }
- mAdapter.bindStandAloneView(mList[i], mActivity, mCursor);
- mCursor.moveToPrevious();
- i++;
- }
- }
-
- /** Returns the number associated with the given entry in {{@link #mList}. */
- private String getPhoneNumberForListEntry(int index) {
- // The entries are added backward, so count from the end of the cursor.
- mCursor.moveToPosition(mCursor.getCount() - index - 1);
- return mCursor.getString(CallLogQuery.NUMBER);
- }
-
- //
- // HELPERS to insert numbers in the call log DB.
- //
-
- /**
- * Insert a certain number of random numbers in the DB. Makes sure
- * there is at least one private and one unknown number in the DB.
- * @param num Of entries to be inserted.
- */
- private void insertRandomEntries(int num) {
- if (num < 10) {
- throw new IllegalArgumentException("num should be >= 10");
- }
- boolean privateOrUnknownOrVm[];
- privateOrUnknownOrVm = insertRandomRange(0, num - 2);
-
- if (privateOrUnknownOrVm[0] && privateOrUnknownOrVm[1]) {
- insertRandomRange(num - 2, num);
- } else {
- insertPrivate(NOW, RAND_DURATION);
- insertUnknown(NOW, RAND_DURATION);
- }
- }
-
- /**
- * Insert a new call entry in the test DB.
- *
- * It includes the values for the cached contact associated with the number.
- *
- * @param number The phone number. For unknown and private numbers,
- * use CallerInfo.UNKNOWN_NUMBER or CallerInfo.PRIVATE_NUMBER.
- * @param date In millisec since epoch. Use NOW to use the current time.
- * @param duration In seconds of the call. Use RAND_DURATION to pick a random one.
- * @param type Either Call.OUTGOING_TYPE or Call.INCOMING_TYPE or Call.MISSED_TYPE.
- * @param cachedName the name of the contact with this number
- * @param cachedNumberType the type of the number, from the contact with this number
- * @param cachedNumberLabel the label of the number, from the contact with this number
- */
- private void insertWithCachedValues(String number, long date, int duration, int type,
- String cachedName, int cachedNumberType, String cachedNumberLabel) {
- insert(number, date, duration, type);
- ContactInfo contactInfo = new ContactInfo();
- contactInfo.lookupUri = TEST_LOOKUP_URI;
- contactInfo.name = cachedName;
- contactInfo.type = cachedNumberType;
- contactInfo.label = cachedNumberLabel;
- String formattedNumber = PhoneNumberUtils.formatNumber(number, TEST_COUNTRY_ISO);
- if (formattedNumber == null) {
- formattedNumber = number;
- }
- contactInfo.formattedNumber = formattedNumber;
- contactInfo.normalizedNumber = number;
- contactInfo.photoId = 0;
- mAdapter.injectContactInfoForTest(number, TEST_COUNTRY_ISO, contactInfo);
- }
-
- /**
- * Insert a new call entry in the test DB.
- * @param number The phone number. For unknown and private numbers,
- * use CallerInfo.UNKNOWN_NUMBER or CallerInfo.PRIVATE_NUMBER.
- * @param date In millisec since epoch. Use NOW to use the current time.
- * @param duration In seconds of the call. Use RAND_DURATION to pick a random one.
- * @param type Either Call.OUTGOING_TYPE or Call.INCOMING_TYPE or Call.MISSED_TYPE.
- */
- private void insert(String number, long date, int duration, int type) {
- insertValues(getValuesToInsert(number, date, duration, type));
- }
-
- /** Inserts the given values in the cursor. */
- private void insertValues(Object[] values) {
- mCursor.addRow(values);
- ++mIndex;
- }
-
- /**
- * Returns the values for a new call entry.
- *
- * @param number The phone number. For unknown and private numbers,
- * use CallerInfo.UNKNOWN_NUMBER or CallerInfo.PRIVATE_NUMBER.
- * @param date In millisec since epoch. Use NOW to use the current time.
- * @param duration In seconds of the call. Use RAND_DURATION to pick a random one.
- * @param type Either Call.OUTGOING_TYPE or Call.INCOMING_TYPE or Call.MISSED_TYPE.
- */
- private Object[] getValuesToInsert(String number, long date, int duration, int type) {
- Object[] values = CallLogQueryTestUtils.createTestExtendedValues();
- values[CallLogQuery.ID] = mIndex;
- values[CallLogQuery.NUMBER] = number;
- values[CallLogQuery.DATE] = date == NOW ? new Date().getTime() : date;
- values[CallLogQuery.DURATION] = duration < 0 ? mRnd.nextInt(10 * 60) : duration;
- if (mVoicemail != null && mVoicemail.equals(number)) {
- assertEquals(Calls.OUTGOING_TYPE, type);
- }
- values[CallLogQuery.CALL_TYPE] = type;
- values[CallLogQuery.COUNTRY_ISO] = TEST_COUNTRY_ISO;
- values[CallLogQuery.SECTION] = CallLogQuery.SECTION_OLD_ITEM;
- return values;
- }
-
- /**
- * Insert a new voicemail entry in the test DB.
- * @param number The phone number. For unknown and private numbers,
- * use CallerInfo.UNKNOWN_NUMBER or CallerInfo.PRIVATE_NUMBER.
- * @param date In millisec since epoch. Use NOW to use the current time.
- * @param duration In seconds of the call. Use RAND_DURATION to pick a random one.
- */
- private void insertVoicemail(String number, long date, int duration) {
- Object[] values = getValuesToInsert(number, date, duration, Calls.VOICEMAIL_TYPE);
- // Must have the same index as the row.
- values[CallLogQuery.VOICEMAIL_URI] =
- ContentUris.withAppendedId(VoicemailContract.Voicemails.CONTENT_URI, mIndex);
- insertValues(values);
- }
-
- /**
- * Insert a new private call entry in the test DB.
- * @param date In millisec since epoch. Use NOW to use the current time.
- * @param duration In seconds of the call. Use RAND_DURATION to pick a random one.
- */
- private void insertPrivate(long date, int duration) {
- insert(CallerInfo.PRIVATE_NUMBER, date, duration, Calls.INCOMING_TYPE);
- }
-
- /**
- * Insert a new unknown call entry in the test DB.
- * @param date In millisec since epoch. Use NOW to use the current time.
- * @param duration In seconds of the call. Use RAND_DURATION to pick a random one.
- */
- private void insertUnknown(long date, int duration) {
- insert(CallerInfo.UNKNOWN_NUMBER, date, duration, Calls.INCOMING_TYPE);
- }
-
- /**
- * Insert a new call to voicemail entry in the test DB.
- * @param date In millisec since epoch. Use NOW to use the current time.
- * @param duration In seconds of the call. Use RAND_DURATION to pick a random one.
- */
- private void insertCalltoVoicemail(long date, int duration) {
- // mVoicemail may be null
- if (mVoicemail != null) {
- insert(mVoicemail, date, duration, Calls.OUTGOING_TYPE);
- }
- }
-
- /**
- * Insert a range [start, end) of random numbers in the DB. For
- * each row, there is a 1/10 probability that the number will be
- * marked as PRIVATE or UNKNOWN or VOICEMAIL. For regular numbers, a number is
- * inserted, its last 4 digits will be the number of the iteration
- * in the range.
- * @param start Of the range.
- * @param end Of the range (excluded).
- * @return An array with 2 booleans [0 = private number, 1 =
- * unknown number, 2 = voicemail] to indicate if at least one
- * private or unknown or voicemail number has been inserted. Since
- * the numbers are random some tests may want to enforce the
- * insertion of such numbers.
- */
- // TODO: Should insert numbers with contact entries too.
- private boolean[] insertRandomRange(int start, int end) {
- boolean[] privateOrUnknownOrVm = new boolean[] {false, false, false};
-
- for (int i = start; i < end; i++ ) {
- int type = mRnd.nextInt(10);
-
- if (0 == type) {
- insertPrivate(NOW, RAND_DURATION);
- privateOrUnknownOrVm[0] = true;
- } else if (1 == type) {
- insertUnknown(NOW, RAND_DURATION);
- privateOrUnknownOrVm[1] = true;
- } else if (2 == type) {
- insertCalltoVoicemail(NOW, RAND_DURATION);
- privateOrUnknownOrVm[2] = true;
- } else {
- int inout = mRnd.nextBoolean() ? Calls.OUTGOING_TYPE : Calls.INCOMING_TYPE;
- String number = new Formatter().format("1800123%04d", i).toString();
- insert(number, NOW, RAND_DURATION, inout);
- }
- }
- return privateOrUnknownOrVm;
- }
-
- /** Asserts that the name text view is shown and contains the given text. */
- private void assertNameIs(CallLogListItemViews views, String name) {
- assertEquals(View.VISIBLE, views.phoneCallDetailsViews.nameView.getVisibility());
- assertEquals(name, views.phoneCallDetailsViews.nameView.getText());
- }
-
- /** Asserts that the number and label text view contains the given text. */
- private void assertNumberAndLabelAre(CallLogListItemViews views, CharSequence number,
- CharSequence label) {
- assertEquals(View.VISIBLE, views.phoneCallDetailsViews.numberView.getVisibility());
- assertEquals(number, views.phoneCallDetailsViews.numberView.getText().toString());
-
- assertEquals(label == null ? View.GONE : View.VISIBLE,
- views.phoneCallDetailsViews.labelView.getVisibility());
- if (label != null) {
- assertEquals(label, views.phoneCallDetailsViews.labelView.getText().toString());
- }
- }
-}
diff --git a/tests/src/com/android/contacts/calllog/CallLogGroupBuilderTest.java b/tests/src/com/android/contacts/calllog/CallLogGroupBuilderTest.java
deleted file mode 100644
index 1fced0b..0000000
--- a/tests/src/com/android/contacts/calllog/CallLogGroupBuilderTest.java
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-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";
- /** A phone number for testing. */
- private static final String TEST_NUMBER2 = "14125555555";
-
- /** The object under test. */
- private CallLogGroupBuilder mBuilder;
- /** Records the created groups. */
- private FakeGroupCreator mFakeGroupCreator;
- /** Cursor to store the values. */
- private MatrixCursor mCursor;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mFakeGroupCreator = new FakeGroupCreator();
- mBuilder = new CallLogGroupBuilder(mFakeGroupCreator);
- createCursor();
- }
-
- @Override
- protected void tearDown() throws Exception {
- mCursor = null;
- mBuilder = null;
- mFakeGroupCreator = null;
- super.tearDown();
- }
-
- public void testAddGroups_NoCalls() {
- mBuilder.addGroups(mCursor);
- assertEquals(0, mFakeGroupCreator.groups.size());
- }
-
- public void testAddGroups_OneCall() {
- addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
- mBuilder.addGroups(mCursor);
- assertEquals(0, mFakeGroupCreator.groups.size());
- }
-
- public void testAddGroups_TwoCallsNotMatching() {
- addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
- addOldCallLogEntry(TEST_NUMBER2, Calls.INCOMING_TYPE);
- mBuilder.addGroups(mCursor);
- assertEquals(0, mFakeGroupCreator.groups.size());
- }
-
- public void testAddGroups_ThreeCallsMatching() {
- addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
- addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
- addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
- mBuilder.addGroups(mCursor);
- assertEquals(1, mFakeGroupCreator.groups.size());
- assertGroupIs(0, 3, false, mFakeGroupCreator.groups.get(0));
- }
-
- public void testAddGroups_MatchingIncomingAndOutgoing() {
- addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
- addOldCallLogEntry(TEST_NUMBER1, Calls.OUTGOING_TYPE);
- addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
- mBuilder.addGroups(mCursor);
- assertEquals(1, mFakeGroupCreator.groups.size());
- assertGroupIs(0, 3, false, mFakeGroupCreator.groups.get(0));
- }
-
- public void testAddGroups_HeaderSplitsGroups() {
- addNewCallLogHeader();
- addNewCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
- addNewCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
- addOldCallLogHeader();
- addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
- addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
- mBuilder.addGroups(mCursor);
- assertEquals(2, mFakeGroupCreator.groups.size());
- assertGroupIs(1, 2, false, mFakeGroupCreator.groups.get(0));
- assertGroupIs(4, 2, false, mFakeGroupCreator.groups.get(1));
- }
-
- public void testAddGroups_Voicemail() {
- // 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);
- }
-
- public void testAddGroups_Missed() {
- // Groups with one or more missed calls.
- assertCallsAreGrouped(Calls.MISSED_TYPE, Calls.MISSED_TYPE);
- 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);
- assertCallsAreGrouped(Calls.MISSED_TYPE, Calls.INCOMING_TYPE);
- assertCallsAreGrouped(Calls.MISSED_TYPE, Calls.OUTGOING_TYPE);
- }
-
- public void testAddGroups_Incoming() {
- // Groups with one or more incoming or outgoing.
- assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.INCOMING_TYPE);
- 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);
- }
-
- public void testAddGroups_Outgoing() {
- // Groups with one or more incoming or outgoing.
- assertCallsAreGrouped(Calls.OUTGOING_TYPE, Calls.INCOMING_TYPE);
- 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);
- }
-
- public void testAddGroups_Mixed() {
- addMultipleOldCallLogEntries(TEST_NUMBER1,
- Calls.VOICEMAIL_TYPE, // Stand-alone
- Calls.INCOMING_TYPE, // Group 1: 1-4
- Calls.OUTGOING_TYPE,
- Calls.MISSED_TYPE,
- Calls.MISSED_TYPE,
- Calls.VOICEMAIL_TYPE, // Stand-alone
- Calls.INCOMING_TYPE, // Stand-alone
- Calls.VOICEMAIL_TYPE, // Stand-alone
- Calls.MISSED_TYPE, // Group 2: 8-10
- Calls.MISSED_TYPE,
- Calls.OUTGOING_TYPE);
- mBuilder.addGroups(mCursor);
- assertEquals(2, mFakeGroupCreator.groups.size());
- assertGroupIs(1, 4, false, mFakeGroupCreator.groups.get(0));
- assertGroupIs(8, 3, false, mFakeGroupCreator.groups.get(1));
- }
-
- public void testEqualPhoneNumbers() {
- // Identical.
- assertTrue(mBuilder.equalNumbers("6505555555", "6505555555"));
- assertTrue(mBuilder.equalNumbers("650 555 5555", "650 555 5555"));
- // Formatting.
- assertTrue(mBuilder.equalNumbers("6505555555", "650 555 5555"));
- assertTrue(mBuilder.equalNumbers("6505555555", "(650) 555-5555"));
- assertTrue(mBuilder.equalNumbers("650 555 5555", "(650) 555-5555"));
- // Short codes.
- assertTrue(mBuilder.equalNumbers("55555", "55555"));
- assertTrue(mBuilder.equalNumbers("55555", "555 55"));
- // Different numbers.
- assertFalse(mBuilder.equalNumbers("6505555555", "650555555"));
- assertFalse(mBuilder.equalNumbers("6505555555", "6505555551"));
- assertFalse(mBuilder.equalNumbers("650 555 5555", "650 555 555"));
- assertFalse(mBuilder.equalNumbers("650 555 5555", "650 555 5551"));
- assertFalse(mBuilder.equalNumbers("55555", "5555"));
- assertFalse(mBuilder.equalNumbers("55555", "55551"));
- // SIP addresses.
- assertTrue(mBuilder.equalNumbers("6505555555@host.com", "6505555555@host.com"));
- assertTrue(mBuilder.equalNumbers("6505555555@host.com", "6505555555@HOST.COM"));
- assertTrue(mBuilder.equalNumbers("user@host.com", "user@host.com"));
- assertTrue(mBuilder.equalNumbers("user@host.com", "user@HOST.COM"));
- assertFalse(mBuilder.equalNumbers("USER@host.com", "user@host.com"));
- assertFalse(mBuilder.equalNumbers("user@host.com", "user@host1.com"));
- // SIP address vs phone number.
- assertFalse(mBuilder.equalNumbers("6505555555@host.com", "6505555555"));
- assertFalse(mBuilder.equalNumbers("6505555555", "6505555555@host.com"));
- assertFalse(mBuilder.equalNumbers("user@host.com", "6505555555"));
- assertFalse(mBuilder.equalNumbers("6505555555", "user@host.com"));
- // Nulls.
- assertTrue(mBuilder.equalNumbers(null, null));
- assertFalse(mBuilder.equalNumbers(null, "6505555555"));
- assertFalse(mBuilder.equalNumbers("6505555555", null));
- assertFalse(mBuilder.equalNumbers(null, "6505555555@host.com"));
- assertFalse(mBuilder.equalNumbers("6505555555@host.com", null));
- }
-
- public void testCompareSipAddresses() {
- // Identical.
- assertTrue(mBuilder.compareSipAddresses("6505555555@host.com", "6505555555@host.com"));
- assertTrue(mBuilder.compareSipAddresses("user@host.com", "user@host.com"));
- // Host is case insensitive.
- assertTrue(mBuilder.compareSipAddresses("6505555555@host.com", "6505555555@HOST.COM"));
- assertTrue(mBuilder.compareSipAddresses("user@host.com", "user@HOST.COM"));
- // Userinfo is case sensitive.
- assertFalse(mBuilder.compareSipAddresses("USER@host.com", "user@host.com"));
- // Different hosts.
- assertFalse(mBuilder.compareSipAddresses("user@host.com", "user@host1.com"));
- // Different users.
- assertFalse(mBuilder.compareSipAddresses("user1@host.com", "user@host.com"));
- // Nulls.
- assertTrue(mBuilder.compareSipAddresses(null, null));
- assertFalse(mBuilder.compareSipAddresses(null, "6505555555@host.com"));
- assertFalse(mBuilder.compareSipAddresses("6505555555@host.com", null));
- }
-
- /** Creates (or recreates) the cursor used to store the call log content for the tests. */
- private void createCursor() {
- mCursor = new MatrixCursor(CallLogQuery.EXTENDED_PROJECTION);
- }
-
- /** Clears the content of the {@link FakeGroupCreator} used in the tests. */
- private void clearFakeGroupCreator() {
- mFakeGroupCreator.groups.clear();
- }
-
- /** Asserts that calls of the given types are grouped together into a single group. */
- private void assertCallsAreGrouped(int... types) {
- createCursor();
- clearFakeGroupCreator();
- addMultipleOldCallLogEntries(TEST_NUMBER1, types);
- mBuilder.addGroups(mCursor);
- assertEquals(1, mFakeGroupCreator.groups.size());
- assertGroupIs(0, types.length, false, mFakeGroupCreator.groups.get(0));
-
- }
-
- /** Asserts that calls of the given types are not grouped together at all. */
- private void assertCallsAreNotGrouped(int... types) {
- createCursor();
- clearFakeGroupCreator();
- addMultipleOldCallLogEntries(TEST_NUMBER1, types);
- mBuilder.addGroups(mCursor);
- assertEquals(0, mFakeGroupCreator.groups.size());
- }
-
- /** Adds a set of calls with the given types, all from the same number, in the old section. */
- private void addMultipleOldCallLogEntries(String number, int... types) {
- for (int type : types) {
- addOldCallLogEntry(number, type);
- }
- }
-
- /** Adds a call with the given number and type to the old section of the call log. */
- private void addOldCallLogEntry(String number, int type) {
- addCallLogEntry(number, type, CallLogQuery.SECTION_OLD_ITEM);
- }
-
- /** Adds a call with the given number and type to the new section of the call log. */
- private void addNewCallLogEntry(String number, int type) {
- addCallLogEntry(number, type, CallLogQuery.SECTION_NEW_ITEM);
- }
-
- /** Adds a call log entry with the given number and type to the cursor. */
- private void addCallLogEntry(String number, int type, int section) {
- if (section != CallLogQuery.SECTION_NEW_ITEM
- && section != CallLogQuery.SECTION_OLD_ITEM) {
- throw new IllegalArgumentException("not an item section: " + section);
- }
- mCursor.moveToNext();
- Object[] values = CallLogQueryTestUtils.createTestExtendedValues();
- values[CallLogQuery.ID] = mCursor.getPosition();
- values[CallLogQuery.NUMBER] = number;
- values[CallLogQuery.CALL_TYPE] = type;
- values[CallLogQuery.SECTION] = section;
- mCursor.addRow(values);
- }
-
- /** Adds the old section header to the call log. */
- private void addOldCallLogHeader() {
- addCallLogHeader(CallLogQuery.SECTION_OLD_HEADER);
- }
-
- /** Adds the new section header to the call log. */
- private void addNewCallLogHeader() {
- addCallLogHeader(CallLogQuery.SECTION_NEW_HEADER);
- }
-
- /** Adds a call log entry with a header to the cursor. */
- private void addCallLogHeader(int section) {
- if (section != CallLogQuery.SECTION_NEW_HEADER
- && section != CallLogQuery.SECTION_OLD_HEADER) {
- throw new IllegalArgumentException("not a header section: " + section);
- }
- mCursor.moveToNext();
- Object[] values = CallLogQueryTestUtils.createTestExtendedValues();
- values[CallLogQuery.ID] = mCursor.getPosition();
- values[CallLogQuery.SECTION] = section;
- mCursor.addRow(values);
- }
-
- /** Asserts that the group matches the given values. */
- private void assertGroupIs(int cursorPosition, int size, boolean expanded, GroupSpec group) {
- assertEquals(cursorPosition, group.cursorPosition);
- assertEquals(size, group.size);
- assertEquals(expanded, group.expanded);
- }
-
- /** Defines an added group. Used by the {@link FakeGroupCreator}. */
- private static class GroupSpec {
- /** The starting position of the group. */
- public final int cursorPosition;
- /** The number of elements in the group. */
- public final int size;
- /** Whether the group should be initially expanded. */
- public final boolean expanded;
-
- public GroupSpec(int cursorPosition, int size, boolean expanded) {
- this.cursorPosition = cursorPosition;
- this.size = size;
- this.expanded = expanded;
- }
- }
-
- /** Fake implementation of a GroupCreator which stores the created groups in a member field. */
- private static class FakeGroupCreator implements CallLogGroupBuilder.GroupCreator {
- /** The list of created groups. */
- public final List<GroupSpec> groups = newArrayList();
-
- @Override
- public void addGroup(int cursorPosition, int size, boolean expanded) {
- groups.add(new GroupSpec(cursorPosition, size, expanded));
- }
- }
-}
diff --git a/tests/src/com/android/contacts/calllog/CallLogListItemHelperTest.java b/tests/src/com/android/contacts/calllog/CallLogListItemHelperTest.java
deleted file mode 100644
index a184f75..0000000
--- a/tests/src/com/android/contacts/calllog/CallLogListItemHelperTest.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-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}.
- */
-public class CallLogListItemHelperTest extends AndroidTestCase {
- /** A test phone number for phone calls. */
- private static final String TEST_NUMBER = "14125555555";
- /** The formatted version of {@link #TEST_NUMBER}. */
- private static final String TEST_FORMATTED_NUMBER = "1-412-255-5555";
- /** A test date value for phone calls. */
- private static final long TEST_DATE = 1300000000;
- /** A test duration value for phone calls. */
- private static final long TEST_DURATION = 62300;
- /** A test voicemail number. */
- private static final String TEST_VOICEMAIL_NUMBER = "123";
- /** The country ISO name used in the tests. */
- private static final String TEST_COUNTRY_ISO = "US";
- /** The geocoded location used in the tests. */
- private static final String TEST_GEOCODE = "United States";
-
- /** The object under test. */
- private CallLogListItemHelper mHelper;
-
- /** The views used in the tests. */
- private CallLogListItemViews mViews;
- private PhoneNumberHelper mPhoneNumberHelper;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- Context context = getContext();
- Resources resources = context.getResources();
- CallTypeHelper callTypeHelper = new CallTypeHelper(resources);
- mPhoneNumberHelper = new TestPhoneNumberHelper(resources, TEST_VOICEMAIL_NUMBER);
- PhoneCallDetailsHelper phoneCallDetailsHelper = new PhoneCallDetailsHelper(
- resources, callTypeHelper, mPhoneNumberHelper);
- mHelper = new CallLogListItemHelper(phoneCallDetailsHelper, mPhoneNumberHelper, resources);
- mViews = CallLogListItemViews.createForTest(context);
- }
-
- @Override
- protected void tearDown() throws Exception {
- mHelper = null;
- mViews = null;
- super.tearDown();
- }
-
- public void testSetPhoneCallDetails() {
- setPhoneCallDetailsWithNumber("12125551234", "1-212-555-1234");
- assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
- }
-
- public void testSetPhoneCallDetails_Unknown() {
- setPhoneCallDetailsWithNumber(CallerInfo.UNKNOWN_NUMBER, CallerInfo.UNKNOWN_NUMBER);
- assertNoCallButton();
- }
-
- public void testSetPhoneCallDetails_Private() {
- setPhoneCallDetailsWithNumber(CallerInfo.PRIVATE_NUMBER, CallerInfo.PRIVATE_NUMBER);
- assertNoCallButton();
- }
-
- public void testSetPhoneCallDetails_Payphone() {
- setPhoneCallDetailsWithNumber(CallerInfo.PAYPHONE_NUMBER, CallerInfo.PAYPHONE_NUMBER);
- assertNoCallButton();
- }
-
- public void testSetPhoneCallDetails_VoicemailNumber() {
- setPhoneCallDetailsWithNumber(TEST_VOICEMAIL_NUMBER, TEST_VOICEMAIL_NUMBER);
- assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
- }
-
- public void testSetPhoneCallDetails_ReadVoicemail() {
- setPhoneCallDetailsWithTypes(Calls.VOICEMAIL_TYPE);
- assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
- }
-
- public void testSetPhoneCallDetails_UnreadVoicemail() {
- setUnreadPhoneCallDetailsWithTypes(Calls.VOICEMAIL_TYPE);
- assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
- }
-
- public void testSetPhoneCallDetails_VoicemailFromUnknown() {
- setPhoneCallDetailsWithNumberAndType(CallerInfo.UNKNOWN_NUMBER, CallerInfo.UNKNOWN_NUMBER,
- Calls.VOICEMAIL_TYPE);
- assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
- }
-
- /** Asserts that the whole call area is gone. */
- private void assertNoCallButton() {
- assertEquals(View.GONE, mViews.secondaryActionView.getVisibility());
- assertEquals(View.GONE, mViews.dividerView.getVisibility());
- }
-
- /** Sets the details of a phone call using the specified phone number. */
- private void setPhoneCallDetailsWithNumber(String number, String formattedNumber) {
- setPhoneCallDetailsWithNumberAndType(number, formattedNumber, Calls.INCOMING_TYPE);
- }
-
- /** Sets the details of a phone call using the specified phone number. */
- private void setPhoneCallDetailsWithNumberAndType(String number, String formattedNumber,
- int callType) {
- mHelper.setPhoneCallDetails(mViews,
- new PhoneCallDetails(number, formattedNumber, TEST_COUNTRY_ISO, TEST_GEOCODE,
- new int[]{ callType }, TEST_DATE, TEST_DURATION),
- false);
- }
-
- /** Sets the details of a phone call using the specified call type. */
- private void setPhoneCallDetailsWithTypes(int... types) {
- mHelper.setPhoneCallDetails(mViews,
- new PhoneCallDetails(TEST_NUMBER, TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO,
- TEST_GEOCODE, types, TEST_DATE, TEST_DURATION),
- false);
- }
-
- /** Sets the details of a phone call using the specified call type. */
- private void setUnreadPhoneCallDetailsWithTypes(int... types) {
- mHelper.setPhoneCallDetails(mViews,
- new PhoneCallDetails(TEST_NUMBER, TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO,
- TEST_GEOCODE, types, TEST_DATE, TEST_DURATION),
- true);
- }
-}
diff --git a/tests/src/com/android/contacts/calllog/CallLogQueryTestUtils.java b/tests/src/com/android/contacts/calllog/CallLogQueryTestUtils.java
deleted file mode 100644
index a88bf4f..0000000
--- a/tests/src/com/android/contacts/calllog/CallLogQueryTestUtils.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-import static junit.framework.Assert.assertEquals;
-
-import android.provider.CallLog.Calls;
-
-import junit.framework.Assert;
-
-/**
- * Helper class to create test values for {@link CallLogQuery}.
- */
-public class CallLogQueryTestUtils {
- public static Object[] createTestValues() {
- Object[] values = new Object[]{
- 0L, "", 0L, 0L, Calls.INCOMING_TYPE, "", "", "", null, 0, null, null, null, null,
- 0L, null, 0,
- };
- assertEquals(CallLogQuery._PROJECTION.length, values.length);
- return values;
- }
-
- public static Object[] createTestExtendedValues() {
- Object[] values = new Object[]{
- 0L, "", 0L, 0L, Calls.INCOMING_TYPE, "", "", "", null, 0, null, null, null, null,
- 0L, null, 1, CallLogQuery.SECTION_OLD_ITEM
- };
- Assert.assertEquals(CallLogQuery.EXTENDED_PROJECTION.length, values.length);
- return values;
- }
-}
diff --git a/tests/src/com/android/contacts/calllog/TestPhoneNumberHelper.java b/tests/src/com/android/contacts/calllog/TestPhoneNumberHelper.java
deleted file mode 100644
index 2bbd978..0000000
--- a/tests/src/com/android/contacts/calllog/TestPhoneNumberHelper.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.calllog;
-
-import android.content.res.Resources;
-
-/**
- * Modified version of {@link PhoneNumberHelper} to be used in tests that allows injecting the
- * voicemail number.
- */
-public final class TestPhoneNumberHelper extends PhoneNumberHelper {
- private CharSequence mVoicemailNumber;
-
- public TestPhoneNumberHelper(Resources resources, CharSequence voicemailNumber) {
- super(resources);
- mVoicemailNumber = voicemailNumber;
- }
-
- @Override
- public boolean isVoicemailNumber(CharSequence number) {
- return mVoicemailNumber.equals(number);
- }
-}
\ No newline at end of file
diff --git a/tests/src/com/android/contacts/detail/ContactDetailFragmentTests.java b/tests/src/com/android/contacts/detail/ContactDetailFragmentTests.java
index b1d1daa..0b86912 100644
--- a/tests/src/com/android/contacts/detail/ContactDetailFragmentTests.java
+++ b/tests/src/com/android/contacts/detail/ContactDetailFragmentTests.java
@@ -44,7 +44,7 @@
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);
+ ImDataItem im = (ImDataItem) DataItem.createFrom(values);
DetailViewEntry entry = new ContactDetailFragment.DetailViewEntry();
ContactDetailFragment.buildImActions(mContext, entry, im);
@@ -62,7 +62,7 @@
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);
+ ImDataItem im = (ImDataItem) DataItem.createFrom(values);
DetailViewEntry entry = new ContactDetailFragment.DetailViewEntry();
ContactDetailFragment.buildImActions(mContext, entry, im);
@@ -82,7 +82,7 @@
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);
+ ImDataItem im = (ImDataItem) DataItem.createFrom(values);
DetailViewEntry entry = new ContactDetailFragment.DetailViewEntry();
ContactDetailFragment.buildImActions(mContext, entry, im);
@@ -102,7 +102,7 @@
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);
+ ImDataItem im = (ImDataItem) DataItem.createFrom(values);
DetailViewEntry entry = new ContactDetailFragment.DetailViewEntry();
ContactDetailFragment.buildImActions(mContext, entry, im);
@@ -127,7 +127,7 @@
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));
+ (EmailDataItem) DataItem.createFrom(values));
DetailViewEntry entry = new ContactDetailFragment.DetailViewEntry();
ContactDetailFragment.buildImActions(mContext, entry, im);
diff --git a/tests/src/com/android/contacts/format/PrefixHighligherTest.java b/tests/src/com/android/contacts/format/PrefixHighligherTest.java
index 668330b..7f6e491 100644
--- a/tests/src/com/android/contacts/format/PrefixHighligherTest.java
+++ b/tests/src/com/android/contacts/format/PrefixHighligherTest.java
@@ -16,77 +16,70 @@
package com.android.contacts.format;
-import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
-import android.widget.TextView;
+
+import junit.framework.TestCase;
/**
* Unit tests for {@link PrefixHighlighter}.
*/
@SmallTest
-public class PrefixHighligherTest extends AndroidTestCase {
+public class PrefixHighligherTest extends TestCase {
private static final int TEST_PREFIX_HIGHLIGHT_COLOR = 0xFF0000;
- /** The HTML code used to mark the start of the highlighted part. */
- private static final String START = "<font color =\"#1ff0000\">";
- /** The HTML code used to mark the end of the highlighted part. */
- private static final String END = "</font>";
/** The object under test. */
private PrefixHighlighter mPrefixHighlighter;
- /** The view to on which the text is set. */
- private TextView mView;
@Override
protected void setUp() throws Exception {
super.setUp();
mPrefixHighlighter = new PrefixHighlighter(TEST_PREFIX_HIGHLIGHT_COLOR);
- mView = new TextView(getContext());
- // This guarantees that the text will be stored as a spannable so that we can determine
- // which styles have been applied to it.
- mView.setText("", TextView.BufferType.SPANNABLE);
}
- public void testSetText_EmptyPrefix() {
- mPrefixHighlighter.setText(mView, "", new char[0]);
- SpannedTestUtils.checkHtmlText("", mView);
+ public void testApply_EmptyPrefix() {
+ CharSequence seq = mPrefixHighlighter.apply("", new char[0]);
+ SpannedTestUtils.assertNotSpanned(seq, "");
- mPrefixHighlighter.setText(mView, "test", new char[0]);
- SpannedTestUtils.checkHtmlText("test", mView);
+ seq = mPrefixHighlighter.apply("test", new char[0]);
+ SpannedTestUtils.assertNotSpanned(seq, "test");
}
public void testSetText_MatchingPrefix() {
- mPrefixHighlighter.setText(mView, "test", "TE".toCharArray());
- SpannedTestUtils.checkHtmlText(START + "te" + END + "st", mView);
+ final char[] charArray = "TE".toCharArray();
- mPrefixHighlighter.setText(mView, "Test", "TE".toCharArray());
- SpannedTestUtils.checkHtmlText(START + "Te" + END + "st", mView);
+ CharSequence seq = mPrefixHighlighter.apply("test", charArray);
+ SpannedTestUtils.assertPrefixSpan(seq, 0, 1);
- mPrefixHighlighter.setText(mView, "TEst", "TE".toCharArray());
- SpannedTestUtils.checkHtmlText(START + "TE" + END + "st", mView);
+ seq = mPrefixHighlighter.apply("Test", charArray);
+ SpannedTestUtils.assertPrefixSpan(seq, 0, 1);
- mPrefixHighlighter.setText(mView, "a test", "TE".toCharArray());
- SpannedTestUtils.checkHtmlText("a " + START + "te" + END + "st", mView);
+ seq = mPrefixHighlighter.apply("TEst", charArray);
+ SpannedTestUtils.assertPrefixSpan(seq, 0, 1);
+
+ seq = mPrefixHighlighter.apply("a test", charArray);
+ SpannedTestUtils.assertPrefixSpan(seq, 2, 3);
}
public void testSetText_NotMatchingPrefix() {
- mPrefixHighlighter.setText(mView, "test", "TA".toCharArray());
- SpannedTestUtils.checkHtmlText("test", mView);
+ final CharSequence seq = mPrefixHighlighter.apply("test", "TA".toCharArray());
+ SpannedTestUtils.assertNotSpanned(seq, "test");
}
public void testSetText_FirstMatch() {
- mPrefixHighlighter.setText(mView, "a test's tests are not tests", "TE".toCharArray());
- SpannedTestUtils.checkHtmlText("a " +START + "te" + END + "st's tests are not tests",
- mView);
+ final CharSequence seq = mPrefixHighlighter.apply("a test's tests are not tests",
+ "TE".toCharArray());
+ SpannedTestUtils.assertPrefixSpan(seq, 2, 3);
}
public void testSetText_NoMatchingMiddleOfWord() {
- mPrefixHighlighter.setText(mView, "atest", "TE".toCharArray());
- SpannedTestUtils.checkHtmlText("atest", mView);
+ final char[] charArray = "TE".toCharArray();
+ CharSequence seq = mPrefixHighlighter.apply("atest", charArray);
+ SpannedTestUtils.assertNotSpanned(seq, "atest");
- mPrefixHighlighter.setText(mView, "atest otest", "TE".toCharArray());
- SpannedTestUtils.checkHtmlText("atest otest", mView);
+ seq = mPrefixHighlighter.apply("atest otest", charArray);
+ SpannedTestUtils.assertNotSpanned(seq, "atest otest");
- mPrefixHighlighter.setText(mView, "atest test", "TE".toCharArray());
- SpannedTestUtils.checkHtmlText("atest " + START + "te" + END + "st", mView);
+ seq = mPrefixHighlighter.apply("atest test", charArray);
+ SpannedTestUtils.assertPrefixSpan(seq, 6, 7);
}
}
diff --git a/tests/src/com/android/contacts/format/SpannedTestUtils.java b/tests/src/com/android/contacts/format/SpannedTestUtils.java
index ce228a7..6fa028d 100644
--- a/tests/src/com/android/contacts/format/SpannedTestUtils.java
+++ b/tests/src/com/android/contacts/format/SpannedTestUtils.java
@@ -20,6 +20,7 @@
import android.text.Html;
import android.text.Spanned;
import android.text.TextUtils;
+import android.text.style.ForegroundColorSpan;
import android.widget.TextView;
import junit.framework.Assert;
@@ -45,4 +46,38 @@
}
}
+
+ /**
+ * Assert span exists in the correct location.
+ *
+ * @param seq The spannable string to check.
+ * @param start The starting index.
+ * @param end The ending index.
+ */
+ public static void assertPrefixSpan(CharSequence seq, int start, int end) {
+ Assert.assertTrue(seq instanceof Spanned);
+ Spanned spannable = (Spanned) seq;
+
+ if (start > 0) {
+ Assert.assertEquals(0, getNumForegroundColorSpansBetween(spannable, 0, start - 1));
+ }
+ Assert.assertEquals(1, getNumForegroundColorSpansBetween(spannable, start, end));
+ Assert.assertEquals(0, getNumForegroundColorSpansBetween(spannable, end + 1,
+ spannable.length() - 1));
+ }
+
+ private static int getNumForegroundColorSpansBetween(Spanned value, int start, int end) {
+ return value.getSpans(start, end, ForegroundColorSpan.class).length;
+ }
+
+ /**
+ * Asserts that the given character sequence is not a Spanned object and text is correct.
+ *
+ * @param seq The sequence to check.
+ * @param expected The expected text.
+ */
+ public static void assertNotSpanned(CharSequence seq, String expected) {
+ Assert.assertFalse(seq instanceof Spanned);
+ Assert.assertEquals(expected, seq);
+ }
}
diff --git a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
index fcbd83d..3b856ea 100644
--- a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
+++ b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
@@ -29,13 +29,13 @@
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.common.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 com.android.contacts.common.test.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 a82e0f6..4e347b7 100644
--- a/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java
+++ b/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java
@@ -30,7 +30,7 @@
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.SmallTest;
-import com.android.contacts.interactions.PhoneNumberInteraction.InteractionType;
+import com.android.contacts.common.util.ContactDisplayUtils;
import com.android.contacts.interactions.PhoneNumberInteraction.PhoneItem;
import com.android.contacts.tests.mocks.ContactsMockContext;
import com.android.contacts.tests.mocks.MockContentProvider;
@@ -60,7 +60,7 @@
private final static class TestPhoneNumberInteraction extends PhoneNumberInteraction {
private ArrayList<PhoneItem> mPhoneList;
- public TestPhoneNumberInteraction(Context context, InteractionType interactionType,
+ public TestPhoneNumberInteraction(Context context, int interactionType,
OnDismissListener dismissListener) {
super(context, interactionType, dismissListener);
}
@@ -94,7 +94,7 @@
Phone.CONTENT_ITEM_TYPE);
TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
- mContext, InteractionType.SMS, null);
+ mContext, ContactDisplayUtils.INTERACTION_SMS, null);
interaction.startInteraction(contactUri);
interaction.getLoader().waitForLoader();
@@ -113,7 +113,7 @@
Phone.CONTENT_ITEM_TYPE);
TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
- mContext, InteractionType.SMS, null);
+ mContext, ContactDisplayUtils.INTERACTION_SMS, null);
interaction.startInteraction(dataUri);
interaction.getLoader().waitForLoader();
@@ -134,7 +134,7 @@
2, "456", 1, null, null, Phone.TYPE_HOME, null, Phone.CONTENT_ITEM_TYPE);
TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
- mContext, InteractionType.SMS, null);
+ mContext, ContactDisplayUtils.INTERACTION_SMS, null);
interaction.startInteraction(contactUri);
interaction.getLoader().waitForLoader();
@@ -175,7 +175,7 @@
Phone.CONTENT_ITEM_TYPE);
TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
- mContext, InteractionType.PHONE_CALL, null);
+ mContext, ContactDisplayUtils.INTERACTION_CALL, null);
interaction.startInteraction(contactUri);
interaction.getLoader().waitForLoader();
@@ -193,7 +193,7 @@
.returnRow(1, "example@example.com", 0, null, null, Phone.TYPE_HOME, null,
SipAddress.CONTENT_ITEM_TYPE);
TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
- mContext, InteractionType.PHONE_CALL, null);
+ mContext, ContactDisplayUtils.INTERACTION_CALL, null);
interaction.startInteraction(contactUri);
interaction.getLoader().waitForLoader();
@@ -214,7 +214,7 @@
Phone.CONTENT_ITEM_TYPE);
TestPhoneNumberInteraction interaction = new TestPhoneNumberInteraction(
- mContext, InteractionType.PHONE_CALL, null);
+ mContext, ContactDisplayUtils.INTERACTION_CALL, null);
interaction.startInteraction(contactUri);
interaction.getLoader().waitForLoader();
diff --git a/tests/src/com/android/contacts/list/ContactListItemViewTest.java b/tests/src/com/android/contacts/list/ContactListItemViewTest.java
index 748876f..996a1aa 100644
--- a/tests/src/com/android/contacts/list/ContactListItemViewTest.java
+++ b/tests/src/com/android/contacts/list/ContactListItemViewTest.java
@@ -21,11 +21,13 @@
import android.provider.ContactsContract;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
+import android.text.SpannableString;
+import android.text.Spanned;
import android.widget.TextView;
import com.android.contacts.activities.PeopleActivity;
+import com.android.contacts.common.test.IntegrationTestUtils;
import com.android.contacts.format.SpannedTestUtils;
-import com.android.contacts.util.IntegrationTestUtils;
/**
* Unit tests for {@link ContactListItemView}.
@@ -66,7 +68,7 @@
view.showDisplayName(cursor, 0, ContactsContract.Preferences.DISPLAY_ORDER_PRIMARY);
- SpannedTestUtils.checkHtmlText("John Doe", view.getNameTextView());
+ assertEquals(view.getNameTextView().getText().toString(), "John Doe");
}
public void testShowDisplayName_Unknown() {
@@ -76,7 +78,7 @@
view.setUnknownNameText("unknown");
view.showDisplayName(cursor, 0, ContactsContract.Preferences.DISPLAY_ORDER_PRIMARY);
- SpannedTestUtils.checkHtmlText("unknown", view.getNameTextView());
+ assertEquals(view.getNameTextView().getText().toString(), "unknown");
}
public void testShowDisplayName_WithPrefix() {
@@ -86,8 +88,9 @@
view.setHighlightedPrefix("DOE".toCharArray());
view.showDisplayName(cursor, 0, ContactsContract.Preferences.DISPLAY_ORDER_PRIMARY);
- SpannedTestUtils.checkHtmlText("John " + START + "Doe" + END,
- view.getNameTextView());
+ CharSequence seq = view.getNameTextView().getText();
+ assertEquals("John Doe", seq.toString());
+ SpannedTestUtils.assertPrefixSpan(seq, 5, 7);
}
public void testShowDisplayName_WithPrefixReversed() {
@@ -97,16 +100,20 @@
view.setHighlightedPrefix("DOE".toCharArray());
view.showDisplayName(cursor, 0, ContactsContract.Preferences.DISPLAY_ORDER_ALTERNATIVE);
- SpannedTestUtils.checkHtmlText("John " + START + "Doe" + END,
- view.getNameTextView());
+ CharSequence seq = view.getNameTextView().getText();
+ assertEquals("John Doe", seq.toString());
+ SpannedTestUtils.assertPrefixSpan(seq, 5, 7);
}
public void testSetSnippet_Prefix() {
ContactListItemView view = createView();
view.setHighlightedPrefix("TEST".toCharArray());
view.setSnippet("This is a test");
- SpannedTestUtils.checkHtmlText("This is a " + START + "test" + END,
- view.getSnippetView());
+
+ CharSequence seq = view.getSnippetView().getText();
+
+ assertEquals("This is a test", seq.toString());
+ SpannedTestUtils.assertPrefixSpan(seq, 10, 13);
}
/** Creates the view to be tested. */
diff --git a/tests/src/com/android/contacts/model/RawContactTest.java b/tests/src/com/android/contacts/model/RawContactTest.java
new file mode 100644
index 0000000..f09e64f
--- /dev/null
+++ b/tests/src/com/android/contacts/model/RawContactTest.java
@@ -0,0 +1,117 @@
+/*
+ * 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.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit test for {@link RawContact}.
+ */
+public class RawContactTest extends TestCase {
+
+ private RawContact buildRawContact() {
+ final ContentValues values = new ContentValues();
+ values.put("key1", "value1");
+ values.put("key2", "value2");
+
+ final ContentValues dataItem = new ContentValues();
+ dataItem.put("key3", "value3");
+ dataItem.put("key4", "value4");
+
+ final RawContact contact = new RawContact(values);
+ contact.addDataItemValues(dataItem);
+
+ return contact;
+ }
+
+ private RawContact buildRawContact2() {
+ final ContentValues values = new ContentValues();
+ values.put("key11", "value11");
+ values.put("key22", "value22");
+
+ final ContentValues dataItem = new ContentValues();
+ dataItem.put("key33", "value33");
+ dataItem.put("key44", "value44");
+
+ final RawContact contact = new RawContact(values);
+ contact.addDataItemValues(dataItem);
+
+ return contact;
+ }
+
+ public void testNotEquals() {
+ final RawContact one = buildRawContact();
+ final RawContact two = buildRawContact2();
+ assertFalse(one.equals(two));
+ }
+
+ public void testEquals() {
+ assertEquals(buildRawContact(), buildRawContact());
+ }
+
+ public void testParcelable() {
+ assertParcelableEquals(buildRawContact());
+ }
+
+ private RawContact.NamedDataItem buildNamedDataItem() {
+ final ContentValues values = new ContentValues();
+ values.put("key1", "value1");
+ values.put("key2", "value2");
+ final Uri uri = Uri.fromParts("content:", "ssp", "fragment");
+
+ return new RawContact.NamedDataItem(uri, values);
+ }
+
+ private RawContact.NamedDataItem buildNamedDataItem2() {
+ final ContentValues values = new ContentValues();
+ values.put("key11", "value11");
+ values.put("key22", "value22");
+ final Uri uri = Uri.fromParts("content:", "blah", "blah");
+
+ return new RawContact.NamedDataItem(uri, values);
+ }
+
+ public void testNamedDataItemEquals() {
+ assertEquals(buildNamedDataItem(), buildNamedDataItem());
+ }
+
+ public void testNamedDataItemNotEquals() {
+ assertFalse(buildNamedDataItem().equals(buildNamedDataItem2()));
+ }
+
+ public void testNamedDataItemParcelable() {
+ assertParcelableEquals(buildNamedDataItem());
+ }
+
+ private void assertParcelableEquals(Parcelable parcelable) {
+ final Parcel parcel = Parcel.obtain();
+ try {
+ parcel.writeParcelable(parcelable, 0);
+ parcel.setDataPosition(0);
+
+ Parcelable out = parcel.readParcelable(parcelable.getClass().getClassLoader());
+ assertEquals(parcelable, out);
+ } finally {
+ parcel.recycle();
+ }
+ }
+}
diff --git a/tests/src/com/android/contacts/model/account/AccountTypeTest.java b/tests/src/com/android/contacts/model/account/AccountTypeTest.java
index ad111d9..3276011 100644
--- a/tests/src/com/android/contacts/model/account/AccountTypeTest.java
+++ b/tests/src/com/android/contacts/model/account/AccountTypeTest.java
@@ -50,7 +50,7 @@
AccountType.getResourceText(c, packageName, externalResID, DEFAULT));
// Load from the contacts package itself.
- final int internalResId = com.android.contacts.R.string.launcherDialer;
+ final int internalResId = com.android.contacts.R.string.people;
assertEquals(c.getString(internalResId),
AccountType.getResourceText(c, null, internalResId, DEFAULT));
}
diff --git a/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java b/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
index 519dc5c..d7ea5bf 100644
--- a/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
+++ b/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
@@ -512,7 +512,7 @@
}
final Intent intent = new Intent("android.intent.action.VIEW");
intent.setData(uri);
- bindIntentToClass(intent, "com.android.contacts.CallDetailActivity");
+ bindIntentToClass(intent, "com.android.dialer.CallDetailActivity");
startActivity(intent);
break;
}
diff --git a/tests/src/com/android/contacts/tests/calllog/FillCallLogTestActivity.java b/tests/src/com/android/contacts/tests/calllog/FillCallLogTestActivity.java
deleted file mode 100644
index d04d978..0000000
--- a/tests/src/com/android/contacts/tests/calllog/FillCallLogTestActivity.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.tests.calllog;
-
-import android.app.Activity;
-import android.app.LoaderManager;
-import android.content.ContentProviderClient;
-import android.content.ContentValues;
-import android.content.CursorLoader;
-import android.content.Loader;
-import android.database.Cursor;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.provider.CallLog.Calls;
-import android.util.Log;
-import android.view.View;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.android.contacts.tests.R;
-
-import java.util.Random;
-
-/**
- * Activity to add entries to the call log for testing.
- */
-public class FillCallLogTestActivity extends Activity {
- private static final String TAG = "FillCallLogTestActivity";
- /** Identifier of the loader for querying the call log. */
- private static final int CALLLOG_LOADER_ID = 1;
-
- private static final Random RNG = new Random();
- private static final int[] CALL_TYPES = new int[] {
- Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE, Calls.MISSED_TYPE,
- };
-
- private TextView mNumberTextView;
- private Button mAddButton;
- private ProgressBar mProgressBar;
- private CheckBox mUseRandomNumbers;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.fill_call_log_test);
- mNumberTextView = (TextView) findViewById(R.id.number);
- mAddButton = (Button) findViewById(R.id.add);
- mProgressBar = (ProgressBar) findViewById(R.id.progress);
- mUseRandomNumbers = (CheckBox) findViewById(R.id.use_random_numbers);
-
- mAddButton.setOnClickListener(new View.OnClickListener(){
- @Override
- public void onClick(View v) {
- int count;
- try {
- count = Integer.parseInt(mNumberTextView.getText().toString());
- if (count > 100) {
- throw new RuntimeException("Number too large. Max=100");
- }
- } catch (RuntimeException e) {
- Toast.makeText(FillCallLogTestActivity.this, e.toString(), Toast.LENGTH_LONG)
- .show();
- return;
- }
- addEntriesToCallLog(count, mUseRandomNumbers.isChecked());
- mNumberTextView.setEnabled(false);
- mAddButton.setEnabled(false);
- mProgressBar.setProgress(0);
- mProgressBar.setMax(count);
- mProgressBar.setVisibility(View.VISIBLE);
- }
- });
- }
-
- /**
- * Adds a number of entries to the call log. The content of the entries is based on existing
- * entries.
- *
- * @param count the number of entries to add
- */
- private void addEntriesToCallLog(final int count, boolean useRandomNumbers) {
- if (useRandomNumbers) {
- addRandomNumbers(count);
- } else {
- getLoaderManager().initLoader(CALLLOG_LOADER_ID, null,
- new CallLogLoaderListener(count));
- }
- }
-
- /**
- * Calls when the insertion has completed.
- *
- * @param message the message to show in a toast to the user
- */
- private void insertCompleted(String message) {
- // Hide the progress bar.
- mProgressBar.setVisibility(View.GONE);
- // Re-enable the add button.
- mNumberTextView.setEnabled(true);
- mAddButton.setEnabled(true);
- mNumberTextView.setText("");
- Toast.makeText(this, message, Toast.LENGTH_LONG).show();
- }
-
-
- /**
- * Creates a {@link ContentValues} object containing values corresponding to the given cursor.
- *
- * @param cursor the cursor from which to get the values
- * @return a newly created content values object
- */
- private ContentValues createContentValuesFromCursor(Cursor cursor) {
- ContentValues values = new ContentValues();
- for (int column = 0; column < cursor.getColumnCount();
- ++column) {
- String name = cursor.getColumnName(column);
- switch (cursor.getType(column)) {
- case Cursor.FIELD_TYPE_STRING:
- values.put(name, cursor.getString(column));
- break;
- case Cursor.FIELD_TYPE_INTEGER:
- values.put(name, cursor.getLong(column));
- break;
- case Cursor.FIELD_TYPE_FLOAT:
- values.put(name, cursor.getDouble(column));
- break;
- case Cursor.FIELD_TYPE_BLOB:
- values.put(name, cursor.getBlob(column));
- break;
- case Cursor.FIELD_TYPE_NULL:
- values.putNull(name);
- break;
- default:
- Log.d(TAG, "Invalid value in cursor: " + cursor.getType(column));
- break;
- }
- }
- return values;
- }
-
- private void addRandomNumbers(int count) {
- ContentValues[] values = new ContentValues[count];
- for (int i = 0; i < count; i++) {
- values[i] = new ContentValues();
- values[i].put(Calls.NUMBER, generateRandomNumber());
- values[i].put(Calls.DATE, System.currentTimeMillis()); // Will be randomized later
- values[i].put(Calls.DURATION, 1); // Will be overwritten later
- }
- new AsyncCallLogInserter(values).execute(new Void[0]);
- }
-
- private static String generateRandomNumber() {
- return String.format("5%09d", RNG.nextInt(1000000000));
- }
-
- /** Invokes {@link AsyncCallLogInserter} when the call log has loaded. */
- private final class CallLogLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> {
- /** The number of items to insert when done. */
- private final int mCount;
-
- private CallLogLoaderListener(int count) {
- mCount = count;
- }
-
- @Override
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- Log.d(TAG, "onCreateLoader");
- return new CursorLoader(FillCallLogTestActivity.this, Calls.CONTENT_URI,
- null, null, null, null);
- }
-
- @Override
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- try {
- Log.d(TAG, "onLoadFinished");
-
- if (data.getCount() == 0) {
- // If there are no entries in the call log, we cannot generate new ones.
- insertCompleted(getString(R.string.noLogEntriesToast));
- return;
- }
-
- data.moveToPosition(-1);
-
- ContentValues[] values = new ContentValues[mCount];
- for (int index = 0; index < mCount; ++index) {
- if (!data.moveToNext()) {
- data.moveToFirst();
- }
- values[index] = createContentValuesFromCursor(data);
- }
- new AsyncCallLogInserter(values).execute(new Void[0]);
- } finally {
- // This is a one shot loader.
- getLoaderManager().destroyLoader(CALLLOG_LOADER_ID);
- }
- }
-
- @Override
- public void onLoaderReset(Loader<Cursor> loader) {}
- }
-
- /** Inserts a given number of entries in the call log based on the values given. */
- private final class AsyncCallLogInserter extends AsyncTask<Void, Integer, Integer> {
- /** The number of items to insert. */
- private final ContentValues[] mValues;
-
- public AsyncCallLogInserter(ContentValues[] values) {
- mValues = values;
- }
-
- @Override
- protected Integer doInBackground(Void... params) {
- Log.d(TAG, "doInBackground");
- return insertIntoCallLog();
- }
-
- @Override
- protected void onProgressUpdate(Integer... values) {
- Log.d(TAG, "onProgressUpdate");
- updateCount(values[0]);
- }
-
- @Override
- protected void onPostExecute(Integer count) {
- Log.d(TAG, "onPostExecute");
- insertCompleted(getString(R.string.addedLogEntriesToast, count));
- }
-
- /**
- * Inserts a number of entries in the call log based on the given templates.
- *
- * @return the number of inserted entries
- */
- private Integer insertIntoCallLog() {
- int inserted = 0;
-
- for (int index = 0; index < mValues.length; ++index) {
- ContentValues values = mValues[index];
- // These should not be set.
- values.putNull(Calls._ID);
- // Add some randomness to the date. For each new entry being added, add an extra
- // day to the maximum possible offset from the original.
- values.put(Calls.DATE,
- values.getAsLong(Calls.DATE)
- - RNG.nextInt(24 * 60 * 60 * (index + 1)) * 1000L);
- // Add some randomness to the duration.
- if (values.getAsLong(Calls.DURATION) > 0) {
- values.put(Calls.DURATION, RNG.nextInt(30 * 60 * 60 * 1000));
- }
-
- // Overwrite type.
- values.put(Calls.TYPE, CALL_TYPES[RNG.nextInt(CALL_TYPES.length)]);
-
- // Clear cached columns.
- values.putNull(Calls.CACHED_FORMATTED_NUMBER);
- values.putNull(Calls.CACHED_LOOKUP_URI);
- values.putNull(Calls.CACHED_MATCHED_NUMBER);
- values.putNull(Calls.CACHED_NAME);
- values.putNull(Calls.CACHED_NORMALIZED_NUMBER);
- values.putNull(Calls.CACHED_NUMBER_LABEL);
- values.putNull(Calls.CACHED_NUMBER_TYPE);
- values.putNull(Calls.CACHED_PHOTO_ID);
-
- // Insert into the call log the newly generated entry.
- ContentProviderClient contentProvider =
- getContentResolver().acquireContentProviderClient(
- Calls.CONTENT_URI);
- try {
- Log.d(TAG, "adding entry to call log");
- contentProvider.insert(Calls.CONTENT_URI, values);
- ++inserted;
- this.publishProgress(inserted);
- } catch (RemoteException e) {
- Log.d(TAG, "insert failed", e);
- }
- }
- return inserted;
- }
- }
-
- /**
- * Updates the count shown to the user corresponding to the number of entries added.
- *
- * @param count the number of entries inserted so far
- */
- public void updateCount(Integer count) {
- mProgressBar.setProgress(count);
- }
-}
diff --git a/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java b/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java
index efd5ac2..f5f6084 100644
--- a/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java
+++ b/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java
@@ -20,7 +20,7 @@
import android.net.Uri;
import android.widget.ImageView;
-import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.common.ContactPhotoManager;
/**
* A photo preloader that always uses the "no contact" picture and never executes any real
diff --git a/tests/src/com/android/contacts/util/BitmapUtilTests.java b/tests/src/com/android/contacts/util/BitmapUtilTests.java
deleted file mode 100644
index 554fc97..0000000
--- a/tests/src/com/android/contacts/util/BitmapUtilTests.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.util;
-
-import android.graphics.Bitmap;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-/**
- * Tests for {@link BitmapUtil}.
- */
-@SmallTest
-public class BitmapUtilTests extends AndroidTestCase {
- public void testGetSmallerExtentFromBytes1() throws Exception {
- assertEquals(100, BitmapUtil.getSmallerExtentFromBytes(createJpegRawData(100, 100)));
- assertEquals(100, BitmapUtil.getSmallerExtentFromBytes(createPngRawData(100, 100)));
- }
-
- public void testGetSmallerExtentFromBytes2() throws Exception {
- assertEquals(50, BitmapUtil.getSmallerExtentFromBytes(createJpegRawData(200, 50)));
- assertEquals(50, BitmapUtil.getSmallerExtentFromBytes(createPngRawData(200, 50)));
- }
-
- public void testGetSmallerExtentFromBytes3() throws Exception {
- assertEquals(40, BitmapUtil.getSmallerExtentFromBytes(createJpegRawData(40, 150)));
- assertEquals(40, BitmapUtil.getSmallerExtentFromBytes(createPngRawData(40, 150)));
- }
-
- public void testFindOptimalSampleSizeExact() throws Exception {
- assertEquals(1, BitmapUtil.findOptimalSampleSize(512, 512));
- }
-
- public void testFindOptimalSampleSizeBigger() throws Exception {
- assertEquals(1, BitmapUtil.findOptimalSampleSize(512, 1024));
- }
-
- public void testFindOptimalSampleSizeSmaller1() throws Exception {
- assertEquals(2, BitmapUtil.findOptimalSampleSize(512, 256));
- }
-
- public void testFindOptimalSampleSizeSmaller2() throws Exception {
- assertEquals(2, BitmapUtil.findOptimalSampleSize(512, 230));
- }
-
- public void testFindOptimalSampleSizeSmaller3() throws Exception {
- assertEquals(2, BitmapUtil.findOptimalSampleSize(512, 129));
- }
-
- public void testFindOptimalSampleSizeSmaller4() throws Exception {
- assertEquals(4, BitmapUtil.findOptimalSampleSize(512, 128));
- }
-
- public void testFindOptimalSampleSizeUnknownOriginal() throws Exception {
- assertEquals(1, BitmapUtil.findOptimalSampleSize(-1, 128));
- }
-
- public void testFindOptimalSampleSizeUnknownTarget() throws Exception {
- assertEquals(1, BitmapUtil.findOptimalSampleSize(128, -1));
- }
-
- public void testDecodeWithSampleSize1() throws IOException {
- assertBitmapSize(128, 64, BitmapUtil.decodeBitmapFromBytes(createJpegRawData(128, 64), 1));
- assertBitmapSize(128, 64, BitmapUtil.decodeBitmapFromBytes(createPngRawData(128, 64), 1));
- }
-
- public void testDecodeWithSampleSize2() throws IOException {
- assertBitmapSize(64, 32, BitmapUtil.decodeBitmapFromBytes(createJpegRawData(128, 64), 2));
- assertBitmapSize(64, 32, BitmapUtil.decodeBitmapFromBytes(createPngRawData(128, 64), 2));
- }
-
- public void testDecodeWithSampleSize2a() throws IOException {
- assertBitmapSize(25, 20, BitmapUtil.decodeBitmapFromBytes(createJpegRawData(50, 40), 2));
- assertBitmapSize(25, 20, BitmapUtil.decodeBitmapFromBytes(createPngRawData(50, 40), 2));
- }
-
- public void testDecodeWithSampleSize4() throws IOException {
- assertBitmapSize(32, 16, BitmapUtil.decodeBitmapFromBytes(createJpegRawData(128, 64), 4));
- assertBitmapSize(32, 16, BitmapUtil.decodeBitmapFromBytes(createPngRawData(128, 64), 4));
- }
-
- private void assertBitmapSize(int expectedWidth, int expectedHeight, Bitmap bitmap) {
- assertEquals(expectedWidth, bitmap.getWidth());
- assertEquals(expectedHeight, bitmap.getHeight());
- }
-
- private byte[] createJpegRawData(int sourceWidth, int sourceHeight) throws IOException {
- return createRawData(Bitmap.CompressFormat.JPEG, sourceWidth, sourceHeight);
- }
-
- private byte[] createPngRawData(int sourceWidth, int sourceHeight) throws IOException {
- return createRawData(Bitmap.CompressFormat.PNG, sourceWidth, sourceHeight);
- }
-
- private byte[] createRawData(Bitmap.CompressFormat format, int sourceWidth,
- int sourceHeight) throws IOException {
- // Create a temp bitmap as our source
- Bitmap b = Bitmap.createBitmap(sourceWidth, sourceHeight, Bitmap.Config.ARGB_8888);
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- b.compress(format, 50, outputStream);
- final byte[] data = outputStream.toByteArray();
- outputStream.close();
- return data;
- }
-}
diff --git a/tests/src/com/android/contacts/util/ExpirableCacheTest.java b/tests/src/com/android/contacts/util/ExpirableCacheTest.java
deleted file mode 100644
index 33e176e..0000000
--- a/tests/src/com/android/contacts/util/ExpirableCacheTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.util;
-
-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}.
- */
-@SmallTest
-public class ExpirableCacheTest extends AndroidTestCase {
- /** The object under test. */
- private ExpirableCache<String, Integer> mCache;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- LruCache<String, CachedValue<Integer>> lruCache =
- new LruCache<String, ExpirableCache.CachedValue<Integer>>(20);
- mCache = ExpirableCache.create(lruCache);
- }
-
- @Override
- protected void tearDown() throws Exception {
- mCache = null;
- super.tearDown();
- }
-
- public void testPut() {
- mCache.put("a", 1);
- mCache.put("b", 2);
- assertEquals(1, mCache.getPossiblyExpired("a").intValue());
- assertEquals(2, mCache.getPossiblyExpired("b").intValue());
- mCache.put("a", 3);
- assertEquals(3, mCache.getPossiblyExpired("a").intValue());
- }
-
- public void testGet_NotExisting() {
- assertNull(mCache.getPossiblyExpired("a"));
- mCache.put("b", 1);
- assertNull(mCache.getPossiblyExpired("a"));
- }
-
- public void testGet_Expired() {
- mCache.put("a", 1);
- assertEquals(1, mCache.getPossiblyExpired("a").intValue());
- mCache.expireAll();
- assertEquals(1, mCache.getPossiblyExpired("a").intValue());
- }
-
- public void testGetNotExpired_NotExisting() {
- assertNull(mCache.get("a"));
- mCache.put("b", 1);
- assertNull(mCache.get("a"));
- }
-
- public void testGetNotExpired_Expired() {
- mCache.put("a", 1);
- assertEquals(1, mCache.get("a").intValue());
- mCache.expireAll();
- assertNull(mCache.get("a"));
- }
-
- public void testGetCachedValue_NotExisting() {
- assertNull(mCache.getCachedValue("a"));
- mCache.put("b", 1);
- assertNull(mCache.getCachedValue("a"));
- }
-
- public void testGetCachedValue_Expired() {
- mCache.put("a", 1);
- assertFalse("Should not be expired", mCache.getCachedValue("a").isExpired());
- mCache.expireAll();
- assertTrue("Should be expired", mCache.getCachedValue("a").isExpired());
- }
-
- public void testGetChangedValue_PutAfterExpired() {
- mCache.put("a", 1);
- mCache.expireAll();
- mCache.put("a", 1);
- assertFalse("Should not be expired", mCache.getCachedValue("a").isExpired());
- }
-
- public void testComputingCache() {
- // Creates a cache in which all unknown values default to zero.
- mCache = ExpirableCache.create(
- new LruCache<String, ExpirableCache.CachedValue<Integer>>(10) {
- @Override
- protected CachedValue<Integer> create(String key) {
- return mCache.newCachedValue(0);
- }
- });
-
- // The first time we request a new value, we add it to the cache.
- CachedValue<Integer> cachedValue = mCache.getCachedValue("a");
- assertNotNull("Should have been created implicitly", cachedValue);
- assertEquals(0, cachedValue.getValue().intValue());
- assertFalse("Should not be expired", cachedValue.isExpired());
-
- // If we expire all the values, the implicitly created value will also be marked as expired.
- mCache.expireAll();
- CachedValue<Integer> expiredCachedValue = mCache.getCachedValue("a");
- assertNotNull("Should have been created implicitly", expiredCachedValue);
- assertEquals(0, expiredCachedValue.getValue().intValue());
- assertTrue("Should be expired", expiredCachedValue.isExpired());
- }
-}
diff --git a/tests/src/com/android/contacts/util/FakeAsyncTaskExecutor.java b/tests/src/com/android/contacts/util/FakeAsyncTaskExecutor.java
deleted file mode 100644
index 8c97f21..0000000
--- a/tests/src/com/android/contacts/util/FakeAsyncTaskExecutor.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.util;
-
-import android.app.Instrumentation;
-import android.os.AsyncTask;
-
-import com.google.common.collect.Lists;
-
-import junit.framework.Assert;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.ThreadSafe;
-
-/**
- * Test implementation of AsyncTaskExecutor.
- * <p>
- * This class is thread-safe. As per the contract of the AsyncTaskExecutor, the submit methods must
- * be called from the main ui thread, however the other public methods may be called from any thread
- * (most commonly the test thread).
- * <p>
- * Tasks submitted to this executor will not be run immediately. Rather they will be stored in a
- * list of submitted tasks, where they can be examined. They can also be run on-demand using the run
- * methods, so that different ordering of AsyncTask execution can be simulated.
- * <p>
- * The onPreExecute method of the submitted AsyncTask will be called synchronously during the
- * call to {@link #submit(Object, AsyncTask, Object...)}.
- */
-@ThreadSafe
-public class FakeAsyncTaskExecutor implements AsyncTaskExecutor {
- private static final long DEFAULT_TIMEOUT_MS = 10000;
-
- /** The maximum length of time in ms to wait for tasks to execute during tests. */
- private final long mTimeoutMs = DEFAULT_TIMEOUT_MS;
-
- private final Object mLock = new Object();
- @GuardedBy("mLock") private final List<SubmittedTask> mSubmittedTasks = Lists.newArrayList();
-
- private final DelayedExecutor mBlockingExecutor = new DelayedExecutor();
- private final Instrumentation mInstrumentation;
-
- /** Create a fake AsyncTaskExecutor for use in unit tests. */
- public FakeAsyncTaskExecutor(Instrumentation instrumentation) {
- Assert.assertNotNull(instrumentation);
- mInstrumentation = instrumentation;
- }
-
- /** Encapsulates an async task with the params and identifier it was submitted with. */
- public interface SubmittedTask {
- Runnable getRunnable();
- Object getIdentifier();
- AsyncTask<?, ?, ?> getAsyncTask();
- }
-
- private static final class SubmittedTaskImpl implements SubmittedTask {
- private final Object mIdentifier;
- private final Runnable mRunnable;
- private final AsyncTask<?, ?, ?> mAsyncTask;
-
- public SubmittedTaskImpl(Object identifier, Runnable runnable,
- AsyncTask<?, ?, ?> asyncTask) {
- mIdentifier = identifier;
- mRunnable = runnable;
- mAsyncTask = asyncTask;
- }
-
- @Override
- public Object getIdentifier() {
- return mIdentifier;
- }
-
- @Override
- public Runnable getRunnable() {
- return mRunnable;
- }
-
- @Override
- public AsyncTask<?, ?, ?> getAsyncTask() {
- return mAsyncTask;
- }
-
- @Override
- public String toString() {
- return "SubmittedTaskImpl [mIdentifier=" + mIdentifier + "]";
- }
- }
-
- private class DelayedExecutor implements Executor {
- private final Object mNextLock = new Object();
- @GuardedBy("mNextLock") private Object mNextIdentifier;
- @GuardedBy("mNextLock") private AsyncTask<?, ?, ?> mNextTask;
-
- @Override
- public void execute(Runnable command) {
- synchronized (mNextLock) {
- Assert.assertNotNull(mNextTask);
- mSubmittedTasks.add(new SubmittedTaskImpl(mNextIdentifier,
- command, mNextTask));
- mNextIdentifier = null;
- mNextTask = null;
- }
- }
-
- public <T> AsyncTask<T, ?, ?> submit(Object identifier,
- AsyncTask<T, ?, ?> task, T... params) {
- synchronized (mNextLock) {
- Assert.assertNull(mNextIdentifier);
- Assert.assertNull(mNextTask);
- mNextIdentifier = identifier;
- Assert.assertNotNull("Already had a valid task.\n"
- + "Are you calling AsyncTaskExecutor.submit(...) from within the "
- + "onPreExecute() method of another task being submitted?\n"
- + "Sorry! Not that's not supported.", task);
- mNextTask = task;
- }
- return task.executeOnExecutor(this, params);
- }
- }
-
- @Override
- public <T> AsyncTask<T, ?, ?> submit(Object identifier, AsyncTask<T, ?, ?> task, T... params) {
- AsyncTaskExecutors.checkCalledFromUiThread();
- return mBlockingExecutor.submit(identifier, task, params);
- }
-
- /**
- * Runs a single task matching the given identifier.
- * <p>
- * Removes the matching task from the list of submitted tasks, then runs it. The executor used
- * to execute this async task will be a same-thread executor.
- * <p>
- * Fails if there was not exactly one task matching the given identifier.
- * <p>
- * This method blocks until the AsyncTask has completely finished executing.
- */
- public void runTask(Object identifier) throws InterruptedException {
- List<SubmittedTask> tasks = getSubmittedTasksByIdentifier(identifier, true);
- Assert.assertEquals("Expected one task " + identifier + ", got " + tasks, 1, tasks.size());
- runTask(tasks.get(0));
- }
-
- /**
- * Runs all tasks whose identifier matches the given identifier.
- * <p>
- * Removes all matching tasks from the list of submitted tasks, and runs them. The executor used
- * to execute these async tasks will be a same-thread executor.
- * <p>
- * Fails if there were no tasks matching the given identifier.
- * <p>
- * This method blocks until the AsyncTask objects have completely finished executing.
- */
- public void runAllTasks(Object identifier) throws InterruptedException {
- List<SubmittedTask> tasks = getSubmittedTasksByIdentifier(identifier, true);
- Assert.assertTrue("There were no tasks with identifier " + identifier, tasks.size() > 0);
- for (SubmittedTask task : tasks) {
- runTask(task);
- }
- }
-
- /**
- * Executes a single {@link SubmittedTask}.
- * <p>
- * Blocks until the task has completed running.
- */
- private <T> void runTask(final SubmittedTask submittedTask) throws InterruptedException {
- submittedTask.getRunnable().run();
- // Block until the onPostExecute or onCancelled has finished.
- // Unfortunately we can't be sure when the AsyncTask will have posted its result handling
- // code to the main ui thread, the best we can do is wait for the Status to be FINISHED.
- final CountDownLatch latch = new CountDownLatch(1);
- class AsyncTaskHasFinishedRunnable implements Runnable {
- @Override
- public void run() {
- if (submittedTask.getAsyncTask().getStatus() == AsyncTask.Status.FINISHED) {
- latch.countDown();
- } else {
- mInstrumentation.waitForIdle(this);
- }
- }
- }
- mInstrumentation.waitForIdle(new AsyncTaskHasFinishedRunnable());
- Assert.assertTrue(latch.await(mTimeoutMs, TimeUnit.MILLISECONDS));
- }
-
- private List<SubmittedTask> getSubmittedTasksByIdentifier(
- Object identifier, boolean remove) {
- Assert.assertNotNull(identifier);
- List<SubmittedTask> results = Lists.newArrayList();
- synchronized (mLock) {
- Iterator<SubmittedTask> iter = mSubmittedTasks.iterator();
- while (iter.hasNext()) {
- SubmittedTask task = iter.next();
- if (identifier.equals(task.getIdentifier())) {
- results.add(task);
- iter.remove();
- }
- }
- }
- return results;
- }
-
- /** Get a factory that will return this instance - useful for testing. */
- public AsyncTaskExecutors.AsyncTaskExecutorFactory getFactory() {
- return new AsyncTaskExecutors.AsyncTaskExecutorFactory() {
- @Override
- public AsyncTaskExecutor createAsyncTaskExeuctor() {
- return FakeAsyncTaskExecutor.this;
- }
- };
- }
-}
diff --git a/tests/src/com/android/contacts/util/IntegrationTestUtils.java b/tests/src/com/android/contacts/util/IntegrationTestUtils.java
deleted file mode 100644
index 8c9dd6c..0000000
--- a/tests/src/com/android/contacts/util/IntegrationTestUtils.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.util;
-
-import static android.os.PowerManager.ACQUIRE_CAUSES_WAKEUP;
-import static android.os.PowerManager.FULL_WAKE_LOCK;
-import static android.os.PowerManager.ON_AFTER_RELEASE;
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.content.Context;
-import android.os.PowerManager;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import com.google.common.base.Preconditions;
-
-import junit.framework.Assert;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.FutureTask;
-
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.ThreadSafe;
-
-/** Some utility methods for making integration testing smoother. */
-@ThreadSafe
-public class IntegrationTestUtils {
- private static final String TAG = "IntegrationTestUtils";
-
- private final Instrumentation mInstrumentation;
- private final Object mLock = new Object();
- @GuardedBy("mLock") private PowerManager.WakeLock mWakeLock;
-
- public IntegrationTestUtils(Instrumentation instrumentation) {
- mInstrumentation = instrumentation;
- }
-
- /**
- * Find a view by a given resource id, from the given activity, and click it, iff it is
- * enabled according to {@link View#isEnabled()}.
- */
- public void clickButton(final Activity activity, final int buttonResourceId) throws Throwable {
- runOnUiThreadAndGetTheResult(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- View view = activity.findViewById(buttonResourceId);
- Assert.assertNotNull(view);
- if (view.isEnabled()) {
- view.performClick();
- }
- return null;
- }
- });
- }
-
- /** Returns the result of running {@link TextView#getText()} on the ui thread. */
- public CharSequence getText(final TextView view) throws Throwable {
- return runOnUiThreadAndGetTheResult(new Callable<CharSequence>() {
- @Override
- public CharSequence call() {
- return view.getText();
- }
- });
- }
-
- // TODO: Move this class and the appropriate documentation into a test library, having checked
- // first to see if exactly this code already exists or not.
- /**
- * Execute a callable on the ui thread, returning its result synchronously.
- * <p>
- * Waits for an idle sync on the main thread (see {@link Instrumentation#waitForIdle(Runnable)})
- * before executing this callable.
- */
- public <T> T runOnUiThreadAndGetTheResult(Callable<T> callable) throws Throwable {
- FutureTask<T> future = new FutureTask<T>(callable);
- mInstrumentation.waitForIdle(future);
- try {
- return future.get();
- } catch (ExecutionException e) {
- // Unwrap the cause of the exception and re-throw it.
- throw e.getCause();
- }
- }
-
- /**
- * Wake up the screen, useful in tests that want or need the screen to be on.
- * <p>
- * This is usually called from setUp() for tests that require it. After calling this method,
- * {@link #releaseScreenWakeLock()} must be called, this is usually done from tearDown().
- */
- public void acquireScreenWakeLock(Context context) {
- synchronized (mLock) {
- Preconditions.checkState(mWakeLock == null, "mWakeLock was already held");
- mWakeLock = ((PowerManager) context.getSystemService(Context.POWER_SERVICE))
- .newWakeLock(ACQUIRE_CAUSES_WAKEUP | ON_AFTER_RELEASE | FULL_WAKE_LOCK, TAG);
- mWakeLock.acquire();
- }
- }
-
- /** Release the wake lock previously acquired with {@link #acquireScreenWakeLock(Context)}. */
- public void releaseScreenWakeLock() {
- synchronized (mLock) {
- // We don't use Preconditions to force you to have acquired before release.
- // This is because we don't want unnecessary exceptions in tearDown() since they'll
- // typically mask the actual exception that happened during the test.
- // The other reason is that this method is most likely to be called from tearDown(),
- // which is invoked within a finally block, so it's not infrequently the case that
- // the setUp() method fails before getting the lock, at which point we don't want
- // to fail in tearDown().
- if (mWakeLock != null) {
- mWakeLock.release();
- mWakeLock = null;
- }
- }
- }
-
- /**
- * Gets all {@link TextView} objects whose {@link TextView#getText()} contains the given text as
- * a substring.
- */
- public List<TextView> getTextViewsWithString(final Activity activity, final String text)
- throws Throwable {
- return runOnUiThreadAndGetTheResult(new Callable<List<TextView>>() {
- @Override
- public List<TextView> call() throws Exception {
- List<TextView> matchingViews = new ArrayList<TextView>();
- for (TextView textView : getAllViews(TextView.class, getRootView(activity))) {
- if (textView.getText().toString().contains(text)) {
- matchingViews.add(textView);
- }
- }
- return matchingViews;
- }
- });
- }
-
- /** Find the root view for a given activity. */
- public static View getRootView(Activity activity) {
- return activity.findViewById(android.R.id.content).getRootView();
- }
-
- /**
- * Gets a list of all views of a given type, rooted at the given parent.
- * <p>
- * This method will recurse down through all {@link ViewGroup} instances looking for
- * {@link View} instances of the supplied class type. Specifically it will use the
- * {@link Class#isAssignableFrom(Class)} method as the test for which views to add to the list,
- * so if you provide {@code View.class} as your type, you will get every view. The parent itself
- * will be included also, should it be of the right type.
- * <p>
- * This call manipulates the ui, and as such should only be called from the application's main
- * thread.
- */
- private static <T extends View> List<T> getAllViews(final Class<T> clazz, final View parent) {
- List<T> results = new ArrayList<T>();
- if (parent.getClass().equals(clazz)) {
- results.add(clazz.cast(parent));
- }
- if (parent instanceof ViewGroup) {
- ViewGroup viewGroup = (ViewGroup) parent;
- for (int i = 0; i < viewGroup.getChildCount(); ++i) {
- results.addAll(getAllViews(clazz, viewGroup.getChildAt(i)));
- }
- }
- return results;
- }
-}
diff --git a/tests/src/com/android/contacts/util/LocaleTestUtils.java b/tests/src/com/android/contacts/util/LocaleTestUtils.java
deleted file mode 100644
index e0a8670..0000000
--- a/tests/src/com/android/contacts/util/LocaleTestUtils.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.util;
-
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-
-import java.util.Locale;
-
-/**
- * Utility class to save and restore the locale of the system.
- * <p>
- * This can be used for tests that assume to be run in a certain locale, e.g., because they
- * check against strings in a particular language or require an assumption on how the system
- * will behave in a specific locale.
- * <p>
- * In your test, you can change the locale with the following code:
- * <pre>
- * public class CanadaFrenchTest extends AndroidTestCase {
- * private LocaleTestUtils mLocaleTestUtils;
- *
- * @Override
- * public void setUp() throws Exception {
- * super.setUp();
- * mLocaleTestUtils = new LocaleTestUtils(getContext());
- * mLocaleTestUtils.setLocale(Locale.CANADA_FRENCH);
- * }
- *
- * @Override
- * public void tearDown() throws Exception {
- * mLocaleTestUtils.restoreLocale();
- * mLocaleTestUtils = null;
- * super.tearDown();
- * }
- *
- * ...
- * }
- * </pre>
- * Note that one should not call {@link #setLocale(Locale)} more than once without calling
- * {@link #restoreLocale()} first.
- * <p>
- * This class is not thread-safe. Usually its methods should be invoked only from the test thread.
- */
-public class LocaleTestUtils {
- private final Context mContext;
- private boolean mSaved;
- private Locale mSavedContextLocale;
- private Locale mSavedSystemLocale;
-
- /**
- * Create a new instance that can be used to set and reset the locale for the given context.
- *
- * @param context the context on which to alter the locale
- */
- public LocaleTestUtils(Context context) {
- mContext = context;
- mSaved = false;
- }
-
- /**
- * Set the locale to the given value and saves the previous value.
- *
- * @param locale the value to which the locale should be set
- * @throws IllegalStateException if the locale was already set
- */
- public void setLocale(Locale locale) {
- if (mSaved) {
- throw new IllegalStateException(
- "call restoreLocale() before calling setLocale() again");
- }
- mSavedContextLocale = setResourcesLocale(mContext.getResources(), locale);
- mSavedSystemLocale = setResourcesLocale(Resources.getSystem(), locale);
- mSaved = true;
- }
-
- /**
- * Restores the previously set locale.
- *
- * @throws IllegalStateException if the locale was not set using {@link #setLocale(Locale)}
- */
- public void restoreLocale() {
- if (!mSaved) {
- throw new IllegalStateException("call setLocale() before calling restoreLocale()");
- }
- setResourcesLocale(mContext.getResources(), mSavedContextLocale);
- setResourcesLocale(Resources.getSystem(), mSavedSystemLocale);
- mSaved = false;
- }
-
- /**
- * Sets the locale for the given resources and returns the previous locale.
- *
- * @param resources the resources on which to set the locale
- * @param locale the value to which to set the locale
- * @return the previous value of the locale for the resources
- */
- private Locale setResourcesLocale(Resources resources, Locale locale) {
- Configuration contextConfiguration = new Configuration(resources.getConfiguration());
- Locale savedLocale = contextConfiguration.locale;
- contextConfiguration.locale = locale;
- resources.updateConfiguration(contextConfiguration, null);
- return savedLocale;
- }
-}
\ 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
deleted file mode 100644
index 801c162..0000000
--- a/tests/src/com/android/contacts/voicemail/VoicemailStatusHelperImplTest.java
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.voicemail;
-
-import static android.provider.VoicemailContract.Status.CONFIGURATION_STATE;
-import static android.provider.VoicemailContract.Status.CONFIGURATION_STATE_CAN_BE_CONFIGURED;
-import static android.provider.VoicemailContract.Status.CONFIGURATION_STATE_NOT_CONFIGURED;
-import static android.provider.VoicemailContract.Status.DATA_CHANNEL_STATE;
-import static android.provider.VoicemailContract.Status.DATA_CHANNEL_STATE_NO_CONNECTION;
-import static android.provider.VoicemailContract.Status.DATA_CHANNEL_STATE_OK;
-import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE;
-import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING;
-import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION;
-import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_OK;
-
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-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;
-
-/**
- * Unit tests for {@link VoicemailStatusHelperImpl}.
- */
-public class VoicemailStatusHelperImplTest extends AndroidTestCase {
- private static final String[] TEST_PACKAGES = new String[] {
- "com.test.package1",
- "com.test.package2"
- };
-
- private static final Uri TEST_SETTINGS_URI = Uri.parse("http://www.visual.voicemail.setup");
- private static final Uri TEST_VOICEMAIL_URI = Uri.parse("tel:901");
-
- private static final int ACTION_MSG_CALL_VOICEMAIL =
- R.string.voicemail_status_action_call_server;
- private static final int ACTION_MSG_CONFIGURE = R.string.voicemail_status_action_configure;
-
- private static final int STATUS_MSG_NONE = -1;
- private static final int STATUS_MSG_VOICEMAIL_NOT_AVAILABLE =
- R.string.voicemail_status_voicemail_not_available;
- private static final int STATUS_MSG_AUDIO_NOT_AVAIALABLE =
- R.string.voicemail_status_audio_not_available;
- private static final int STATUS_MSG_MESSAGE_WAITING = R.string.voicemail_status_messages_waiting;
- private static final int STATUS_MSG_INVITE_FOR_CONFIGURATION =
- R.string.voicemail_status_configure_voicemail;
-
- // Object under test.
- private VoicemailStatusHelper mStatusHelper;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mStatusHelper = new VoicemailStatusHelperImpl();
- }
-
- @Override
- protected void tearDown() throws Exception {
- for (String sourcePackage : TEST_PACKAGES) {
- deleteEntryForPackage(sourcePackage);
- }
- // Set member variables to null so that they are garbage collected across different runs
- // of the tests.
- mStatusHelper = null;
- super.tearDown();
- }
-
-
- public void testNoStatusEntries() {
- assertEquals(0, getStatusMessages().size());
- }
-
- public void testAllOK() {
- insertEntryForPackage(TEST_PACKAGES[0], getAllOkStatusValues());
- insertEntryForPackage(TEST_PACKAGES[1], getAllOkStatusValues());
- assertEquals(0, getStatusMessages().size());
- }
-
- public void testNotAllOKForOnePackage() {
- insertEntryForPackage(TEST_PACKAGES[0], getAllOkStatusValues());
- insertEntryForPackage(TEST_PACKAGES[1], getAllOkStatusValues());
-
- ContentValues values = new ContentValues();
- // Good data channel + no notification
- // action: call voicemail
- // msg: voicemail not available in call log page & none in call details page.
- values.put(NOTIFICATION_CHANNEL_STATE, NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
- values.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_OK);
- updateEntryForPackage(TEST_PACKAGES[1], values);
- checkExpectedMessage(TEST_PACKAGES[1], values, STATUS_MSG_VOICEMAIL_NOT_AVAILABLE,
- STATUS_MSG_NONE, ACTION_MSG_CALL_VOICEMAIL);
-
- // Message waiting + good data channel - no action.
- values.put(NOTIFICATION_CHANNEL_STATE, NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING);
- values.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_OK);
- updateEntryForPackage(TEST_PACKAGES[1], values);
- checkNoMessages(TEST_PACKAGES[1], values);
-
- // No data channel + no notification
- // action: call voicemail
- // msg: voicemail not available in call log page & audio not available in call details page.
- values.put(NOTIFICATION_CHANNEL_STATE, NOTIFICATION_CHANNEL_STATE_OK);
- values.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_NO_CONNECTION);
- updateEntryForPackage(TEST_PACKAGES[1], values);
- checkExpectedMessage(TEST_PACKAGES[1], values, STATUS_MSG_VOICEMAIL_NOT_AVAILABLE,
- STATUS_MSG_AUDIO_NOT_AVAIALABLE, ACTION_MSG_CALL_VOICEMAIL);
-
- // No data channel + Notification OK
- // action: call voicemail
- // msg: voicemail not available in call log page & audio not available in call details page.
- values.put(NOTIFICATION_CHANNEL_STATE, NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
- values.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_NO_CONNECTION);
- updateEntryForPackage(TEST_PACKAGES[1], values);
- checkExpectedMessage(TEST_PACKAGES[1], values, STATUS_MSG_VOICEMAIL_NOT_AVAILABLE,
- STATUS_MSG_AUDIO_NOT_AVAIALABLE, ACTION_MSG_CALL_VOICEMAIL);
-
- // No data channel + Notification OK
- // action: call voicemail
- // msg: message waiting in call log page & audio not available in call details page.
- values.put(NOTIFICATION_CHANNEL_STATE, NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING);
- values.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_NO_CONNECTION);
- updateEntryForPackage(TEST_PACKAGES[1], values);
- checkExpectedMessage(TEST_PACKAGES[1], values, STATUS_MSG_MESSAGE_WAITING,
- STATUS_MSG_AUDIO_NOT_AVAIALABLE, ACTION_MSG_CALL_VOICEMAIL);
-
- // Not configured. No user action, so no message.
- values.put(CONFIGURATION_STATE, CONFIGURATION_STATE_NOT_CONFIGURED);
- updateEntryForPackage(TEST_PACKAGES[1], values);
- checkNoMessages(TEST_PACKAGES[1], values);
-
- // Can be configured - invite user for configure voicemail.
- values.put(CONFIGURATION_STATE, CONFIGURATION_STATE_CAN_BE_CONFIGURED);
- updateEntryForPackage(TEST_PACKAGES[1], values);
- checkExpectedMessage(TEST_PACKAGES[1], values, STATUS_MSG_INVITE_FOR_CONFIGURATION,
- STATUS_MSG_NONE, ACTION_MSG_CONFIGURE, TEST_SETTINGS_URI);
- }
-
- // Test that priority of messages are handled well.
- public void testMessageOrdering() {
- insertEntryForPackage(TEST_PACKAGES[0], getAllOkStatusValues());
- insertEntryForPackage(TEST_PACKAGES[1], getAllOkStatusValues());
-
- final ContentValues valuesNoNotificationGoodDataChannel = new ContentValues();
- valuesNoNotificationGoodDataChannel.put(NOTIFICATION_CHANNEL_STATE,
- NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
- valuesNoNotificationGoodDataChannel.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_OK);
-
- final ContentValues valuesNoNotificationNoDataChannel = new ContentValues();
- valuesNoNotificationNoDataChannel.put(NOTIFICATION_CHANNEL_STATE,
- NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
- valuesNoNotificationNoDataChannel.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_NO_CONNECTION);
-
- // Package1 with valuesNoNotificationGoodDataChannel and
- // package2 with valuesNoNotificationNoDataChannel. Package2 should be above.
- updateEntryForPackage(TEST_PACKAGES[0], valuesNoNotificationGoodDataChannel);
- updateEntryForPackage(TEST_PACKAGES[1], valuesNoNotificationNoDataChannel);
- List<StatusMessage> messages = getStatusMessages();
- assertEquals(2, messages.size());
- assertEquals(TEST_PACKAGES[0], messages.get(1).sourcePackage);
- assertEquals(TEST_PACKAGES[1], messages.get(0).sourcePackage);
-
- // Now reverse the values - ordering should be reversed as well.
- updateEntryForPackage(TEST_PACKAGES[0], valuesNoNotificationNoDataChannel);
- updateEntryForPackage(TEST_PACKAGES[1], valuesNoNotificationGoodDataChannel);
- messages = getStatusMessages();
- assertEquals(2, messages.size());
- assertEquals(TEST_PACKAGES[0], messages.get(0).sourcePackage);
- assertEquals(TEST_PACKAGES[1], messages.get(1).sourcePackage);
- }
-
- /** Checks that the expected source status message is returned by VoicemailStatusHelper. */
- private void checkExpectedMessage(String sourcePackage, ContentValues values,
- int expectedCallLogMsg, int expectedCallDetailsMsg, int expectedActionMsg,
- Uri expectedUri) {
- List<StatusMessage> messages = getStatusMessages();
- assertEquals(1, messages.size());
- checkMessageMatches(messages.get(0), sourcePackage, expectedCallLogMsg,
- expectedCallDetailsMsg, expectedActionMsg, expectedUri);
- }
-
- private void checkExpectedMessage(String sourcePackage, ContentValues values,
- int expectedCallLogMsg, int expectedCallDetailsMessage, int expectedActionMsg) {
- checkExpectedMessage(sourcePackage, values, expectedCallLogMsg, expectedCallDetailsMessage,
- expectedActionMsg, TEST_VOICEMAIL_URI);
- }
-
- private void checkMessageMatches(StatusMessage message, String expectedSourcePackage,
- int expectedCallLogMsg, int expectedCallDetailsMsg, int expectedActionMsg,
- Uri expectedUri) {
- assertEquals(expectedSourcePackage, message.sourcePackage);
- assertEquals(expectedCallLogMsg, message.callLogMessageId);
- assertEquals(expectedCallDetailsMsg, message.callDetailsMessageId);
- assertEquals(expectedActionMsg, message.actionMessageId);
- if (expectedUri == null) {
- assertNull(message.actionUri);
- } else {
- assertEquals(expectedUri, message.actionUri);
- }
- }
-
- private void checkNoMessages(String sourcePackage, ContentValues values) {
- assertEquals(1, updateEntryForPackage(sourcePackage, values));
- List<StatusMessage> messages = getStatusMessages();
- assertEquals(0, messages.size());
- }
-
- private ContentValues getAllOkStatusValues() {
- ContentValues values = new ContentValues();
- values.put(Status.SETTINGS_URI, TEST_SETTINGS_URI.toString());
- values.put(Status.VOICEMAIL_ACCESS_URI, TEST_VOICEMAIL_URI.toString());
- values.put(Status.CONFIGURATION_STATE, Status.CONFIGURATION_STATE_OK);
- values.put(Status.DATA_CHANNEL_STATE, Status.DATA_CHANNEL_STATE_OK);
- values.put(Status.NOTIFICATION_CHANNEL_STATE, Status.NOTIFICATION_CHANNEL_STATE_OK);
- return values;
- }
-
- private void insertEntryForPackage(String sourcePackage, ContentValues values) {
- // If insertion fails then try update as the record might already exist.
- if (getContentResolver().insert(Status.buildSourceUri(sourcePackage), values) == null) {
- updateEntryForPackage(sourcePackage, values);
- }
- }
-
- private void deleteEntryForPackage(String sourcePackage) {
- getContentResolver().delete(Status.buildSourceUri(sourcePackage), null, null);
- }
-
- private int updateEntryForPackage(String sourcePackage, ContentValues values) {
- return getContentResolver().update(
- Status.buildSourceUri(sourcePackage), values, null, null);
- }
-
- private List<StatusMessage> getStatusMessages() {
- // Restrict the cursor to only the the test packages to eliminate any side effects if there
- // are other status messages already stored on the device.
- Cursor cursor = getContentResolver().query(Status.CONTENT_URI,
- VoicemailStatusHelperImpl.PROJECTION, getTestPackageSelection(), null, null);
- return mStatusHelper.getStatusMessages(cursor);
- }
-
- private String getTestPackageSelection() {
- StringBuilder sb = new StringBuilder();
- for (String sourcePackage : TEST_PACKAGES) {
- if (sb.length() > 0) {
- sb.append(" OR ");
- }
- sb.append(String.format("(source_package='%s')", sourcePackage));
- }
- return sb.toString();
- }
-
- private ContentResolver getContentResolver() {
- return getContext().getContentResolver();
- }
-}