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