1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.dialer.app.voicemail; 18 19 import android.annotation.TargetApi; 20 import android.app.PendingIntent; 21 import android.content.BroadcastReceiver; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.os.Build.VERSION_CODES; 25 import android.preference.PreferenceManager; 26 import android.support.v4.os.BuildCompat; 27 import android.support.v4.os.UserManagerCompat; 28 import android.telecom.PhoneAccountHandle; 29 import android.telephony.TelephonyManager; 30 import com.android.dialer.app.calllog.DefaultVoicemailNotifier; 31 import com.android.dialer.common.Assert; 32 import com.android.dialer.common.LogUtil; 33 import com.android.dialer.common.PerAccountSharedPreferences; 34 import com.android.voicemail.VoicemailComponent; 35 36 /** 37 * Receives {@link TelephonyManager#ACTION_SHOW_VOICEMAIL_NOTIFICATION}, and forwards to {@link 38 * DefaultVoicemailNotifier}. Will ignore the notification if the account has visual voicemail. 39 * Legacy voicemail is the traditional, non-visual, dial-in voicemail. 40 */ 41 @TargetApi(VERSION_CODES.O) 42 public class LegacyVoicemailNotificationReceiver extends BroadcastReceiver { 43 44 private static final String LEGACY_VOICEMAIL_COUNT = "legacy_voicemail_count"; 45 46 @Override onReceive(Context context, Intent intent)47 public void onReceive(Context context, Intent intent) { 48 LogUtil.i( 49 "LegacyVoicemailNotificationReceiver.onReceive", "received legacy voicemail notification"); 50 Assert.checkArgument(BuildCompat.isAtLeastO()); 51 52 PhoneAccountHandle phoneAccountHandle = 53 Assert.isNotNull(intent.getParcelableExtra(TelephonyManager.EXTRA_PHONE_ACCOUNT_HANDLE)); 54 55 int count = intent.getIntExtra(TelephonyManager.EXTRA_NOTIFICATION_COUNT, -1); 56 57 if (!hasVoicemailCountChanged(context, phoneAccountHandle, count)) { 58 LogUtil.i( 59 "LegacyVoicemailNotificationReceiver.onReceive", 60 "voicemail count hasn't changed, ignoring"); 61 return; 62 } 63 64 if (count == -1) { 65 // Carrier might not send voicemail count. Missing extra means there are unknown numbers of 66 // voicemails (One or more). Treat it as 1 so the generic version will be shown. ("Voicemail" 67 // instead of "X voicemails") 68 count = 1; 69 } 70 71 if (count == 0) { 72 LogUtil.i("LegacyVoicemailNotificationReceiver.onReceive", "clearing notification"); 73 new DefaultVoicemailNotifier(context).cancelLegacyNotification(); 74 return; 75 } 76 77 if (UserManagerCompat.isUserUnlocked(context) 78 && VoicemailComponent.get(context) 79 .getVoicemailClient() 80 .isActivated(context, phoneAccountHandle)) { 81 LogUtil.i( 82 "LegacyVoicemailNotificationReceiver.onReceive", 83 "visual voicemail is activated, ignoring notification"); 84 return; 85 } 86 87 String voicemailNumber = intent.getStringExtra(TelephonyManager.EXTRA_VOICEMAIL_NUMBER); 88 PendingIntent callVoicemailIntent = 89 intent.getParcelableExtra(TelephonyManager.EXTRA_CALL_VOICEMAIL_INTENT); 90 PendingIntent voicemailSettingIntent = 91 intent.getParcelableExtra(TelephonyManager.EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT); 92 93 LogUtil.i("LegacyVoicemailNotificationReceiver.onReceive", "sending notification"); 94 new DefaultVoicemailNotifier(context) 95 .notifyLegacyVoicemail( 96 phoneAccountHandle, 97 count, 98 voicemailNumber, 99 callVoicemailIntent, 100 voicemailSettingIntent); 101 } 102 hasVoicemailCountChanged( Context context, PhoneAccountHandle phoneAccountHandle, int newCount)103 private static boolean hasVoicemailCountChanged( 104 Context context, PhoneAccountHandle phoneAccountHandle, int newCount) { 105 // Need credential encrypted storage to access preferences. 106 if (!UserManagerCompat.isUserUnlocked(context)) { 107 LogUtil.i( 108 "LegacyVoicemailNotificationReceiver.onReceive", 109 "User locked, bypassing voicemail count check"); 110 return true; 111 } 112 113 if (newCount == -1) { 114 // Carrier does not report voicemail count 115 return true; 116 } 117 118 PerAccountSharedPreferences preferences = 119 new PerAccountSharedPreferences( 120 context, phoneAccountHandle, PreferenceManager.getDefaultSharedPreferences(context)); 121 // Carriers may send multiple notifications for the same voicemail. 122 if (newCount != 0 && newCount == preferences.getInt(LEGACY_VOICEMAIL_COUNT, -1)) { 123 return false; 124 } 125 preferences.edit().putInt(LEGACY_VOICEMAIL_COUNT, newCount).apply(); 126 return true; 127 } 128 } 129