1 /*
2  * Copyright (C) 2011 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;
18 
19 import android.content.ContentValues;
20 import android.content.ContentUris;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.net.Uri;
24 import android.provider.ContactsContract;
25 import android.telecom.PhoneAccountHandle;
26 
27 import com.android.contacts.common.CallUtil;
28 import com.android.contacts.common.model.Contact;
29 import com.android.contacts.common.model.ContactLoader;
30 import com.android.dialer.CallDetailActivity;
31 import com.android.dialer.util.IntentUtil;
32 import com.android.dialer.util.IntentUtil.CallIntentBuilder;
33 import com.android.dialer.util.TelecomUtil;
34 import com.android.incallui.Call.LogState;
35 
36 import java.util.ArrayList;
37 
38 /**
39  * Used to create an intent to attach to an action in the call log.
40  * <p>
41  * The intent is constructed lazily with the given information.
42  */
43 public abstract class IntentProvider {
44 
45     private static final String TAG = IntentProvider.class.getSimpleName();
46 
getIntent(Context context)47     public abstract Intent getIntent(Context context);
48 
getReturnCallIntentProvider(final String number)49     public static IntentProvider getReturnCallIntentProvider(final String number) {
50         return getReturnCallIntentProvider(number, null);
51     }
52 
getReturnCallIntentProvider(final String number, final PhoneAccountHandle accountHandle)53     public static IntentProvider getReturnCallIntentProvider(final String number,
54             final PhoneAccountHandle accountHandle) {
55         return new IntentProvider() {
56             @Override
57             public Intent getIntent(Context context) {
58                 return new CallIntentBuilder(number)
59                         .setPhoneAccountHandle(accountHandle)
60                         .setCallInitiationType(LogState.INITIATION_CALL_LOG)
61                         .build();
62             }
63         };
64     }
65 
66     public static IntentProvider getReturnVideoCallIntentProvider(final String number) {
67         return getReturnVideoCallIntentProvider(number, null);
68     }
69 
70     public static IntentProvider getReturnVideoCallIntentProvider(final String number,
71             final PhoneAccountHandle accountHandle) {
72         return new IntentProvider() {
73             @Override
74             public Intent getIntent(Context context) {
75                 return new CallIntentBuilder(number)
76                         .setPhoneAccountHandle(accountHandle)
77                         .setCallInitiationType(LogState.INITIATION_CALL_LOG)
78                         .setIsVideoCall(true)
79                         .build();
80             }
81         };
82     }
83 
84     public static IntentProvider getReturnVoicemailCallIntentProvider() {
85         return new IntentProvider() {
86             @Override
87             public Intent getIntent(Context context) {
88                 return new CallIntentBuilder(CallUtil.getVoicemailUri())
89                         .setCallInitiationType(LogState.INITIATION_CALL_LOG)
90                         .build();
91             }
92         };
93     }
94 
95     public static IntentProvider getSendSmsIntentProvider(final String number) {
96         return new IntentProvider() {
97             @Override
98             public Intent getIntent(Context context) {
99                 return IntentUtil.getSendSmsIntent(number);
100             }
101         };
102     }
103 
104     /**
105      * Retrieves the call details intent provider for an entry in the call log.
106      *
107      * @param id The call ID of the first call in the call group.
108      * @param extraIds The call ID of the other calls grouped together with the call.
109      * @param voicemailUri If call log entry is for a voicemail, the voicemail URI.
110      * @return The call details intent provider.
111      */
112     public static IntentProvider getCallDetailIntentProvider(
113             final long id, final long[] extraIds, final String voicemailUri) {
114         return new IntentProvider() {
115             @Override
116             public Intent getIntent(Context context) {
117                 Intent intent = new Intent(context, CallDetailActivity.class);
118                 // Check if the first item is a voicemail.
119                 if (voicemailUri != null) {
120                     intent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI,
121                             Uri.parse(voicemailUri));
122                 }
123 
124                 if (extraIds != null && extraIds.length > 0) {
125                     intent.putExtra(CallDetailActivity.EXTRA_CALL_LOG_IDS, extraIds);
126                 } else {
127                     // If there is a single item, use the direct URI for it.
128                     intent.setData(ContentUris.withAppendedId(TelecomUtil.getCallLogUri(context),
129                             id));
130                 }
131                 return intent;
132             }
133         };
134     }
135 
136     /**
137      * Retrieves an add contact intent for the given contact and phone call details.
138      */
139     public static IntentProvider getAddContactIntentProvider(
140             final Uri lookupUri,
141             final CharSequence name,
142             final CharSequence number,
143             final int numberType,
144             final boolean isNewContact) {
145         return new IntentProvider() {
146             @Override
147             public Intent getIntent(Context context) {
148                 Contact contactToSave = null;
149 
150                 if (lookupUri != null) {
151                     contactToSave = ContactLoader.parseEncodedContactEntity(lookupUri);
152                 }
153 
154                 if (contactToSave != null) {
155                     // Populate the intent with contact information stored in the lookup URI.
156                     // Note: This code mirrors code in Contacts/QuickContactsActivity.
157                     final Intent intent;
158                     if (isNewContact) {
159                         intent = IntentUtil.getNewContactIntent();
160                     } else {
161                         intent = IntentUtil.getAddToExistingContactIntent();
162                     }
163 
164                     ArrayList<ContentValues> values = contactToSave.getContentValues();
165                     // Only pre-fill the name field if the provided display name is an nickname
166                     // or better (e.g. structured name, nickname)
167                     if (contactToSave.getDisplayNameSource()
168                             >= ContactsContract.DisplayNameSources.NICKNAME) {
169                         intent.putExtra(ContactsContract.Intents.Insert.NAME,
170                                 contactToSave.getDisplayName());
171                     } else if (contactToSave.getDisplayNameSource()
172                             == ContactsContract.DisplayNameSources.ORGANIZATION) {
173                         // This is probably an organization. Instead of copying the organization
174                         // name into a name entry, copy it into the organization entry. This
175                         // way we will still consider the contact an organization.
176                         final ContentValues organization = new ContentValues();
177                         organization.put(ContactsContract.CommonDataKinds.Organization.COMPANY,
178                                 contactToSave.getDisplayName());
179                         organization.put(ContactsContract.Data.MIMETYPE,
180                                 ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE);
181                         values.add(organization);
182                     }
183 
184                     // Last time used and times used are aggregated values from the usage stat
185                     // table. They need to be removed from data values so the SQL table can insert
186                     // properly
187                     for (ContentValues value : values) {
188                         value.remove(ContactsContract.Data.LAST_TIME_USED);
189                         value.remove(ContactsContract.Data.TIMES_USED);
190                     }
191 
192                     intent.putExtra(ContactsContract.Intents.Insert.DATA, values);
193 
194                     return intent;
195                 } else {
196                     // If no lookup uri is provided, rely on the available phone number and name.
197                     if (isNewContact) {
198                         return IntentUtil.getNewContactIntent(name, number, numberType);
199                     } else {
200                         return IntentUtil.getAddToExistingContactIntent(name, number, numberType);
201                     }
202                 }
203             }
204         };
205     }
206 }
207