Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4f4a9814 authored by twyen's avatar twyen Committed by android-build-merger
Browse files

Merge "Implement VoicemailDataSource" am: a68f3429

am: 0e451506

Change-Id: Ic5958aeda4e33fc6815d23bc61c3c36c69c93381
parents 7c4b0299 0e451506
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -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() {
+2 −0
Original line number Diff line number Diff line
@@ -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")
          + ");";

+21 −0
Original line number Diff line number Diff line
@@ -132,6 +132,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}.
     *
@@ -155,6 +174,8 @@ public class AnnotatedCallLogContract {
          PHONE_ACCOUNT_COLOR,
          FEATURES,
          NUMBER_ATTRIBUTES,
          IS_VOICEMAIL_CALL,
          VOICEMAIL_CALL_TAG,
          CALL_TYPE
        };
  }
+6 −9
Original line number Diff line number Diff line
@@ -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
+111 −0
Original line number Diff line number Diff line
/*
 * 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) {}
}
Loading