Merge "Use dark theme for alerts if device is in dark mode"
diff --git a/src/com/android/phone/SimPhonebookProvider.java b/src/com/android/phone/SimPhonebookProvider.java
index 04c4f48..8952865 100644
--- a/src/com/android/phone/SimPhonebookProvider.java
+++ b/src/com/android/phone/SimPhonebookProvider.java
@@ -43,7 +43,7 @@
import android.telephony.TelephonyFrameworkInitializer;
import android.telephony.TelephonyManager;
import android.util.ArraySet;
-import android.util.Pair;
+import android.util.SparseArray;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -55,10 +55,10 @@
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.MoreExecutors;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
@@ -333,19 +333,25 @@
if (recordsSize == null || getRecordCount(recordsSize) == 0) {
return;
}
+ int efid = efIdForEfType(efType);
+ // Have to load the existing records to get the size because there may be more than one
+ // phonebook set in which case the total capacity is the sum of the capacity of EF_ADN for
+ // all the phonebook sets whereas the recordsSize is just the size for a single EF.
+ List<AdnRecord> existingRecords = mIccPhoneBookSupplier.get()
+ .getAdnRecordsInEfForSubscriber(subscriptionInfo.getSubscriptionId(), efid);
+ if (existingRecords == null) {
+ existingRecords = ImmutableList.of();
+ }
MatrixCursor.RowBuilder row = result.newRow()
.add(ElementaryFiles.SLOT_INDEX, subscriptionInfo.getSimSlotIndex())
.add(ElementaryFiles.SUBSCRIPTION_ID, subscriptionInfo.getSubscriptionId())
.add(ElementaryFiles.EF_TYPE, efType)
- .add(ElementaryFiles.MAX_RECORDS, getRecordCount(recordsSize))
+ .add(ElementaryFiles.MAX_RECORDS, existingRecords.size())
.add(ElementaryFiles.NAME_MAX_LENGTH,
AdnRecord.getMaxAlphaTagBytes(getRecordSize(recordsSize)))
.add(ElementaryFiles.PHONE_NUMBER_MAX_LENGTH,
AdnRecord.getMaxPhoneNumberDigits());
if (result.getColumnIndex(ElementaryFiles.RECORD_COUNT) != -1) {
- int efid = efIdForEfType(efType);
- List<AdnRecord> existingRecords = mIccPhoneBookSupplier.get()
- .getAdnRecordsInEfForSubscriber(subscriptionInfo.getSubscriptionId(), efid);
int nonEmptyCount = 0;
for (AdnRecord record : existingRecords) {
if (!record.isEmpty()) {
@@ -368,39 +374,46 @@
return new MatrixCursor(projection, 0);
}
MatrixCursor result = new MatrixCursor(projection, records.size());
- List<Pair<AdnRecord, MatrixCursor.RowBuilder>> rowBuilders = new ArrayList<>(
- records.size());
- for (AdnRecord record : records) {
+ SparseArray<MatrixCursor.RowBuilder> rowBuilders = new SparseArray<>(records.size());
+ for (int i = 0; i < records.size(); i++) {
+ AdnRecord record = records.get(i);
if (!record.isEmpty()) {
- rowBuilders.add(Pair.create(record, result.newRow()));
+ rowBuilders.put(i, result.newRow());
}
}
// This is kind of ugly but avoids looking up columns in an inner loop.
for (String column : projection) {
switch (column) {
case SimRecords.SUBSCRIPTION_ID:
- for (Pair<AdnRecord, MatrixCursor.RowBuilder> row : rowBuilders) {
- row.second.add(args.subscriptionId);
+ for (int i = 0; i < rowBuilders.size(); i++) {
+ rowBuilders.valueAt(i).add(args.subscriptionId);
}
break;
case SimRecords.ELEMENTARY_FILE_TYPE:
- for (Pair<AdnRecord, MatrixCursor.RowBuilder> row : rowBuilders) {
- row.second.add(args.efType);
+ for (int i = 0; i < rowBuilders.size(); i++) {
+ rowBuilders.valueAt(i).add(args.efType);
}
break;
case SimRecords.RECORD_NUMBER:
- for (Pair<AdnRecord, MatrixCursor.RowBuilder> row : rowBuilders) {
- row.second.add(row.first.getRecId());
+ for (int i = 0; i < rowBuilders.size(); i++) {
+ int index = rowBuilders.keyAt(i);
+ MatrixCursor.RowBuilder rowBuilder = rowBuilders.valueAt(i);
+ // See b/201685690. The logical record number, i.e. the 1-based index in the
+ // list, is used the rather than AdnRecord.getRecId() because getRecId is
+ // not offset when a single logical EF is made up of multiple physical EFs.
+ rowBuilder.add(index + 1);
}
break;
case SimRecords.NAME:
- for (Pair<AdnRecord, MatrixCursor.RowBuilder> row : rowBuilders) {
- row.second.add(row.first.getAlphaTag());
+ for (int i = 0; i < rowBuilders.size(); i++) {
+ AdnRecord record = records.get(rowBuilders.keyAt(i));
+ rowBuilders.valueAt(i).add(record.getAlphaTag());
}
break;
case SimRecords.PHONE_NUMBER:
- for (Pair<AdnRecord, MatrixCursor.RowBuilder> row : rowBuilders) {
- row.second.add(row.first.getNumber());
+ for (int i = 0; i < rowBuilders.size(); i++) {
+ AdnRecord record = records.get(rowBuilders.keyAt(i));
+ rowBuilders.valueAt(i).add(record.getNumber());
}
break;
default:
@@ -765,20 +778,9 @@
if (records == null || args.recordNumber > records.size()) {
return null;
}
- AdnRecord result = records.get(args.recordNumber - 1);
- // This should be true but the service could have a different implementation.
- if (result.getRecId() == args.recordNumber) {
- return result;
- }
- for (AdnRecord record : records) {
- if (record.getRecId() == args.recordNumber) {
- return result;
- }
- }
- return null;
+ return records.get(args.recordNumber - 1);
}
-
private int[] getRecordsSizeForEf(PhonebookArgs args) {
try {
return mIccPhoneBookSupplier.get().getAdnRecordsSizeForSubscriber(
diff --git a/tests/src/com/android/phone/SimPhonebookProviderTest.java b/tests/src/com/android/phone/SimPhonebookProviderTest.java
index 848ba42..d8518f8 100644
--- a/tests/src/com/android/phone/SimPhonebookProviderTest.java
+++ b/tests/src/com/android/phone/SimPhonebookProviderTest.java
@@ -181,16 +181,16 @@
public void query_entityFiles_multiSim_returnsCursorWithRowForEachSimEf() {
setupSimsWithSubscriptionIds(2, 3, 7);
- mIccPhoneBook.setRecordsSize(2, IccConstants.EF_ADN, 10, 25);
- mIccPhoneBook.setRecordsSize(2, IccConstants.EF_FDN, 5, 20);
- mIccPhoneBook.setRecordsSize(2, IccConstants.EF_SDN, 15, 20);
- mIccPhoneBook.setRecordsSize(3, IccConstants.EF_ADN, 100, 30);
+ mIccPhoneBook.setupEfWithSizes(2, IccConstants.EF_ADN, 10, 25);
+ mIccPhoneBook.setupEfWithSizes(2, IccConstants.EF_FDN, 5, 20);
+ mIccPhoneBook.setupEfWithSizes(2, IccConstants.EF_SDN, 15, 20);
+ mIccPhoneBook.setupEfWithSizes(3, IccConstants.EF_ADN, 100, 30);
// These Will be omitted from results because zero size indicates the EF is not supported.
- mIccPhoneBook.setRecordsSize(3, IccConstants.EF_FDN, 0, 0);
- mIccPhoneBook.setRecordsSize(3, IccConstants.EF_SDN, 0, 0);
- mIccPhoneBook.setRecordsSize(7, IccConstants.EF_ADN, 0, 0);
- mIccPhoneBook.setRecordsSize(7, IccConstants.EF_FDN, 0, 0);
- mIccPhoneBook.setRecordsSize(7, IccConstants.EF_SDN, 0, 0);
+ mIccPhoneBook.setupEfWithSizes(3, IccConstants.EF_FDN, 0, 0);
+ mIccPhoneBook.setupEfWithSizes(3, IccConstants.EF_SDN, 0, 0);
+ mIccPhoneBook.setupEfWithSizes(7, IccConstants.EF_ADN, 0, 0);
+ mIccPhoneBook.setupEfWithSizes(7, IccConstants.EF_FDN, 0, 0);
+ mIccPhoneBook.setupEfWithSizes(7, IccConstants.EF_SDN, 0, 0);
String[] projection = {
ElementaryFiles.SLOT_INDEX, ElementaryFiles.SUBSCRIPTION_ID,
@@ -212,15 +212,44 @@
public void query_entityFiles_simWithZeroSizes_returnsEmptyCursor() {
setupSimsWithSubscriptionIds(1);
- mIccPhoneBook.setRecordsSize(1, IccConstants.EF_ADN, 0, 0);
- mIccPhoneBook.setRecordsSize(1, IccConstants.EF_FDN, 0, 0);
- mIccPhoneBook.setRecordsSize(1, IccConstants.EF_SDN, 0, 0);
+ mIccPhoneBook.setupEfWithSizes(1, IccConstants.EF_ADN, 0, 0);
+ mIccPhoneBook.setupEfWithSizes(1, IccConstants.EF_FDN, 0, 0);
+ mIccPhoneBook.setupEfWithSizes(1, IccConstants.EF_SDN, 0, 0);
try (Cursor cursor = mResolver.query(ElementaryFiles.CONTENT_URI, null, null, null)) {
assertThat(cursor).hasCount(0);
}
}
+ /**
+ * USIM cards support more than 255 records by having multiple files for one EF type but
+ * IIccPhoneBook.getAdnRecordsSizeForSubscriber returns the size for a single file and so is
+ * inaccurate for such SIMs.
+ *
+ * <p>See b/201385523#comment4 and b/201685690
+ */
+ @Test
+ public void query_entityFiles_adnRecordCountExceedsSize_returnsAdnRecordCountAsMaxRecords() {
+ setupSimsWithSubscriptionIds(1);
+
+ // There are 400 records returned by getAdnRecordsInEfForSubscriber but the count returned
+ // by getAdnRecordsSizeForSubscriber is only 200.
+ AdnRecord[] records = mIccPhoneBook.createEmptyRecords(IccConstants.EF_ADN, 400);
+ mIccPhoneBook.setRecordsSize(1, IccConstants.EF_ADN, 200, 20);
+ mIccPhoneBook.setRecords(1, IccConstants.EF_ADN, records);
+
+ String[] projection = {
+ ElementaryFiles.SUBSCRIPTION_ID, ElementaryFiles.EF_TYPE,
+ ElementaryFiles.MAX_RECORDS
+ };
+ try (Cursor cursor = mResolver.query(
+ ElementaryFiles.CONTENT_URI, projection, null, null)) {
+ assertThat(cursor).hasCount(1);
+ assertThat(cursor)
+ .atRow(0).hasRowValues(1, ElementaryFiles.EF_ADN, 400);
+ }
+ }
+
@Test
public void query_entityFilesItem_nullProjection_returnsCursorWithCorrectProjection() {
setupSimsWithSubscriptionIds(1);
@@ -549,7 +578,7 @@
@Test
public void query_adnRecords_zeroSizeEf_throwsCorrectException() {
setupSimsWithSubscriptionIds(1);
- mIccPhoneBook.setRecordsSize(1, IccConstants.EF_ADN, 0, 0);
+ mIccPhoneBook.setupEfWithSizes(1, IccConstants.EF_ADN, 0, 0);
IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
() -> mResolver.query(SimRecords.getContentUri(1, EF_ADN), null, null, null));
@@ -618,9 +647,9 @@
@Test
public void query_itemUriEmptyRecord_returnsEmptyCursor() {
setupSimsWithSubscriptionIds(1);
- mIccPhoneBook.setRecordsSize(1, IccConstants.EF_ADN, 1, 30);
- mIccPhoneBook.setRecordsSize(1, IccConstants.EF_FDN, 1, 30);
- mIccPhoneBook.setRecordsSize(1, IccConstants.EF_SDN, 1, 30);
+ mIccPhoneBook.setupEfWithSizes(1, IccConstants.EF_ADN, 1, 30);
+ mIccPhoneBook.setupEfWithSizes(1, IccConstants.EF_FDN, 1, 30);
+ mIccPhoneBook.setupEfWithSizes(1, IccConstants.EF_SDN, 1, 30);
try (Cursor adnItem = mResolver.query(SimRecords.getItemUri(1, ElementaryFiles.EF_ADN, 1),
null, null, null);
@@ -638,9 +667,9 @@
@Test
public void query_itemUriIndexExceedsMax_returnsEmptyCursor() {
setupSimsWithSubscriptionIds(1);
- mIccPhoneBook.setRecordsSize(1, IccConstants.EF_ADN, 1, 30);
- mIccPhoneBook.setRecordsSize(1, IccConstants.EF_FDN, 1, 30);
- mIccPhoneBook.setRecordsSize(1, IccConstants.EF_SDN, 1, 30);
+ mIccPhoneBook.setupEfWithSizes(1, IccConstants.EF_ADN, 1, 30);
+ mIccPhoneBook.setupEfWithSizes(1, IccConstants.EF_FDN, 1, 30);
+ mIccPhoneBook.setupEfWithSizes(1, IccConstants.EF_SDN, 1, 30);
try (Cursor adnItem = mResolver.query(SimRecords.getItemUri(1, ElementaryFiles.EF_ADN, 2),
null, null, null);
@@ -741,7 +770,7 @@
@Test
public void insert_efFull_throwsCorrectException() {
setupSimsWithSubscriptionIds(1);
- mIccPhoneBook.setRecordsSize(1, IccConstants.EF_ADN, 1, 30);
+ mIccPhoneBook.setupEfWithSizes(1, IccConstants.EF_ADN, 1, 30);
mIccPhoneBook.addRecord(1, IccConstants.EF_ADN, "Existing", "8005550101");
ContentValues values = new ContentValues();
@@ -843,7 +872,7 @@
@Test
public void insert_phoneNumberOmitted_throwsCorrectException() {
setupSimsWithSubscriptionIds(1);
- mIccPhoneBook.setRecordsSize(1, IccConstants.EF_ADN, 1, 25);
+ mIccPhoneBook.setupEfWithSizes(1, IccConstants.EF_ADN, 1, 25);
ContentValues values = new ContentValues();
values.put(SimRecords.NAME, "Name");
@@ -856,7 +885,7 @@
@Test
public void insert_nameTooLong_throwsCorrectException() {
setupSimsWithSubscriptionIds(1);
- mIccPhoneBook.setRecordsSize(1, IccConstants.EF_ADN, 1, 25);
+ mIccPhoneBook.setupEfWithSizes(1, IccConstants.EF_ADN, 1, 25);
ContentValues values = new ContentValues();
// Name is limited to 11 characters when the max record size is 25
@@ -879,7 +908,7 @@
@Test
public void insert_phoneNumberTooLong_throwsCorrectException() {
setupSimsWithSubscriptionIds(1);
- mIccPhoneBook.setRecordsSize(1, IccConstants.EF_ADN, 1, 25);
+ mIccPhoneBook.setupEfWithSizes(1, IccConstants.EF_ADN, 1, 25);
ContentValues values = new ContentValues();
values.put(SimRecords.NAME, "Name");
@@ -895,7 +924,7 @@
@Test
public void insert_numberWithInvalidCharacters_throwsCorrectException() {
setupSimsWithSubscriptionIds(1);
- mIccPhoneBook.setRecordsSize(1, IccConstants.EF_ADN, 1, 32);
+ mIccPhoneBook.setupEfWithSizes(1, IccConstants.EF_ADN, 1, 32);
ContentValues values = new ContentValues();
values.put(SimRecords.NAME, "Name");
@@ -915,7 +944,7 @@
@Test
public void insert_unsupportedColumn_throwsCorrectException() {
setupSimsWithSubscriptionIds(1);
- mIccPhoneBook.setRecordsSize(1, IccConstants.EF_ADN, 1, 25);
+ mIccPhoneBook.setupEfWithSizes(1, IccConstants.EF_ADN, 1, 25);
ContentValues values = new ContentValues();
values.put(SimRecords.NAME, "Name");
@@ -1007,7 +1036,7 @@
@Test
public void update_indexExceedingMax_returnsZero() {
setupSimsWithSubscriptionIds(1);
- mIccPhoneBook.setRecordsSize(1, IccConstants.EF_ADN, 1, 30);
+ mIccPhoneBook.setupEfWithSizes(1, IccConstants.EF_ADN, 1, 30);
ContentValues values = new ContentValues();
values.put(SimRecords.NAME, "name");
@@ -1046,7 +1075,7 @@
public void delete_indexExceedingMax_returnsZero() {
setupSimsWithSubscriptionIds(1);
mIccPhoneBook.makeAllEfsSupported(1);
- mIccPhoneBook.setRecordsSize(1, IccConstants.EF_ADN, 1, 30);
+ mIccPhoneBook.setupEfWithSizes(1, IccConstants.EF_ADN, 1, 30);
int result = mResolver.delete(SimRecords.getItemUri(1, ElementaryFiles.EF_ADN, 2), null);
@@ -1067,7 +1096,7 @@
@Test
public void update_nameOrNumberTooLong_throwsCorrectException() {
setupSimsWithSubscriptionIds(1);
- mIccPhoneBook.setRecordsSize(1, IccConstants.EF_ADN, 1, 25);
+ mIccPhoneBook.setupEfWithSizes(1, IccConstants.EF_ADN, 1, 25);
mIccPhoneBook.addRecord(1, IccConstants.EF_ADN, "Initial", "8005550101");
ContentValues values = new ContentValues();
@@ -1097,7 +1126,7 @@
@Test
public void update_numberWithInvalidCharacters_throwsCorrectException() {
setupSimsWithSubscriptionIds(1);
- mIccPhoneBook.setRecordsSize(1, IccConstants.EF_ADN, 1, 32);
+ mIccPhoneBook.setupEfWithSizes(1, IccConstants.EF_ADN, 1, 32);
mIccPhoneBook.addRecord(1, IccConstants.EF_ADN, "Initial", "8005550101");
ContentValues values = new ContentValues();
@@ -1324,7 +1353,7 @@
// The key for both maps is the (subscription ID, efid)
private Map<Pair<Integer, Integer>, AdnRecord[]> mRecords = new HashMap<>();
// The value is the single record size
- private Map<Pair<Integer, Integer>, Integer> mRecordSizes = new HashMap<>();
+ private Map<Pair<Integer, Integer>, int[]> mRecordSizes = new HashMap<>();
private int mDefaultSubscriptionId = 101;
@@ -1332,7 +1361,7 @@
// Assume that if records are being added then the test wants it to be a valid
// elementary file so set sizes as well.
if (!mRecordSizes.containsKey(key)) {
- setRecordsSize(key.first, key.second,
+ setupEfWithSizes(key.first, key.second,
Math.max(record.getRecId(), DEFAULT_RECORDS_COUNT), DEFAULT_RECORD_SIZE);
}
mRecords.get(key)[record.getRecId() - 1] = record;
@@ -1402,18 +1431,33 @@
* subscription IDs.
*/
public void makeAllEfsSupported(int subscriptionId) {
- setRecordsSize(subscriptionId, IccConstants.EF_ADN, DEFAULT_RECORDS_COUNT,
+ setupEfWithSizes(subscriptionId, IccConstants.EF_ADN, DEFAULT_RECORDS_COUNT,
DEFAULT_RECORD_SIZE);
- setRecordsSize(subscriptionId, IccConstants.EF_FDN, DEFAULT_RECORDS_COUNT,
+ setupEfWithSizes(subscriptionId, IccConstants.EF_FDN, DEFAULT_RECORDS_COUNT,
DEFAULT_RECORD_SIZE);
- setRecordsSize(subscriptionId, IccConstants.EF_SDN, DEFAULT_RECORDS_COUNT,
+ setupEfWithSizes(subscriptionId, IccConstants.EF_SDN, DEFAULT_RECORDS_COUNT,
DEFAULT_RECORD_SIZE);
}
+ public void setRecords(int subscriptionId, int efid, AdnRecord[] records) {
+ mRecords.put(Pair.create(subscriptionId, efid), records);
+ }
+
public void setRecordsSize(int subscriptionId, int efid, int maxRecordCount,
int maxRecordSize) {
+ setRecordsSize(Pair.create(subscriptionId, efid), maxRecordCount, maxRecordSize);
+ }
+
+ private void setRecordsSize(Pair<Integer, Integer> key, int maxRecordCount,
+ int maxRecordSize) {
+ int[] sizes = { maxRecordSize, maxRecordSize * maxRecordCount, maxRecordCount };
+ mRecordSizes.put(key, sizes);
+ }
+
+ public void setupEfWithSizes(int subscriptionId, int efid, int maxRecordCount,
+ int maxRecordSize) {
Pair<Integer, Integer> key = Pair.create(subscriptionId, efid);
- mRecordSizes.put(key, maxRecordSize);
+ setRecordsSize(key, maxRecordCount, maxRecordSize);
AdnRecord[] records = mRecords.computeIfAbsent(key, unused ->
createEmptyRecords(efid, maxRecordCount));
if (records.length < maxRecordCount) {
@@ -1421,7 +1465,7 @@
}
}
- private AdnRecord[] createEmptyRecords(int efid, int count) {
+ AdnRecord[] createEmptyRecords(int efid, int count) {
AdnRecord[] records = new AdnRecord[count];
for (int i = 0; i < records.length; i++) {
if (records[i] == null) {
@@ -1499,12 +1543,11 @@
@Override
public int[] getAdnRecordsSizeForSubscriber(int subId, int efid) {
Pair<Integer, Integer> key = Pair.create(subId, efid);
- Integer recordSize = mRecordSizes.get(key);
- if (recordSize == null) {
+ int[] recordsSize = mRecordSizes.get(key);
+ if (recordsSize == null) {
return new int[]{0, 0, 0};
}
- int count = mRecords.get(key).length;
- return new int[]{recordSize, recordSize * count, count};
+ return recordsSize;
}
@Override