diff options
author | twyen <twyen@google.com> | 2018-01-03 11:11:14 -0800 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-01-03 11:12:11 -0800 |
commit | b3b437048465ab8da902fb9107c883331481da2c (patch) | |
tree | ab8bb36e5cf7545e74a7d33161f621299a672831 /java | |
parent | 15fd7535818344e905745b390a1b4098ca4d2cf1 (diff) |
Only consider writable accounts for preferred SIM
Some apps will add their own account to contacts and cause PhoneLookup to return multiple accounts. Since Contacts cannot write to these accounts the preferred SIM settings on them does not make sense.
In this CL a reduced version of AccountTypeManager is used to determine if the account is writable. External accounts (which capabilities are determined by parsing their sync adapter) are not supported.
Bug: 70689051
Test: CallingAccountSelectorTest
PiperOrigin-RevId: 180693656
Change-Id: I24e93860cd576777c6d3861f65f75baa234dac87
Diffstat (limited to 'java')
-rw-r--r-- | java/com/android/dialer/precall/impl/CallingAccountSelector.java | 69 | ||||
-rw-r--r-- | java/com/android/dialer/precall/impl/PreferredAccountUtil.java | 22 |
2 files changed, 82 insertions, 9 deletions
diff --git a/java/com/android/dialer/precall/impl/CallingAccountSelector.java b/java/com/android/dialer/precall/impl/CallingAccountSelector.java index a61a3b1c6..d407296da 100644 --- a/java/com/android/dialer/precall/impl/CallingAccountSelector.java +++ b/java/com/android/dialer/precall/impl/CallingAccountSelector.java @@ -18,6 +18,7 @@ package com.android.dialer.precall.impl; import android.app.Activity; import android.content.ContentResolver; +import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.Intent; @@ -28,8 +29,10 @@ import android.net.Uri; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; import android.provider.ContactsContract.Contacts; +import android.provider.ContactsContract.Data; import android.provider.ContactsContract.PhoneLookup; import android.provider.ContactsContract.QuickContact; +import android.provider.ContactsContract.RawContacts; import android.support.annotation.MainThread; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -59,6 +62,7 @@ import com.android.dialer.preferredsim.suggestion.SimSuggestionComponent; import com.android.dialer.preferredsim.suggestion.SuggestionProvider.Suggestion; import com.android.dialer.telecom.TelecomUtil; import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -296,7 +300,7 @@ public class CallingAccountSelector implements PreCallAction { if (!isPreferredSimEnabled(context)) { return result; } - result.dataId = getDataId(context.getContentResolver(), phoneNumber); + result.dataId = getDataId(context, phoneNumber); if (result.dataId.isPresent()) { result.phoneAccountHandle = getPreferredAccount(context, result.dataId.get()); } @@ -313,24 +317,33 @@ public class CallingAccountSelector implements PreCallAction { @WorkerThread @NonNull private static Optional<String> getDataId( - @NonNull ContentResolver contentResolver, @Nullable String phoneNumber) { + @NonNull Context context, @Nullable String phoneNumber) { Assert.isWorkerThread(); if (VERSION.SDK_INT < VERSION_CODES.N) { return Optional.absent(); } try (Cursor cursor = - contentResolver.query( - Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber)), - new String[] {PhoneLookup.DATA_ID}, - null, - null, - null)) { + context + .getContentResolver() + .query( + Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber)), + new String[] {PhoneLookup.DATA_ID}, + null, + null, + null)) { if (cursor == null) { return Optional.absent(); } + ImmutableSet<String> validAccountTypes = PreferredAccountUtil.getValidAccountTypes(context); Set<String> result = new ArraySet<>(); while (cursor.moveToNext()) { - result.add(cursor.getString(0)); + Optional<String> accountType = + getAccountType(context.getContentResolver(), cursor.getLong(0)); + if (accountType.isPresent() && validAccountTypes.contains(accountType.get())) { + result.add(cursor.getString(0)); + } else { + LogUtil.i("CallingAccountSelector.getDataId", "ignoring non-writable " + accountType); + } } // TODO(twyen): if there are multiples attempt to grab from the contact that initiated the // call. @@ -344,6 +357,44 @@ public class CallingAccountSelector implements PreCallAction { } @WorkerThread + private static Optional<String> getAccountType(ContentResolver contentResolver, long dataId) { + Assert.isWorkerThread(); + Optional<Long> rawContactId = getRawContactId(contentResolver, dataId); + if (!rawContactId.isPresent()) { + return Optional.absent(); + } + try (Cursor cursor = + contentResolver.query( + ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId.get()), + new String[] {RawContacts.ACCOUNT_TYPE}, + null, + null, + null)) { + if (cursor == null || !cursor.moveToFirst()) { + return Optional.absent(); + } + return Optional.of(cursor.getString(0)); + } + } + + @WorkerThread + private static Optional<Long> getRawContactId(ContentResolver contentResolver, long dataId) { + Assert.isWorkerThread(); + try (Cursor cursor = + contentResolver.query( + ContentUris.withAppendedId(Data.CONTENT_URI, dataId), + new String[] {Data.RAW_CONTACT_ID}, + null, + null, + null)) { + if (cursor == null || !cursor.moveToFirst()) { + return Optional.absent(); + } + return Optional.of(cursor.getLong(0)); + } + } + + @WorkerThread @NonNull private static Optional<PhoneAccountHandle> getPreferredAccount( @NonNull Context context, @NonNull String dataId) { diff --git a/java/com/android/dialer/precall/impl/PreferredAccountUtil.java b/java/com/android/dialer/precall/impl/PreferredAccountUtil.java index a41cb6e78..650588829 100644 --- a/java/com/android/dialer/precall/impl/PreferredAccountUtil.java +++ b/java/com/android/dialer/precall/impl/PreferredAccountUtil.java @@ -30,7 +30,9 @@ import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.TextUtils; import com.android.dialer.common.LogUtil; +import com.android.dialer.configprovider.ConfigProviderComponent; import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; /** * Utilities for looking up and validating preferred {@link PhoneAccountHandle}. Contacts should @@ -91,4 +93,24 @@ public class PreferredAccountUtil { } return false; } + + /** + * Return a set of {@link android.accounts.Account#type} that is known to have writable contacts. + * This is a light weight implementation of {@link + * com.android.contacts.common.model.AccountTypeManager#getAccountTypes(boolean)}. External + * accounts are not supported. + */ + public static ImmutableSet<String> getValidAccountTypes(Context context) { + return ImmutableSet.copyOf( + ConfigProviderComponent.get(context) + .getConfigProvider() + .getString( + "preferred_sim_valid_account_types", + "com.google;" + + "com.osp.app.signin;" + + "com.android.exchange;" + + "com.google.android.exchange;" + + "com.google.android.gm.exchange") + .split(";")); + } } |