diff options
Diffstat (limited to 'java/com/android/incallui/StatusBarNotifier.java')
-rw-r--r-- | java/com/android/incallui/StatusBarNotifier.java | 183 |
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. |