summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java')
-rw-r--r--java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java166
1 files changed, 136 insertions, 30 deletions
diff --git a/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java b/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java
index f2063283f..1bdbb8a1b 100644
--- a/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java
+++ b/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java
@@ -28,25 +28,30 @@ import android.os.Handler;
import android.preference.PreferenceManager;
import android.provider.CallLog;
import android.provider.CallLog.Calls;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.support.annotation.ColorInt;
import android.support.annotation.MainThread;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.support.annotation.WorkerThread;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
import android.text.TextUtils;
import android.util.ArraySet;
-import com.android.dialer.DialerPhoneNumber;
+import com.android.dialer.CallTypes;
import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog;
import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.CoalescedAnnotatedCallLog;
import com.android.dialer.calllog.datasources.CallLogDataSource;
import com.android.dialer.calllog.datasources.CallLogMutations;
import com.android.dialer.calllog.datasources.util.RowCombiner;
+import com.android.dialer.calllogutils.PhoneAccountUtils;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
import com.android.dialer.common.concurrent.ThreadUtil;
import com.android.dialer.phonenumberproto.DialerPhoneNumberUtil;
+import com.android.dialer.theme.R;
import com.android.dialer.util.PermissionsUtil;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
-import com.google.protobuf.InvalidProtocolBufferException;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
@@ -79,6 +84,7 @@ public class SystemCallLogDataSource implements CallLogDataSource {
LogUtil.i("SystemCallLogDataSource.registerContentObservers", "no call log permissions");
return;
}
+ // TODO(zachh): Need to somehow register observers if user enables permission after launch?
appContext
.getContentResolver()
@@ -99,8 +105,11 @@ public class SystemCallLogDataSource implements CallLogDataSource {
* column is unused). This means that we can't detect deletes without scanning the entire table,
* which would be too slow. So, we just rely on content observers to trigger rebuilds when any
* change is made to the system call log.
+ *
+ * Just return false unless the table has never been written to.
*/
- return false;
+ return !PreferenceManager.getDefaultSharedPreferences(appContext)
+ .contains(PREF_LAST_TIMESTAMP_PROCESSED);
}
@WorkerThread
@@ -143,33 +152,31 @@ public class SystemCallLogDataSource implements CallLogDataSource {
@Override
public ContentValues coalesce(List<ContentValues> individualRowsSortedByTimestampDesc) {
- // TODO: Complete implementation.
+ // TODO(zachh): Complete implementation.
ContentValues coalescedValues =
new RowCombiner(individualRowsSortedByTimestampDesc)
.useMostRecentLong(AnnotatedCallLog.TIMESTAMP)
+ .useMostRecentLong(AnnotatedCallLog.NEW)
+ .useMostRecentString(AnnotatedCallLog.NUMBER_TYPE_LABEL)
+ .useMostRecentString(AnnotatedCallLog.NAME)
+ .useMostRecentString(AnnotatedCallLog.FORMATTED_NUMBER)
+ .useMostRecentString(AnnotatedCallLog.PHOTO_URI)
+ .useMostRecentLong(AnnotatedCallLog.PHOTO_ID)
+ .useMostRecentString(AnnotatedCallLog.LOOKUP_URI)
+ .useMostRecentString(AnnotatedCallLog.GEOCODED_LOCATION)
+ .useSingleValueString(AnnotatedCallLog.PHONE_ACCOUNT_LABEL)
+ .useSingleValueLong(AnnotatedCallLog.PHONE_ACCOUNT_COLOR)
.combine();
- // All phone numbers in the provided group should be equivalent (but could be formatted
- // differently). Arbitrarily show the raw phone number of the most recent call.
- DialerPhoneNumber mostRecentPhoneNumber =
- getMostRecentPhoneNumber(individualRowsSortedByTimestampDesc);
- coalescedValues.put(
- CoalescedAnnotatedCallLog.FORMATTED_NUMBER,
- mostRecentPhoneNumber.getRawInput().getNumber());
- return coalescedValues;
- }
-
- private static DialerPhoneNumber getMostRecentPhoneNumber(
- List<ContentValues> individualRowsSortedByTimestampDesc) {
- DialerPhoneNumber dialerPhoneNumber;
- byte[] protoBytes =
- individualRowsSortedByTimestampDesc.get(0).getAsByteArray(AnnotatedCallLog.NUMBER);
- try {
- dialerPhoneNumber = DialerPhoneNumber.parseFrom(protoBytes);
- } catch (InvalidProtocolBufferException e) {
- throw Assert.createAssertionFailException("couldn't parse DialerPhoneNumber", e);
+ CallTypes.Builder callTypes = CallTypes.newBuilder();
+ // Store a maximum of 3 call types since that's all we show to users via icons.
+ for (int i = 0; i < 3 && i < individualRowsSortedByTimestampDesc.size(); i++) {
+ callTypes.addType(
+ individualRowsSortedByTimestampDesc.get(i).getAsInteger(AnnotatedCallLog.TYPE));
}
- return dialerPhoneNumber;
+ coalescedValues.put(CoalescedAnnotatedCallLog.CALL_TYPES, callTypes.build().toByteArray());
+
+ return coalescedValues;
}
@TargetApi(Build.VERSION_CODES.M) // Uses try-with-resources
@@ -182,14 +189,32 @@ public class SystemCallLogDataSource implements CallLogDataSource {
DialerPhoneNumberUtil dialerPhoneNumberUtil =
new DialerPhoneNumberUtil(PhoneNumberUtil.getInstance());
- // TODO: Really should be getting last 1000 by timestamp, not by last modified.
+ // TODO(zachh): Really should be getting last 1000 by timestamp, not by last modified.
try (Cursor cursor =
appContext
.getContentResolver()
.query(
Calls.CONTENT_URI, // Excludes voicemail
new String[] {
- Calls._ID, Calls.DATE, Calls.LAST_MODIFIED, Calls.NUMBER, Calls.COUNTRY_ISO
+ Calls._ID,
+ Calls.DATE,
+ Calls.LAST_MODIFIED,
+ Calls.NUMBER,
+ Calls.TYPE,
+ Calls.COUNTRY_ISO,
+ Calls.CACHED_NAME,
+ Calls.CACHED_FORMATTED_NUMBER,
+ Calls.CACHED_PHOTO_URI,
+ Calls.CACHED_PHOTO_ID,
+ Calls.CACHED_LOOKUP_URI,
+ Calls.CACHED_NUMBER_TYPE,
+ Calls.CACHED_NUMBER_LABEL,
+ Calls.IS_READ,
+ Calls.NEW,
+ Calls.GEOCODED_LOCATION,
+ Calls.PHONE_ACCOUNT_COMPONENT_NAME,
+ Calls.PHONE_ACCOUNT_ID,
+ Calls.FEATURES
},
Calls.LAST_MODIFIED + " > ?",
new String[] {String.valueOf(previousTimestampProcessed)},
@@ -210,7 +235,23 @@ public class SystemCallLogDataSource implements CallLogDataSource {
int dateColumn = cursor.getColumnIndexOrThrow(Calls.DATE);
int lastModifiedColumn = cursor.getColumnIndexOrThrow(Calls.LAST_MODIFIED);
int numberColumn = cursor.getColumnIndexOrThrow(Calls.NUMBER);
+ int typeColumn = cursor.getColumnIndexOrThrow(Calls.TYPE);
int countryIsoColumn = cursor.getColumnIndexOrThrow(Calls.COUNTRY_ISO);
+ int cachedNameColumn = cursor.getColumnIndexOrThrow(Calls.CACHED_NAME);
+ int cachedFormattedNumberColumn =
+ cursor.getColumnIndexOrThrow(Calls.CACHED_FORMATTED_NUMBER);
+ int cachedPhotoUriColumn = cursor.getColumnIndexOrThrow(Calls.CACHED_PHOTO_URI);
+ int cachedPhotoIdColumn = cursor.getColumnIndexOrThrow(Calls.CACHED_PHOTO_ID);
+ int cachedLookupUriColumn = cursor.getColumnIndexOrThrow(Calls.CACHED_LOOKUP_URI);
+ int cachedNumberTypeColumn = cursor.getColumnIndexOrThrow(Calls.CACHED_NUMBER_TYPE);
+ int cachedNumberLabelColumn = cursor.getColumnIndexOrThrow(Calls.CACHED_NUMBER_LABEL);
+ int isReadColumn = cursor.getColumnIndexOrThrow(Calls.IS_READ);
+ int newColumn = cursor.getColumnIndexOrThrow(Calls.NEW);
+ int geocodedLocationColumn = cursor.getColumnIndexOrThrow(Calls.GEOCODED_LOCATION);
+ int phoneAccountComponentColumn =
+ cursor.getColumnIndexOrThrow(Calls.PHONE_ACCOUNT_COMPONENT_NAME);
+ int phoneAccountIdColumn = cursor.getColumnIndexOrThrow(Calls.PHONE_ACCOUNT_ID);
+ int featuresColumn = cursor.getColumnIndexOrThrow(Calls.FEATURES);
// The cursor orders by LAST_MODIFIED DESC, so the first result is the most recent timestamp
// processed.
@@ -219,14 +260,53 @@ public class SystemCallLogDataSource implements CallLogDataSource {
long id = cursor.getLong(idColumn);
long date = cursor.getLong(dateColumn);
String numberAsStr = cursor.getString(numberColumn);
+ long type = cursor.getInt(typeColumn);
String countryIso = cursor.getString(countryIsoColumn);
-
- byte[] numberAsProtoBytes =
- dialerPhoneNumberUtil.parse(numberAsStr, countryIso).toByteArray();
+ String cachedName = cursor.getString(cachedNameColumn);
+ String formattedNumber = cursor.getString(cachedFormattedNumberColumn);
+ String cachedPhotoUri = cursor.getString(cachedPhotoUriColumn);
+ long cachedPhotoId = cursor.getLong(cachedPhotoIdColumn);
+ String cachedLookupUri = cursor.getString(cachedLookupUriColumn);
+ int cachedNumberType = cursor.getInt(cachedNumberTypeColumn);
+ String cachedNumberLabel = cursor.getString(cachedNumberLabelColumn);
+ int isRead = cursor.getInt(isReadColumn);
+ int isNew = cursor.getInt(newColumn);
+ String geocodedLocation = cursor.getString(geocodedLocationColumn);
+ String phoneAccountComponentName = cursor.getString(phoneAccountComponentColumn);
+ String phoneAccountId = cursor.getString(phoneAccountIdColumn);
+ int features = cursor.getInt(featuresColumn);
ContentValues contentValues = new ContentValues();
contentValues.put(AnnotatedCallLog.TIMESTAMP, date);
- contentValues.put(AnnotatedCallLog.NUMBER, numberAsProtoBytes);
+
+ if (!TextUtils.isEmpty(numberAsStr)) {
+ byte[] numberAsProtoBytes =
+ dialerPhoneNumberUtil.parse(numberAsStr, countryIso).toByteArray();
+ // TODO(zachh): Need to handle post-dial digits; different on N and M.
+ contentValues.put(AnnotatedCallLog.NUMBER, numberAsProtoBytes);
+ }
+
+ contentValues.put(AnnotatedCallLog.TYPE, type);
+ contentValues.put(AnnotatedCallLog.NAME, cachedName);
+ contentValues.put(AnnotatedCallLog.FORMATTED_NUMBER, formattedNumber);
+ contentValues.put(AnnotatedCallLog.PHOTO_URI, cachedPhotoUri);
+ contentValues.put(AnnotatedCallLog.PHOTO_ID, cachedPhotoId);
+ contentValues.put(AnnotatedCallLog.LOOKUP_URI, cachedLookupUri);
+
+ // Phone.getTypeLabel returns "Custom" if given (0, null) which is not of any use. Just
+ // omit setting the label if there's no information for it.
+ if (cachedNumberType != 0 || cachedNumberLabel != null) {
+ contentValues.put(
+ AnnotatedCallLog.NUMBER_TYPE_LABEL,
+ Phone.getTypeLabel(appContext.getResources(), cachedNumberType, cachedNumberLabel)
+ .toString());
+ }
+ contentValues.put(AnnotatedCallLog.IS_READ, isRead);
+ contentValues.put(AnnotatedCallLog.NEW, isNew);
+ contentValues.put(AnnotatedCallLog.GEOCODED_LOCATION, geocodedLocation);
+ populatePhoneAccountLabelAndColor(
+ appContext, contentValues, phoneAccountComponentName, phoneAccountId);
+ contentValues.put(AnnotatedCallLog.FEATURES, features);
if (existingAnnotatedCallLogIds.contains(id)) {
mutations.update(id, contentValues);
@@ -238,6 +318,32 @@ public class SystemCallLogDataSource implements CallLogDataSource {
}
}
+ private void populatePhoneAccountLabelAndColor(
+ Context appContext,
+ ContentValues contentValues,
+ String phoneAccountComponentName,
+ String phoneAccountId) {
+ PhoneAccountHandle phoneAccountHandle =
+ PhoneAccountUtils.getAccount(phoneAccountComponentName, phoneAccountId);
+ if (phoneAccountHandle == null) {
+ return;
+ }
+ String label = PhoneAccountUtils.getAccountLabel(appContext, phoneAccountHandle);
+ if (TextUtils.isEmpty(label)) {
+ return;
+ }
+ contentValues.put(AnnotatedCallLog.PHONE_ACCOUNT_LABEL, label);
+
+ @ColorInt int color = PhoneAccountUtils.getAccountColor(appContext, phoneAccountHandle);
+ if (color == PhoneAccount.NO_HIGHLIGHT_COLOR) {
+ color =
+ appContext
+ .getResources()
+ .getColor(R.color.dialer_secondary_text_color, appContext.getTheme());
+ }
+ contentValues.put(AnnotatedCallLog.PHONE_ACCOUNT_COLOR, color);
+ }
+
private static void handleDeletes(
Context appContext, Set<Long> existingAnnotatedCallLogIds, CallLogMutations mutations) {
Set<Long> systemCallLogIds =