aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarcus Hagerott <mhagerott@google.com>2021-11-02 10:35:27 -0700
committerMarcus Hagerott <mhagerott@google.com>2021-12-03 09:40:35 -0800
commit5f48b2ce4c02fc18c205479add7b8451ce63317c (patch)
treefaf01813851efabb334c0079d809ba466829b0e5 /src
parent7c94fba31988343706f5f3abf0c0231aa1a8ef21 (diff)
downloadContactsProvider-5f48b2ce4c02fc18c205479add7b8451ce63317c.tar.gz
Revert "Migrate custom local account to AOSP local account"
This reverts commit 20428525d38d92bf6f4631fe040dd26b02be4c97 which added the 1602 DB upgrade and adds a 1603 updgrade to clean up the changes that were made in 1602. Reverting because partners are concerned about backwards compatibility. Test: atest ContactsProviderTests CtsContactsProviderTestCases BUG=188347648 BUG=179694648 Change-Id: Ib5f675c7794aca57088b492084dcea30169923a5
Diffstat (limited to 'src')
-rw-r--r--src/com/android/providers/contacts/ContactsDatabaseHelper.java202
-rw-r--r--src/com/android/providers/contacts/ContactsProvider2.java6
2 files changed, 32 insertions, 176 deletions
diff --git a/src/com/android/providers/contacts/ContactsDatabaseHelper.java b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
index fb3dd555..e9b830a8 100644
--- a/src/com/android/providers/contacts/ContactsDatabaseHelper.java
+++ b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
@@ -91,11 +91,9 @@ import android.util.Base64;
import android.util.Log;
import android.util.Slog;
-import androidx.annotation.NonNull;
-import androidx.annotation.VisibleForTesting;
-
import com.android.common.content.SyncStateContentProviderHelper;
import com.android.internal.R.bool;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.providers.contacts.aggregation.util.CommonNicknameCache;
import com.android.providers.contacts.database.ContactsTableUtil;
import com.android.providers.contacts.database.DeletedContactsTableUtil;
@@ -112,7 +110,6 @@ import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
-import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
@@ -150,7 +147,7 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper {
* 1600-1699 T
* </pre>
*/
- static final int DATABASE_VERSION = 1602;
+ static final int DATABASE_VERSION = 1603;
private static final int MINIMUM_SUPPORTED_VERSION = 700;
@VisibleForTesting
@@ -296,15 +293,6 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper {
+ "INNER JOIN view_raw_contacts ON (name_lookup.raw_contact_id = "
+ "view_raw_contacts._id)";
- /**
- * Used for display name lookup key queries.
- *
- * <p>See comment on {@link Views#RAW_CONTACTS_LOOKUP_COMPAT} for more detail.
- */
- public static final String NAME_LOOKUP_JOIN_RAW_CONTACTS_LOOKUP_COMPAT = "name_lookup "
- + "INNER JOIN view_raw_contacts_lookup_compat ON (name_lookup.raw_contact_id = "
- + "view_raw_contacts_lookup_compat._id)";
-
public static final String RAW_CONTACTS_JOIN_ACCOUNTS = Tables.RAW_CONTACTS
+ " JOIN " + Tables.ACCOUNTS + " ON ("
+ AccountsColumns.CONCRETE_ID + "=" + RawContactsColumns.CONCRETE_ACCOUNT_ID
@@ -339,12 +327,6 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper {
public static final String RAW_ENTITIES = "view_raw_entities";
public static final String GROUPS = "view_groups";
public static final String SETTINGS = "view_settings";
- /**
- * View used for lookup key queries that allows lookup keys created for a custom local
- * account to continue to resolve to the same contact even though these accounts were
- * converted to the default AOSP local account.
- */
- public static final String RAW_CONTACTS_LOOKUP_COMPAT = "view_raw_contacts_lookup_compat";
/** The data_usage_stat table with the low-res columns. */
public static final String DATA_USAGE_LR = "view_data_usage";
@@ -714,12 +696,6 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper {
String CONCRETE_ACCOUNT_TYPE = Tables.ACCOUNTS + "." + ACCOUNT_TYPE;
String CONCRETE_DATA_SET = Tables.ACCOUNTS + "." + DATA_SET;
- String ACCOUNT_TYPE_AND_DATA_SET =
- "(CASE WHEN " + AccountsColumns.CONCRETE_DATA_SET + " IS NULL"
- + " THEN " + AccountsColumns.CONCRETE_ACCOUNT_TYPE
- + " ELSE " + AccountsColumns.CONCRETE_ACCOUNT_TYPE + "||'/'||"
- + AccountsColumns.CONCRETE_DATA_SET
- + " END)";
}
public interface DirectoryColumns {
@@ -976,17 +952,6 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper {
private NameSplitter.Name mName = new NameSplitter.Name();
private CharArrayBuffer mCharArrayBuffer = new CharArrayBuffer(128);
private NameSplitter mNameSplitter;
- /**
- * The account that was used for local contacts on the OS the device was first shipped with.
- *
- * <p>Prior to Android T it was common for OEMs to define their own custom local acount types
- * but this fragmentation was problematic so these were migrated to match the AOSP convention
- * for the local account. This variable has the "original" OEM specified local account rather
- * than the current one for use in code that performs the migration and ensures compatibility.
- *
- * <p>Note: this is set lazily but is really only mutable for testability.
- */
- private AccountWithDataSet mOriginalLocalAccount;
private final Executor mLazilyCreatedExecutor =
new ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
@@ -1629,7 +1594,6 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper {
createContactsTriggers(db);
createContactsIndexes(db, false /* we build stats table later */);
createPresenceTables(db);
- createLocalAccountCompatViews(db);
loadNicknameLookupTable(db);
@@ -1908,8 +1872,11 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper {
+ AccountsColumns.CONCRETE_ACCOUNT_NAME + " AS " + RawContacts.ACCOUNT_NAME + ","
+ AccountsColumns.CONCRETE_ACCOUNT_TYPE + " AS " + RawContacts.ACCOUNT_TYPE + ","
+ AccountsColumns.CONCRETE_DATA_SET + " AS " + RawContacts.DATA_SET + ","
- + AccountsColumns.ACCOUNT_TYPE_AND_DATA_SET + " AS "
- + RawContacts.ACCOUNT_TYPE_AND_DATA_SET + ","
+ + "(CASE WHEN " + AccountsColumns.CONCRETE_DATA_SET + " IS NULL THEN "
+ + AccountsColumns.CONCRETE_ACCOUNT_TYPE
+ + " ELSE " + AccountsColumns.CONCRETE_ACCOUNT_TYPE + "||'/'||"
+ + AccountsColumns.CONCRETE_DATA_SET + " END) AS "
+ + RawContacts.ACCOUNT_TYPE_AND_DATA_SET + ","
+ RawContactsColumns.CONCRETE_SOURCE_ID + " AS " + RawContacts.SOURCE_ID + ","
+ RawContactsColumns.CONCRETE_BACKUP_ID + " AS " + RawContacts.BACKUP_ID + ","
+ RawContactsColumns.CONCRETE_VERSION + " AS " + RawContacts.VERSION + ","
@@ -2246,8 +2213,11 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper {
+ AccountsColumns.CONCRETE_ACCOUNT_NAME + " AS " + Groups.ACCOUNT_NAME + ","
+ AccountsColumns.CONCRETE_ACCOUNT_TYPE + " AS " + Groups.ACCOUNT_TYPE + ","
+ AccountsColumns.CONCRETE_DATA_SET + " AS " + Groups.DATA_SET + ","
- + AccountsColumns.ACCOUNT_TYPE_AND_DATA_SET
- + " AS " + Groups.ACCOUNT_TYPE_AND_DATA_SET + ","
+ + "(CASE WHEN " + AccountsColumns.CONCRETE_DATA_SET
+ + " IS NULL THEN " + AccountsColumns.CONCRETE_ACCOUNT_TYPE
+ + " ELSE " + AccountsColumns.CONCRETE_ACCOUNT_TYPE
+ + "||'/'||" + AccountsColumns.CONCRETE_DATA_SET + " END) AS "
+ + Groups.ACCOUNT_TYPE_AND_DATA_SET + ","
+ Groups.SOURCE_ID + ","
+ Groups.VERSION + ","
+ Groups.DIRTY + ","
@@ -2321,79 +2291,6 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper {
);
}
- @VisibleForTesting
- void createLocalAccountCompatViews(SQLiteDatabase db) {
- db.execSQL("DROP VIEW IF EXISTS " + Views.RAW_CONTACTS_LOOKUP_COMPAT + ";");
-
- AccountWithDataSet originalLocalAccount = getOriginalLocalAccount();
- String localAccountName = originalLocalAccount.getAccountName();
- String localAccountType = originalLocalAccount.getAccountType();
- String accountNameSqlLiteral;
- String accountTypeSqlLiteral;
- if (TextUtils.isEmpty(localAccountName) || TextUtils.isEmpty(localAccountType)) {
- accountNameSqlLiteral = "NULL";
- accountTypeSqlLiteral = "NULL";
- } else {
- accountNameSqlLiteral = DatabaseUtils.sqlEscapeString(localAccountName);
- accountTypeSqlLiteral = DatabaseUtils.sqlEscapeString(localAccountType);
- }
-
- // Basically every local raw contact will appear twice in the results; once joined with the
- // new local name and type (i.e. null) and once with the original name and type. This allows
- // lookup keys generated with the previous account to continue to function.
- String lookupCompatSelect = "SELECT "
- + RawContactsColumns.CONCRETE_ID + ", "
- + RawContacts.CONTACT_ID + ", "
- + RawContacts.SOURCE_ID + ", "
- + AccountsColumns.CONCRETE_ACCOUNT_NAME + ", "
- + AccountsColumns.ACCOUNT_TYPE_AND_DATA_SET
- + " FROM " + Tables.RAW_CONTACTS_JOIN_ACCOUNTS
- + " UNION SELECT "
- + RawContactsColumns.CONCRETE_ID + ", "
- + RawContacts.CONTACT_ID + ", "
- + RawContacts.SOURCE_ID + ", "
- + accountNameSqlLiteral + ","
- + accountTypeSqlLiteral
- + " FROM " + Tables.RAW_CONTACTS
- + " WHERE " + RawContactsColumns.ACCOUNT_ID + "=" + Clauses.LOCAL_ACCOUNT_ID;
-
- db.execSQL(
- "CREATE VIEW " + Views.RAW_CONTACTS_LOOKUP_COMPAT + "("
- + RawContacts._ID + ", "
- + RawContacts.CONTACT_ID + ", "
- + RawContacts.SOURCE_ID + ", "
- + RawContacts.ACCOUNT_NAME + ", "
- + RawContacts.ACCOUNT_TYPE_AND_DATA_SET
- + ")"
- + " AS " + lookupCompatSelect);
- }
-
- @NonNull
- private AccountWithDataSet getOriginalLocalAccount() {
- if (mOriginalLocalAccount != null) {
- return mOriginalLocalAccount;
- }
- String name = mContext.getString(R.string.config_originalLocalAccountName);
- String type = mContext.getString(R.string.config_originalLocalAccountType);
- if (name.isEmpty() || type.isEmpty()) {
- name = mContext.getString(
- com.android.internal.R.string.config_rawContactsLocalAccountName);
- type = mContext.getString(
- com.android.internal.R.string.config_rawContactsLocalAccountType);
- }
- if (name.isEmpty() || type.isEmpty()) {
- mOriginalLocalAccount = AccountWithDataSet.LOCAL;
- } else {
- mOriginalLocalAccount = new AccountWithDataSet(name, type, null);
- }
- return mOriginalLocalAccount;
- }
-
- @VisibleForTesting
- public void setOriginalLocalAccount(@NonNull AccountWithDataSet localAccount) {
- this.mOriginalLocalAccount = localAccount;
- }
-
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i(TAG, "ContactsProvider cannot proceed because downgrading your database is not " +
@@ -2727,11 +2624,18 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper {
}
if (isUpgradeRequired(oldVersion, newVersion, 1602)) {
- upgradeToVersion1602(db);
- upgradeViewsAndTriggers = true;
+ // 1602 was used for an upgrade that was reverted and is now a no-op. It is safe to skip
+ // it but the database version should not be reused because droidfood devices may have
+ // run the upgrade.
oldVersion = 1602;
}
+ if (isUpgradeRequired(oldVersion, newVersion, 1603)) {
+ upgradeToVersion1603(db);
+ upgradeViewsAndTriggers = true;
+ oldVersion = 1603;
+ }
+
// We extracted "calls" and "voicemail_status" at this point, but we can't remove them here
// yet, until CallLogDatabaseHelper moves the data.
@@ -2741,7 +2645,6 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper {
createSettingsView(db);
createContactsTriggers(db);
createContactsIndexes(db, false /* we build stats table later */);
- createLocalAccountCompatViews(db);
upgradeLegacyApiSupport = true;
rebuildSqliteStats = true;
}
@@ -3562,58 +3465,13 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper {
}
}
- private void upgradeToVersion1602(SQLiteDatabase db) {
- AccountWithDataSet originalLocalAccount = getOriginalLocalAccount();
-
- if (Objects.equals(AccountWithDataSet.LOCAL, originalLocalAccount)) {
- // Nothing to do.
- return;
- }
- String localName = originalLocalAccount.getAccountName();
- String localType = originalLocalAccount.getAccountType();
- // Change the custom local account if there is one to be to be consistent with the AOSP
- // convention of using NULL.
- ContentValues values = new ContentValues();
- values.putNull("account_name");
- values.putNull("account_type");
- int count = db.update("accounts", values,
- "((account_name ISNULL AND account_type ISNULL)"
- + " OR (account_name = ? AND account_type = ?))"
- + " AND data_set IS NULL",
- new String[] {
- localName,
- localType,
- });
- if (count <= 1) {
- // Only 1 local account so nothing left to do. This should pretty much always be true
- // given how local accounts usually work
- return;
- }
- // Else: the original local account was coexisting with the AOSP local account so try to
- // clean up by consolidating them. The one with the higher account ID will be migrated to
- // the one with the lower ID
- long migrateTo;
- long migrateFrom;
- try (Cursor cursor = db.query(
- "accounts",
- new String[] { "_id" },
- "account_name ISNULL AND account_type ISNULL AND data_set ISNULL",
- null, null, null, "_id ASC")) {
- if (cursor == null || cursor.getCount() != 2) {
- return;
- }
- cursor.moveToFirst();
- migrateTo = cursor.getLong(0);
- cursor.moveToNext();
- migrateFrom = cursor.getLong(0);
+ private void upgradeToVersion1603(SQLiteDatabase db) {
+ try {
+ // Drop the view that was created in 1602 which was reverted
+ db.execSQL("DROP VIEW IF EXISTS view_raw_contacts_lookup_compat");
+ } catch (SQLException ignore) {
+ Log.v(TAG, "Version 1603: failed to remove view_raw_contacts_lookup_compat.");
}
-
- values.clear();
- values.put("account_id", migrateTo);
- String selection = "account_id = " + migrateFrom;
- db.update("raw_contacts", values, selection, null);
- db.update("groups", values, selection, null);
- db.delete("accounts", "_id = " + migrateFrom, null);
}
/**
@@ -4182,8 +4040,7 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper {
* @return ID of the specified account, or null if the account doesn't exist.
*/
public Long getAccountIdOrNull(AccountWithDataSet accountWithDataSet) {
- if (accountWithDataSet == null
- || Objects.equals(getOriginalLocalAccount(), accountWithDataSet)) {
+ if (accountWithDataSet == null) {
accountWithDataSet = AccountWithDataSet.LOCAL;
}
final SQLiteStatement select = getWritableDatabase().compileStatement(
@@ -4217,8 +4074,7 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper {
* This must be used in a transaction, so there's no need for synchronization.
*/
public long getOrCreateAccountIdInTransaction(AccountWithDataSet accountWithDataSet) {
- if (accountWithDataSet == null
- || Objects.equals(getOriginalLocalAccount(), accountWithDataSet)) {
+ if (accountWithDataSet == null) {
accountWithDataSet = AccountWithDataSet.LOCAL;
}
Long id = getAccountIdOrNull(accountWithDataSet);
diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java
index e135208c..495c3d44 100644
--- a/src/com/android/providers/contacts/ContactsProvider2.java
+++ b/src/com/android/providers/contacts/ContactsProvider2.java
@@ -7784,7 +7784,7 @@ public class ContactsProvider2 extends AbstractContactsProvider
}
private interface LookupBySourceIdQuery {
- String TABLE = Views.RAW_CONTACTS_LOOKUP_COMPAT;
+ String TABLE = Views.RAW_CONTACTS;
String COLUMNS[] = {
RawContacts.CONTACT_ID,
RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
@@ -7840,7 +7840,7 @@ public class ContactsProvider2 extends AbstractContactsProvider
}
private interface LookupByRawContactIdQuery {
- String TABLE = Views.RAW_CONTACTS_LOOKUP_COMPAT;
+ String TABLE = Views.RAW_CONTACTS;
String COLUMNS[] = {
RawContacts.CONTACT_ID,
@@ -7895,7 +7895,7 @@ public class ContactsProvider2 extends AbstractContactsProvider
}
private interface LookupByDisplayNameQuery {
- String TABLE = Tables.NAME_LOOKUP_JOIN_RAW_CONTACTS_LOOKUP_COMPAT;
+ String TABLE = Tables.NAME_LOOKUP_JOIN_RAW_CONTACTS;
String COLUMNS[] = {
RawContacts.CONTACT_ID,
RawContacts.ACCOUNT_TYPE_AND_DATA_SET,