summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/calllog
diff options
context:
space:
mode:
authortwyen <twyen@google.com>2018-03-19 15:20:59 -0700
committerCopybara-Service <copybara-piper@google.com>2018-03-19 15:23:28 -0700
commitcd3d49843431913c2ff042d2294a8b5201877882 (patch)
tree7bd55b5175802fe3ac8fe4c45bf27cdd583ee580 /java/com/android/dialer/calllog
parentf4a48247329967ecc3f952b8604f122d0cbc2e28 (diff)
Implement VoicemailDataSource
This data source determines if the call is to the voicemail inbox. isVoicemail() is removed from NumberAttributes and PhoneLookup. It is yet decided how in call UI should handle voicemail calls in the future. TAG_CHANGE_OK=proto not in prod yet. Please clear app data. TYPE_CHANGE_OK=above Bug: 70989587 Test: Unit tests PiperOrigin-RevId: 189650273 Change-Id: Iafebf1abb18c74301b62a72d1d04deecd6d78d29
Diffstat (limited to 'java/com/android/dialer/calllog')
-rw-r--r--java/com/android/dialer/calllog/CallLogModule.java6
-rw-r--r--java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java2
-rw-r--r--java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java21
-rw-r--r--java/com/android/dialer/calllog/database/contract/number_attributes.proto15
-rw-r--r--java/com/android/dialer/calllog/datasources/voicemail/VoicemailDataSource.java111
-rw-r--r--java/com/android/dialer/calllog/model/CoalescedRow.java10
-rw-r--r--java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java8
-rw-r--r--java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java3
-rw-r--r--java/com/android/dialer/calllog/ui/menu/Modules.java3
9 files changed, 164 insertions, 15 deletions
diff --git a/java/com/android/dialer/calllog/CallLogModule.java b/java/com/android/dialer/calllog/CallLogModule.java
index 6c85fd631..9dd9a794d 100644
--- a/java/com/android/dialer/calllog/CallLogModule.java
+++ b/java/com/android/dialer/calllog/CallLogModule.java
@@ -20,6 +20,7 @@ import com.android.dialer.calllog.datasources.CallLogDataSource;
import com.android.dialer.calllog.datasources.DataSources;
import com.android.dialer.calllog.datasources.phonelookup.PhoneLookupDataSource;
import com.android.dialer.calllog.datasources.systemcalllog.SystemCallLogDataSource;
+import com.android.dialer.calllog.datasources.voicemail.VoicemailDataSource;
import com.google.common.collect.ImmutableList;
import dagger.Module;
import dagger.Provides;
@@ -31,10 +32,11 @@ public abstract class CallLogModule {
@Provides
static DataSources provideCallLogDataSources(
SystemCallLogDataSource systemCallLogDataSource,
- PhoneLookupDataSource phoneLookupDataSource) {
+ PhoneLookupDataSource phoneLookupDataSource,
+ VoicemailDataSource voicemailDataSource) {
// System call log must be first, see getDataSourcesExcludingSystemCallLog below.
ImmutableList<CallLogDataSource> allDataSources =
- ImmutableList.of(systemCallLogDataSource, phoneLookupDataSource);
+ ImmutableList.of(systemCallLogDataSource, phoneLookupDataSource, voicemailDataSource);
return new DataSources() {
@Override
public SystemCallLogDataSource getSystemCallLogDataSource() {
diff --git a/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java b/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java
index c8387377b..3b67ff2d7 100644
--- a/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java
+++ b/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java
@@ -56,6 +56,8 @@ class AnnotatedCallLogDatabaseHelper extends SQLiteOpenHelper {
+ (AnnotatedCallLog.VOICEMAIL_URI + " text, ")
+ (AnnotatedCallLog.CALL_TYPE + " integer not null, ")
+ (AnnotatedCallLog.NUMBER_ATTRIBUTES + " blob, ")
+ + (AnnotatedCallLog.IS_VOICEMAIL_CALL + " integer, ")
+ + (AnnotatedCallLog.VOICEMAIL_CALL_TAG + " text, ")
+ (AnnotatedCallLog.TRANSCRIPTION_STATE + " integer")
+ ");";
diff --git a/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java b/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java
index c181d7573..b1cf6e495 100644
--- a/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java
+++ b/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java
@@ -133,6 +133,25 @@ public class AnnotatedCallLogContract {
String NUMBER_ATTRIBUTES = "number_attributes";
/**
+ * Whether the call is to the voicemail inbox.
+ *
+ * <p>TYPE: INTEGER (boolean)
+ *
+ * @see android.telecom.TelecomManager#isVoiceMailNumber(android.telecom.PhoneAccountHandle,
+ * String)
+ */
+ String IS_VOICEMAIL_CALL = "is_voicemail_call";
+
+ /**
+ * The "name" of the voicemail inbox. This is provided by the SIM to show as the caller ID
+ *
+ * <p>TYPE: TEXT
+ *
+ * @see android.telephony.TelephonyManager#getVoiceMailAlphaTag()
+ */
+ String VOICEMAIL_CALL_TAG = "voicemail_call_tag";
+
+ /**
* Copied from {@link android.provider.CallLog.Calls#TYPE}.
*
* <p>Type: INTEGER (int)
@@ -155,6 +174,8 @@ public class AnnotatedCallLogContract {
PHONE_ACCOUNT_COLOR,
FEATURES,
NUMBER_ATTRIBUTES,
+ IS_VOICEMAIL_CALL,
+ VOICEMAIL_CALL_TAG,
CALL_TYPE
};
}
diff --git a/java/com/android/dialer/calllog/database/contract/number_attributes.proto b/java/com/android/dialer/calllog/database/contract/number_attributes.proto
index e24f393f7..2e93291ab 100644
--- a/java/com/android/dialer/calllog/database/contract/number_attributes.proto
+++ b/java/com/android/dialer/calllog/database/contract/number_attributes.proto
@@ -24,7 +24,7 @@ package com.android.dialer;
import "java/com/android/dialer/logging/contact_source.proto";
// Information related to the phone number of the call.
-// Next ID: 13
+// Next ID: 12
message NumberAttributes {
// The name (which may be a person's name or business name, but not a number)
// formatted exactly as it should appear to the user. If the user's locale or
@@ -52,22 +52,19 @@ message NumberAttributes {
// The number is a call to a business from nearby places lookup.
optional bool is_business = 6;
- // The number is a call to the voicemail inbox.
- optional bool is_voicemail = 7;
-
// Can the number be reported as invalid through People API
- optional bool can_report_as_invalid_number = 8;
+ optional bool can_report_as_invalid_number = 7;
// True if the CP2 information is incomplete and needs to be queried at
// display time.
- optional bool is_cp2_info_incomplete = 9;
+ optional bool is_cp2_info_incomplete = 8;
// Whether the number is blocked.
- optional bool is_blocked = 10;
+ optional bool is_blocked = 9;
// Whether the number is spam.
- optional bool is_spam = 11;
+ optional bool is_spam = 10;
// Source of the contact associated with the number.
- optional com.android.dialer.logging.ContactSource.Type contact_source = 12;
+ optional com.android.dialer.logging.ContactSource.Type contact_source = 11;
} \ No newline at end of file
diff --git a/java/com/android/dialer/calllog/datasources/voicemail/VoicemailDataSource.java b/java/com/android/dialer/calllog/datasources/voicemail/VoicemailDataSource.java
new file mode 100644
index 000000000..e8dc3e1eb
--- /dev/null
+++ b/java/com/android/dialer/calllog/datasources/voicemail/VoicemailDataSource.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.dialer.calllog.datasources.voicemail;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.telephony.TelephonyManager;
+import com.android.dialer.DialerPhoneNumber;
+import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog;
+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.common.concurrent.Annotations.BackgroundExecutor;
+import com.android.dialer.compat.telephony.TelephonyManagerCompat;
+import com.android.dialer.telecom.TelecomUtil;
+import com.android.dialer.util.PermissionsUtil;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.protobuf.InvalidProtocolBufferException;
+import java.util.List;
+import java.util.Map.Entry;
+import javax.inject.Inject;
+
+/** Provide information for whether the call is a call to the voicemail inbox. */
+public class VoicemailDataSource implements CallLogDataSource {
+
+ private final ListeningExecutorService backgroundExecutor;
+
+ @Inject
+ VoicemailDataSource(@BackgroundExecutor ListeningExecutorService backgroundExecutor) {
+ this.backgroundExecutor = backgroundExecutor;
+ }
+
+ @Override
+ public ListenableFuture<Boolean> isDirty(Context appContext) {
+ // The isVoicemail status is immutable and permanent. The call will always show as "Voicemail"
+ // even if the SIM is swapped. Dialing the row will result in some unexpected number after a SIM
+ // swap but this is deemed acceptable.
+ return Futures.immediateFuture(false);
+ }
+
+ @Override
+ @SuppressWarnings("missingPermission")
+ public ListenableFuture<Void> fill(Context appContext, CallLogMutations mutations) {
+ if (!PermissionsUtil.hasReadPhoneStatePermissions(appContext)) {
+ return Futures.immediateFuture(null);
+ }
+ return backgroundExecutor.submit(
+ () -> {
+ TelecomManager telecomManager = appContext.getSystemService(TelecomManager.class);
+ for (Entry<Long, ContentValues> insert : mutations.getInserts().entrySet()) {
+ ContentValues values = insert.getValue();
+ PhoneAccountHandle phoneAccountHandle =
+ TelecomUtil.composePhoneAccountHandle(
+ values.getAsString(AnnotatedCallLog.PHONE_ACCOUNT_COMPONENT_NAME),
+ values.getAsString(AnnotatedCallLog.PHONE_ACCOUNT_ID));
+ DialerPhoneNumber dialerPhoneNumber;
+ try {
+ dialerPhoneNumber =
+ DialerPhoneNumber.parseFrom(values.getAsByteArray(AnnotatedCallLog.NUMBER));
+ } catch (InvalidProtocolBufferException e) {
+ throw new IllegalStateException(e);
+ }
+
+ if (telecomManager.isVoiceMailNumber(
+ phoneAccountHandle, dialerPhoneNumber.getNormalizedNumber())) {
+ values.put(AnnotatedCallLog.IS_VOICEMAIL_CALL, 1);
+ TelephonyManager telephonyManager =
+ TelephonyManagerCompat.getTelephonyManagerForPhoneAccountHandle(
+ appContext, phoneAccountHandle);
+ values.put(
+ AnnotatedCallLog.VOICEMAIL_CALL_TAG, telephonyManager.getVoiceMailAlphaTag());
+ }
+ }
+ return null;
+ });
+ }
+
+ @Override
+ public ListenableFuture<Void> onSuccessfulFill(Context appContext) {
+ return Futures.immediateFuture(null);
+ }
+
+ @Override
+ public ContentValues coalesce(List<ContentValues> individualRowsSortedByTimestampDesc) {
+ return new RowCombiner(individualRowsSortedByTimestampDesc)
+ .useMostRecentInt(AnnotatedCallLog.IS_VOICEMAIL_CALL)
+ .useMostRecentString(AnnotatedCallLog.VOICEMAIL_CALL_TAG)
+ .combine();
+ }
+
+ @Override
+ public void registerContentObservers(Context appContext) {}
+}
diff --git a/java/com/android/dialer/calllog/model/CoalescedRow.java b/java/com/android/dialer/calllog/model/CoalescedRow.java
index 2b6db97a2..737e736d6 100644
--- a/java/com/android/dialer/calllog/model/CoalescedRow.java
+++ b/java/com/android/dialer/calllog/model/CoalescedRow.java
@@ -39,6 +39,7 @@ public abstract class CoalescedRow {
.setFeatures(0)
.setCallType(0)
.setNumberAttributes(NumberAttributes.getDefaultInstance())
+ .setIsVoicemailCall(false)
.setCoalescedIds(CoalescedIds.getDefaultInstance());
}
@@ -80,6 +81,11 @@ public abstract class CoalescedRow {
public abstract NumberAttributes numberAttributes();
+ public abstract boolean isVoicemailCall();
+
+ @Nullable
+ public abstract String voicemailCallTag();
+
public abstract CoalescedIds coalescedIds();
/** Builder for {@link CoalescedRow}. */
@@ -117,6 +123,10 @@ public abstract class CoalescedRow {
public abstract Builder setNumberAttributes(NumberAttributes numberAttributes);
+ public abstract Builder setIsVoicemailCall(boolean isVoicemail);
+
+ public abstract Builder setVoicemailCallTag(@Nullable String tag);
+
public abstract Builder setCoalescedIds(CoalescedIds coalescedIds);
public abstract CoalescedRow build();
diff --git a/java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java b/java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java
index 0b1c6c990..a5cfd3f59 100644
--- a/java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java
+++ b/java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java
@@ -44,8 +44,10 @@ final class CoalescedAnnotatedCallLogCursorLoader extends CursorLoader {
private static final int PHONE_ACCOUNT_COLOR = 11;
private static final int FEATURES = 12;
private static final int NUMBER_ATTRIBUTES = 13;
- private static final int CALL_TYPE = 14;
- private static final int COALESCED_IDS = 15;
+ private static final int IS_VOICEMAIL_CALL = 14;
+ private static final int VOICEMAIL_CALL_TAG = 15;
+ private static final int CALL_TYPE = 16;
+ private static final int COALESCED_IDS = 17;
CoalescedAnnotatedCallLogCursorLoader(Context context) {
// CoalescedAnnotatedCallLog requires that PROJECTION be ALL_COLUMNS and the following params be
@@ -98,6 +100,8 @@ final class CoalescedAnnotatedCallLogCursorLoader extends CursorLoader {
.setFeatures(cursor.getInt(FEATURES))
.setCallType(cursor.getInt(CALL_TYPE))
.setNumberAttributes(numberAttributes)
+ .setIsVoicemailCall(cursor.getInt(IS_VOICEMAIL_CALL) == 1)
+ .setVoicemailCallTag(cursor.getString(VOICEMAIL_CALL_TAG))
.setCoalescedIds(coalescedIds)
.build();
}
diff --git a/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java
index 4c2d124d7..74be21b0c 100644
--- a/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java
+++ b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java
@@ -153,7 +153,8 @@ final class NewCallLogViewHolder extends RecyclerView.ViewHolder {
private void setPhoto(CoalescedRow row) {
PhotoInfo.Builder photoInfoBuilder =
- NumberAttributesConverter.toPhotoInfoBuilder(row.numberAttributes());
+ NumberAttributesConverter.toPhotoInfoBuilder(row.numberAttributes())
+ .setIsVoicemail(row.isVoicemailCall());
if (!TextUtils.isEmpty(row.formattedNumber())) {
photoInfoBuilder.setFormattedNumber(row.formattedNumber());
}
diff --git a/java/com/android/dialer/calllog/ui/menu/Modules.java b/java/com/android/dialer/calllog/ui/menu/Modules.java
index fd5f6a348..69b42e304 100644
--- a/java/com/android/dialer/calllog/ui/menu/Modules.java
+++ b/java/com/android/dialer/calllog/ui/menu/Modules.java
@@ -176,7 +176,8 @@ final class Modules {
private static PhotoInfo createPhotoInfoFromRow(CoalescedRow row) {
PhotoInfo.Builder photoInfoBuilder =
NumberAttributesConverter.toPhotoInfoBuilder(row.numberAttributes())
- .setIsVideo((row.features() & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO);
+ .setIsVideo((row.features() & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO)
+ .setIsVoicemail(row.isVoicemailCall());
if (!TextUtils.isEmpty(row.formattedNumber())) {
photoInfoBuilder.setFormattedNumber(row.formattedNumber());
}