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
17package android.support.v7.mms;
18
19import android.content.Context;
20import android.content.res.Configuration;
21import android.os.Build;
22import android.telephony.SmsManager;
23import android.telephony.SubscriptionInfo;
24import android.telephony.SubscriptionManager;
25import android.telephony.TelephonyManager;
26import android.text.TextUtils;
27import android.util.Log;
28
29import java.net.MalformedURLException;
30import java.net.URL;
31
32/**
33 * Utility methods
34 */
35class Utils {
36    /**
37     * Check if MMS API is available
38     *
39     * @return true if MMS API is available, false otherwise
40     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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