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