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.calldetails.CallDetailsActivity;
28import com.android.dialer.calldetails.CallDetailsEntries;
29import com.android.dialer.callintent.CallInitiationType;
30import com.android.dialer.callintent.CallIntentBuilder;
31import com.android.dialer.dialercontact.DialerContact;
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, DialerContact contact, boolean canReportCallerId) {
116    return new IntentProvider() {
117      @Override
118      public Intent getIntent(Context context) {
119        return CallDetailsActivity.newInstance(
120            context, callDetailsEntries, contact, canReportCallerId);
121      }
122    };
123  }
124
125  /** Retrieves an add contact intent for the given contact and phone call details. */
126  public static IntentProvider getAddContactIntentProvider(
127      final Uri lookupUri,
128      final CharSequence name,
129      final CharSequence number,
130      final int numberType,
131      final boolean isNewContact) {
132    return new IntentProvider() {
133      @Override
134      public Intent getIntent(Context context) {
135        Contact contactToSave = null;
136
137        if (lookupUri != null) {
138          contactToSave = ContactLoader.parseEncodedContactEntity(lookupUri);
139        }
140
141        if (contactToSave != null) {
142          // Populate the intent with contact information stored in the lookup URI.
143          // Note: This code mirrors code in Contacts/QuickContactsActivity.
144          final Intent intent;
145          if (isNewContact) {
146            intent = IntentUtil.getNewContactIntent();
147          } else {
148            intent = IntentUtil.getAddToExistingContactIntent();
149          }
150
151          ArrayList<ContentValues> values = contactToSave.getContentValues();
152          // Only pre-fill the name field if the provided display name is an nickname
153          // or better (e.g. structured name, nickname)
154          if (contactToSave.getDisplayNameSource()
155              >= ContactsContract.DisplayNameSources.NICKNAME) {
156            intent.putExtra(ContactsContract.Intents.Insert.NAME, contactToSave.getDisplayName());
157          } else if (contactToSave.getDisplayNameSource()
158              == ContactsContract.DisplayNameSources.ORGANIZATION) {
159            // This is probably an organization. Instead of copying the organization
160            // name into a name entry, copy it into the organization entry. This
161            // way we will still consider the contact an organization.
162            final ContentValues organization = new ContentValues();
163            organization.put(
164                ContactsContract.CommonDataKinds.Organization.COMPANY,
165                contactToSave.getDisplayName());
166            organization.put(
167                ContactsContract.Data.MIMETYPE,
168                ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE);
169            values.add(organization);
170          }
171
172          // Last time used and times used are aggregated values from the usage stat
173          // table. They need to be removed from data values so the SQL table can insert
174          // properly
175          for (ContentValues value : values) {
176            value.remove(ContactsContract.Data.LAST_TIME_USED);
177            value.remove(ContactsContract.Data.TIMES_USED);
178          }
179
180          intent.putExtra(ContactsContract.Intents.Insert.DATA, values);
181
182          return intent;
183        } else {
184          // If no lookup uri is provided, rely on the available phone number and name.
185          if (isNewContact) {
186            return IntentUtil.getNewContactIntent(name, number, numberType);
187          } else {
188            return IntentUtil.getAddToExistingContactIntent(name, number, numberType);
189          }
190        }
191      }
192    };
193  }
194
195  public abstract Intent getIntent(Context context);
196}
197