summaryrefslogtreecommitdiff
path: root/java/com/android/incallui/StatusBarNotifier.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/incallui/StatusBarNotifier.java')
-rw-r--r--java/com/android/incallui/StatusBarNotifier.java183
1 files changed, 94 insertions, 89 deletions
diff --git a/java/com/android/incallui/StatusBarNotifier.java b/java/com/android/incallui/StatusBarNotifier.java
index 165b30b52..e6969c147 100644
--- a/java/com/android/incallui/StatusBarNotifier.java
+++ b/java/com/android/incallui/StatusBarNotifier.java
@@ -28,8 +28,6 @@ import static com.android.incallui.NotificationBroadcastReceiver.ACTION_HANG_UP_
import android.Manifest;
import android.app.ActivityManager;
import android.app.Notification;
-import android.app.Notification.Builder;
-import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
@@ -61,17 +59,19 @@ import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import com.android.contacts.common.ContactsUtils;
import com.android.contacts.common.ContactsUtils.UserType;
-import com.android.contacts.common.lettertiles.LetterTileDrawable;
import com.android.contacts.common.preference.ContactsPreferences;
-import com.android.contacts.common.util.BitmapUtil;
import com.android.contacts.common.util.ContactDisplayUtils;
+import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
-import com.android.dialer.enrichedcall.EnrichedCallComponent;
+import com.android.dialer.configprovider.ConfigProviderBindings;
+import com.android.dialer.contactphoto.BitmapUtil;
import com.android.dialer.enrichedcall.EnrichedCallManager;
import com.android.dialer.enrichedcall.Session;
+import com.android.dialer.lettertile.LetterTileDrawable;
+import com.android.dialer.lettertile.LetterTileDrawable.ContactType;
import com.android.dialer.multimedia.MultimediaData;
-import com.android.dialer.notification.NotificationChannelManager;
-import com.android.dialer.notification.NotificationChannelManager.Channel;
+import com.android.dialer.notification.DialerNotificationManager;
+import com.android.dialer.notification.NotificationChannelId;
import com.android.dialer.oem.MotorolaUtils;
import com.android.dialer.util.DrawableConverter;
import com.android.incallui.ContactInfoCache.ContactCacheEntry;
@@ -93,6 +93,9 @@ import java.util.Objects;
public class StatusBarNotifier
implements InCallPresenter.InCallStateListener, EnrichedCallManager.StateChangedListener {
+ private static final String NOTIFICATION_TAG = "STATUS_BAR_NOTIFIER";
+ private static final int NOTIFICATION_ID = 1;
+
// Notification types
// Indicates that no notification is currently showing.
private static final int NOTIFICATION_NONE = 0;
@@ -104,14 +107,10 @@ public class StatusBarNotifier
// This is non-interruptive, but otherwise behaves the same as NOTIFICATION_INCOMING_CALL
private static final int NOTIFICATION_INCOMING_CALL_QUIET = 3;
- private static final int PENDING_INTENT_REQUEST_CODE_NON_FULL_SCREEN = 0;
- private static final int PENDING_INTENT_REQUEST_CODE_FULL_SCREEN = 1;
-
private static final long[] VIBRATE_PATTERN = new long[] {0, 1000, 1000};
private final Context mContext;
private final ContactInfoCache mContactInfoCache;
- private final NotificationManager mNotificationManager;
private final DialerRingtoneManager mDialerRingtoneManager;
@Nullable private ContactsPreferences mContactsPreferences;
private int mCurrentNotification = NOTIFICATION_NONE;
@@ -124,11 +123,9 @@ public class StatusBarNotifier
private StatusBarCallListener mStatusBarCallListener;
public StatusBarNotifier(@NonNull Context context, @NonNull ContactInfoCache contactInfoCache) {
- Objects.requireNonNull(context);
- mContext = context;
+ mContext = Assert.isNotNull(context);
mContactsPreferences = ContactsPreferencesFactory.newContactsPreferences(mContext);
mContactInfoCache = contactInfoCache;
- mNotificationManager = context.getSystemService(NotificationManager.class);
mDialerRingtoneManager =
new DialerRingtoneManager(
new InCallTonePlayer(new ToneGeneratorFactory(), new PausableExecutorImpl()),
@@ -140,23 +137,17 @@ public class StatusBarNotifier
* Should only be called from a irrecoverable state where it is necessary to dismiss all
* notifications.
*/
- static void clearAllCallNotifications(Context backupContext) {
- LogUtil.i(
+ static void clearAllCallNotifications(Context context) {
+ LogUtil.e(
"StatusBarNotifier.clearAllCallNotifications",
"something terrible happened, clear all InCall notifications");
- NotificationManager notificationManager =
- backupContext.getSystemService(NotificationManager.class);
- notificationManager.cancel(R.id.notification_ongoing_call);
+ DialerNotificationManager.cancel(context, NOTIFICATION_TAG, NOTIFICATION_ID);
}
private static int getWorkStringFromPersonalString(int resId) {
if (resId == R.string.notification_ongoing_call) {
return R.string.notification_ongoing_work_call;
- } else if (resId == R.string.notification_ongoing_call_wifi) {
- return R.string.notification_ongoing_work_call_wifi;
- } else if (resId == R.string.notification_incoming_call_wifi) {
- return R.string.notification_incoming_work_call_wifi;
} else if (resId == R.string.notification_incoming_call) {
return R.string.notification_incoming_work_call;
} else {
@@ -173,12 +164,6 @@ public class StatusBarNotifier
return PendingIntent.getBroadcast(context, 0, intent, 0);
}
- private static void setColorized(@NonNull Builder builder) {
- if (BuildCompat.isAtLeastO()) {
- builder.setColorized(true);
- }
- }
-
/** Creates notifications according to the state we receive from {@link InCallPresenter}. */
@Override
@RequiresPermission(Manifest.permission.READ_PHONE_STATE)
@@ -226,7 +211,7 @@ public class StatusBarNotifier
}
if (mCurrentNotification != NOTIFICATION_NONE) {
LogUtil.i("StatusBarNotifier.cancelNotification", "cancel");
- mNotificationManager.cancel(R.id.notification_ongoing_call);
+ DialerNotificationManager.cancel(mContext, NOTIFICATION_TAG, NOTIFICATION_ID);
}
mCurrentNotification = NOTIFICATION_NONE;
}
@@ -313,11 +298,19 @@ public class StatusBarNotifier
if (callState == DialerCall.State.INCOMING
|| callState == DialerCall.State.CALL_WAITING
|| isVideoUpgradeRequest) {
- boolean alreadyActive =
- callList.getActiveOrBackgroundCall() != null
- && InCallPresenter.getInstance().isShowingInCallUi();
- notificationType =
- alreadyActive ? NOTIFICATION_INCOMING_CALL_QUIET : NOTIFICATION_INCOMING_CALL;
+ if (ConfigProviderBindings.get(mContext)
+ .getBoolean("quiet_incoming_call_if_ui_showing", true)) {
+ notificationType =
+ InCallPresenter.getInstance().isShowingInCallUi()
+ ? NOTIFICATION_INCOMING_CALL_QUIET
+ : NOTIFICATION_INCOMING_CALL;
+ } else {
+ boolean alreadyActive =
+ callList.getActiveOrBackgroundCall() != null
+ && InCallPresenter.getInstance().isShowingInCallUi();
+ notificationType =
+ alreadyActive ? NOTIFICATION_INCOMING_CALL_QUIET : NOTIFICATION_INCOMING_CALL;
+ }
} else {
notificationType = NOTIFICATION_IN_CALL;
}
@@ -365,13 +358,13 @@ public class StatusBarNotifier
LogUtil.i("StatusBarNotifier.buildAndSendNotification", "notificationType=" + notificationType);
switch (notificationType) {
case NOTIFICATION_INCOMING_CALL:
- NotificationChannelManager.applyChannel(
- builder, mContext, Channel.INCOMING_CALL, accountHandle);
+ if (BuildCompat.isAtLeastO()) {
+ builder.setChannelId(NotificationChannelId.INCOMING_CALL);
+ }
configureFullScreenIntent(builder, createLaunchPendingIntent(true /* isFullScreen */));
// Set the notification category and bump the priority for incoming calls
builder.setCategory(Notification.CATEGORY_CALL);
// This will be ignored on O+ and handled by the channel
- //noinspection deprecation
builder.setPriority(Notification.PRIORITY_MAX);
if (mCurrentNotification != NOTIFICATION_INCOMING_CALL) {
LogUtil.i(
@@ -379,18 +372,22 @@ public class StatusBarNotifier
"Canceling old notification so this one can be noisy");
// Moving from a non-interuptive notification (or none) to a noisy one. Cancel the old
// notification (if there is one) so the fullScreenIntent or HUN will show
- mNotificationManager.cancel(R.id.notification_ongoing_call);
+ DialerNotificationManager.cancel(mContext, NOTIFICATION_TAG, NOTIFICATION_ID);
}
break;
case NOTIFICATION_INCOMING_CALL_QUIET:
- NotificationChannelManager.applyChannel(
- builder, mContext, Channel.ONGOING_CALL, accountHandle);
+ if (BuildCompat.isAtLeastO()) {
+ builder.setChannelId(NotificationChannelId.ONGOING_CALL);
+ }
break;
case NOTIFICATION_IN_CALL:
- setColorized(publicBuilder);
- setColorized(builder);
- NotificationChannelManager.applyChannel(
- builder, mContext, Channel.ONGOING_CALL, accountHandle);
+ if (BuildCompat.isAtLeastO()) {
+ publicBuilder.setColorized(true);
+ builder.setColorized(true);
+ builder.setChannelId(NotificationChannelId.ONGOING_CALL);
+ }
+ break;
+ default:
break;
}
@@ -436,7 +433,7 @@ public class StatusBarNotifier
"displaying notification for " + notificationType);
try {
- mNotificationManager.notify(R.id.notification_ongoing_call, notification);
+ DialerNotificationManager.notify(mContext, NOTIFICATION_TAG, NOTIFICATION_ID, notification);
} catch (RuntimeException e) {
// TODO(b/34744003): Move the memory stats into silent feedback PSD.
ActivityManager activityManager = mContext.getSystemService(ActivityManager.class);
@@ -565,8 +562,9 @@ public class StatusBarNotifier
@VisibleForTesting
@Nullable
String getContentTitle(ContactCacheEntry contactInfo, DialerCall call) {
- if (call.isConferenceCall() && !call.hasProperty(Details.PROPERTY_GENERIC_CONFERENCE)) {
- return mContext.getResources().getString(R.string.conference_call_name);
+ if (call.isConferenceCall()) {
+ return CallerInfoUtils.getConferenceString(
+ mContext, call.hasProperty(Details.PROPERTY_GENERIC_CONFERENCE));
}
String preferredName =
@@ -604,20 +602,16 @@ public class StatusBarNotifier
if (contactInfo.photo == null) {
int width = (int) resources.getDimension(android.R.dimen.notification_large_icon_width);
int height = (int) resources.getDimension(android.R.dimen.notification_large_icon_height);
- int contactType = LetterTileDrawable.TYPE_DEFAULT;
+ @ContactType
+ int contactType =
+ LetterTileDrawable.getContactTypeFromPrimitives(
+ CallerInfoUtils.isVoiceMailNumber(context, call),
+ call.isSpam(),
+ contactInfo.isBusiness,
+ call.getNumberPresentation(),
+ call.isConferenceCall() && !call.hasProperty(Details.PROPERTY_GENERIC_CONFERENCE));
LetterTileDrawable lettertile = new LetterTileDrawable(resources);
- // TODO: Deduplicate across Dialer. b/36195917
- if (CallerInfoUtils.isVoiceMailNumber(context, call)) {
- contactType = LetterTileDrawable.TYPE_VOICEMAIL;
- } else if (contactInfo.isBusiness) {
- contactType = LetterTileDrawable.TYPE_BUSINESS;
- } else if (call.getNumberPresentation() == TelecomManager.PRESENTATION_RESTRICTED) {
- contactType = LetterTileDrawable.TYPE_GENERIC_AVATAR;
- } else if (call.isConferenceCall()
- && !call.hasProperty(Details.PROPERTY_GENERIC_CONFERENCE)) {
- contactType = LetterTileDrawable.TYPE_CONFERENCE;
- }
lettertile.setCanonicalDialerLetterTileDetails(
contactInfo.namePrimary == null ? contactInfo.number : contactInfo.namePrimary,
contactInfo.lookupKey,
@@ -663,13 +657,17 @@ public class StatusBarNotifier
return R.drawable.quantum_ic_videocam_white_24;
} else if (call.hasProperty(PROPERTY_HIGH_DEF_AUDIO)
&& MotorolaUtils.shouldShowHdIconInNotification(mContext)) {
- // Normally when a call is ongoing the status bar displays an icon of a phone with animated
- // lines. This is a helpful hint for users so they know how to get back to the call.
- // For Sprint HD calls, we replace this icon with an icon of a phone with a HD badge.
- // This is a carrier requirement.
+ // Normally when a call is ongoing the status bar displays an icon of a phone. This is a
+ // helpful hint for users so they know how to get back to the call. For Sprint HD calls, we
+ // replace this icon with an icon of a phone with a HD badge. This is a carrier requirement.
return R.drawable.ic_hd_call;
}
- return R.anim.on_going_call;
+ // If ReturnToCall is enabled, use the static icon. The animated one will show in the bubble.
+ if (ReturnToCallController.isEnabled(mContext)) {
+ return R.drawable.quantum_ic_call_vd_theme_24;
+ } else {
+ return R.drawable.on_going_call;
+ }
}
/** Returns the message to use with the notification. */
@@ -689,27 +687,19 @@ public class StatusBarNotifier
}
int resId = R.string.notification_ongoing_call;
+ String wifiBrand = mContext.getString(R.string.notification_call_wifi_brand);
if (call.hasProperty(Details.PROPERTY_WIFI)) {
- resId = R.string.notification_ongoing_call_wifi;
+ resId = R.string.notification_ongoing_call_wifi_template;
}
if (isIncomingOrWaiting) {
- EnrichedCallManager manager = EnrichedCallComponent.get(mContext).getEnrichedCallManager();
- Session session = null;
- if (call.getNumber() != null) {
- session =
- manager.getSession(
- call.getUniqueCallId(),
- call.getNumber(),
- manager.createIncomingCallComposerFilter());
- }
-
if (call.isSpam()) {
resId = R.string.notification_incoming_spam_call;
- } else if (session != null) {
- resId = getECIncomingCallText(session);
+ } else if (shouldShowEnrichedCallNotification(call.getEnrichedCallSession())) {
+ resId = getECIncomingCallText(call.getEnrichedCallSession());
} else if (call.hasProperty(Details.PROPERTY_WIFI)) {
- resId = R.string.notification_incoming_call_wifi;
+ resId = R.string.notification_incoming_call_wifi_template;
+
} else {
resId = R.string.notification_incoming_call;
}
@@ -726,11 +716,25 @@ public class StatusBarNotifier
boolean isWorkCall = call.hasProperty(PROPERTY_ENTERPRISE_CALL);
if (userType == ContactsUtils.USER_TYPE_WORK || isWorkCall) {
resId = getWorkStringFromPersonalString(resId);
+ wifiBrand = mContext.getString(R.string.notification_call_wifi_work_brand);
+ }
+
+ if (resId == R.string.notification_incoming_call_wifi_template
+ || resId == R.string.notification_ongoing_call_wifi_template) {
+ // TODO(b/64525903): Potentially apply this template logic everywhere.
+ return mContext.getString(resId, wifiBrand);
}
return mContext.getString(resId);
}
+ private boolean shouldShowEnrichedCallNotification(Session session) {
+ if (session == null) {
+ return false;
+ }
+ return session.getMultimediaData().hasData() || session.getMultimediaData().isImportant();
+ }
+
private int getECIncomingCallText(Session session) {
int resId;
MultimediaData data = session.getMultimediaData();
@@ -756,8 +760,10 @@ public class StatusBarNotifier
} else {
resId = R.string.important_notification_incoming_call_with_photo;
}
- } else {
+ } else if (hasSubject) {
resId = R.string.important_notification_incoming_call_with_message;
+ } else {
+ resId = R.string.important_notification_incoming_call;
}
if (mContext.getString(resId).length() > 50) {
resId = R.string.important_notification_incoming_call_attachments;
@@ -827,13 +833,9 @@ public class StatusBarNotifier
"will show \"answer\" action in the incoming call Notification");
PendingIntent answerVoicePendingIntent =
createNotificationPendingIntent(mContext, ACTION_ANSWER_VOICE_INCOMING_CALL);
- // We put animation resources in "anim" folder instead of "drawable", which causes Android
- // Studio to complain.
- // TODO: Move "anim" resources to "drawable" as recommended in AnimationDrawable doc?
- //noinspection ResourceType
builder.addAction(
new Notification.Action.Builder(
- Icon.createWithResource(mContext, R.anim.on_going_call),
+ Icon.createWithResource(mContext, R.drawable.quantum_ic_call_white_24),
getActionText(
R.string.notification_action_answer, R.color.notification_action_accept),
answerVoicePendingIntent)
@@ -863,7 +865,7 @@ public class StatusBarNotifier
createNotificationPendingIntent(mContext, ACTION_HANG_UP_ONGOING_CALL);
builder.addAction(
new Notification.Action.Builder(
- Icon.createWithResource(mContext, R.drawable.ic_call_end_white_24dp),
+ Icon.createWithResource(mContext, R.drawable.quantum_ic_call_end_white_24),
mContext.getText(R.string.notification_action_end_call),
hangupPendingIntent)
.build());
@@ -931,7 +933,7 @@ public class StatusBarNotifier
builder.setOngoing(true);
builder.setOnlyAlertOnce(true);
// This will be ignored on O+ and handled by the channel
- //noinspection deprecation
+ // noinspection deprecation
builder.setPriority(Notification.PRIORITY_HIGH);
return builder;
@@ -942,11 +944,11 @@ public class StatusBarNotifier
InCallActivity.getIntent(
mContext, false /* showDialpad */, false /* newOutgoingCall */, isFullScreen);
- int requestCode = PENDING_INTENT_REQUEST_CODE_NON_FULL_SCREEN;
+ int requestCode = InCallActivity.PENDING_INTENT_REQUEST_CODE_NON_FULL_SCREEN;
if (isFullScreen) {
// Use a unique request code so that the pending intent isn't clobbered by the
// non-full screen pending intent.
- requestCode = PENDING_INTENT_REQUEST_CODE_FULL_SCREEN;
+ requestCode = InCallActivity.PENDING_INTENT_REQUEST_CODE_FULL_SCREEN;
}
// PendingIntent that can be used to launch the InCallActivity. The
@@ -1005,6 +1007,9 @@ public class StatusBarNotifier
@Override
public void onInternationalCallOnWifi() {}
+ @Override
+ public void onEnrichedCallSessionUpdate() {}
+
/**
* Responds to changes in the session modification state for the call by dismissing the status
* bar notification as required.