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