1 /* 2 * Copyright (C) 2015 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 androidx.appcompat.mms; 18 19 import android.content.Context; 20 import android.content.res.Configuration; 21 import android.os.Build; 22 import android.telephony.SmsManager; 23 import android.telephony.SubscriptionInfo; 24 import android.telephony.SubscriptionManager; 25 import android.telephony.TelephonyManager; 26 import android.text.TextUtils; 27 import android.util.Log; 28 29 import java.net.MalformedURLException; 30 import java.net.URL; 31 32 /** 33 * Utility methods 34 */ 35 class Utils { 36 /** 37 * Check if MMS API is available 38 * 39 * @return true if MMS API is available, false otherwise 40 */ hasMmsApi()41 static boolean hasMmsApi() { 42 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; 43 } 44 45 /** 46 * Check if support multi-SIM 47 * 48 * @return true if MSIM is supported, false otherwise 49 */ supportMSim()50 static boolean supportMSim() { 51 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1; 52 } 53 54 /** 55 * Check if support APIs for getting UserAgent and UAProfUrl 56 * 57 * @return true if those APIs are supported, false otherwise 58 */ hasUserAgentApi()59 static boolean hasUserAgentApi() { 60 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; 61 } 62 63 /** 64 * Get system SmsManager 65 * 66 * @param subId the subscription ID of the SmsManager 67 * @return the SmsManager for the input subId 68 */ getSmsManager(final int subId)69 static SmsManager getSmsManager(final int subId) { 70 if (supportMSim()) { 71 return SmsManager.getSmsManagerForSubscriptionId(subId); 72 } else { 73 return SmsManager.getDefault(); 74 } 75 } 76 77 /** 78 * Get the real subscription ID if the input is -1 79 * 80 * @param subId input subscription ID 81 * @return the default SMS subscription ID if the input is -1, otherwise the original 82 */ getEffectiveSubscriptionId(int subId)83 static int getEffectiveSubscriptionId(int subId) { 84 if (supportMSim()) { 85 if (subId == MmsManager.DEFAULT_SUB_ID) { 86 subId = SmsManager.getDefaultSmsSubscriptionId(); 87 } 88 } 89 if (subId < 0) { 90 subId = MmsManager.DEFAULT_SUB_ID; 91 } 92 return subId; 93 } 94 95 /** 96 * Get MCC/MNC of an SIM subscription 97 * 98 * @param context the Context to use 99 * @param subId the SIM subId 100 * @return a non-empty array with exactly two elements, first is mcc and last is mnc. 101 */ getMccMnc(final Context context, final int subId)102 static int[] getMccMnc(final Context context, final int subId) { 103 final int[] mccMnc = new int[] { 0, 0 }; 104 if (Utils.supportMSim()) { 105 final SubscriptionManager subscriptionManager = SubscriptionManager.from(context); 106 final SubscriptionInfo subInfo = subscriptionManager.getActiveSubscriptionInfo(subId); 107 if (subInfo != null) { 108 mccMnc[0] = subInfo.getMcc(); 109 mccMnc[1] = subInfo.getMnc(); 110 } 111 } else { 112 final TelephonyManager telephonyManager = 113 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 114 final String mccMncString = telephonyManager.getSimOperator(); 115 try { 116 mccMnc[0] = Integer.parseInt(mccMncString.substring(0, 3)); 117 mccMnc[1] = Integer.parseInt(mccMncString.substring(3)); 118 } catch (Exception e) { 119 Log.w(MmsService.TAG, "Invalid mcc/mnc from system " + mccMncString + ": " + e); 120 mccMnc[0] = 0; 121 mccMnc[1] = 0; 122 } 123 } 124 return mccMnc; 125 } 126 127 /** 128 * Get a subscription's Context so we can load resources from it 129 * 130 * @param context the sub-independent Context 131 * @param subId the SIM's subId 132 * @return the sub-dependent Context 133 */ getSubDepContext(final Context context, final int subId)134 static Context getSubDepContext(final Context context, final int subId) { 135 if (!supportMSim()) { 136 return context; 137 } 138 final int[] mccMnc = getMccMnc(context, subId); 139 final int mcc = mccMnc[0]; 140 final int mnc = mccMnc[1]; 141 if (mcc == 0 && mnc == 0) { 142 return context; 143 } 144 final Configuration subConfig = new Configuration(); 145 subConfig.mcc = mcc; 146 subConfig.mnc = mnc; 147 return context.createConfigurationContext(subConfig); 148 } 149 150 /** 151 * Redact the URL for non-VERBOSE logging. Replace url with only the host part and the length 152 * of the input URL string. 153 * 154 * @param urlString 155 * @return 156 */ redactUrlForNonVerbose(String urlString)157 static String redactUrlForNonVerbose(String urlString) { 158 if (Log.isLoggable(MmsService.TAG, Log.VERBOSE)) { 159 // Don't redact for VERBOSE level logging 160 return urlString; 161 } 162 if (TextUtils.isEmpty(urlString)) { 163 return urlString; 164 } 165 String protocol = "http"; 166 String host = ""; 167 try { 168 final URL url = new URL(urlString); 169 protocol = url.getProtocol(); 170 host = url.getHost(); 171 } catch (MalformedURLException e) { 172 // Ignore 173 } 174 // Print "http://host[length]" 175 final StringBuilder sb = new StringBuilder(); 176 sb.append(protocol).append("://").append(host) 177 .append("[").append(urlString.length()).append("]"); 178 return sb.toString(); 179 } 180 } 181