• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.ui.menu;
18 
19 import android.content.Context;
20 import android.provider.CallLog.Calls;
21 import android.telecom.PhoneAccountHandle;
22 import android.text.TextUtils;
23 import com.android.dialer.blockreportspam.BlockReportSpamDialogInfo;
24 import com.android.dialer.calldetails.CallDetailsActivity;
25 import com.android.dialer.callintent.CallInitiationType;
26 import com.android.dialer.calllog.model.CoalescedRow;
27 import com.android.dialer.calllogutils.CallLogContactTypes;
28 import com.android.dialer.calllogutils.PhoneNumberDisplayUtil;
29 import com.android.dialer.dialercontact.DialerContact;
30 import com.android.dialer.historyitemactions.DividerModule;
31 import com.android.dialer.historyitemactions.HistoryItemActionModule;
32 import com.android.dialer.historyitemactions.IntentModule;
33 import com.android.dialer.historyitemactions.SharedModules;
34 import com.android.dialer.logging.ReportingLocation;
35 import com.android.dialer.phonenumberutil.PhoneNumberHelper;
36 import com.android.dialer.telecom.TelecomUtil;
37 import com.google.common.base.Optional;
38 import java.util.ArrayList;
39 import java.util.Collections;
40 import java.util.List;
41 
42 /**
43  * Configures the modules for the bottom sheet; these are the rows below the top row (primary
44  * action) in the bottom sheet.
45  */
46 @SuppressWarnings("Guava")
47 final class Modules {
48 
fromRow(Context context, CoalescedRow row)49   static List<HistoryItemActionModule> fromRow(Context context, CoalescedRow row) {
50     // Conditionally add each module, which are items in the bottom sheet's menu.
51     List<HistoryItemActionModule> modules = new ArrayList<>();
52 
53     String normalizedNumber = row.number().getNormalizedNumber();
54     boolean canPlaceCalls =
55         PhoneNumberHelper.canPlaceCallsTo(normalizedNumber, row.numberPresentation());
56 
57     if (canPlaceCalls) {
58       modules.addAll(createModulesForCalls(context, row, normalizedNumber));
59       Optional<HistoryItemActionModule> moduleForSendingTextMessage =
60           SharedModules.createModuleForSendingTextMessage(
61               context, normalizedNumber, row.numberAttributes().getIsBlocked());
62       if (moduleForSendingTextMessage.isPresent()) {
63         modules.add(moduleForSendingTextMessage.get());
64       }
65     }
66 
67     if (!modules.isEmpty()) {
68       modules.add(new DividerModule());
69     }
70 
71 
72     // TODO(zachh): Module for CallComposer.
73 
74     if (canPlaceCalls) {
75       Optional<HistoryItemActionModule> moduleForAddingToContacts =
76           SharedModules.createModuleForAddingToContacts(
77               context,
78               row.number(),
79               row.numberAttributes().getName(),
80               row.numberAttributes().getLookupUri(),
81               row.numberAttributes().getIsBlocked(),
82               row.numberAttributes().getIsSpam());
83       if (moduleForAddingToContacts.isPresent()) {
84         modules.add(moduleForAddingToContacts.get());
85       }
86 
87       BlockReportSpamDialogInfo blockReportSpamDialogInfo =
88           BlockReportSpamDialogInfo.newBuilder()
89               .setNormalizedNumber(row.number().getNormalizedNumber())
90               .setCountryIso(row.number().getCountryIso())
91               .setCallType(row.callType())
92               .setReportingLocation(ReportingLocation.Type.CALL_LOG_HISTORY)
93               .setContactSource(row.numberAttributes().getContactSource())
94               .build();
95       modules.addAll(
96           SharedModules.createModulesHandlingBlockedOrSpamNumber(
97               context,
98               blockReportSpamDialogInfo,
99               row.numberAttributes().getIsBlocked(),
100               row.numberAttributes().getIsSpam()));
101 
102       Optional<HistoryItemActionModule> moduleForCopyingNumber =
103           SharedModules.createModuleForCopyingNumber(context, normalizedNumber);
104       if (moduleForCopyingNumber.isPresent()) {
105         modules.add(moduleForCopyingNumber.get());
106       }
107     }
108 
109     // TODO(zachh): Revisit if DialerContact is the best thing to pass to CallDetails; could
110     // it use a HistoryItemPrimaryActionInfo instead?
111     modules.add(createModuleForAccessingCallDetails(context, row));
112 
113     modules.add(new DeleteCallLogItemModule(context, row.coalescedIds()));
114 
115     return modules;
116   }
117 
createModulesForCalls( Context context, CoalescedRow row, String normalizedNumber)118   private static List<HistoryItemActionModule> createModulesForCalls(
119       Context context, CoalescedRow row, String normalizedNumber) {
120     // Don't add call options if a number is blocked.
121     if (row.numberAttributes().getIsBlocked()) {
122       return Collections.emptyList();
123     }
124 
125     List<HistoryItemActionModule> modules = new ArrayList<>();
126     PhoneAccountHandle phoneAccountHandle =
127         TelecomUtil.composePhoneAccountHandle(
128             row.phoneAccountComponentName(), row.phoneAccountId());
129 
130     // Add an audio call item
131     modules.add(
132         IntentModule.newCallModule(
133             context, normalizedNumber, phoneAccountHandle, CallInitiationType.Type.CALL_LOG));
134 
135     // Add a video item if (1) the call log entry is for a video call, and (2) the call is not spam.
136     if ((row.features() & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO
137         && !row.numberAttributes().getIsSpam()) {
138       modules.add(
139           IntentModule.newVideoCallModule(
140               context, normalizedNumber, phoneAccountHandle, CallInitiationType.Type.CALL_LOG));
141     }
142 
143     // TODO(zachh): Also show video option if the call log entry is for an audio call but video
144     // capabilities are present?
145 
146     return modules;
147   }
148 
createModuleForAccessingCallDetails( Context context, CoalescedRow row)149   private static HistoryItemActionModule createModuleForAccessingCallDetails(
150       Context context, CoalescedRow row) {
151     boolean canReportAsInvalidNumber = row.numberAttributes().getCanReportAsInvalidNumber();
152     boolean canSupportAssistedDialing = !TextUtils.isEmpty(row.numberAttributes().getLookupUri());
153 
154     return new IntentModule(
155         context,
156         CallDetailsActivity.newInstance(
157             context,
158             row.coalescedIds(),
159             createDialerContactFromRow(context, row),
160             canReportAsInvalidNumber,
161             canSupportAssistedDialing),
162         R.string.call_details_menu_label,
163         R.drawable.quantum_ic_info_outline_vd_theme_24);
164   }
165 
createDialerContactFromRow(Context context, CoalescedRow row)166   private static DialerContact createDialerContactFromRow(Context context, CoalescedRow row) {
167     Optional<String> presentationName =
168         PhoneNumberDisplayUtil.getNameForPresentation(context, row.numberPresentation());
169     if (presentationName.isPresent()) {
170       return DialerContact.newBuilder()
171           .setNameOrNumber(presentationName.get())
172           .setContactType(CallLogContactTypes.getContactType(row))
173           .build();
174     }
175 
176     String normalizedNumber = row.number().getNormalizedNumber();
177     DialerContact.Builder dialerContactBuilder =
178         DialerContact.newBuilder()
179             .setNumber(normalizedNumber)
180             .setContactType(CallLogContactTypes.getContactType(row))
181             .setPhotoId(row.numberAttributes().getPhotoId());
182 
183     if (!row.numberAttributes().getName().isEmpty()) {
184       dialerContactBuilder.setNameOrNumber(row.numberAttributes().getName());
185       if (row.formattedNumber() != null) {
186         dialerContactBuilder.setDisplayNumber(row.formattedNumber());
187       }
188     } else if (!TextUtils.isEmpty(row.formattedNumber())) {
189       dialerContactBuilder.setNameOrNumber(row.formattedNumber());
190     }
191 
192     dialerContactBuilder.setNumberLabel(row.numberAttributes().getNumberTypeLabel());
193     dialerContactBuilder.setPhotoUri(row.numberAttributes().getPhotoUri());
194     dialerContactBuilder.setContactUri(row.numberAttributes().getLookupUri());
195 
196     return dialerContactBuilder.build();
197   }
198 }
199