1 /*
2  * Copyright (C) 2016 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.server.telecom.settings;
18 
19 import android.app.Notification;
20 import android.app.NotificationManager;
21 import android.app.PendingIntent;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.os.PersistableBundle;
25 import android.os.UserHandle;
26 import android.provider.BlockedNumberContract;
27 import android.provider.BlockedNumbersManager;
28 import android.telephony.CarrierConfigManager;
29 import android.telephony.PhoneNumberUtils;
30 import android.text.BidiFormatter;
31 import android.text.Spannable;
32 import android.text.SpannableString;
33 import android.text.TextDirectionHeuristics;
34 import android.widget.Toast;
35 
36 import com.android.server.telecom.R;
37 import com.android.server.telecom.SystemSettingsUtil;
38 import com.android.server.telecom.flags.FeatureFlags;
39 import com.android.server.telecom.ui.NotificationChannelManager;
40 
41 import java.util.Locale;
42 
43 public final class BlockedNumbersUtil {
BlockedNumbersUtil()44     private BlockedNumbersUtil() {}
45 
46     private static final int EMERGENCY_CALL_NOTIFICATION = 150;
47 
48     /**
49      * @return locale and default to US if no locale was returned.
50      */
getLocaleDefaultToUS()51     public static String getLocaleDefaultToUS() {
52         String countryIso = Locale.getDefault().getCountry();
53         if (countryIso == null || countryIso.length() != 2) {
54             countryIso = "US";
55         }
56         return countryIso;
57     }
58 
59     /**
60      * Attempts to format the number, or returns the original number if it is not formattable. Also
61      * wraps the returned number as LTR.
62      */
formatNumber(String number)63     public static String formatNumber(String number){
64       String formattedNumber = PhoneNumberUtils.formatNumber(number, getLocaleDefaultToUS());
65       return BidiFormatter.getInstance().unicodeWrap(
66               formattedNumber == null ? number : formattedNumber,
67               TextDirectionHeuristics.LTR);
68     }
69 
70     /**
71      * Formats the number in the string and shows a toast for {@link Toast#LENGTH_SHORT}.
72      *
73      * <p>Adds the number in a TsSpan so that it reads as a phone number when talk back is on.
74      */
showToastWithFormattedNumber(Context context, int stringId, String number)75     public static void showToastWithFormattedNumber(Context context, int stringId, String number) {
76         String formattedNumber = formatNumber(number);
77         String message = context.getString(stringId, formattedNumber);
78         int startingPosition = message.indexOf(formattedNumber);
79         Spannable messageSpannable = new SpannableString(message);
80         PhoneNumberUtils.addTtsSpan(messageSpannable, startingPosition,
81                 startingPosition + formattedNumber.length());
82         Toast.makeText(
83                 context,
84                 messageSpannable,
85                 Toast.LENGTH_SHORT).show();
86     }
87 
88     /**
89      * Updates an emergency call notification
90      *
91      * @param context context to start CallBlockDisabledActivity.
92      * @param showNotification if {@code true} show notification, {@code false} cancel notification.
93      */
updateEmergencyCallNotification(Context context, boolean showNotification)94     public static void updateEmergencyCallNotification(Context context, boolean showNotification) {
95         NotificationManager notificationManager =
96                 (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
97         if (showNotification) {
98             Intent intent = new Intent(context, CallBlockDisabledActivity.class);
99             PendingIntent pendingIntent = PendingIntent.getActivity(
100                     context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT
101                             | PendingIntent.FLAG_IMMUTABLE);
102 
103             String title = context.getString(
104                     R.string.phone_strings_call_blocking_turned_off_notification_title_txt);
105             String message = context.getString(
106                     R.string.phone_strings_call_blocking_turned_off_notification_text_txt);
107             Notification.Builder builder = new Notification.Builder(context);
108             Notification notification = builder.setSmallIcon(android.R.drawable.stat_sys_warning)
109                     .setTicker(message)
110                     .setContentTitle(title)
111                     .setContentText(message)
112                     .setContentIntent(pendingIntent)
113                     .setShowWhen(true)
114                     .setChannelId(NotificationChannelManager.CHANNEL_ID_CALL_BLOCKING)
115                     .build();
116 
117             notification.flags |= Notification.FLAG_NO_CLEAR;
118             notificationManager.notifyAsUser(null /* tag */ , EMERGENCY_CALL_NOTIFICATION,
119                     notification, new UserHandle(UserHandle.USER_OWNER));
120         } else {
121             notificationManager.cancelAsUser(null /* tag */ , EMERGENCY_CALL_NOTIFICATION,
122                     new UserHandle(UserHandle.USER_OWNER));
123         }
124     }
125 
126     /**
127      * Returns the platform configuration for whether to enable enhanced call blocking feature.
128      *
129      * @param context the application context
130      * @return If {@code true} means enhanced call blocking enabled by platform,
131      *            {@code false} otherwise.
132      */
isEnhancedCallBlockingEnabledByPlatform(Context context)133     public static boolean isEnhancedCallBlockingEnabledByPlatform(Context context) {
134         CarrierConfigManager configManager = (CarrierConfigManager) context.getSystemService(
135                 Context.CARRIER_CONFIG_SERVICE);
136         PersistableBundle carrierConfig = configManager.getConfig();
137         if (carrierConfig == null) {
138             carrierConfig = configManager.getDefaultConfig();
139         }
140         return carrierConfig.getBoolean(
141                 CarrierConfigManager.KEY_SUPPORT_ENHANCED_CALL_BLOCKING_BOOL)
142                 || new SystemSettingsUtil().isEnhancedCallBlockingEnabled(context);
143     }
144 
145     /**
146      * Get the blocking setting status from {@link BlockedNumberProvider} SharedPreferences.
147      *
148      * @param context the application context
149      * @param key preference key of SharedPreferences.
150      * @return If {@code true} means the key enabled in the SharedPreferences,
151      *            {@code false} otherwise.
152      */
getBlockedNumberSetting(Context context, String key, FeatureFlags featureFlags)153     public static boolean getBlockedNumberSetting(Context context, String key,
154             FeatureFlags featureFlags) {
155         return featureFlags.telecomMainlineBlockedNumbersManager()
156                 ? context.getSystemService(BlockedNumbersManager.class).getBlockedNumberSetting(key)
157                 : BlockedNumberContract.SystemContract.getEnhancedBlockSetting(context, key);
158     }
159 
160     /**
161      * Set the blocking setting status to {@link BlockedNumberProvider} SharedPreferences.
162      *
163      * @param context the application context
164      * @param key preference key of SharedPreferences.
165      * @param value the register value to the SharedPreferences.
166      */
setBlockedNumberSetting(Context context, String key, boolean value, FeatureFlags featureFlags)167     public static void setBlockedNumberSetting(Context context, String key, boolean value,
168             FeatureFlags featureFlags) {
169         if (featureFlags.telecomMainlineBlockedNumbersManager()) {
170             context.getSystemService(BlockedNumbersManager.class).setBlockedNumberSetting(key,
171                     value);
172         } else {
173             BlockedNumberContract.SystemContract.setEnhancedBlockSetting(context, key, value);
174         }
175     }
176 }
177