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; 25 import android.os.Build.VERSION_CODES; 26 import android.support.annotation.VisibleForTesting; 27 import android.support.v4.os.BuildCompat; 28 import android.support.v4.os.UserManagerCompat; 29 import android.telecom.PhoneAccountHandle; 30 import android.telephony.TelephonyManager; 31 import com.android.dialer.app.calllog.LegacyVoicemailNotifier; 32 import com.android.dialer.common.Assert; 33 import com.android.dialer.common.LogUtil; 34 import com.android.dialer.common.PerAccountSharedPreferences; 35 import com.android.dialer.compat.telephony.TelephonyManagerCompat; 36 import com.android.dialer.storage.StorageComponent; 37 import com.android.voicemail.VoicemailClient; 38 import com.android.voicemail.VoicemailComponent; 39 40 /** 41 * Receives {@link TelephonyManager#ACTION_SHOW_VOICEMAIL_NOTIFICATION}, and forwards to {@link 42 * LegacyVoicemailNotifier}. Will ignore the notification if the account has visual voicemail. 43 * Legacy voicemail is the traditional, non-visual, dial-in voicemail. 44 */ 45 @TargetApi(VERSION_CODES.O) 46 public class LegacyVoicemailNotificationReceiver extends BroadcastReceiver { 47 48 @VisibleForTesting static final String LEGACY_VOICEMAIL_DISMISSED = "legacy_voicemail_dismissed"; 49 50 @Override onReceive(Context context, Intent intent)51 public void onReceive(Context context, Intent intent) { 52 53 if (!TelephonyManager.ACTION_SHOW_VOICEMAIL_NOTIFICATION.equals(intent.getAction()) 54 && !VoicemailClient.ACTION_SHOW_LEGACY_VOICEMAIL.equals(intent.getAction())) { 55 return; 56 } 57 58 LogUtil.i( 59 "LegacyVoicemailNotificationReceiver.onReceive", "received legacy voicemail notification"); 60 if (!BuildCompat.isAtLeastO()) { 61 LogUtil.e( 62 "LegacyVoicemailNotificationReceiver.onReceive", 63 "SDK not finalized: SDK_INT=" 64 + Build.VERSION.SDK_INT 65 + ", PREVIEW_SDK_INT=" 66 + Build.VERSION.PREVIEW_SDK_INT 67 + ", RELEASE=" 68 + Build.VERSION.RELEASE); 69 return; 70 } 71 72 PhoneAccountHandle phoneAccountHandle = 73 Assert.isNotNull(intent.getParcelableExtra(TelephonyManager.EXTRA_PHONE_ACCOUNT_HANDLE)); 74 int count = intent.getIntExtra(TelephonyManager.EXTRA_NOTIFICATION_COUNT, -1); 75 76 boolean isRefresh = intent.getBooleanExtra(TelephonyManagerCompat.EXTRA_IS_REFRESH, false); 77 LogUtil.i("LegacyVoicemailNotificationReceiver.onReceive", "isRefresh: " + isRefresh); 78 PerAccountSharedPreferences preferences = getSharedPreferences(context, phoneAccountHandle); 79 if (isRefresh) { 80 if (preferences.getBoolean(LEGACY_VOICEMAIL_DISMISSED, false)) { 81 LogUtil.i( 82 "LegacyVoicemailNotificationReceiver.onReceive", 83 "notification dismissed, ignoring refresh"); 84 return; 85 } 86 } else { 87 setDismissed(context, phoneAccountHandle, false); 88 } 89 90 if (count == -1) { 91 // Carrier might not send voicemail count. Missing extra means there are unknown numbers of 92 // voicemails (One or more). Treat it as 1 so the generic version will be shown. ("Voicemail" 93 // instead of "X voicemails") 94 count = 1; 95 } 96 97 if (count == 0) { 98 LogUtil.i("LegacyVoicemailNotificationReceiver.onReceive", "clearing notification"); 99 LegacyVoicemailNotifier.cancelNotification(context, phoneAccountHandle); 100 return; 101 } 102 103 if (!intent.getBooleanExtra(VoicemailClient.EXTRA_IS_LEGACY_MODE, false) 104 && UserManagerCompat.isUserUnlocked(context) 105 && VoicemailComponent.get(context) 106 .getVoicemailClient() 107 .isActivated(context, phoneAccountHandle)) { 108 LogUtil.i( 109 "LegacyVoicemailNotificationReceiver.onReceive", 110 "visual voicemail is activated, ignoring notification"); 111 return; 112 } 113 114 String voicemailNumber = intent.getStringExtra(TelephonyManager.EXTRA_VOICEMAIL_NUMBER); 115 PendingIntent callVoicemailIntent = 116 intent.getParcelableExtra(TelephonyManager.EXTRA_CALL_VOICEMAIL_INTENT); 117 PendingIntent voicemailSettingIntent = 118 intent.getParcelableExtra(TelephonyManager.EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT); 119 120 LogUtil.i("LegacyVoicemailNotificationReceiver.onReceive", "sending notification"); 121 LegacyVoicemailNotifier.showNotification( 122 context, 123 phoneAccountHandle, 124 count, 125 voicemailNumber, 126 callVoicemailIntent, 127 voicemailSettingIntent, 128 isRefresh); 129 } 130 setDismissed( Context context, PhoneAccountHandle phoneAccountHandle, boolean dismissed)131 public static void setDismissed( 132 Context context, PhoneAccountHandle phoneAccountHandle, boolean dismissed) { 133 getSharedPreferences(context, phoneAccountHandle) 134 .edit() 135 .putBoolean(LEGACY_VOICEMAIL_DISMISSED, dismissed) 136 .apply(); 137 } 138 139 @VisibleForTesting getSharedPreferences( Context context, PhoneAccountHandle phoneAccountHandle)140 static PerAccountSharedPreferences getSharedPreferences( 141 Context context, PhoneAccountHandle phoneAccountHandle) { 142 return new PerAccountSharedPreferences( 143 context, phoneAccountHandle, StorageComponent.get(context).unencryptedSharedPrefs()); 144 } 145 } 146