summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/app/calllog/DefaultVoicemailNotifier.java
diff options
context:
space:
mode:
authorEric Erfanian <erfanian@google.com>2017-08-31 06:57:16 -0700
committerEric Erfanian <erfanian@google.com>2017-08-31 16:13:53 +0000
commit2ca4318cc1ee57dda907ba2069bd61d162b1baef (patch)
treee282668a9587cf6c1ec7b604dea860400c75c6c7 /java/com/android/dialer/app/calllog/DefaultVoicemailNotifier.java
parent68038172793ee0e2ab3e2e56ddfbeb82879d1f58 (diff)
Update Dialer source to latest internal Google revision.
Previously, Android's Dialer app was developed in an internal Google source control system and only exported to public during AOSP drops. The Dialer team is now switching to a public development model similar to the telephony team. This CL represents all internal Google changes that were committed to Dialer between the public O release and today's tip of tree on internal master. This CL squashes those changes into a single commit. In subsequent changes, changes will be exported on a per-commit basis. Test: make, flash install, run Merged-In: I45270eaa8ce732d71a1bd84b08c7fa0e99af3160 Change-Id: I529aaeb88535b9533c0ae4ef4e6c1222d4e0f1c8 PiperOrigin-RevId: 167068436
Diffstat (limited to 'java/com/android/dialer/app/calllog/DefaultVoicemailNotifier.java')
-rw-r--r--java/com/android/dialer/app/calllog/DefaultVoicemailNotifier.java446
1 files changed, 0 insertions, 446 deletions
diff --git a/java/com/android/dialer/app/calllog/DefaultVoicemailNotifier.java b/java/com/android/dialer/app/calllog/DefaultVoicemailNotifier.java
deleted file mode 100644
index 58fe6fa2c..000000000
--- a/java/com/android/dialer/app/calllog/DefaultVoicemailNotifier.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.dialer.app.calllog;
-
-import android.annotation.TargetApi;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.net.Uri;
-import android.os.Build.VERSION;
-import android.os.Build.VERSION_CODES;
-import android.os.PersistableBundle;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.annotation.VisibleForTesting;
-import android.support.annotation.WorkerThread;
-import android.support.v4.os.BuildCompat;
-import android.support.v4.util.Pair;
-import android.telecom.PhoneAccount;
-import android.telecom.PhoneAccountHandle;
-import android.telecom.TelecomManager;
-import android.telephony.CarrierConfigManager;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import com.android.contacts.common.compat.TelephonyManagerCompat;
-import com.android.contacts.common.util.ContactDisplayUtils;
-import com.android.dialer.app.DialtactsActivity;
-import com.android.dialer.app.R;
-import com.android.dialer.app.calllog.CallLogNotificationsQueryHelper.NewCall;
-import com.android.dialer.app.contactinfo.ContactPhotoLoader;
-import com.android.dialer.app.list.DialtactsPagerAdapter;
-import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler;
-import com.android.dialer.blocking.FilteredNumbersUtil;
-import com.android.dialer.calllogutils.PhoneAccountUtils;
-import com.android.dialer.common.Assert;
-import com.android.dialer.common.LogUtil;
-import com.android.dialer.common.concurrent.DialerExecutor.Worker;
-import com.android.dialer.common.concurrent.DialerExecutors;
-import com.android.dialer.logging.DialerImpression;
-import com.android.dialer.logging.Logger;
-import com.android.dialer.notification.NotificationChannelManager;
-import com.android.dialer.notification.NotificationChannelManager.Channel;
-import com.android.dialer.phonenumbercache.ContactInfo;
-import com.android.dialer.telecom.TelecomUtil;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/** Shows a voicemail notification in the status bar. */
-public class DefaultVoicemailNotifier implements Worker<Void, Void> {
-
- public static final String TAG = "VoicemailNotifier";
-
- /** The tag used to identify notifications from this class. */
- static final String VISUAL_VOICEMAIL_NOTIFICATION_TAG = "DefaultVoicemailNotifier";
- /** The identifier of the notification of new voicemails. */
- private static final int VISUAL_VOICEMAIL_NOTIFICATION_ID = R.id.notification_visual_voicemail;
-
- private static final int LEGACY_VOICEMAIL_NOTIFICATION_ID = R.id.notification_legacy_voicemail;
- private static final String LEGACY_VOICEMAIL_NOTIFICATION_TAG = "legacy_voicemail";
-
- private final Context context;
- private final CallLogNotificationsQueryHelper queryHelper;
- private final FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler;
-
- @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
- DefaultVoicemailNotifier(
- Context context,
- CallLogNotificationsQueryHelper queryHelper,
- FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler) {
- this.context = context;
- this.queryHelper = queryHelper;
- this.filteredNumberAsyncQueryHandler = filteredNumberAsyncQueryHandler;
- }
-
- public DefaultVoicemailNotifier(Context context) {
- this(
- context,
- CallLogNotificationsQueryHelper.getInstance(context),
- new FilteredNumberAsyncQueryHandler(context));
- }
-
- @Nullable
- @Override
- public Void doInBackground(@Nullable Void input) throws Throwable {
- updateNotification();
- return null;
- }
-
- /**
- * Updates the notification and notifies of the call with the given URI.
- *
- * <p>Clears the notification if there are no new voicemails, and notifies if the given URI
- * corresponds to a new voicemail.
- *
- * <p>It is not safe to call this method from the main thread.
- */
- @VisibleForTesting
- @WorkerThread
- void updateNotification() {
- Assert.isWorkerThread();
- // Lookup the list of new voicemails to include in the notification.
- final List<NewCall> newCalls = queryHelper.getNewVoicemails();
-
- if (newCalls == null) {
- // Query failed, just return.
- return;
- }
-
- Resources resources = context.getResources();
-
- // This represents a list of names to include in the notification.
- String callers = null;
-
- // Maps each number into a name: if a number is in the map, it has already left a more
- // recent voicemail.
- final Map<String, ContactInfo> contactInfos = new ArrayMap<>();
-
- // Iterate over the new voicemails to determine all the information above.
- Iterator<NewCall> itr = newCalls.iterator();
- while (itr.hasNext()) {
- NewCall newCall = itr.next();
-
- // Skip notifying for numbers which are blocked.
- if (!FilteredNumbersUtil.hasRecentEmergencyCall(context)
- && filteredNumberAsyncQueryHandler.getBlockedIdSynchronous(
- newCall.number, newCall.countryIso)
- != null) {
- itr.remove();
-
- if (newCall.voicemailUri != null) {
- // Delete the voicemail.
- CallLogAsyncTaskUtil.deleteVoicemailSynchronous(context, newCall.voicemailUri);
- }
- continue;
- }
-
- // Check if we already know the name associated with this number.
- ContactInfo contactInfo = contactInfos.get(newCall.number);
- if (contactInfo == null) {
- contactInfo =
- queryHelper.getContactInfo(
- newCall.number, newCall.numberPresentation, newCall.countryIso);
- contactInfos.put(newCall.number, contactInfo);
- // This is a new caller. Add it to the back of the list of callers.
- if (TextUtils.isEmpty(callers)) {
- callers = contactInfo.name;
- } else {
- callers =
- resources.getString(
- R.string.notification_voicemail_callers_list, callers, contactInfo.name);
- }
- }
- }
-
- if (newCalls.isEmpty()) {
- // No voicemails to notify about
- return;
- }
-
- Notification.Builder groupSummary =
- createNotificationBuilder()
- .setContentTitle(
- resources.getQuantityString(
- R.plurals.notification_voicemail_title, newCalls.size(), newCalls.size()))
- .setContentText(callers)
- .setDeleteIntent(createMarkNewVoicemailsAsOldIntent(null))
- .setGroupSummary(true)
- .setContentIntent(newVoicemailIntent(null));
-
- if (BuildCompat.isAtLeastO()) {
- groupSummary.setGroupAlertBehavior(Notification.GROUP_ALERT_CHILDREN);
- }
-
- NotificationChannelManager.applyChannel(
- groupSummary,
- context,
- Channel.VOICEMAIL,
- PhoneAccountHandles.getAccount(context, newCalls.get(0)));
-
- LogUtil.i(TAG, "Creating visual voicemail notification");
- getNotificationManager()
- .notify(
- VISUAL_VOICEMAIL_NOTIFICATION_TAG,
- VISUAL_VOICEMAIL_NOTIFICATION_ID,
- groupSummary.build());
-
- for (NewCall voicemail : newCalls) {
- getNotificationManager()
- .notify(
- voicemail.callsUri.toString(),
- VISUAL_VOICEMAIL_NOTIFICATION_ID,
- createNotificationForVoicemail(voicemail, contactInfos));
- }
- }
-
- /**
- * Replicates how packages/services/Telephony/NotificationMgr.java handles legacy voicemail
- * notification. The notification will not be stackable because no information is available for
- * individual voicemails.
- */
- @TargetApi(VERSION_CODES.O)
- public void notifyLegacyVoicemail(
- @NonNull PhoneAccountHandle phoneAccountHandle,
- int count,
- String voicemailNumber,
- PendingIntent callVoicemailIntent,
- PendingIntent voicemailSettingIntent) {
- Assert.isNotNull(phoneAccountHandle);
- Assert.checkArgument(BuildCompat.isAtLeastO());
- TelephonyManager telephonyManager =
- context
- .getSystemService(TelephonyManager.class)
- .createForPhoneAccountHandle(phoneAccountHandle);
- Assert.isNotNull(telephonyManager);
- LogUtil.i(TAG, "Creating legacy voicemail notification");
-
- PersistableBundle carrierConfig = telephonyManager.getCarrierConfig();
-
- String notificationTitle =
- context
- .getResources()
- .getQuantityString(R.plurals.notification_voicemail_title, count, count);
-
- TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
- PhoneAccount phoneAccount = telecomManager.getPhoneAccount(phoneAccountHandle);
-
- String notificationText;
- PendingIntent pendingIntent;
-
- if (voicemailSettingIntent != null) {
- // If the voicemail number if unknown, instead of calling voicemail, take the user
- // to the voicemail settings.
- notificationText = context.getString(R.string.notification_voicemail_no_vm_number);
- pendingIntent = voicemailSettingIntent;
- } else {
- if (PhoneAccountUtils.getSubscriptionPhoneAccounts(context).size() > 1) {
- notificationText = phoneAccount.getShortDescription().toString();
- } else {
- notificationText =
- String.format(
- context.getString(R.string.notification_voicemail_text_format),
- PhoneNumberUtils.formatNumber(voicemailNumber));
- }
- pendingIntent = callVoicemailIntent;
- }
- Notification.Builder builder = new Notification.Builder(context);
- builder
- .setSmallIcon(android.R.drawable.stat_notify_voicemail)
- .setColor(context.getColor(R.color.dialer_theme_color))
- .setWhen(System.currentTimeMillis())
- .setContentTitle(notificationTitle)
- .setContentText(notificationText)
- .setContentIntent(pendingIntent)
- .setSound(telephonyManager.getVoicemailRingtoneUri(phoneAccountHandle))
- .setOngoing(
- carrierConfig.getBoolean(
- CarrierConfigManager.KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL));
-
- if (telephonyManager.isVoicemailVibrationEnabled(phoneAccountHandle)) {
- builder.setDefaults(Notification.DEFAULT_VIBRATE);
- }
-
- NotificationChannelManager.applyChannel(
- builder, context, Channel.VOICEMAIL, phoneAccountHandle);
- Notification notification = builder.build();
- getNotificationManager()
- .notify(LEGACY_VOICEMAIL_NOTIFICATION_TAG, LEGACY_VOICEMAIL_NOTIFICATION_ID, notification);
- }
-
- public void cancelLegacyNotification() {
- LogUtil.i(TAG, "Clearing legacy voicemail notification");
- getNotificationManager()
- .cancel(LEGACY_VOICEMAIL_NOTIFICATION_TAG, LEGACY_VOICEMAIL_NOTIFICATION_ID);
- }
-
- /**
- * Determines which ringtone Uri and Notification defaults to use when updating the notification
- * for the given call.
- */
- private Pair<Uri, Integer> getNotificationInfo(@Nullable NewCall callToNotify) {
- LogUtil.v(TAG, "getNotificationInfo");
- if (callToNotify == null) {
- LogUtil.i(TAG, "callToNotify == null");
- return new Pair<>(null, 0);
- }
- PhoneAccountHandle accountHandle = PhoneAccountHandles.getAccount(context, callToNotify);
- if (accountHandle == null) {
- LogUtil.i(TAG, "No default phone account found, using default notification ringtone");
- return new Pair<>(null, Notification.DEFAULT_ALL);
- }
- return new Pair<>(
- TelephonyManagerCompat.getVoicemailRingtoneUri(getTelephonyManager(), accountHandle),
- getNotificationDefaults(accountHandle));
- }
-
- private int getNotificationDefaults(PhoneAccountHandle accountHandle) {
- if (VERSION.SDK_INT >= VERSION_CODES.N) {
- return TelephonyManagerCompat.isVoicemailVibrationEnabled(
- getTelephonyManager(), accountHandle)
- ? Notification.DEFAULT_VIBRATE
- : 0;
- }
- return Notification.DEFAULT_ALL;
- }
-
- /** Creates a pending intent that marks all new voicemails as old. */
- private PendingIntent createMarkNewVoicemailsAsOldIntent(@Nullable Uri voicemailUri) {
- Intent intent = new Intent(context, CallLogNotificationsService.class);
- intent.setAction(CallLogNotificationsService.ACTION_MARK_NEW_VOICEMAILS_AS_OLD);
- intent.setData(voicemailUri);
- return PendingIntent.getService(context, 0, intent, 0);
- }
-
- private NotificationManager getNotificationManager() {
- return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
- }
-
- private TelephonyManager getTelephonyManager() {
- return (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
- }
-
- private Notification createNotificationForVoicemail(
- @NonNull NewCall voicemail, @NonNull Map<String, ContactInfo> contactInfos) {
- Pair<Uri, Integer> notificationInfo = getNotificationInfo(voicemail);
- ContactInfo contactInfo = contactInfos.get(voicemail.number);
-
- Notification.Builder notificationBuilder =
- createNotificationBuilder()
- .setContentTitle(
- context
- .getResources()
- .getQuantityString(R.plurals.notification_voicemail_title, 1, 1))
- .setContentText(
- ContactDisplayUtils.getTtsSpannedPhoneNumber(
- context.getResources(),
- R.string.notification_new_voicemail_ticker,
- contactInfo.name))
- .setWhen(voicemail.dateMs)
- .setSound(notificationInfo.first)
- .setDefaults(notificationInfo.second);
-
- if (voicemail.voicemailUri != null) {
- notificationBuilder.setDeleteIntent(
- createMarkNewVoicemailsAsOldIntent(voicemail.voicemailUri));
- }
-
- NotificationChannelManager.applyChannel(
- notificationBuilder,
- context,
- Channel.VOICEMAIL,
- PhoneAccountHandles.getAccount(context, voicemail));
-
- ContactPhotoLoader loader = new ContactPhotoLoader(context, contactInfo);
- Bitmap photoIcon = loader.loadPhotoIcon();
- if (photoIcon != null) {
- notificationBuilder.setLargeIcon(photoIcon);
- }
- if (!TextUtils.isEmpty(voicemail.transcription)) {
- Logger.get(context)
- .logImpression(DialerImpression.Type.VVM_NOTIFICATION_CREATED_WITH_TRANSCRIPTION);
- notificationBuilder.setStyle(
- new Notification.BigTextStyle().bigText(voicemail.transcription));
- }
- notificationBuilder.setContentIntent(newVoicemailIntent(voicemail));
- Logger.get(context).logImpression(DialerImpression.Type.VVM_NOTIFICATION_CREATED);
- return notificationBuilder.build();
- }
-
- private Notification.Builder createNotificationBuilder() {
- return new Notification.Builder(context)
- .setSmallIcon(android.R.drawable.stat_notify_voicemail)
- .setColor(context.getColor(R.color.dialer_theme_color))
- .setGroup(VISUAL_VOICEMAIL_NOTIFICATION_TAG)
- .setOnlyAlertOnce(true)
- .setAutoCancel(true);
- }
-
- private PendingIntent newVoicemailIntent(@Nullable NewCall voicemail) {
- Intent intent =
- DialtactsActivity.getShowTabIntent(context, DialtactsPagerAdapter.TAB_INDEX_VOICEMAIL);
- // TODO (b/35486204): scroll to this voicemail
- if (voicemail != null) {
- intent.setData(voicemail.voicemailUri);
- }
- intent.putExtra(DialtactsActivity.EXTRA_CLEAR_NEW_VOICEMAILS, true);
- return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
- }
-
- /**
- * Updates the voicemail notifications displayed.
- *
- * @param runnable Called when the async update task completes no matter if it succeeds or fails.
- * May be null.
- */
- static void updateVoicemailNotifications(Context context, Runnable runnable) {
- if (!TelecomUtil.isDefaultDialer(context)) {
- LogUtil.i(
- "DefaultVoicemailNotifier.updateVoicemailNotifications",
- "not default dialer, not scheduling update to voicemail notifications");
- return;
- }
-
- DialerExecutors.createNonUiTaskBuilder(new DefaultVoicemailNotifier(context))
- .onSuccess(
- output -> {
- LogUtil.i(
- "DefaultVoicemailNotifier.updateVoicemailNotifications",
- "update voicemail notifications successful");
- if (runnable != null) {
- runnable.run();
- }
- })
- .onFailure(
- throwable -> {
- LogUtil.i(
- "DefaultVoicemailNotifier.updateVoicemailNotifications",
- "update voicemail notifications failed");
- if (runnable != null) {
- runnable.run();
- }
- })
- .build()
- .executeParallel(null);
- }
-}