Merge tag 'android-11.0.0_r48' into int/11/fp3
Android 11.0.0 Release 48 (RD2A.211001.002)
* tag 'android-11.0.0_r48':
Change-Id: I6e38400b92008149f6db6a1ba459d5f647f3deb5
diff --git a/java/com/android/vcard/VCardComposer.java b/java/com/android/vcard/VCardComposer.java
index 7b59c7d..e9c230e 100644
--- a/java/com/android/vcard/VCardComposer.java
+++ b/java/com/android/vcard/VCardComposer.java
@@ -139,6 +139,8 @@
private boolean mFirstVCardEmittedInDoCoMoCase;
private Cursor mCursor;
+ private EntityIterator mEntityIterator;
+ private Entity mEntity;
private boolean mCursorSuppliedFromOutside;
private int mIdColumn;
private Uri mContentUriForRawContactsEntity;
@@ -366,6 +368,8 @@
if (!initInterMainPart()) {
return false;
}
+ initEntityIterator();
+
return initInterLastPart();
}
@@ -439,6 +443,22 @@
return mIdColumn >= 0;
}
+ private void initEntityIterator() {
+ StringBuilder selection = new StringBuilder();
+ selection.append(Data.CONTACT_ID).append(" IN (");
+ do {
+ selection.append(mCursor.getString(mIdColumn));
+ if (!mCursor.isLast()) {
+ selection.append(",");
+ }
+ } while (mCursor.moveToNext());
+ selection.append(")");
+ mEntityIterator = RawContacts
+ .newEntityIterator(mContentResolver.query(mContentUriForRawContactsEntity, null,
+ selection.toString(), null, Data.CONTACT_ID));
+ mCursor.moveToFirst();
+ }
+
private boolean initInterLastPart() {
mInitDone = true;
mTerminateCalled = false;
@@ -465,8 +485,9 @@
// return createOneEntryInternal("-1", getEntityIteratorMethod);
}
- final String vcard = createOneEntryInternal(mCursor.getLong(mIdColumn),
- getEntityIteratorMethod);
+ final String vcard = (mEntityIterator == null || getEntityIteratorMethod != null)
+ ?createOneEntryInternal(mCursor.getLong(mIdColumn),getEntityIteratorMethod)
+ :createOneEntryInternalByIterator();
if (!mCursor.moveToNext()) {
Log.e(LOG_TAG, "Cursor#moveToNext() returned false");
}
@@ -498,6 +519,57 @@
RawContactEntitlesInfo getRawContactEntitlesInfo(long contactId);
}
+ private String createOneEntryInternalByIterator() {
+ if (!mEntityIterator.hasNext()) {
+ if (mEntity == null) {
+ Log.e(LOG_TAG, "EntityIterator#hasNext() returned false");
+ return null;
+ }
+ }
+ final Map<String, List<ContentValues>> contentValuesListMap = new HashMap<String, List<ContentValues>>();
+ int lastContactId = -1;
+ if (mEntity != null) {
+ lastContactId = mEntity.getEntityValues().getAsInteger(Data.CONTACT_ID);
+ for (NamedContentValues namedContentValues : mEntity.getSubValues()) {
+ ContentValues contentValues = namedContentValues.values;
+ String key = contentValues.getAsString(Data.MIMETYPE);
+ if (key != null) {
+ List<ContentValues> contentValuesList = contentValuesListMap.get(key);
+ if (contentValuesList == null) {
+ contentValuesList = new ArrayList<ContentValues>();
+ contentValuesListMap.put(key, contentValuesList);
+ }
+ contentValuesList.add(contentValues);
+ }
+ }
+ mEntity = null;
+ }
+ while (mEntityIterator.hasNext()) {
+ Entity entity = mEntityIterator.next();
+ int contactId = entity.getEntityValues().getAsInteger(Data.CONTACT_ID);
+ if ((lastContactId == -1 || contactId == lastContactId)) {
+ for (NamedContentValues namedContentValues : entity.getSubValues()) {
+ ContentValues contentValues = namedContentValues.values;
+ String key = contentValues.getAsString(Data.MIMETYPE);
+ if (key != null) {
+ List<ContentValues> contentValuesList = contentValuesListMap.get(key);
+ if (contentValuesList == null) {
+ contentValuesList = new ArrayList<ContentValues>();
+ contentValuesListMap.put(key, contentValuesList);
+ }
+ contentValuesList.add(contentValues);
+ }
+ }
+ lastContactId = contactId;
+ } else {
+ lastContactId = contactId;
+ mEntity = entity;
+ break;
+ }
+ }
+ return buildVCard(contentValuesListMap);
+ }
+
private String createOneEntryInternal(long contactId,
final Method getEntityIteratorMethod) {
final Map<String, List<ContentValues>> contentValuesListMap =
@@ -633,6 +705,14 @@
}
mCursor = null;
}
+ if(mEntityIterator != null){
+ try{
+ mEntityIterator.close();
+ } catch (SQLiteException e) {
+ Log.e(LOG_TAG, "SQLiteException on EntityIterator#close(): " + e.getMessage());
+ }
+ mEntityIterator = null;
+ }
}
@Override
@@ -668,6 +748,9 @@
Log.w(LOG_TAG, "This object is not ready yet.");
return false;
}
+ if(mEntityIterator != null){
+ return ((!mEntityIterator.hasNext()) && mEntity == null) || mCursor.isAfterLast();
+ }
return mCursor.isAfterLast();
}
diff --git a/java/com/android/vcard/VCardEntryCommitter.java b/java/com/android/vcard/VCardEntryCommitter.java
index 7f8e885..dbb5d91 100644
--- a/java/com/android/vcard/VCardEntryCommitter.java
+++ b/java/com/android/vcard/VCardEntryCommitter.java
@@ -70,7 +70,15 @@
final long start = System.currentTimeMillis();
mOperationList = vcardEntry.constructInsertOperations(mContentResolver, mOperationList);
mCounter++;
- if (mCounter >= 20) {
+ //because the max batch size is 500 defined in ContactsProvider,so we can enlarge this batch
+ //size to reduce db open/close times. From testing results, we can see performance better
+ //when batch size is more bigger.And also each vcardEntry may have some operation records.
+ //So we set threshold as 450, batch operations will be executed when threshold reached.
+ //Testing result.
+ //batch size : 100 200 300 400 450 490 20(mCounter)
+ //consume time(10000 contacts): 178s 143s 127s 124s 119s 117s 195s
+ //consume time (1000 contacts): 17.3s 13.9s 12.6s 12.2s 11.8s 11.6s 19.8s
+ if (mOperationList != null && mOperationList.size() >= 450) {
mCreatedUris.add(pushIntoContentResolver(mOperationList));
mCounter = 0;
mOperationList = null;
@@ -104,4 +112,4 @@
public ArrayList<Uri> getCreatedUris() {
return mCreatedUris;
}
-}
\ No newline at end of file
+}