DO NOT MERGE - Mark RQ3A.210410.001 as merged
Bug: 190855093
Merged-In: I65f05fd54a28a550e9ace22d694502df479471dc
Change-Id: I5036f060660256c19189e0871340c2fd3217c882
diff --git a/Android.bp b/Android.bp
index 08288f8..27c5b2f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,3 +1,34 @@
+package {
+ default_applicable_licenses: ["packages_apps_Contacts_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'fileGroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// See: http://go/android-license-faq
+license {
+ name: "packages_apps_Contacts_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ "SPDX-license-identifier-BSD",
+ "SPDX-license-identifier-CC-BY",
+ ],
+ license_text: [
+ "NOTICE",
+ ],
+}
+
android_app {
name: "Contacts",
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index c9dc980..e233db9 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -74,6 +74,7 @@
android:launchMode="singleTop"
android:resizeableActivity="true"
android:theme="@style/LaunchScreenTheme"
+ android:exported="true"
android:visibleToInstantApps="true"
>
<intent-filter>
@@ -184,6 +185,7 @@
android:theme="@style/ContactPickerTheme"
android:uiOptions="splitActionBarWhenNarrow"
android:windowSoftInputMode="adjustResize"
+ android:exported="true"
android:visibleToInstantApps="true">
<meta-data android:name="android.app.shortcuts.new_config"
android:value="true" />
@@ -286,6 +288,7 @@
<activity
android:name=".activities.ShowOrCreateActivity"
+ android:exported="true"
android:theme="@android:style/Theme.Material.Light.Dialog.NoActionBar">
<intent-filter>
@@ -303,6 +306,7 @@
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/Theme.QuickContact"
+ android:exported="true"
android:windowSoftInputMode="stateUnchanged">
<intent-filter>
@@ -331,7 +335,8 @@
<!-- Responsible for creating notification channels when boot is completed or when app is
re-installed -->
- <receiver android:name=".interactions.OnBootOrUpgradeReceiver">
+ <receiver android:name=".interactions.OnBootOrUpgradeReceiver"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
@@ -342,6 +347,7 @@
android:name="ContactShortcut"
android:icon="@drawable/logo_quick_contacts_color_44in48dp"
android:label="@string/shortcutContact"
+ android:exported="true"
android:targetActivity=".activities.ContactSelectionActivity">
<intent-filter>
@@ -355,6 +361,7 @@
android:name="alias.DialShortcut"
android:icon="@drawable/logo_quick_contacts_dialer_color_44in48dp"
android:label="@string/shortcutDialContact"
+ android:exported="true"
android:targetActivity=".activities.ContactSelectionActivity">
<intent-filter>
@@ -370,6 +377,7 @@
android:name="alias.MessageShortcut"
android:icon="@drawable/logo_quick_contacts_mail_color_44in48dp"
android:label="@string/shortcutMessageContact"
+ android:exported="true"
android:targetActivity=".activities.ContactSelectionActivity">
<intent-filter>
@@ -389,6 +397,7 @@
<!-- Edit or create a contact with only the most important fields displayed initially. -->
<activity
android:name=".activities.ContactEditorActivity"
+ android:exported="true"
android:theme="@style/EditorActivityTheme">
<intent-filter>
@@ -418,6 +427,7 @@
<activity
android:name=".activities.ContactEditorSpringBoardActivity"
+ android:exported="true"
android:theme="@style/TransparentThemeAppCompat">
<intent-filter>
@@ -430,7 +440,8 @@
</intent-filter>
</activity>
- <activity android:name=".test.FragmentTestActivity">
+ <activity android:name=".test.FragmentTestActivity"
+ android:exported="true">
<intent-filter>
<category android:name="android.intent.category.TEST"/>
</intent-filter>
@@ -456,6 +467,7 @@
<activity
android:name=".activities.AttachPhotoActivity"
android:label="@string/attach_photo_dialog_title"
+ android:exported="true"
android:taskAffinity="">
<intent-filter>
<action android:name="android.intent.action.ATTACH_DATA"/>
@@ -468,6 +480,7 @@
<activity
android:name=".vcard.ImportVCardActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
+ android:exported="true"
android:theme="@style/BackgroundOnlyTheme">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
@@ -483,6 +496,7 @@
<activity
android:name=".vcard.NfcImportVCardActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
+ android:exported="true"
android:theme="@style/BackgroundOnlyTheme">
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
@@ -528,6 +542,7 @@
are set lower, so that the user does not see a disambig dialog -->
<activity
android:name="com.android.contacts.NonPhoneActivity"
+ android:exported="true"
android:theme="@style/NonPhoneActivityTheme">
<intent-filter android:priority="-1">
<action android:name="android.intent.action.MAIN"/>
@@ -556,6 +571,7 @@
<activity
android:name="com.android.contacts.dialog.CallSubjectDialog"
android:theme="@style/Theme.CallSubjectDialogTheme"
+ android:exported="true"
android:windowSoftInputMode="stateVisible|adjustResize">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..d97975c
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+ license_type: NOTICE
+}
diff --git a/lint-baseline.xml b/lint-baseline.xml
new file mode 100644
index 0000000..75b8078
--- /dev/null
+++ b/lint-baseline.xml
@@ -0,0 +1,521 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="Cast from `PhoneAccountHandle` to `Parcelable` requires API level 23 (current min is 21)"
+ errorLine1=" arguments.putParcelable(ARG_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/dialog/CallSubjectDialog.java"
+ line="249"
+ column="59"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast from `PhoneAccountHandle` to `Parcelable` requires API level 23 (current min is 21)"
+ errorLine1=" intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/CallUtil.java"
+ line="87"
+ column="72"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telecom.TelecomManager#getCallCapablePhoneAccounts`"
+ errorLine1=" List<PhoneAccountHandle> accountHandles = telecommMgr.getCallCapablePhoneAccounts();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/CallUtil.java"
+ line="164"
+ column="67"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telecom.TelecomManager#getPhoneAccount`"
+ errorLine1=" PhoneAccount account = telecommMgr.getPhoneAccount(accountHandle);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/CallUtil.java"
+ line="166"
+ column="52"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telecom.PhoneAccount#hasCapabilities`"
+ errorLine1=" if (account.hasCapabilities(PhoneAccount.CAPABILITY_VIDEO_CALLING)) {"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/CallUtil.java"
+ line="168"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telecom.PhoneAccount#hasCapabilities`"
+ errorLine1=" if (account.hasCapabilities(PhoneAccountSdkCompat"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/CallUtil.java"
+ line="175"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telecom.TelecomManager#getCallCapablePhoneAccounts`"
+ errorLine1=" List<PhoneAccountHandle> accountHandles = telecommMgr.getCallCapablePhoneAccounts();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/CallUtil.java"
+ line="211"
+ column="67"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telecom.TelecomManager#getPhoneAccount`"
+ errorLine1=" PhoneAccount account = telecommMgr.getPhoneAccount(accountHandle);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/CallUtil.java"
+ line="213"
+ column="52"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telecom.PhoneAccount#hasCapabilities`"
+ errorLine1=" if (account != null && account.hasCapabilities(PhoneAccount.CAPABILITY_CALL_SUBJECT)) {"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/CallUtil.java"
+ line="214"
+ column="48"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.content.ContentProviderOperation#isInsert`"
+ errorLine1=" return cpoWrapper.getOperation().isInsert();"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/compat/CompatUtils.java"
+ line="48"
+ column="46"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.content.ContentProviderOperation#isUpdate`"
+ errorLine1=" return cpoWrapper.getOperation().isUpdate();"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/compat/CompatUtils.java"
+ line="58"
+ column="46"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.content.ContentProviderOperation#isDelete`"
+ errorLine1=" return cpoWrapper.getOperation().isDelete();"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/compat/CompatUtils.java"
+ line="68"
+ column="46"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.content.ContentProviderOperation#isAssertQuery`"
+ errorLine1=" return cpoWrapper.getOperation().isAssertQuery();"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/compat/CompatUtils.java"
+ line="77"
+ column="46"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.widget.QuickContactBadge#setPrioritizedMimeType`"
+ errorLine1=" quickContact.setPrioritizedMimeType(Phone.CONTENT_ITEM_TYPE);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/list/ContactEntryListAdapter.java"
+ line="721"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 24 (current min is 21): `android.provider.ContactsContract.Directory#ENTERPRISE_CONTENT_URI`"
+ errorLine1=" public static final Uri ENTERPRISE_CONTENT_URI = Directory.ENTERPRISE_CONTENT_URI;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/compat/DirectorySdkCompat.java"
+ line="26"
+ column="54"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 24 (current min is 21): `android.provider.BlockedNumberContract#canCurrentUserBlockNumbers`"
+ errorLine1=" && BlockedNumberContract.canCurrentUserBlockNumbers(getContext());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/preference/DisplayOptionsPreferenceFragment.java"
+ line="300"
+ column="42"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 28 (current min is 21): `android.content.pm.PackageInfo#getLongVersionCode`"
+ errorLine1=" sCachedVersionCode = Long.toString(info.getLongVersionCode());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/util/HelpUtils.java"
+ line="125"
+ column="57"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 26 (current min is 21): `android.graphics.drawable.AdaptiveIconDrawable#getExtraInsetFraction`"
+ errorLine1=" return 1 / (1 + (2 * AdaptiveIconDrawable.getExtraInsetFraction()));"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/lettertiles/LetterTileDrawable.java"
+ line="293"
+ column="51"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telecom.PhoneAccount#getIcon`"
+ errorLine1=" return phoneAccount.getIcon();"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/compat/PhoneAccountCompat.java"
+ line="45"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.graphics.drawable.Icon#loadDrawable`"
+ errorLine1=" return accountIcon.loadDrawable(context);"
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/compat/PhoneAccountCompat.java"
+ line="84"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 23 (current min is 21): `android.telecom.PhoneAccount`"
+ errorLine1=" return (Drawable) PhoneAccount.class.getMethod("createIconDrawable", Context.class)"
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/compat/PhoneAccountCompat.java"
+ line="91"
+ column="31"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telephony.PhoneNumberUtils#createTtsSpannable`"
+ errorLine1=" return PhoneNumberUtils.createTtsSpannable(phoneNumber);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/compat/PhoneNumberUtilsCompat.java"
+ line="85"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telephony.PhoneNumberUtils#createTtsSpan`"
+ errorLine1=" return PhoneNumberUtils.createTtsSpan(phoneNumber);"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/compat/PhoneNumberUtilsCompat.java"
+ line="93"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telephony.PhoneNumberUtils#addTtsSpan`"
+ errorLine1=" PhoneNumberUtils.addTtsSpan(s, start, endExclusive);"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/compat/PhoneNumberUtilsCompat.java"
+ line="118"
+ column="30"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 23 (current min is 21): `android.provider.ContactsContract.ProviderStatus#CONTENT_URI`"
+ errorLine1=" .registerContentObserver(ProviderStatus.CONTENT_URI, false, this);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/list/ProviderStatusWatcher.java"
+ line="132"
+ column="42"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 23 (current min is 21): `android.provider.ContactsContract.ProviderStatus#CONTENT_URI`"
+ errorLine1=" Cursor cursor = mContext.getContentResolver().query(ProviderStatus.CONTENT_URI,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/list/ProviderStatusWatcher.java"
+ line="219"
+ column="69"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Field requires API level 23 (current min is 21): `android.provider.ContactsContract.ProviderStatus#CONTENT_URI`"
+ errorLine1=" if (!ProviderStatus.CONTENT_URI.equals(uri)) return;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/list/ProviderStatusWatcher.java"
+ line="270"
+ column="14"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 22 (current min is 21): `android.app.Activity#getReferrer`"
+ errorLine1=" if (mReferrer == null && CompatUtils.isLollipopMr1Compatible() && getReferrer() != null) {"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/quickcontact/QuickContactActivity.java"
+ line="652"
+ column="75"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 22 (current min is 21): `android.app.Activity#getReferrer`"
+ errorLine1=" mReferrer = getReferrer().getAuthority();"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/quickcontact/QuickContactActivity.java"
+ line="653"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 23 (current min is 21): `android.telecom.PhoneAccountHandle`"
+ errorLine1=" (PhoneAccountHandle) resultData.getParcelable("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/widget/SelectPhoneAccountDialogFragment.java"
+ line="130"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Cast from `PhoneAccountHandle` to `Parcelable` requires API level 23 (current min is 21)"
+ errorLine1=" selectedAccountHandle);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/widget/SelectPhoneAccountDialogFragment.java"
+ line="171"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telecom.TelecomManager#getPhoneAccount`"
+ errorLine1=" PhoneAccount account = mTelecomManager.getPhoneAccount(accountHandle);"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/widget/SelectPhoneAccountDialogFragment.java"
+ line="247"
+ column="52"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telecom.PhoneAccount#getLabel`"
+ errorLine1=" holder.labelTextView.setText(account.getLabel());"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/widget/SelectPhoneAccountDialogFragment.java"
+ line="251"
+ column="50"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telecom.PhoneAccount#getAddress`"
+ errorLine1=" if (account.getAddress() == null ||"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/widget/SelectPhoneAccountDialogFragment.java"
+ line="252"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telecom.PhoneAccount#getAddress`"
+ errorLine1=" TextUtils.isEmpty(account.getAddress().getSchemeSpecificPart())) {"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/widget/SelectPhoneAccountDialogFragment.java"
+ line="253"
+ column="47"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telecom.PhoneAccount#getAddress`"
+ errorLine1=" account.getAddress().getSchemeSpecificPart()));"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/widget/SelectPhoneAccountDialogFragment.java"
+ line="259"
+ column="41"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level R (current min is 21): `android.telephony.TelephonyManager#getSubscriptionId`"
+ errorLine1=" return new SimCard(telephony.getSimSerialNumber(), telephony.getSubscriptionId(),"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/model/SimCard.java"
+ line="244"
+ column="74"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 21): `android.provider.SimPhonebookContract.SimRecords#getContentUri`"
+ errorLine1=" SimRecords.getContentUri("
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/database/SimContactDaoImpl.java"
+ line="130"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 26 (current min is 21): `android.content.ContentResolver#query`"
+ errorLine1=" final Cursor cursor = mResolver.query(uri,"
+ errorLine2=" ~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/database/SimContactDaoImpl.java"
+ line="265"
+ column="45"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telecom.TelecomManager#placeCall`"
+ errorLine1=" telecomManager.placeCall(intent.getData(), intent.getExtras());"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/compat/telecom/TelecomManagerCompat.java"
+ line="43"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 22 (current min is 21): `android.telephony.TelephonyManager#isVoiceCapable`"
+ errorLine1=" return telephonyManager.isVoiceCapable();"
+ errorLine2=" ~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/compat/TelephonyManagerCompat.java"
+ line="49"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telephony.TelephonyManager#getPhoneCount`"
+ errorLine1=" return telephonyManager.getPhoneCount();"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/compat/TelephonyManagerCompat.java"
+ line="71"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telephony.TelephonyManager#getDeviceId`"
+ errorLine1=" return telephonyManager.getDeviceId(slotId);"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/compat/TelephonyManagerCompat.java"
+ line="93"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telephony.TelephonyManager#isTtyModeSupported`"
+ errorLine1=" return telephonyManager.isTtyModeSupported();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/compat/TelephonyManagerCompat.java"
+ line="111"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.telephony.TelephonyManager#isHearingAidCompatibilitySupported`"
+ errorLine1=" return telephonyManager.isHearingAidCompatibilitySupported();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/compat/TelephonyManagerCompat.java"
+ line="131"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 23 (current min is 21): `android.provider.Telephony.Threads#getOrCreateThreadId`"
+ errorLine1=" return Telephony.Threads.getOrCreateThreadId(context, recipient);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/src/com/android/contacts/compat/TelephonyThreadsCompat.java"
+ line="51"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="`android:contentInsetStartWithNavigation` requires API level 24 (current min is 21)"
+ errorLine1=" <item name="android:contentInsetStartWithNavigation">72dp</item>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Contacts/res/values/styles.xml"
+ line="215"
+ column="15"/>
+ </issue>
+
+</issues>
diff --git a/res/layout-land/contact_editor_fragment.xml b/res/layout-land/contact_editor_fragment.xml
index 6f026aa..e68d7a3 100644
--- a/res/layout-land/contact_editor_fragment.xml
+++ b/res/layout-land/contact_editor_fragment.xml
@@ -31,7 +31,7 @@
<include layout="@layout/photo_editor_view" />
- <!-- Dummy view so the first input field is not initially focused. b/21644158 -->
+ <!-- Placeholder view so the first input field is not initially focused. b/21644158 -->
<View
android:layout_width="0dp"
android:layout_height="0dp"
diff --git a/res/layout/contact_editor_fragment.xml b/res/layout/contact_editor_fragment.xml
index 03a84e1..694e1f6 100644
--- a/res/layout/contact_editor_fragment.xml
+++ b/res/layout/contact_editor_fragment.xml
@@ -38,7 +38,7 @@
<include layout="@layout/photo_editor_view" />
- <!-- Dummy view so the first input field is not initially focused. b/21644158 -->
+ <!-- Placeholder view so the first input field is not initially focused. b/21644158 -->
<View
android:layout_width="0dp"
android:layout_height="0dp"
diff --git a/res/layout/menu_item_action_view.xml b/res/layout/menu_item_action_view.xml
index 62eb758..1f8066e 100644
--- a/res/layout/menu_item_action_view.xml
+++ b/res/layout/menu_item_action_view.xml
@@ -15,7 +15,8 @@
limitations under the License.
-->
-<!-- A dummy action view to attach extra hidden content description to menuItem for Talkback. -->
+<!-- A placeholder action view to attach extra hidden content description to
+ menuItem for Talkback. -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
@@ -24,4 +25,4 @@
<View
android:layout_width="1dp"
android:layout_height= "1dp" />
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 928940b..1d85767 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -156,7 +156,7 @@
<string name="search_results_searching" msgid="1373859095361975648">"Haetaan..."</string>
<string name="event_edit_field_hint_text" msgid="1720286136507504896">"Päivämäärä"</string>
<string name="group_edit_field_hint_text" msgid="1159504474053684478">"Tunniste"</string>
- <string name="cancel_button_content_description" msgid="7407595608883650004">"Peruuta"</string>
+ <string name="cancel_button_content_description" msgid="7407595608883650004">"Peru"</string>
<string name="back_arrow_content_description" msgid="6727142616775523605">"Takaisin"</string>
<string name="action_menu_back_from_edit_select" msgid="7911226757462657242">"sulje"</string>
<string name="aggregation_suggestion_edit_dialog_message" msgid="4339333746086996062">"Haluatko muokata valittuja yhteystietoja? Antamasi tiedot kopioidaan."</string>
@@ -180,7 +180,7 @@
<string name="toast_text_copied" msgid="845906090076228771">"Teksti kopioitu"</string>
<string name="cancel_confirmation_dialog_message" msgid="7486892574762212762">"Hylätäänkö muutokset?"</string>
<string name="cancel_confirmation_dialog_cancel_editing_button" msgid="8280294641821133477">"Hylkää"</string>
- <string name="cancel_confirmation_dialog_keep_editing_button" msgid="7117943783437253341">"Peruuta"</string>
+ <string name="cancel_confirmation_dialog_keep_editing_button" msgid="7117943783437253341">"Peru"</string>
<string name="leave_customize_confirmation_dialog_message" msgid="5330853530872707231">"Hylätäänkö muokkaukset?"</string>
<string name="enter_contact_name" msgid="521859148893732679">"Hae yhteystiedoista"</string>
<string name="title_edit_group" msgid="4246193439931854759">"Poista yhteystiedot"</string>
@@ -389,8 +389,8 @@
<string name="import_from_vcf_file" msgid="6776403212804361301">".vcf-tiedosto"</string>
<string name="nothing_to_import_message" msgid="2594519620375509783">"Ei tuotavia tietoja"</string>
<string name="import_from_vcf_file_confirmation_message" msgid="8579284961401472204">"Tuodaanko yhteystiedot vCard-tiedostosta?"</string>
- <string name="cancel_import_confirmation_message" msgid="1007412828398265611">"Peruuta kohteen <xliff:g id="FILENAME">%s</xliff:g> tuonti?"</string>
- <string name="cancel_export_confirmation_message" msgid="370693160959236239">"Peruuta kohteen <xliff:g id="FILENAME">%s</xliff:g> vienti?"</string>
+ <string name="cancel_import_confirmation_message" msgid="1007412828398265611">"Peru kohteen <xliff:g id="FILENAME">%s</xliff:g> tuonti?"</string>
+ <string name="cancel_export_confirmation_message" msgid="370693160959236239">"Peru kohteen <xliff:g id="FILENAME">%s</xliff:g> vienti?"</string>
<string name="cancel_vcard_import_or_export_failed" msgid="3041814872516288484">"vCardin tuonnin/viennin peruutus epäonn."</string>
<string name="fail_reason_unknown" msgid="3721044979355043778">"Tuntematon virhe."</string>
<string name="fail_reason_could_not_open_file" msgid="6015509564074145162">"Tiedostoa \"<xliff:g id="FILE_NAME">%1$s</xliff:g>\" ei voi avata: <xliff:g id="EXACT_REASON">%2$s</xliff:g>"</string>
@@ -494,7 +494,7 @@
</plurals>
<string name="sim_import_failed_toast" msgid="358117391138073786">"SIM-yhteystietojen tuonti epäonnistui."</string>
<string name="sim_import_title" msgid="8202961146093040684">"Tuo SIM-kortilta"</string>
- <string name="sim_import_cancel_content_description" msgid="4746065462808862682">"Peruuta"</string>
+ <string name="sim_import_cancel_content_description" msgid="4746065462808862682">"Peru"</string>
<string name="auto_sync_off" msgid="7039314601316227882">"Automaattinen synkronointi ei ole käytössä. Ota toiminto käyttöön napauttamalla."</string>
<string name="dismiss_sync_alert" msgid="4057176963960104786">"Hylkää"</string>
<string name="account_sync_off" msgid="6187683798342006021">"Tilin synkronointi ei ole käytössä. Ota toiminto käyttöön napauttamalla."</string>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index 27dec42..5d76267 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -50,12 +50,12 @@
<string name="splitConfirmationWithPendingChanges" msgid="8617395780141069527">"तपाईँले पहिल्यै गरेका परिवर्तनहरू सुरक्षित गर्न र यस सम्पर्कलाई बहु सम्पर्कहरूमा अनलिंक गर्न चाहनुहुन्छ?"</string>
<string name="splitConfirmationWithPendingChanges_positive_button" msgid="131293000921403021">"सुरक्षित गरी अनलिकं गर्नुहोस्"</string>
<string name="joinConfirmation" msgid="1245184431169363397">"तपाईँले पहिलेनै गरिएका परिवर्तनहरूलाई तपाईँले चयन गरेका सम्पर्क ठेगाना सँग सुरक्षित गरी लिंक गर्न चाहनुहुन्छ?"</string>
- <string name="joinConfirmation_positive_button" msgid="8300713422725610480">"सुरक्षित गर्नुहोस् र लिंक गर्नुहोस्"</string>
+ <string name="joinConfirmation_positive_button" msgid="8300713422725610480">"सेभ गर्नुहोस् र लिंक गर्नुहोस्"</string>
<string name="contacts_linking_progress_bar" msgid="7922930766022513619">"लिङ्क गर्दै"</string>
<string name="contacts_unlinking_progress_bar" msgid="5696679068872394167">"अनलिङ्क गर्दै"</string>
<string name="menu_joinAggregate" msgid="3116395302755287038">"लिंक"</string>
<string name="menu_linkedContacts" msgid="6363718333551613063">"लिंक गरिएका सम्पर्कहरू हेर्ने"</string>
- <string name="menu_save" msgid="7204524700499687371">"सुरक्षित गर्नुहोस्"</string>
+ <string name="menu_save" msgid="7204524700499687371">"सेभ गर्नुहोस्"</string>
<string name="titleJoinContactDataWith" msgid="7342386037654890242">"सम्पर्क ठेगानाहरू लिंक गर्नुहोस्"</string>
<string name="blurbJoinContactDataWith" msgid="132105056919797709">"तपाईँले <xliff:g id="NAME">%s</xliff:g> मा लिंक हुन चाहनु भएको सम्पर्क ठेगाना चयन गर्नुहोस्:"</string>
<string name="separatorJoinAggregateSuggestions" msgid="8347769365870796983">"सुझाव गरिएका सम्पर्कहरू"</string>
@@ -153,7 +153,7 @@
<string name="take_new_photo" msgid="4383091978116875778">"नयाँ फोटो खिच्नुहोस्"</string>
<string name="pick_photo" msgid="2050859661654812588">"फोटो छान्नुहोस्"</string>
<string name="pick_new_photo" msgid="4218112182908240970">"नयाँ फोटो चयन गर्नुहोस्"</string>
- <string name="search_results_searching" msgid="1373859095361975648">"खोजी कार्य गर्दै..."</string>
+ <string name="search_results_searching" msgid="1373859095361975648">"खोजिँदै छ..."</string>
<string name="event_edit_field_hint_text" msgid="1720286136507504896">"मिति"</string>
<string name="group_edit_field_hint_text" msgid="1159504474053684478">"लेबल"</string>
<string name="cancel_button_content_description" msgid="7407595608883650004">"रद्द गर्नुहोस्"</string>
@@ -262,17 +262,17 @@
<string name="call_assistant" msgid="8556909944379826616">"<xliff:g id="CUSTOM_LABEL">%s</xliff:g> मा कल गर्नुहोस्"</string>
<string name="call_mms" msgid="1760746475672950386">"MMS कल"</string>
<string name="call_by_shortcut" msgid="5707329943368933423">"<xliff:g id="CONTACT_NAME">%s</xliff:g> (कल गर्नुहोस्)"</string>
- <string name="sms_custom" msgid="3684453744622817362">"<xliff:g id="CUSTOM_LABEL">%s</xliff:g> मा पाठ सन्देश पठाउनुहोस्"</string>
+ <string name="sms_custom" msgid="3684453744622817362">"<xliff:g id="CUSTOM_LABEL">%s</xliff:g> मा टेक्स्ट म्यासेज पठाउनुहोस्"</string>
<string name="sms_home" msgid="6132392861245316613">"पाठ गृह"</string>
<string name="sms_mobile" msgid="433949735070334192">"पाठ मोबाइल"</string>
<string name="sms_work" msgid="7784676780449153911">"पाठ काम"</string>
<string name="sms_fax_work" msgid="8239716828120939345">"पाठलाई काममा फ्याक्स गर्नुहोस्"</string>
<string name="sms_fax_home" msgid="6887675360794775735">"पाठलाई घर फ्याक्स गर्नुहोस्"</string>
- <string name="sms_pager" msgid="1052540072760129272">"पाठ सन्देश पेजरमा"</string>
+ <string name="sms_pager" msgid="1052540072760129272">"टेक्स्ट म्यासेज पेजरमा"</string>
<string name="sms_other" msgid="3584200156296349098">"पाठ"</string>
<string name="sms_callback" msgid="6932315941997609031">"पाठ कलब्याक"</string>
<string name="sms_car" msgid="6051606941547979352">"पाठ कार"</string>
- <string name="sms_company_main" msgid="4801585186677340070">"कार्पायलय मूख्यमा पाठ सन्देश"</string>
+ <string name="sms_company_main" msgid="4801585186677340070">"कार्पायलय मूख्यमा टेक्स्ट म्यासेज"</string>
<string name="sms_isdn" msgid="8093269429091061478">"पाठ ISDN"</string>
<string name="sms_main" msgid="624730854551629076">"पाठ मूल"</string>
<string name="sms_other_fax" msgid="8272996838482574564">"पाठ फ्याक्स"</string>
@@ -321,7 +321,7 @@
<string name="organizationLabelsGroup" msgid="2342482097897299099">"संगठन"</string>
<string name="relationLabelsGroup" msgid="8931615792208307291">"सम्बन्ध"</string>
<string name="eventLabelsGroup" msgid="8625868552164376823">"विशेष मिति"</string>
- <string name="sms" msgid="4246338112764847384">"पाठ सन्देश"</string>
+ <string name="sms" msgid="4246338112764847384">"टेक्स्ट म्यासेज"</string>
<string name="postal_address" msgid="5031809899673855074">"ठेगाना"</string>
<string name="ghostData_company" msgid="3873500610390675876">"कम्पनी"</string>
<string name="ghostData_title" msgid="8584897460662904533">"शीर्षक"</string>
@@ -375,7 +375,7 @@
<string name="display_warn_remove_ungrouped" msgid="522866344738506017">"\" <xliff:g id="GROUP">%s</xliff:g> \" लाई सिङ्कबाट हटाउनाले समूहमा नरहेका सम्पर्कहरूलाई पनि हटाउने छ।"</string>
<string name="savingDisplayGroups" msgid="6779839417901711381">"प्रदर्शन विकल्पहरू बचत गर्दै ..."</string>
<string name="listCustomView" msgid="5782275477737032610">"आफू अनुकूल पारिएको दृश्य"</string>
- <string name="dialog_new_contact_account" msgid="5652018124788855057">"आयातीत सम्पर्कहरू निम्नमा सुरक्षित गर्नुहोस्:"</string>
+ <string name="dialog_new_contact_account" msgid="5652018124788855057">"आयातीत सम्पर्कहरू निम्नमा सेभ गर्नुहोस्:"</string>
<string name="import_from_sim" msgid="7825280799813847991">"SIM कार्ड"</string>
<string name="import_from_sim_summary_fmt" msgid="4234771828377985321">"SIM <xliff:g id="SIM_NAME">%1$s</xliff:g>"</string>
<plurals name="import_from_sim_secondary_contact_count_fmt" formatted="false" msgid="8737770002554878728">
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index a4a0fa6..008f1ef 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -356,11 +356,11 @@
<string name="chat" msgid="8390862712584830532">"ਚੈਟ"</string>
<string name="description_minus_button" msgid="1305985971158054217">"ਮਿਟਾਓ"</string>
<string name="expand_name_fields_description" msgid="6059558159338959487">"ਹੋਰ ਨਾਮ ਖੇਤਰ ਦਿਖਾਓ"</string>
- <string name="collapse_name_fields_description" msgid="7950435675716414477">"ਨਾਮ ਖੇਤਰਾਂ ਨੂੰ ਸੁੰਗੇੜੋ"</string>
+ <string name="collapse_name_fields_description" msgid="7950435675716414477">"ਨਾਮ ਖੇਤਰਾਂ ਨੂੰ ਸਮੇਟੋ"</string>
<string name="expand_phonetic_name_fields_description" msgid="7414340689396399173">"ਹੋਰ ਧੁਨੀਆਤਮਿਕ ਨਾਮ ਖੇਤਰ ਦਿਖਾਓ"</string>
- <string name="collapse_phonetic_name_fields_description" msgid="4614902922362144094">"ਫ਼ੋਨੈਟਿਕ ਨਾਮ ਖੇਤਰਾਂ ਨੂੰ ਸੁੰਗੇੜੋ"</string>
+ <string name="collapse_phonetic_name_fields_description" msgid="4614902922362144094">"ਫ਼ੋਨੈਟਿਕ ਨਾਮ ਖੇਤਰਾਂ ਨੂੰ ਸਮੇਟੋ"</string>
<string name="expand_fields_description" msgid="8604448646798943909">"ਵਿਸਤਾਰ ਕਰੋ"</string>
- <string name="collapse_fields_description" msgid="3213872920491992960">"ਸੁੰਗੇੜੋ"</string>
+ <string name="collapse_fields_description" msgid="3213872920491992960">"ਸਮੇਟੋ"</string>
<string name="announce_expanded_fields" msgid="8410808184164186871">"ਵਿਸਤਾਰ ਕੀਤਾ ਗਿਆ"</string>
<string name="announce_collapsed_fields" msgid="7611318715383228182">"ਸੁੰਗੇੜਿਆ ਗਿਆ"</string>
<string name="list_filter_all_accounts" msgid="6173785387972096770">"ਸਾਰੇ ਸੰਪਰਕ"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index a6bacf1..a1be30f 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -207,7 +207,7 @@
<string name="date_time_set" msgid="8526160894146496334">"Definir"</string>
<string name="header_im_entry" msgid="3581797653862294826">"MI"</string>
<string name="header_organization_entry" msgid="7428066442988227441">"Entidade"</string>
- <string name="header_nickname_entry" msgid="1110276804512795150">"Pseudónimo"</string>
+ <string name="header_nickname_entry" msgid="1110276804512795150">"Alcunha"</string>
<string name="header_note_entry" msgid="339680292368016788">"Nota"</string>
<string name="header_website_entry" msgid="3618691707215428785">"Website"</string>
<string name="header_event_entry" msgid="70962228694476731">"Evento"</string>
@@ -304,7 +304,7 @@
<string name="account_phone" msgid="8044426231251817556">"Dispositivo"</string>
<string name="account_sim" msgid="3200457113308694663">"SIM"</string>
<string name="nameLabelsGroup" msgid="513809148312046843">"Nome"</string>
- <string name="nicknameLabelsGroup" msgid="794390116782033956">"Pseudónimo"</string>
+ <string name="nicknameLabelsGroup" msgid="794390116782033956">"Alcunha"</string>
<string name="name_given" msgid="3883661251894628431">"Nome próprio"</string>
<string name="name_family" msgid="2907432135923624482">"Apelido"</string>
<string name="name_prefix" msgid="8857117624713905211">"Título académico ou profissional"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index e980543..0869174 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -495,9 +495,9 @@
<string name="sim_import_failed_toast" msgid="358117391138073786">"Không nhập được liên hệ trên SIM"</string>
<string name="sim_import_title" msgid="8202961146093040684">"Nhập từ SIM"</string>
<string name="sim_import_cancel_content_description" msgid="4746065462808862682">"Hủy"</string>
- <string name="auto_sync_off" msgid="7039314601316227882">"Tự động đồng bộ hóa đang tắt. Hãy nhấn để bật."</string>
+ <string name="auto_sync_off" msgid="7039314601316227882">"Tính năng tự động đồng bộ hóa đang tắt. Hãy nhấn để bật."</string>
<string name="dismiss_sync_alert" msgid="4057176963960104786">"Loại bỏ"</string>
- <string name="account_sync_off" msgid="6187683798342006021">"Đồng bộ hóa tài khoản đang tắt. Hãy nhấn để bật."</string>
+ <string name="account_sync_off" msgid="6187683798342006021">"Tính năng đồng bộ hóa tài khoản đang tắt. Hãy nhấn để bật."</string>
<string name="turn_auto_sync_on_dialog_title" msgid="3812155064863594938">"Bật tự động đồng bộ hóa?"</string>
<string name="turn_auto_sync_on_dialog_body" msgid="5386810641905184682">"Những thay đổi bạn thực hiện đối với tất cả ứng dụng và tài khoản, không chỉ với Danh bạ Google, sẽ luôn được cập nhật giữa web và thiết bị của bạn."</string>
<string name="turn_auto_sync_on_dialog_confirm_btn" msgid="5575717918836806519">"Bật"</string>
diff --git a/src/com/android/contacts/CallUtil.java b/src/com/android/contacts/CallUtil.java
index bba1faa..0f09df9 100644
--- a/src/com/android/contacts/CallUtil.java
+++ b/src/com/android/contacts/CallUtil.java
@@ -109,7 +109,7 @@
/**
* Return an Intent for making a phone call. A given Uri will be used as is (without any
- * sanity check).
+ * quick check).
*/
public static Intent getCallIntent(Uri uri) {
return new Intent(Intent.ACTION_CALL, uri);
diff --git a/src/com/android/contacts/ContactPhotoManager.java b/src/com/android/contacts/ContactPhotoManager.java
index e5f808d..1468ed7 100644
--- a/src/com/android/contacts/ContactPhotoManager.java
+++ b/src/com/android/contacts/ContactPhotoManager.java
@@ -602,8 +602,8 @@
private static final String[] COLUMNS = new String[] { Photo._ID, Photo.PHOTO };
/**
- * Dummy object used to indicate that a bitmap for a given key could not be stored in the
- * cache.
+ * Placeholder object used to indicate that a bitmap for a given key could not
+ * be stored in the cache.
*/
private static final BitmapHolder BITMAP_UNAVAILABLE;
diff --git a/src/com/android/contacts/SimImportFragment.java b/src/com/android/contacts/SimImportFragment.java
index cee1b1a..1d16df0 100644
--- a/src/com/android/contacts/SimImportFragment.java
+++ b/src/com/android/contacts/SimImportFragment.java
@@ -18,7 +18,6 @@
import android.app.Activity;
import android.app.Fragment;
import android.app.LoaderManager;
-import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.content.Loader;
@@ -26,7 +25,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.snackbar.Snackbar;
-import androidx.localbroadcastmanager.content.LocalBroadcastManager;
+
import androidx.collection.ArrayMap;
import androidx.core.view.ViewCompat;
import androidx.core.widget.ContentLoadingProgressBar;
@@ -372,7 +371,7 @@
if (position < 0 || position >= getCount()) {
return View.NO_ID;
}
- return getItem(position).getId();
+ return getItem(position).getRecordNumber();
}
@Override
diff --git a/src/com/android/contacts/database/SimContactDaoImpl.java b/src/com/android/contacts/database/SimContactDaoImpl.java
index 5ba6bd5..54106f0 100644
--- a/src/com/android/contacts/database/SimContactDaoImpl.java
+++ b/src/com/android/contacts/database/SimContactDaoImpl.java
@@ -26,20 +26,20 @@
import android.net.Uri;
import android.os.Build;
import android.os.RemoteException;
-import android.provider.BaseColumns;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
-import androidx.annotation.VisibleForTesting;
-import androidx.collection.ArrayMap;
+import android.provider.SimPhonebookContract;
+import android.provider.SimPhonebookContract.SimRecords;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
-import android.text.TextUtils;
import android.util.SparseArray;
+import androidx.collection.ArrayMap;
+
import com.android.contacts.R;
import com.android.contacts.compat.CompatUtils;
import com.android.contacts.model.SimCard;
@@ -47,6 +47,7 @@
import com.android.contacts.model.account.AccountWithDataSet;
import com.android.contacts.util.PermissionsUtil;
import com.android.contacts.util.SharedPreferenceUtil;
+
import com.google.common.base.Joiner;
import java.util.ArrayList;
@@ -75,14 +76,6 @@
// query parameter limit.
static final int QUERY_MAX_BATCH_SIZE = 100;
- @VisibleForTesting
- public static final Uri ICC_CONTENT_URI = Uri.parse("content://icc/adn");
-
- public static String _ID = BaseColumns._ID;
- public static String NAME = "name";
- public static String NUMBER = "number";
- public static String EMAILS = "emails";
-
private final Context mContext;
private final ContentResolver mResolver;
private final TelephonyManager mTelephonyManager;
@@ -128,18 +121,14 @@
if (sim.hasValidSubscriptionId()) {
return loadSimContacts(sim.getSubscriptionId());
}
- return loadSimContacts();
+ // Return an empty list.
+ return new ArrayList<>(0);
}
public ArrayList<SimContact> loadSimContacts(int subscriptionId) {
- return loadFrom(ICC_CONTENT_URI.buildUpon()
- .appendPath("subId")
- .appendPath(String.valueOf(subscriptionId))
- .build());
- }
-
- public ArrayList<SimContact> loadSimContacts() {
- return loadFrom(ICC_CONTENT_URI);
+ return loadFrom(
+ SimRecords.getContentUri(
+ subscriptionId, SimPhonebookContract.ElementaryFiles.EF_ADN));
}
@Override
@@ -273,7 +262,12 @@
private static final Object SIM_READ_LOCK = new Object();
private ArrayList<SimContact> loadFrom(Uri uri) {
synchronized (SIM_READ_LOCK) {
- final Cursor cursor = mResolver.query(uri, null, null, null, null);
+ final Cursor cursor = mResolver.query(uri,
+ new String[]{
+ SimRecords.RECORD_NUMBER,
+ SimRecords.NAME,
+ SimRecords.PHONE_NUMBER
+ }, null, null);
if (cursor == null) {
// Assume null means there are no SIM contacts.
return new ArrayList<>(0);
@@ -288,22 +282,20 @@
}
private ArrayList<SimContact> loadFromCursor(Cursor cursor) {
- final int colId = cursor.getColumnIndex(_ID);
- final int colName = cursor.getColumnIndex(NAME);
- final int colNumber = cursor.getColumnIndex(NUMBER);
- final int colEmails = cursor.getColumnIndex(EMAILS);
+ final int colRecordNumber = cursor.getColumnIndex(SimRecords.RECORD_NUMBER);
+ final int colName = cursor.getColumnIndex(SimRecords.NAME);
+ final int colNumber = cursor.getColumnIndex(SimRecords.PHONE_NUMBER);
final ArrayList<SimContact> result = new ArrayList<>();
while (cursor.moveToNext()) {
- final long id = cursor.getLong(colId);
+ final int recordNumber = cursor.getInt(colRecordNumber);
final String name = cursor.getString(colName);
final String number = cursor.getString(colNumber);
- final String emails = cursor.getString(colEmails);
- final SimContact contact = new SimContact(id, name, number, parseEmails(emails));
+ final SimContact contact = new SimContact(recordNumber, name, number, null);
// Only include contact if it has some useful data
- if (contact.hasName() || contact.hasPhone() || contact.hasEmails()) {
+ if (contact.hasName() || contact.hasPhone()) {
result.add(contact);
}
}
@@ -392,10 +384,6 @@
return ops;
}
- private String[] parseEmails(String emails) {
- return !TextUtils.isEmpty(emails) ? emails.split(",") : null;
- }
-
private boolean hasTelephony() {
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
}
diff --git a/src/com/android/contacts/model/SimCard.java b/src/com/android/contacts/model/SimCard.java
index ea74379..969d96d 100644
--- a/src/com/android/contacts/model/SimCard.java
+++ b/src/com/android/contacts/model/SimCard.java
@@ -19,6 +19,7 @@
import androidx.annotation.RequiresApi;
import android.telephony.PhoneNumberUtils;
import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
@@ -78,11 +79,6 @@
mCountryCode = countryCode != null ? countryCode.toUpperCase(Locale.US) : null;
}
- public SimCard(String simId, CharSequence carrierName,
- CharSequence displayName, String phoneNumber, String countryCode) {
- this(simId, NO_SUBSCRIPTION_ID, carrierName, displayName, phoneNumber, countryCode);
- }
-
public String getSimId() {
return mSimId;
}
@@ -245,12 +241,14 @@
public static SimCard create(TelephonyManager telephony, String displayLabel) {
if (telephony.getSimState() == TelephonyManager.SIM_STATE_READY) {
- return new SimCard(telephony.getSimSerialNumber(),
+ return new SimCard(telephony.getSimSerialNumber(), telephony.getSubscriptionId(),
telephony.getSimOperatorName(), displayLabel, telephony.getLine1Number(),
telephony.getSimCountryIso());
} else {
// This should never happen but in case it does just fallback to an "empty" instance
- return new SimCard(/* SIM id */ "", /* operator name */ null, displayLabel,
+ return new SimCard(/* SIM id */ "",
+ /* subscriptionId */ SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+ /* operator name */ null, displayLabel,
/* phone number */ "", /* Country code */ null);
}
}
diff --git a/src/com/android/contacts/model/SimContact.java b/src/com/android/contacts/model/SimContact.java
index 7babe27..820e346 100644
--- a/src/com/android/contacts/model/SimContact.java
+++ b/src/com/android/contacts/model/SimContact.java
@@ -43,28 +43,28 @@
* Holds data for contacts loaded from the SIM card.
*/
public class SimContact implements Parcelable {
- private final long mId;
+ private final int mRecordNumber;
private final String mName;
private final String mPhone;
private final String[] mEmails;
- public SimContact(long id, String name, String phone) {
- this(id, name, phone, null);
+ public SimContact(int recordNumber, String name, String phone) {
+ this(recordNumber, name, phone, null);
}
- public SimContact(long id, String name, String phone, String[] emails) {
- mId = id;
+ public SimContact(int recordNumber, String name, String phone, String[] emails) {
+ mRecordNumber = recordNumber;
mName = name;
mPhone = phone == null ? "" : phone.trim();
mEmails = emails;
}
public SimContact(SimContact other) {
- this(other.mId, other.mName, other.mPhone, other.mEmails);
+ this(other.mRecordNumber, other.mName, other.mPhone, other.mEmails);
}
- public long getId() {
- return mId;
+ public int getRecordNumber() {
+ return mRecordNumber;
}
public String getName() {
@@ -117,7 +117,7 @@
}
public void appendAsContactRow(MatrixCursor cursor) {
- cursor.newRow().add(ContactsContract.Contacts._ID, mId)
+ cursor.newRow().add(ContactsContract.Contacts._ID, mRecordNumber)
.add(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY, mName)
.add(ContactsContract.Contacts.LOOKUP_KEY, getLookupKey());
}
@@ -152,7 +152,7 @@
@Override
public String toString() {
return "SimContact{" +
- "mId=" + mId +
+ "mId=" + mRecordNumber +
", mName='" + mName + '\'' +
", mPhone='" + mPhone + '\'' +
", mEmails=" + Arrays.toString(mEmails) +
@@ -166,13 +166,13 @@
final SimContact that = (SimContact) o;
- return mId == that.mId && Objects.equals(mName, that.mName) &&
+ return mRecordNumber == that.mRecordNumber && Objects.equals(mName, that.mName) &&
Objects.equals(mPhone, that.mPhone) && Arrays.equals(mEmails, that.mEmails);
}
@Override
public int hashCode() {
- int result = (int) (mId ^ (mId >>> 32));
+ int result = (int) (mRecordNumber ^ (mRecordNumber >>> 32));
result = 31 * result + (mName != null ? mName.hashCode() : 0);
result = 31 * result + (mPhone != null ? mPhone.hashCode() : 0);
result = 31 * result + Arrays.hashCode(mEmails);
@@ -186,7 +186,7 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeLong(mId);
+ dest.writeInt(mRecordNumber);
dest.writeString(mName);
dest.writeString(mPhone);
dest.writeStringArray(mEmails);
@@ -195,11 +195,11 @@
public static final Creator<SimContact> CREATOR = new Creator<SimContact>() {
@Override
public SimContact createFromParcel(Parcel source) {
- final long id = source.readLong();
+ final int recordNumber = source.readInt();
final String name = source.readString();
final String phone = source.readString();
final String[] emails = source.createStringArray();
- return new SimContact(id, name, phone, emails);
+ return new SimContact(recordNumber, name, phone, emails);
}
@Override
@@ -253,7 +253,7 @@
@Override
public int compare(SimContact lhs, SimContact rhs) {
// We assume ids are unique.
- return Long.compare(lhs.mId, rhs.mId);
+ return Long.compare(lhs.mRecordNumber, rhs.mRecordNumber);
}
};
}
diff --git a/src/com/android/contacts/preference/ContactsPreferences.java b/src/com/android/contacts/preference/ContactsPreferences.java
index 85da891..e478b9b 100644
--- a/src/com/android/contacts/preference/ContactsPreferences.java
+++ b/src/com/android/contacts/preference/ContactsPreferences.java
@@ -246,7 +246,7 @@
* true if the contact editor should show the "accounts changed" notification, that is:
* - If it's the first launch.
* - Or, if the default account has been removed.
- * (And some extra sanity check)
+ * (And some extra soundness check)
*
* Note if this method returns {@code false}, the caller can safely assume that
* {@link #getDefaultAccount} will return a valid account. (Either an account which still
diff --git a/src/com/android/contacts/util/StopWatch.java b/src/com/android/contacts/util/StopWatch.java
index 4300eff..1797d2a 100644
--- a/src/com/android/contacts/util/StopWatch.java
+++ b/src/com/android/contacts/util/StopWatch.java
@@ -84,7 +84,7 @@
}
/**
- * Return a dummy instance that does no operations.
+ * Return a no-op StopWatch instance that does no operations.
*/
public static StopWatch getNullStopWatch() {
return NullStopWatch.INSTANCE;
diff --git a/tests/Android.bp b/tests/Android.bp
index 2e1d47b..10ebbc9 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -1,3 +1,13 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "packages_apps_Contacts_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ // SPDX-license-identifier-CC-BY
+ default_applicable_licenses: ["packages_apps_Contacts_license"],
+}
+
android_test {
name: "ContactsTests",
@@ -12,6 +22,8 @@
static_libs: [
"androidx.test.rules",
+ "androidx.test.runner",
+ "androidx.test.ext.junit",
"hamcrest-library",
"mockito-target-minus-junit4",
"ub-uiautomator",
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index f61efda..f22f92c 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -40,7 +40,8 @@
<uses-library android:name="android.test.runner" />
<meta-data android:name="com.android.contacts.iconset" android:resource="@xml/iconset" />
- <activity android:name=".allintents.AllIntentsActivity">
+ <activity android:name=".allintents.AllIntentsActivity"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
@@ -48,7 +49,8 @@
</intent-filter>
</activity>
- <activity android:name=".allintents.ResultActivity">
+ <activity android:name=".allintents.ResultActivity"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
diff --git a/tests/src/com/android/contacts/activities/SimImportActivityTest.java b/tests/src/com/android/contacts/activities/SimImportActivityTest.java
index 7069ef1..250ce4b 100644
--- a/tests/src/com/android/contacts/activities/SimImportActivityTest.java
+++ b/tests/src/com/android/contacts/activities/SimImportActivityTest.java
@@ -40,6 +40,8 @@
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Data;
+import android.provider.SimPhonebookContract;
+import android.provider.SimPhonebookContract.SimRecords;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.Until;
@@ -48,9 +50,9 @@
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.filters.SdkSuppress;
-import androidx.test.runner.AndroidJUnit4;
import com.android.contacts.SimImportService;
import com.android.contacts.database.SimContactDao;
@@ -224,10 +226,10 @@
final AccountWithDataSet targetAccount = mAccountHelper.addTestAccount(
mAccountHelper.generateAccountName("SimImportActivity0_targetAccount_"));
- final MockContentProvider iccProvider = new MockContentProvider();
- iccProvider.expect(MockContentProvider.Query.forAnyUri())
- .withDefaultProjection(new String[] {SimContactDaoImpl._ID, SimContactDaoImpl.NAME,
- SimContactDaoImpl.NUMBER, SimContactDaoImpl.EMAILS })
+ final MockContentProvider simPhonebookProvider = new MockContentProvider();
+ simPhonebookProvider.expect(MockContentProvider.Query.forAnyUri())
+ .withProjection(
+ SimRecords.RECORD_NUMBER, SimRecords.NAME, SimRecords.PHONE_NUMBER)
.anyNumberOfTimes()
.returnRow(toCursorRow(new SimContact(1, "Import One", "5550101")))
.returnRow(toCursorRow(new SimContact(2, "Skip Two", "5550102")))
@@ -236,7 +238,7 @@
.returnRow(toCursorRow(new SimContact(5, "Skip Five", "5550105")))
.returnRow(toCursorRow(new SimContact(6, "Import Six", "5550106")));
final MockContentResolver mockResolver = new MockContentResolver();
- mockResolver.addProvider("icc", iccProvider);
+ mockResolver.addProvider(SimPhonebookContract.AUTHORITY, simPhonebookProvider);
final ContentProviderClient contactsProviderClient = mContext.getContentResolver()
.acquireContentProviderClient(ContactsContract.AUTHORITY);
mockResolver.addProvider(ContactsContract.AUTHORITY, new ForwardingContentProvider(
@@ -258,6 +260,7 @@
mActivity = mInstrumentation.startActivitySync(
new Intent(mContext, SimImportActivity.class)
+ .putExtra(SimImportActivity.EXTRA_SUBSCRIPTION_ID, 1)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
assertTrue(mDevice.wait(Until.hasObject(By.desc("Show more")), TIMEOUT));
@@ -319,6 +322,7 @@
mActivity = mInstrumentation.startActivitySync(
new Intent(mContext, SimImportActivity.class)
+ .putExtra(SimImportActivity.EXTRA_SUBSCRIPTION_ID, 1)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
assertTrue(mDevice.wait(Until.hasObject(By.text("Import One")), TIMEOUT));
@@ -351,7 +355,7 @@
}
private Object[] toCursorRow(SimContact contact) {
- return new Object[] { contact.getId(), contact.getName(), contact.getPhone(), null };
+ return new Object[]{contact.getRecordNumber(), contact.getName(), contact.getPhone()};
}
private SimCard someSimCard() {
diff --git a/tests/src/com/android/contacts/database/SimContactDaoTests.java b/tests/src/com/android/contacts/database/SimContactDaoTests.java
index 0b5b37f..680ba10 100644
--- a/tests/src/com/android/contacts/database/SimContactDaoTests.java
+++ b/tests/src/com/android/contacts/database/SimContactDaoTests.java
@@ -45,16 +45,18 @@
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Data;
+import android.provider.SimPhonebookContract;
+import android.provider.SimPhonebookContract.SimRecords;
import android.test.mock.MockContentResolver;
import android.test.mock.MockContext;
import androidx.annotation.RequiresApi;
import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.filters.SdkSuppress;
import androidx.test.filters.SmallTest;
import androidx.test.filters.Suppress;
-import androidx.test.runner.AndroidJUnit4;
import com.android.contacts.model.SimCard;
import com.android.contacts.model.SimContact;
@@ -578,92 +580,78 @@
@RunWith(AndroidJUnit4.class)
public static class LoadContactsUnitTests {
- private MockContentProvider mMockIccProvider;
+ private MockContentProvider mMockSimPhonebookProvider;
private Context mContext;
@Before
public void setUp() {
mContext = mock(MockContext.class);
final MockContentResolver mockResolver = new MockContentResolver();
- mMockIccProvider = new MockContentProvider();
- mockResolver.addProvider("icc", mMockIccProvider);
+ mMockSimPhonebookProvider = new MockContentProvider();
+ mockResolver.addProvider(SimPhonebookContract.AUTHORITY, mMockSimPhonebookProvider);
when(mContext.getContentResolver()).thenReturn(mockResolver);
}
@Test
public void createsContactsFromCursor() {
- mMockIccProvider.expect(MockContentProvider.Query.forAnyUri())
+ mMockSimPhonebookProvider.expect(MockContentProvider.Query.forAnyUri())
.withDefaultProjection(
- SimContactDaoImpl._ID, SimContactDaoImpl.NAME,
- SimContactDaoImpl.NUMBER, SimContactDaoImpl.EMAILS)
+ SimRecords.RECORD_NUMBER, SimRecords.NAME, SimRecords.PHONE_NUMBER)
.withAnyProjection()
.withAnySelection()
.withAnySortOrder()
- .returnRow(1, "Name One", "5550101", null)
- .returnRow(2, "Name Two", "5550102", null)
- .returnRow(3, "Name Three", null, null)
- .returnRow(4, null, "5550104", null)
- .returnRow(5, "Name Five", "5550105",
- "five@example.com,nf@example.com,name.five@example.com")
- .returnRow(6, "Name Six", "5550106", "thesix@example.com");
+ .returnRow(1, "Name One", "5550101")
+ .returnRow(2, "Name Two", "5550102")
+ .returnRow(3, "Name Three", null)
+ .returnRow(4, null, "5550104");
final SimContactDao sut = SimContactDao.create(mContext);
final List<SimContact> contacts = sut
- .loadContactsForSim(new SimCard("123", "carrier", "sim", null, "us"));
+ .loadContactsForSim(new SimCard("123", 1, "carrier", "sim", null, "us"));
assertThat(contacts, equalTo(
Arrays.asList(
new SimContact(1, "Name One", "5550101", null),
new SimContact(2, "Name Two", "5550102", null),
new SimContact(3, "Name Three", null, null),
- new SimContact(4, null, "5550104", null),
- new SimContact(5, "Name Five", "5550105", new String[] {
- "five@example.com", "nf@example.com", "name.five@example.com"
- }),
- new SimContact(6, "Name Six", "5550106", new String[] {
- "thesix@example.com"
- })
+ new SimContact(4, null, "5550104", null)
)));
}
@Test
public void excludesEmptyContactsFromResult() {
- mMockIccProvider.expect(MockContentProvider.Query.forAnyUri())
+ mMockSimPhonebookProvider.expect(MockContentProvider.Query.forAnyUri())
.withDefaultProjection(
- SimContactDaoImpl._ID, SimContactDaoImpl.NAME,
- SimContactDaoImpl.NUMBER, SimContactDaoImpl.EMAILS)
+ SimRecords.RECORD_NUMBER, SimRecords.NAME, SimRecords.PHONE_NUMBER)
.withAnyProjection()
.withAnySelection()
.withAnySortOrder()
- .returnRow(1, "Non Empty1", "5550101", null)
- .returnRow(2, "", "", "")
- .returnRow(3, "Non Empty2", null, null)
- .returnRow(4, null, null, null)
- .returnRow(5, "", null, null)
- .returnRow(6, null, "5550102", null)
- .returnRow(7, null, null, "user@example.com");
+ .returnRow(1, "Non Empty1", "5550101")
+ .returnRow(2, "", "")
+ .returnRow(3, "Non Empty2", null)
+ .returnRow(4, null, null)
+ .returnRow(5, "", null)
+ .returnRow(6, null, "5550102");
final SimContactDao sut = SimContactDao.create(mContext);
final List<SimContact> contacts = sut
- .loadContactsForSim(new SimCard("123", "carrier", "sim", null, "us"));
+ .loadContactsForSim(new SimCard("123", 1, "carrier", "sim", null, "us"));
assertThat(contacts, equalTo(
Arrays.asList(
new SimContact(1, "Non Empty1", "5550101", null),
new SimContact(3, "Non Empty2", null, null),
- new SimContact(6, null, "5550102", null),
- new SimContact(7, null, null, new String[] { "user@example.com" })
+ new SimContact(6, null, "5550102", null)
)));
}
@Test
public void usesSimCardSubscriptionIdIfAvailable() {
- mMockIccProvider.expectQuery(SimContactDaoImpl.ICC_CONTENT_URI.buildUpon()
- .appendPath("subId").appendPath("2").build())
+ mMockSimPhonebookProvider.expectQuery(SimRecords.getContentUri(2,
+ SimPhonebookContract.ElementaryFiles.EF_ADN))
.withDefaultProjection(
- SimContactDaoImpl._ID, SimContactDaoImpl.NAME,
- SimContactDaoImpl.NUMBER, SimContactDaoImpl.EMAILS)
+ SimRecords.RECORD_NUMBER, SimRecords.NAME, SimRecords.PHONE_NUMBER)
.withAnyProjection()
.withAnySelection()
.withAnySortOrder()
@@ -671,32 +659,14 @@
final SimContactDao sut = SimContactDao.create(mContext);
sut.loadContactsForSim(new SimCard("123", 2, "carrier", "sim", null, "us"));
- mMockIccProvider.verify();
- }
-
- @Test
- public void omitsSimCardSubscriptionIdIfUnavailable() {
- mMockIccProvider.expectQuery(SimContactDaoImpl.ICC_CONTENT_URI)
- .withDefaultProjection(
- SimContactDaoImpl._ID, SimContactDaoImpl.NAME,
- SimContactDaoImpl.NUMBER, SimContactDaoImpl.EMAILS)
- .withAnyProjection()
- .withAnySelection()
- .withAnySortOrder()
- .returnEmptyCursor();
-
- final SimContactDao sut = SimContactDao.create(mContext);
- sut.loadContactsForSim(new SimCard("123", SimCard.NO_SUBSCRIPTION_ID,
- "carrier", "sim", null, "us"));
- mMockIccProvider.verify();
+ mMockSimPhonebookProvider.verify();
}
@Test
public void returnsEmptyListForEmptyCursor() {
- mMockIccProvider.expect(MockContentProvider.Query.forAnyUri())
+ mMockSimPhonebookProvider.expect(MockContentProvider.Query.forAnyUri())
.withDefaultProjection(
- SimContactDaoImpl._ID, SimContactDaoImpl.NAME,
- SimContactDaoImpl.NUMBER, SimContactDaoImpl.EMAILS)
+ SimRecords.RECORD_NUMBER, SimRecords.NAME, SimRecords.PHONE_NUMBER)
.withAnyProjection()
.withAnySelection()
.withAnySortOrder()
@@ -704,7 +674,7 @@
final SimContactDao sut = SimContactDao.create(mContext);
List<SimContact> result = sut
- .loadContactsForSim(new SimCard("123", "carrier", "sim", null, "us"));
+ .loadContactsForSim(new SimCard("123", 1, "carrier", "sim", null, "us"));
assertTrue(result.isEmpty());
}
@@ -725,7 +695,7 @@
final SimContactDao sut = SimContactDao.create(mContext);
final List<SimContact> result = sut
- .loadContactsForSim(new SimCard("123", "carrier", "sim", null, "us"));
+ .loadContactsForSim(new SimCard("123", 1, "carrier", "sim", null, "us"));
assertTrue(result.isEmpty());
}
}
diff --git a/tests/src/com/android/contacts/editor/ContactEditorUtilsTest.java b/tests/src/com/android/contacts/editor/ContactEditorUtilsTest.java
index 7ffecc1..06d64a8 100644
--- a/tests/src/com/android/contacts/editor/ContactEditorUtilsTest.java
+++ b/tests/src/com/android/contacts/editor/ContactEditorUtilsTest.java
@@ -197,7 +197,7 @@
}
@Test
- public void testShouldShowAccountChangedNotification_sanity_check() {
+ public void testShouldShowAccountChangedNotification_initial_check() {
// Prepare 1 account and save it as the default.
mTarget.saveDefaultAccount(ACCOUNT_1_A);
diff --git a/tests/src/com/android/contacts/model/RawContactDeltaListTests.java b/tests/src/com/android/contacts/model/RawContactDeltaListTests.java
index 03e1d4f..d9ff184 100644
--- a/tests/src/com/android/contacts/model/RawContactDeltaListTests.java
+++ b/tests/src/com/android/contacts/model/RawContactDeltaListTests.java
@@ -17,6 +17,8 @@
package com.android.contacts.model;
import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
@@ -56,6 +58,8 @@
public static final long CONTACT_BOB = 10;
public static final long CONTACT_MARY = 11;
+ public static final long INSERTED_CONTACT_ID = 3;
+
public static final long PHONE_RED = 20;
public static final long PHONE_GREEN = 21;
public static final long PHONE_BLUE = 22;
@@ -182,6 +186,8 @@
static void assertDiffPattern(ArrayList<CPOWrapper> diff, CPOWrapper... pattern) {
assertEquals("Unexpected operations", pattern.length, diff.size());
+
+ ContentProviderResult[] fakeBackReferences = new ContentProviderResult[diff.size()];
for (int i = 0; i < pattern.length; i++) {
final CPOWrapper expected = pattern[i];
final CPOWrapper found = diff.get(i);
@@ -193,21 +199,25 @@
final String foundType = getTypeString(found);
assertEquals("Unexpected type", expectedType, foundType);
- if (CompatUtils.isDeleteCompat(expected)) continue;
-
- try {
- final ContentValues expectedValues = getValues(expected.getOperation());
- final ContentValues foundValues = getValues(found.getOperation());
-
- expectedValues.remove(BaseColumns._ID);
- foundValues.remove(BaseColumns._ID);
-
- assertEquals("Unexpected values", expectedValues, foundValues);
- } catch (NoSuchFieldException e) {
- fail(e.toString());
- } catch (IllegalAccessException e) {
- fail(e.toString());
+ if (CompatUtils.isDeleteCompat(expected)) {
+ continue;
}
+
+ if (CompatUtils.isInsertCompat(found)) {
+ fakeBackReferences[i] = new ContentProviderResult(
+ ContentUris.withAppendedId(RawContacts.CONTENT_URI, INSERTED_CONTACT_ID));
+ } else if (CompatUtils.isUpdateCompat(found)) {
+ fakeBackReferences[i] = new ContentProviderResult(1);
+ }
+
+
+ ContentValues expectedValues = expected.getOperation().resolveValueBackReferences(
+ new ContentProviderResult[0], 0);
+ ContentValues foundValues = found.getOperation().resolveValueBackReferences(
+ fakeBackReferences, fakeBackReferences.length);
+ expectedValues.remove(BaseColumns._ID);
+ foundValues.remove(BaseColumns._ID);
+ assertEquals("Unexpected values", expectedValues, foundValues);
}
}
@@ -247,6 +257,7 @@
static CPOWrapper buildUpdateAggregationKeepTogether(long rawContactId) {
final ContentValues values = new ContentValues();
values.put(AggregationExceptions.RAW_CONTACT_ID1, rawContactId);
+ values.put(AggregationExceptions.RAW_CONTACT_ID2, INSERTED_CONTACT_ID);
values.put(AggregationExceptions.TYPE, AggregationExceptions.TYPE_KEEP_TOGETHER);
return buildCPOWrapper(AggregationExceptions.CONTENT_URI, TYPE_UPDATE, values);
}
@@ -462,7 +473,8 @@
assertDiffPattern(first,
buildAssertVersion(VER_FIRST),
buildUpdateAggregationSuspended(),
- buildCPOWrapper(Data.CONTENT_URI, TYPE_INSERT, buildDataInsert(bluePhone, CONTACT_BOB)),
+ buildCPOWrapper(Data.CONTENT_URI, TYPE_INSERT,
+ buildDataInsert(bluePhone, CONTACT_BOB)),
buildUpdateAggregationDefault());
// Merge in the second version, verify that our insert remains
@@ -470,7 +482,8 @@
assertDiffPattern(merged,
buildAssertVersion(VER_SECOND),
buildUpdateAggregationSuspended(),
- buildCPOWrapper(Data.CONTENT_URI, TYPE_INSERT, buildDataInsert(bluePhone, CONTACT_BOB)),
+ buildCPOWrapper(Data.CONTENT_URI, TYPE_INSERT,
+ buildDataInsert(bluePhone, CONTACT_BOB)),
buildUpdateAggregationDefault());
}
@@ -479,10 +492,11 @@
VER_FIRST, buildPhone(PHONE_RED)));
final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
VER_SECOND, buildPhone(PHONE_RED)), buildBeforeEntity(mContext, CONTACT_MARY,
- VER_SECOND, buildPhone(PHONE_RED)));
+ VER_SECOND, buildPhone(PHONE_RED)));
// Add new contact locally, should remain insert
final ContentValues joePhoneInsert = buildPhone(PHONE_BLUE);
+ joePhoneInsert.put(Data.RAW_CONTACT_ID, INSERTED_CONTACT_ID);
final RawContactDelta joeContact = buildAfterEntity(joePhoneInsert);
final ContentValues joeContactInsert = joeContact.getValues().getCompleteValues();
joeContactInsert.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_SUSPENDED);
@@ -542,6 +556,7 @@
buildUpdateAggregationDefault());
final ContentValues phoneInsert = phone.getCompleteValues();
+ phoneInsert.put(Data.RAW_CONTACT_ID, INSERTED_CONTACT_ID);
final ContentValues contactInsert = first.getByRawContactId(CONTACT_MARY).getValues()
.getCompleteValues();
contactInsert.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_SUSPENDED);
@@ -562,11 +577,11 @@
final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
VER_SECOND, buildPhone(PHONE_RED)));
- assertEquals((Long)VER_FIRST, getVersion(first, CONTACT_BOB));
- assertEquals((Long)VER_SECOND, getVersion(second, CONTACT_BOB));
+ assertEquals((Long) VER_FIRST, getVersion(first, CONTACT_BOB));
+ assertEquals((Long) VER_SECOND, getVersion(second, CONTACT_BOB));
final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
- assertEquals((Long)VER_SECOND, getVersion(merged, CONTACT_BOB));
+ assertEquals((Long) VER_SECOND, getVersion(merged, CONTACT_BOB));
}
public void testMergeAfterEnsureAndTrim() {
@@ -585,7 +600,8 @@
assertDiffPattern(first,
buildAssertVersion(VER_FIRST),
buildUpdateAggregationSuspended(),
- buildCPOWrapper(Data.CONTENT_URI, TYPE_INSERT, buildDataInsert(bobPhone, CONTACT_BOB)),
+ buildCPOWrapper(Data.CONTENT_URI, TYPE_INSERT,
+ buildDataInsert(bobPhone, CONTACT_BOB)),
buildUpdateAggregationDefault());
// Trim values and ensure that we don't insert things
diff --git a/tests/src/com/android/contacts/tests/FakeSimContactDao.java b/tests/src/com/android/contacts/tests/FakeSimContactDao.java
index c40ab25..ab6c653 100644
--- a/tests/src/com/android/contacts/tests/FakeSimContactDao.java
+++ b/tests/src/com/android/contacts/tests/FakeSimContactDao.java
@@ -110,5 +110,4 @@
result.canReadSimContacts = false;
return result;
}
-
}
diff --git a/tests/src/com/android/contacts/tests/SimContactsTestHelper.java b/tests/src/com/android/contacts/tests/SimContactsTestHelper.java
index 740d013..99c95cb 100644
--- a/tests/src/com/android/contacts/tests/SimContactsTestHelper.java
+++ b/tests/src/com/android/contacts/tests/SimContactsTestHelper.java
@@ -28,13 +28,15 @@
import android.database.Cursor;
import android.net.Uri;
import android.os.RemoteException;
+import android.provider.SimPhonebookContract;
+import android.provider.SimPhonebookContract.ElementaryFiles;
+import android.provider.SimPhonebookContract.SimRecords;
import android.telephony.TelephonyManager;
import androidx.annotation.NonNull;
import androidx.test.InstrumentationRegistry;
import com.android.contacts.database.SimContactDao;
-import com.android.contacts.database.SimContactDaoImpl;
import com.android.contacts.model.SimCard;
import com.android.contacts.model.SimContact;
@@ -47,6 +49,8 @@
private final TelephonyManager mTelephonyManager;
private final ContentResolver mResolver;
private final SimContactDao mSimDao;
+ private final int mSubscriptionId;
+ private final Uri mDefaultSimAdnUri;
public SimContactsTestHelper() {
this(InstrumentationRegistry.getTargetContext());
@@ -57,10 +61,13 @@
mResolver = context.getContentResolver();
mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
mSimDao = SimContactDao.create(context);
+ mSubscriptionId = mTelephonyManager.getSubscriptionId();
+ mDefaultSimAdnUri = SimRecords.getContentUri(
+ mTelephonyManager.getSubscriptionId(), ElementaryFiles.EF_ADN);
}
public int getSimContactCount() {
- Cursor cursor = mContext.getContentResolver().query(SimContactDaoImpl.ICC_CONTENT_URI,
+ Cursor cursor = mContext.getContentResolver().query(mDefaultSimAdnUri,
null, null, null, null);
try {
return cursor.getCount();
@@ -71,15 +78,13 @@
public Uri addSimContact(String name, String number) {
ContentValues values = new ContentValues();
- // Oddly even though it's called name when querying we have to use "tag" for it to work
- // when inserting.
if (name != null) {
- values.put("tag", name);
+ values.put(SimRecords.NAME, name);
}
if (number != null) {
- values.put(SimContactDaoImpl.NUMBER, number);
+ values.put(SimRecords.PHONE_NUMBER, number);
}
- return mResolver.insert(SimContactDaoImpl.ICC_CONTENT_URI, values);
+ return mResolver.insert(mDefaultSimAdnUri, values);
}
public ContentProviderResult[] deleteAllSimContacts()
@@ -92,11 +97,11 @@
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
for (SimContact contact : contacts) {
ops.add(ContentProviderOperation
- .newDelete(SimContactDaoImpl.ICC_CONTENT_URI)
- .withSelection(getWriteSelection(contact), null)
+ .newDelete(SimRecords.getItemUri(
+ mSubscriptionId, ElementaryFiles.EF_ADN, contact.getRecordNumber()))
.build());
}
- return mResolver.applyBatch(SimContactDaoImpl.ICC_CONTENT_URI.getAuthority(), ops);
+ return mResolver.applyBatch(SimPhonebookContract.AUTHORITY, ops);
}
public ContentProviderResult[] restore(ArrayList<ContentProviderOperation> restoreOps)
@@ -106,7 +111,7 @@
// Remove SIM contacts because we assume that caller wants the data to be in the exact
// state as when the restore ops were captured.
deleteAllSimContacts();
- return mResolver.applyBatch(SimContactDaoImpl.ICC_CONTENT_URI.getAuthority(), restoreOps);
+ return mResolver.applyBatch(SimPhonebookContract.AUTHORITY, restoreOps);
}
public ArrayList<ContentProviderOperation> captureRestoreSnapshot() {
@@ -124,24 +129,16 @@
" Please manually remove SIM contacts with emails.");
}
ops.add(ContentProviderOperation
- .newInsert(SimContactDaoImpl.ICC_CONTENT_URI)
- .withValue("tag", contact.getName())
- .withValue("number", contact.getPhone())
+ .newInsert(mDefaultSimAdnUri)
+ .withValue(SimRecords.NAME, contact.getName())
+ .withValue(SimRecords.PHONE_NUMBER, contact.getPhone())
.build());
}
return ops;
}
- public String getWriteSelection(SimContact simContact) {
- return "tag='" + simContact.getName() + "' AND " + SimContactDaoImpl.NUMBER + "='" +
- simContact.getPhone() + "'";
- }
-
- public int deleteSimContact(@NonNull String name, @NonNull String number) {
- // IccProvider doesn't use the selection args.
- final String selection = "tag='" + name + "' AND " +
- SimContactDaoImpl.NUMBER + "='" + number + "'";
- return mResolver.delete(SimContactDaoImpl.ICC_CONTENT_URI, selection, null);
+ public int deleteSimContact(@NonNull Uri recordUri) {
+ return mResolver.delete(recordUri, null);
}
public boolean isSimReady() {
@@ -156,7 +153,7 @@
if (!isSimReady()) return false;
final String name = "writabeProbe" + System.nanoTime();
final Uri uri = addSimContact(name, "15095550101");
- return uri != null && deleteSimContact(name, "15095550101") == 1;
+ return uri != null && deleteSimContact(uri) == 1;
}
public void assumeSimReady() {