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