• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package com.android.dialer.calllog.datasources.voicemail;
18 
19 import android.content.ContentValues;
20 import android.content.Context;
21 import android.telecom.PhoneAccountHandle;
22 import android.telecom.TelecomManager;
23 import android.telephony.TelephonyManager;
24 import com.android.dialer.DialerPhoneNumber;
25 import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog;
26 import com.android.dialer.calllog.datasources.CallLogDataSource;
27 import com.android.dialer.calllog.datasources.CallLogMutations;
28 import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor;
29 import com.android.dialer.compat.telephony.TelephonyManagerCompat;
30 import com.android.dialer.inject.ApplicationContext;
31 import com.android.dialer.telecom.TelecomUtil;
32 import com.android.dialer.util.PermissionsUtil;
33 import com.google.common.util.concurrent.Futures;
34 import com.google.common.util.concurrent.ListenableFuture;
35 import com.google.common.util.concurrent.ListeningExecutorService;
36 import com.google.protobuf.InvalidProtocolBufferException;
37 import java.util.Map.Entry;
38 import javax.inject.Inject;
39 
40 /** Provide information for whether the call is a call to the voicemail inbox. */
41 public class VoicemailDataSource implements CallLogDataSource {
42 
43   private final Context appContext;
44   private final ListeningExecutorService backgroundExecutor;
45 
46   @Inject
VoicemailDataSource( @pplicationContext Context appContext, @BackgroundExecutor ListeningExecutorService backgroundExecutor)47   VoicemailDataSource(
48       @ApplicationContext Context appContext,
49       @BackgroundExecutor ListeningExecutorService backgroundExecutor) {
50     this.appContext = appContext;
51     this.backgroundExecutor = backgroundExecutor;
52   }
53 
54   @Override
isDirty()55   public ListenableFuture<Boolean> isDirty() {
56     // The isVoicemail status is immutable and permanent. The call will always show as "Voicemail"
57     // even if the SIM is swapped. Dialing the row will result in some unexpected number after a SIM
58     // swap but this is deemed acceptable.
59     return Futures.immediateFuture(false);
60   }
61 
62   @Override
63   @SuppressWarnings("missingPermission")
fill(CallLogMutations mutations)64   public ListenableFuture<Void> fill(CallLogMutations mutations) {
65     if (!PermissionsUtil.hasReadPhoneStatePermissions(appContext)) {
66       for (Entry<Long, ContentValues> insert : mutations.getInserts().entrySet()) {
67         insert.getValue().put(AnnotatedCallLog.IS_VOICEMAIL_CALL, 0);
68       }
69       return Futures.immediateFuture(null);
70     }
71 
72     return backgroundExecutor.submit(
73         () -> {
74           TelecomManager telecomManager = appContext.getSystemService(TelecomManager.class);
75           for (Entry<Long, ContentValues> insert : mutations.getInserts().entrySet()) {
76             ContentValues values = insert.getValue();
77             PhoneAccountHandle phoneAccountHandle =
78                 TelecomUtil.composePhoneAccountHandle(
79                     values.getAsString(AnnotatedCallLog.PHONE_ACCOUNT_COMPONENT_NAME),
80                     values.getAsString(AnnotatedCallLog.PHONE_ACCOUNT_ID));
81             DialerPhoneNumber dialerPhoneNumber;
82             try {
83               dialerPhoneNumber =
84                   DialerPhoneNumber.parseFrom(values.getAsByteArray(AnnotatedCallLog.NUMBER));
85             } catch (InvalidProtocolBufferException e) {
86               throw new IllegalStateException(e);
87             }
88 
89             if (telecomManager.isVoiceMailNumber(
90                 phoneAccountHandle, dialerPhoneNumber.getNormalizedNumber())) {
91               values.put(AnnotatedCallLog.IS_VOICEMAIL_CALL, 1);
92               TelephonyManager telephonyManager =
93                   TelephonyManagerCompat.getTelephonyManagerForPhoneAccountHandle(
94                       appContext, phoneAccountHandle);
95               values.put(
96                   AnnotatedCallLog.VOICEMAIL_CALL_TAG, telephonyManager.getVoiceMailAlphaTag());
97             } else {
98               values.put(AnnotatedCallLog.IS_VOICEMAIL_CALL, 0);
99             }
100           }
101           return null;
102         });
103   }
104 
105   @Override
onSuccessfulFill()106   public ListenableFuture<Void> onSuccessfulFill() {
107     return Futures.immediateFuture(null);
108   }
109 
110   @Override
registerContentObservers()111   public void registerContentObservers() {}
112 
113   @Override
unregisterContentObservers()114   public void unregisterContentObservers() {}
115 
116   @Override
clearData()117   public ListenableFuture<Void> clearData() {
118     return Futures.immediateFuture(null);
119   }
120 
121   @Override
getLoggingName()122   public String getLoggingName() {
123     return "VoicemailDataSource";
124   }
125 }
126