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.app.calllog; 18 19 import android.content.ContentValues; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.net.Uri; 23 import android.provider.ContactsContract; 24 import android.support.annotation.Nullable; 25 import android.telecom.PhoneAccount; 26 import android.telecom.PhoneAccountHandle; 27 import android.telephony.TelephonyManager; 28 import com.android.contacts.common.model.Contact; 29 import com.android.contacts.common.model.ContactLoader; 30 import com.android.dialer.calldetails.CallDetailsActivity; 31 import com.android.dialer.calldetails.CallDetailsEntries; 32 import com.android.dialer.callintent.CallInitiationType; 33 import com.android.dialer.callintent.CallIntentBuilder; 34 import com.android.dialer.dialercontact.DialerContact; 35 import com.android.dialer.duo.DuoComponent; 36 import com.android.dialer.duo.DuoConstants; 37 import com.android.dialer.precall.PreCall; 38 import com.android.dialer.util.IntentUtil; 39 import java.util.ArrayList; 40 41 /** 42 * Used to create an intent to attach to an action in the call log. 43 * 44 * <p>The intent is constructed lazily with the given information. 45 */ 46 public abstract class IntentProvider { 47 48 private static final String TAG = IntentProvider.class.getSimpleName(); 49 getReturnCallIntentProvider(final String number)50 public static IntentProvider getReturnCallIntentProvider(final String number) { 51 return getReturnCallIntentProvider(number, null); 52 } 53 getReturnCallIntentProvider( final String number, final PhoneAccountHandle accountHandle)54 public static IntentProvider getReturnCallIntentProvider( 55 final String number, final PhoneAccountHandle accountHandle) { 56 return new IntentProvider() { 57 @Override 58 public Intent getIntent(Context context) { 59 return PreCall.getIntent( 60 context, 61 new CallIntentBuilder(number, CallInitiationType.Type.CALL_LOG) 62 .setPhoneAccountHandle(accountHandle)); 63 } 64 }; 65 } 66 67 public static IntentProvider getAssistedDialIntentProvider( 68 final String number, final Context context, final TelephonyManager telephonyManager) { 69 return new IntentProvider() { 70 @Override 71 public Intent getIntent(Context context) { 72 return PreCall.getIntent( 73 context, 74 new CallIntentBuilder(number, CallInitiationType.Type.CALL_LOG) 75 .setAllowAssistedDial(true)); 76 } 77 }; 78 } 79 80 public static IntentProvider getReturnVideoCallIntentProvider(final String number) { 81 return getReturnVideoCallIntentProvider(number, null); 82 } 83 84 public static IntentProvider getReturnVideoCallIntentProvider( 85 final String number, final PhoneAccountHandle accountHandle) { 86 return new IntentProvider() { 87 @Override 88 public Intent getIntent(Context context) { 89 return PreCall.getIntent( 90 context, 91 new CallIntentBuilder(number, CallInitiationType.Type.CALL_LOG) 92 .setPhoneAccountHandle(accountHandle) 93 .setIsVideoCall(true)); 94 } 95 }; 96 } 97 98 public static IntentProvider getDuoVideoIntentProvider(String number) { 99 return new IntentProvider() { 100 @Override 101 public Intent getIntent(Context context) { 102 return DuoComponent.get(context).getDuo().getIntent(context, number); 103 } 104 }; 105 } 106 107 public static IntentProvider getInstallDuoIntentProvider() { 108 return new IntentProvider() { 109 @Override 110 public Intent getIntent(Context context) { 111 return new Intent( 112 Intent.ACTION_VIEW, 113 new Uri.Builder() 114 .scheme("https") 115 .authority("play.google.com") 116 .appendEncodedPath("store/apps/details") 117 .appendQueryParameter("id", DuoConstants.PACKAGE_NAME) 118 .appendQueryParameter( 119 "referrer", 120 "utm_source=dialer&utm_medium=text&utm_campaign=product") // This string is from 121 // the Duo team 122 .build()); 123 } 124 }; 125 } 126 127 public static IntentProvider getSetUpDuoIntentProvider() { 128 return new IntentProvider() { 129 @Override 130 public Intent getIntent(Context context) { 131 return new Intent(DuoConstants.DUO_ACTIVATE_ACTION).setPackage(DuoConstants.PACKAGE_NAME); 132 } 133 }; 134 } 135 136 public static IntentProvider getDuoInviteIntentProvider(String number) { 137 return new IntentProvider() { 138 @Override 139 public Intent getIntent(Context context) { 140 Intent intent = 141 new Intent(DuoConstants.DUO_INVITE_ACTION) 142 .setPackage(DuoConstants.PACKAGE_NAME) 143 .setData(Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null /* fragment */)); 144 return intent; 145 } 146 }; 147 } 148 149 public static IntentProvider getReturnVoicemailCallIntentProvider( 150 @Nullable PhoneAccountHandle phoneAccountHandle) { 151 return new IntentProvider() { 152 @Override 153 public Intent getIntent(Context context) { 154 return PreCall.getIntent( 155 context, 156 CallIntentBuilder.forVoicemail(phoneAccountHandle, CallInitiationType.Type.CALL_LOG)); 157 } 158 }; 159 } 160 161 public static IntentProvider getSendSmsIntentProvider(final String number) { 162 return new IntentProvider() { 163 @Override 164 public Intent getIntent(Context context) { 165 return IntentUtil.getSendSmsIntent(number); 166 } 167 }; 168 } 169 170 /** 171 * Retrieves the call details intent provider for an entry in the call log. 172 * 173 * @param callDetailsEntries The call details of the other calls grouped together with the call. 174 * @param contact The contact with which this call details intent pertains to. 175 * @param canReportCallerId Whether reporting a caller ID is supported. 176 * @param canSupportAssistedDialing Whether assisted dialing is supported. 177 * @return The call details intent provider. 178 */ 179 public static IntentProvider getCallDetailIntentProvider( 180 CallDetailsEntries callDetailsEntries, 181 DialerContact contact, 182 boolean canReportCallerId, 183 boolean canSupportAssistedDialing) { 184 return new IntentProvider() { 185 @Override 186 public Intent getIntent(Context context) { 187 return CallDetailsActivity.newInstance( 188 context, callDetailsEntries, contact, canReportCallerId, canSupportAssistedDialing); 189 } 190 }; 191 } 192 193 /** Retrieves an add contact intent for the given contact and phone call details. */ 194 public static IntentProvider getAddContactIntentProvider( 195 final Uri lookupUri, 196 final CharSequence name, 197 final CharSequence number, 198 final int numberType, 199 final boolean isNewContact) { 200 return new IntentProvider() { 201 @Override 202 public Intent getIntent(Context context) { 203 Contact contactToSave = null; 204 205 if (lookupUri != null) { 206 contactToSave = ContactLoader.parseEncodedContactEntity(lookupUri); 207 } 208 209 if (contactToSave != null) { 210 // Populate the intent with contact information stored in the lookup URI. 211 // Note: This code mirrors code in Contacts/QuickContactsActivity. 212 final Intent intent; 213 if (isNewContact) { 214 intent = IntentUtil.getNewContactIntent(); 215 } else { 216 intent = IntentUtil.getAddToExistingContactIntent(); 217 } 218 219 ArrayList<ContentValues> values = contactToSave.getContentValues(); 220 // Only pre-fill the name field if the provided display name is an nickname 221 // or better (e.g. structured name, nickname) 222 if (contactToSave.getDisplayNameSource() 223 >= ContactsContract.DisplayNameSources.NICKNAME) { 224 intent.putExtra(ContactsContract.Intents.Insert.NAME, contactToSave.getDisplayName()); 225 } else if (contactToSave.getDisplayNameSource() 226 == ContactsContract.DisplayNameSources.ORGANIZATION) { 227 // This is probably an organization. Instead of copying the organization 228 // name into a name entry, copy it into the organization entry. This 229 // way we will still consider the contact an organization. 230 final ContentValues organization = new ContentValues(); 231 organization.put( 232 ContactsContract.CommonDataKinds.Organization.COMPANY, 233 contactToSave.getDisplayName()); 234 organization.put( 235 ContactsContract.Data.MIMETYPE, 236 ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE); 237 values.add(organization); 238 } 239 240 // Last time used and times used are aggregated values from the usage stat 241 // table. They need to be removed from data values so the SQL table can insert 242 // properly 243 for (ContentValues value : values) { 244 value.remove(ContactsContract.Data.LAST_TIME_USED); 245 value.remove(ContactsContract.Data.TIMES_USED); 246 } 247 248 intent.putExtra(ContactsContract.Intents.Insert.DATA, values); 249 250 return intent; 251 } else { 252 // If no lookup uri is provided, rely on the available phone number and name. 253 if (isNewContact) { 254 return IntentUtil.getNewContactIntent(name, number, numberType); 255 } else { 256 return IntentUtil.getAddToExistingContactIntent(name, number, numberType); 257 } 258 } 259 } 260 }; 261 } 262 263 public abstract Intent getIntent(Context context); 264 } 265