ExternalCallNotifier.java revision ccca31529c07970e89419fb85a9e8153a5396838
1ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/*
2ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Copyright (C) 2017 The Android Open Source Project
3ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
4ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Licensed under the Apache License, Version 2.0 (the "License");
5ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * you may not use this file except in compliance with the License.
6ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * You may obtain a copy of the License at
7ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
8ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *      http://www.apache.org/licenses/LICENSE-2.0
9ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
10ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Unless required by applicable law or agreed to in writing, software
11ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * distributed under the License is distributed on an "AS IS" BASIS,
12ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * See the License for the specific language governing permissions and
14ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * limitations under the License
15ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */
16ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
17ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpackage com.android.incallui;
18ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
19ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.annotation.TargetApi;
20ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.app.Notification;
21ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.app.NotificationManager;
22ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.app.PendingIntent;
23ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.Context;
24ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.Intent;
25ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.graphics.Bitmap;
26ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.graphics.BitmapFactory;
27ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.graphics.drawable.BitmapDrawable;
28ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.net.Uri;
29ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.os.Build.VERSION_CODES;
30ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.support.annotation.NonNull;
31ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.support.annotation.Nullable;
32ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.telecom.Call;
33ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.telecom.PhoneAccount;
34ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.telecom.VideoProfile;
35ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.text.BidiFormatter;
36ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.text.TextDirectionHeuristics;
37ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.text.TextUtils;
38ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.util.ArrayMap;
39ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.ContactsUtils;
40ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.compat.CallCompat;
41ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.preference.ContactsPreferences;
42ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.util.BitmapUtil;
43ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.util.ContactDisplayUtils;
44ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.call.DialerCall;
45ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.call.DialerCallDelegate;
46ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.call.ExternalCallList;
47ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.latencyreport.LatencyReport;
48ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.incallui.util.TelecomCallUtil;
49ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.Map;
50ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
51ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/**
52ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Handles the display of notifications for "external calls".
53ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
54ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * <p>External calls are a representation of a call which is in progress on the user's other device
55ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * (e.g. another phone, or a watch).
56ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */
57ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpublic class ExternalCallNotifier implements ExternalCallList.ExternalCallListener {
58ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
59ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Tag used with the notification manager to uniquely identify external call notifications. */
60ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final String NOTIFICATION_TAG = "EXTERNAL_CALL";
61ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
62ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final int SUMMARY_ID = -1;
63ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private final Context mContext;
64ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private final ContactInfoCache mContactInfoCache;
65ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private Map<Call, NotificationInfo> mNotifications = new ArrayMap<>();
66ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private int mNextUniqueNotificationId;
67ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private ContactsPreferences mContactsPreferences;
68ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean mShowingSummary;
69ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
70ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Initializes a new instance of the external call notifier. */
71ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public ExternalCallNotifier(
72ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      @NonNull Context context, @NonNull ContactInfoCache contactInfoCache) {
73ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mContext = context;
74ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mContactsPreferences = ContactsPreferencesFactory.newContactsPreferences(mContext);
75ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mContactInfoCache = contactInfoCache;
76ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
77ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
78ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
79ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Handles the addition of a new external call by showing a new notification. Triggered by {@link
80ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * CallList#onCallAdded(android.telecom.Call)}.
81ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
82ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
83ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onExternalCallAdded(android.telecom.Call call) {
84ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Log.i(this, "onExternalCallAdded " + call);
85ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mNotifications.containsKey(call)) {
86ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      throw new IllegalArgumentException();
87ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
88ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    NotificationInfo info = new NotificationInfo(call, mNextUniqueNotificationId++);
89ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mNotifications.put(call, info);
90ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
91ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    showNotifcation(info);
92ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
93ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
94ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
95ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Handles the removal of an external call by hiding its associated notification. Triggered by
96ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * {@link CallList#onCallRemoved(android.telecom.Call)}.
97ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
98ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
99ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onExternalCallRemoved(android.telecom.Call call) {
100ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Log.i(this, "onExternalCallRemoved " + call);
101ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
102ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    dismissNotification(call);
103ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
104ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
105ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Handles updates to an external call. */
106ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
107ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onExternalCallUpdated(Call call) {
108ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!mNotifications.containsKey(call)) {
109ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      throw new IllegalArgumentException();
110ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
111ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    postNotification(mNotifications.get(call));
112ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
113ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
114ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
115ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onExternalCallPulled(Call call) {
116ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // no-op; if an external call is pulled, it will be removed via onExternalCallRemoved.
117ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
118ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
119ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
120ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Initiates a call pull given a notification ID.
121ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
122ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param notificationId The notification ID associated with the external call which is to be
123ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *     pulled.
124ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
125ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @TargetApi(VERSION_CODES.N_MR1)
126ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void pullExternalCall(int notificationId) {
127ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    for (NotificationInfo info : mNotifications.values()) {
128ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (info.getNotificationId() == notificationId
129ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          && CallCompat.canPullExternalCall(info.getCall())) {
130ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        info.getCall().pullExternalCall();
131ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        return;
132ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
133ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
134ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
135ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
136ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
137ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Shows a notification for a new external call. Performs a contact cache lookup to find any
138ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * associated photo and information for the call.
139ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
140ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void showNotifcation(final NotificationInfo info) {
141ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // We make a call to the contact info cache to query for supplemental data to what the
142ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // call provides.  This includes the contact name and photo.
143ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // This callback will always get called immediately and synchronously with whatever data
144ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // it has available, and may make a subsequent call later (same thread) if it had to
145ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // call into the contacts provider for more data.
146ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    DialerCall dialerCall =
147ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        new DialerCall(
148ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            mContext,
149ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            new DialerCallDelegateStub(),
150ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            info.getCall(),
151ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            new LatencyReport(),
152ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            false /* registerCallback */);
153ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
154ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mContactInfoCache.findInfo(
155ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        dialerCall,
156ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        false /* isIncoming */,
157ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        new ContactInfoCache.ContactInfoCacheCallback() {
158ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          @Override
159ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          public void onContactInfoComplete(
160ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              String callId, ContactInfoCache.ContactCacheEntry entry) {
161ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
162ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            // Ensure notification still exists as the external call could have been
163ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            // removed during async contact info lookup.
164ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            if (mNotifications.containsKey(info.getCall())) {
165ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              saveContactInfo(info, entry);
166ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            }
167ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          }
168ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
169ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          @Override
170ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          public void onImageLoadComplete(String callId, ContactInfoCache.ContactCacheEntry entry) {
171ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
172ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            // Ensure notification still exists as the external call could have been
173ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            // removed during async contact info lookup.
174ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            if (mNotifications.containsKey(info.getCall())) {
175ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              savePhoto(info, entry);
176ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            }
177ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          }
178ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        });
179ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
180ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
181ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Dismisses a notification for an external call. */
182ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void dismissNotification(Call call) {
183ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!mNotifications.containsKey(call)) {
184ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      throw new IllegalArgumentException();
185ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
186ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
187ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    NotificationManager notificationManager =
188ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
189ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    notificationManager.cancel(NOTIFICATION_TAG, mNotifications.get(call).getNotificationId());
190ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
191ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mNotifications.remove(call);
192ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
193ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mShowingSummary && mNotifications.size() <= 1) {
194ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Where a summary notification is showing and there is now not enough notifications to
195ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // necessitate a summary, cancel the summary.
196ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      notificationManager.cancel(NOTIFICATION_TAG, SUMMARY_ID);
197ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mShowingSummary = false;
198ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
199ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // If there is still a single call requiring a notification, re-post the notification as a
200ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // standalone notification without a summary notification.
201ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (mNotifications.size() == 1) {
202ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        postNotification(mNotifications.values().iterator().next());
203ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
204ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
205ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
206ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
207ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
208ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Attempts to build a large icon to use for the notification based on the contact info and post
209ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * the updated notification to the notification manager.
210ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
211ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void savePhoto(NotificationInfo info, ContactInfoCache.ContactCacheEntry entry) {
212ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Bitmap largeIcon = getLargeIconToDisplay(mContext, entry, info.getCall());
213ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (largeIcon != null) {
214ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      largeIcon = getRoundedIcon(mContext, largeIcon);
215ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
216ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.setLargeIcon(largeIcon);
217ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    postNotification(info);
218ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
219ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
220ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
221ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Builds and stores the contact information the notification will display and posts the updated
222ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * notification to the notification manager.
223ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
224ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void saveContactInfo(NotificationInfo info, ContactInfoCache.ContactCacheEntry entry) {
225ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.setContentTitle(getContentTitle(mContext, mContactsPreferences, entry, info.getCall()));
226ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    info.setPersonReference(getPersonReference(entry, info.getCall()));
227ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    postNotification(info);
228ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
229ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
230ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Rebuild an existing or show a new notification given {@link NotificationInfo}. */
231ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void postNotification(NotificationInfo info) {
232ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Notification.Builder builder = new Notification.Builder(mContext);
233ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Set notification as ongoing since calls are long-running versus a point-in-time notice.
234ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    builder.setOngoing(true);
235ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Make the notification prioritized over the other normal notifications.
236ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    builder.setPriority(Notification.PRIORITY_HIGH);
237ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    builder.setGroup(NOTIFICATION_TAG);
238ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
239ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    boolean isVideoCall = VideoProfile.isVideo(info.getCall().getDetails().getVideoState());
240ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Set the content ("Ongoing call on another device")
241ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    builder.setContentText(
242ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mContext.getString(
243ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            isVideoCall
244ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                ? R.string.notification_external_video_call
245ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                : R.string.notification_external_call));
246ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    builder.setSmallIcon(R.drawable.quantum_ic_call_white_24);
247ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    builder.setContentTitle(info.getContentTitle());
248ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    builder.setLargeIcon(info.getLargeIcon());
249ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    builder.setColor(mContext.getResources().getColor(R.color.dialer_theme_color));
250ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    builder.addPerson(info.getPersonReference());
251ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
252ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Where the external call supports being transferred to the local device, add an action
253ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // to the notification to initiate the call pull process.
254ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (CallCompat.canPullExternalCall(info.getCall())) {
255ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
256ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      Intent intent =
257ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          new Intent(
258ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              NotificationBroadcastReceiver.ACTION_PULL_EXTERNAL_CALL,
259ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              null,
260ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              mContext,
261ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              NotificationBroadcastReceiver.class);
262ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      intent.putExtra(
263ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          NotificationBroadcastReceiver.EXTRA_NOTIFICATION_ID, info.getNotificationId());
264ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      builder.addAction(
265ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          new Notification.Action.Builder(
266ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  R.drawable.quantum_ic_call_white_24,
267ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  mContext.getString(
268ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                      isVideoCall
269ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                          ? R.string.notification_take_video_call
270ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                          : R.string.notification_take_call),
271ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian                  PendingIntent.getBroadcast(mContext, info.getNotificationId(), intent, 0))
272ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              .build());
273ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
274ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
275ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    /**
276ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian     * This builder is used for the notification shown when the device is locked and the user has
277ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian     * set their notification settings to 'hide sensitive content' {@see
278ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian     * Notification.Builder#setPublicVersion}.
279ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian     */
280ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Notification.Builder publicBuilder = new Notification.Builder(mContext);
281ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    publicBuilder.setSmallIcon(R.drawable.quantum_ic_call_white_24);
282ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    publicBuilder.setColor(mContext.getResources().getColor(R.color.dialer_theme_color));
283ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
284ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    builder.setPublicVersion(publicBuilder.build());
285ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Notification notification = builder.build();
286ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
287ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    NotificationManager notificationManager =
288ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
289ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    notificationManager.notify(NOTIFICATION_TAG, info.getNotificationId(), notification);
290ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
291ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!mShowingSummary && mNotifications.size() > 1) {
292ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // If the number of notifications shown is > 1, and we're not already showing a group summary,
293ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // build one now.  This will ensure the like notifications are grouped together.
294ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
295ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      Notification.Builder summary = new Notification.Builder(mContext);
296ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Set notification as ongoing since calls are long-running versus a point-in-time notice.
297ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      summary.setOngoing(true);
298ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Make the notification prioritized over the other normal notifications.
299ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      summary.setPriority(Notification.PRIORITY_HIGH);
300ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      summary.setGroup(NOTIFICATION_TAG);
301ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      summary.setGroupSummary(true);
302ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      summary.setSmallIcon(R.drawable.quantum_ic_call_white_24);
303ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      notificationManager.notify(NOTIFICATION_TAG, SUMMARY_ID, summary.build());
304ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mShowingSummary = true;
305ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
306ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
307ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
308ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
309ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Finds a large icon to display in a notification for a call. For conference calls, a conference
310ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * call icon is used, otherwise if contact info is specified, the user's contact photo or avatar
311ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * is used.
312ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
313ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param context The context.
314ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param contactInfo The contact cache info.
315ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param call The call.
316ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return The large icon to use for the notification.
317ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
318ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private @Nullable Bitmap getLargeIconToDisplay(
319ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      Context context, ContactInfoCache.ContactCacheEntry contactInfo, android.telecom.Call call) {
320ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
321ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Bitmap largeIcon = null;
322ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (call.getDetails().hasProperty(android.telecom.Call.Details.PROPERTY_CONFERENCE)
323ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        && !call.getDetails()
324ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            .hasProperty(android.telecom.Call.Details.PROPERTY_GENERIC_CONFERENCE)) {
325ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
326ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      largeIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.img_conference);
327ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
328ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (contactInfo.photo != null && (contactInfo.photo instanceof BitmapDrawable)) {
329ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      largeIcon = ((BitmapDrawable) contactInfo.photo).getBitmap();
330ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
331ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return largeIcon;
332ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
333ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
334ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
335ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Given a bitmap, returns a rounded version of the icon suitable for display in a notification.
336ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
337ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param context The context.
338ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param bitmap The bitmap to round.
339ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return The rounded bitmap.
340ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
341ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private @Nullable Bitmap getRoundedIcon(Context context, @Nullable Bitmap bitmap) {
342ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (bitmap == null) {
343ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return null;
344ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
345ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final int height =
346ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        (int) context.getResources().getDimension(android.R.dimen.notification_large_icon_height);
347ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final int width =
348ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        (int) context.getResources().getDimension(android.R.dimen.notification_large_icon_width);
349ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return BitmapUtil.getRoundedBitmap(bitmap, width, height);
350ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
351ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
352ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
353ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Builds a notification content title for a call. If the call is a conference call, it is
354ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * identified as such. Otherwise an attempt is made to show an associated contact name or phone
355ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * number.
356ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
357ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param context The context.
358ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param contactsPreferences Contacts preferences, used to determine the preferred formatting for
359ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *     contact names.
360ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param contactInfo The contact info which was looked up in the contact cache.
361ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param call The call to generate a title for.
362ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return The content title.
363ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
364ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private @Nullable String getContentTitle(
365ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      Context context,
366ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      @Nullable ContactsPreferences contactsPreferences,
367ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      ContactInfoCache.ContactCacheEntry contactInfo,
368ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      android.telecom.Call call) {
369ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
370ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (call.getDetails().hasProperty(android.telecom.Call.Details.PROPERTY_CONFERENCE)
371ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        && !call.getDetails()
372ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            .hasProperty(android.telecom.Call.Details.PROPERTY_GENERIC_CONFERENCE)) {
373ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
374ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return context.getResources().getString(R.string.conference_call_name);
375ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
376ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
377ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    String preferredName =
378ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        ContactDisplayUtils.getPreferredDisplayName(
379ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            contactInfo.namePrimary, contactInfo.nameAlternative, contactsPreferences);
380ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (TextUtils.isEmpty(preferredName)) {
381ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return TextUtils.isEmpty(contactInfo.number)
382ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          ? null
383ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          : BidiFormatter.getInstance()
384ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              .unicodeWrap(contactInfo.number, TextDirectionHeuristics.LTR);
385ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
386ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return preferredName;
387ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
388ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
389ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
390ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Gets a "person reference" for a notification, used by the system to determine whether the
391ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * notification should be allowed past notification interruption filters.
392ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
393ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param contactInfo The contact info from cache.
394ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param call The call.
395ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return the person reference.
396ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
397ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private String getPersonReference(ContactInfoCache.ContactCacheEntry contactInfo, Call call) {
398ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
399ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    String number = TelecomCallUtil.getNumber(call);
400ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Query {@link Contacts#CONTENT_LOOKUP_URI} directly with work lookup key is not allowed.
401ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // So, do not pass {@link Contacts#CONTENT_LOOKUP_URI} to NotificationManager to avoid
402ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // NotificationManager using it.
403ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (contactInfo.lookupUri != null && contactInfo.userType != ContactsUtils.USER_TYPE_WORK) {
404ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return contactInfo.lookupUri.toString();
405ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else if (!TextUtils.isEmpty(number)) {
406ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null).toString();
407ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
408ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return "";
409ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
410ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
411ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static class DialerCallDelegateStub implements DialerCallDelegate {
412ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
413ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    @Override
414ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    public DialerCall getDialerCallFromTelecomCall(Call telecomCall) {
415ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return null;
416ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
417ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
418ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
419ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Represents a call and associated cached notification data. */
420ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static class NotificationInfo {
421ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
422ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    @NonNull private final Call mCall;
423ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    private final int mNotificationId;
424ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    @Nullable private String mContentTitle;
425ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    @Nullable private Bitmap mLargeIcon;
426ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    @Nullable private String mPersonReference;
427ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
428ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    public NotificationInfo(@NonNull Call call, int notificationId) {
429ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mCall = call;
430ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mNotificationId = notificationId;
431ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
432ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
433ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    public Call getCall() {
434ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return mCall;
435ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
436ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
437ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    public int getNotificationId() {
438ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return mNotificationId;
439ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
440ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
441ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    public @Nullable String getContentTitle() {
442ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return mContentTitle;
443ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
444ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
445ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    public void setContentTitle(@Nullable String contentTitle) {
446ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mContentTitle = contentTitle;
447ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
448ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
449ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    public @Nullable Bitmap getLargeIcon() {
450ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return mLargeIcon;
451ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
452ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
453ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    public void setLargeIcon(@Nullable Bitmap largeIcon) {
454ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mLargeIcon = largeIcon;
455ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
456ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
457ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    public @Nullable String getPersonReference() {
458ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return mPersonReference;
459ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
460ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
461ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    public void setPersonReference(@Nullable String personReference) {
462ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mPersonReference = personReference;
463ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
464ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
465ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian}
466