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 package com.android.internal.telephony.util; 17 18 import android.annotation.NonNull; 19 import android.app.NotificationChannel; 20 import android.app.NotificationManager; 21 import android.content.BroadcastReceiver; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.IntentFilter; 25 import android.media.AudioAttributes; 26 import android.net.Uri; 27 import android.provider.Settings; 28 import android.telephony.SubscriptionManager; 29 30 import com.android.internal.R; 31 32 import java.util.Arrays; 33 34 35 public class NotificationChannelController { 36 37 /** 38 * list of {@link android.app.NotificationChannel} for telephony service. 39 */ 40 public static final String CHANNEL_ID_ALERT = "alert"; 41 public static final String CHANNEL_ID_CALL_FORWARD = "callForwardNew"; 42 public static final String CHANNEL_ID_MOBILE_DATA_STATUS = "mobileDataAlertNew"; 43 public static final String CHANNEL_ID_SIM = "sim"; 44 public static final String CHANNEL_ID_SMS = "sms"; 45 public static final String CHANNEL_ID_VOICE_MAIL = "voiceMail"; 46 public static final String CHANNEL_ID_WFC = "wfc"; 47 48 /** deprecated channel, replaced with @see #CHANNEL_ID_MOBILE_DATA_STATUS */ 49 private static final String CHANNEL_ID_MOBILE_DATA_ALERT_DEPRECATED = "mobileDataAlert"; 50 /** 51 * deprecated channel, replaced with @see #CHANNEL_ID_CALL_FORWARD 52 * change the importance to default to make sure notification icon shown in the status bar. 53 */ 54 private static final String CHANNEL_ID_CALL_FORWARD_DEPRECATED = "callForward"; 55 56 /** 57 * Creates all notification channels and registers with NotificationManager. If a channel 58 * with the same ID is already registered, NotificationManager will ignore this call. 59 */ createAll(Context context)60 private static void createAll(Context context) { 61 final NotificationChannel alertChannel = new NotificationChannel( 62 CHANNEL_ID_ALERT, 63 context.getText(R.string.notification_channel_network_alert), 64 NotificationManager.IMPORTANCE_DEFAULT); 65 alertChannel.setSound(Settings.System.DEFAULT_NOTIFICATION_URI, 66 new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build()); 67 // allow users to block notifications from system 68 alertChannel.setBlockableSystem(true); 69 70 final NotificationChannel mobileDataStatusChannel = new NotificationChannel( 71 CHANNEL_ID_MOBILE_DATA_STATUS, 72 context.getText(R.string.notification_channel_mobile_data_status), 73 NotificationManager.IMPORTANCE_LOW); 74 // allow users to block notifications from system 75 mobileDataStatusChannel.setBlockableSystem(true); 76 77 final NotificationChannel simChannel = new NotificationChannel( 78 CHANNEL_ID_SIM, 79 context.getText(R.string.notification_channel_sim), 80 NotificationManager.IMPORTANCE_LOW 81 ); 82 simChannel.setSound(null, null); 83 84 final NotificationChannel callforwardChannel = new NotificationChannel( 85 CHANNEL_ID_CALL_FORWARD, 86 context.getText(R.string.notification_channel_call_forward), 87 NotificationManager.IMPORTANCE_DEFAULT); 88 migrateCallFowardNotificationChannel(context, callforwardChannel); 89 90 context.getSystemService(NotificationManager.class) 91 .createNotificationChannels(Arrays.asList( 92 new NotificationChannel(CHANNEL_ID_SMS, 93 context.getText(R.string.notification_channel_sms), 94 NotificationManager.IMPORTANCE_HIGH), 95 new NotificationChannel(CHANNEL_ID_WFC, 96 context.getText(R.string.notification_channel_wfc), 97 NotificationManager.IMPORTANCE_LOW), 98 alertChannel, mobileDataStatusChannel, 99 simChannel, callforwardChannel)); 100 101 // only for update 102 if (getChannel(CHANNEL_ID_VOICE_MAIL, context) != null) { 103 migrateVoicemailNotificationSettings(context); 104 } 105 106 // after channel has been created there is no way to change the channel setting 107 // programmatically. delete the old channel and create a new one with a new ID. 108 if (getChannel(CHANNEL_ID_MOBILE_DATA_ALERT_DEPRECATED, context) != null) { 109 context.getSystemService(NotificationManager.class) 110 .deleteNotificationChannel(CHANNEL_ID_MOBILE_DATA_ALERT_DEPRECATED); 111 } 112 if (getChannel(CHANNEL_ID_CALL_FORWARD_DEPRECATED, context) != null) { 113 context.getSystemService(NotificationManager.class) 114 .deleteNotificationChannel(CHANNEL_ID_CALL_FORWARD_DEPRECATED); 115 } 116 } 117 NotificationChannelController(Context context)118 public NotificationChannelController(Context context) { 119 IntentFilter intentFilter = new IntentFilter(); 120 intentFilter.addAction(Intent.ACTION_LOCALE_CHANGED); 121 intentFilter.addAction(Intent.ACTION_SIM_STATE_CHANGED); 122 context.registerReceiver(mBroadcastReceiver, intentFilter); 123 createAll(context); 124 } 125 getChannel(String channelId, Context context)126 public static NotificationChannel getChannel(String channelId, Context context) { 127 return context.getSystemService(NotificationManager.class) 128 .getNotificationChannel(channelId); 129 } 130 131 /** 132 * migrate deprecated voicemail notification settings to initial notification channel settings 133 * {@link VoicemailNotificationSettingsUtil#getRingTonePreference(Context)}} 134 * {@link VoicemailNotificationSettingsUtil#getVibrationPreference(Context)} 135 * notification settings are based on subId, only migrate if sub id matches. 136 * otherwise fallback to predefined voicemail channel settings. 137 * @param context 138 */ migrateVoicemailNotificationSettings(Context context)139 private static void migrateVoicemailNotificationSettings(Context context) { 140 final NotificationChannel voiceMailChannel = new NotificationChannel( 141 CHANNEL_ID_VOICE_MAIL, 142 context.getText(R.string.notification_channel_voice_mail), 143 NotificationManager.IMPORTANCE_DEFAULT); 144 voiceMailChannel.enableVibration( 145 VoicemailNotificationSettingsUtil.getVibrationPreference(context)); 146 Uri sound = VoicemailNotificationSettingsUtil.getRingTonePreference(context); 147 voiceMailChannel.setSound( 148 (sound == null) ? Settings.System.DEFAULT_NOTIFICATION_URI : sound, 149 new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build()); 150 context.getSystemService(NotificationManager.class) 151 .createNotificationChannel(voiceMailChannel); 152 } 153 154 /** 155 * migrate deprecated call forward notification channel. 156 * @param context 157 */ migrateCallFowardNotificationChannel( Context context, @NonNull NotificationChannel callforwardChannel)158 private static void migrateCallFowardNotificationChannel( 159 Context context, @NonNull NotificationChannel callforwardChannel) { 160 final NotificationChannel deprecatedChannel = 161 getChannel(CHANNEL_ID_CALL_FORWARD_DEPRECATED, context); 162 if (deprecatedChannel != null) { 163 callforwardChannel.setSound(deprecatedChannel.getSound(), 164 deprecatedChannel.getAudioAttributes()); 165 callforwardChannel.setVibrationPattern(deprecatedChannel.getVibrationPattern()); 166 callforwardChannel.enableVibration(deprecatedChannel.shouldVibrate()); 167 } 168 } 169 170 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 171 @Override 172 public void onReceive(Context context, Intent intent) { 173 if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) { 174 // rename all notification channels on locale change 175 createAll(context); 176 } else if (Intent.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) { 177 // migrate voicemail notification settings on sim load 178 if (SubscriptionManager.INVALID_SUBSCRIPTION_ID != 179 SubscriptionManager.getDefaultSubscriptionId()) { 180 migrateVoicemailNotificationSettings(context); 181 } 182 } 183 } 184 }; 185 } 186