1/*
2 * Copyright (C) 2007-2008 Esmertec AG.
3 * Copyright (C) 2007-2008 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package com.android.mms.transaction;
19
20import android.content.Context;
21import android.database.Cursor;
22import android.database.sqlite.SqliteWrapper;
23import android.net.NetworkUtils;
24import android.provider.Telephony;
25import android.text.TextUtils;
26import android.util.Log;
27
28import com.android.internal.telephony.PhoneConstants;
29import com.android.mms.LogTag;
30
31/**
32 * Container of transaction settings. Instances of this class are contained
33 * within Transaction instances to allow overriding of the default APN
34 * settings or of the MMS Client.
35 */
36public class TransactionSettings {
37    private static final String TAG = "TransactionSettings";
38    private static final boolean DEBUG = true;
39    private static final boolean LOCAL_LOGV = false;
40
41    private String mServiceCenter;
42    private String mProxyAddress;
43    private int mProxyPort = -1;
44
45    private static final String[] APN_PROJECTION = {
46            Telephony.Carriers.TYPE,            // 0
47            Telephony.Carriers.MMSC,            // 1
48            Telephony.Carriers.MMSPROXY,        // 2
49            Telephony.Carriers.MMSPORT          // 3
50    };
51    private static final int COLUMN_TYPE         = 0;
52    private static final int COLUMN_MMSC         = 1;
53    private static final int COLUMN_MMSPROXY     = 2;
54    private static final int COLUMN_MMSPORT      = 3;
55
56    /**
57     * Constructor that uses the default settings of the MMS Client.
58     *
59     * @param context The context of the MMS Client
60     */
61    public TransactionSettings(Context context, String apnName) {
62        if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
63            Log.v(TAG, "TransactionSettings: apnName: " + apnName);
64        }
65        String selection = Telephony.Carriers.CURRENT + " IS NOT NULL";
66        String[] selectionArgs = null;
67        if (!TextUtils.isEmpty(apnName)) {
68            selection += " AND " + Telephony.Carriers.APN + "=?";
69            selectionArgs = new String[]{ apnName.trim() };
70        }
71
72        Cursor cursor = SqliteWrapper.query(context, context.getContentResolver(),
73                            Telephony.Carriers.CONTENT_URI,
74                            APN_PROJECTION, selection, selectionArgs, null);
75
76        if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
77            Log.v(TAG, "TransactionSettings looking for apn: " + selection + " returned: " +
78                    (cursor ==null ? "null cursor" : (cursor.getCount() + " hits")));
79        }
80
81        if (cursor == null) {
82            Log.e(TAG, "Apn is not found in Database!");
83            return;
84        }
85
86        boolean sawValidApn = false;
87        try {
88            while (cursor.moveToNext() && TextUtils.isEmpty(mServiceCenter)) {
89                // Read values from APN settings
90                if (isValidApnType(cursor.getString(COLUMN_TYPE), PhoneConstants.APN_TYPE_MMS)) {
91                    sawValidApn = true;
92                    mServiceCenter = NetworkUtils.trimV4AddrZeros(
93                            cursor.getString(COLUMN_MMSC).trim());
94                    mProxyAddress = NetworkUtils.trimV4AddrZeros(
95                            cursor.getString(COLUMN_MMSPROXY));
96                    if (isProxySet()) {
97                        String portString = cursor.getString(COLUMN_MMSPORT);
98                        try {
99                            mProxyPort = Integer.parseInt(portString);
100                        } catch (NumberFormatException e) {
101                            if (TextUtils.isEmpty(portString)) {
102                                Log.w(TAG, "mms port not set!");
103                            } else {
104                                Log.e(TAG, "Bad port number format: " + portString, e);
105                            }
106                        }
107                    }
108                }
109            }
110        } finally {
111            cursor.close();
112        }
113
114        Log.v(TAG, "APN setting: MMSC: " + mServiceCenter + " looked for: " + selection);
115
116        if (sawValidApn && TextUtils.isEmpty(mServiceCenter)) {
117            Log.e(TAG, "Invalid APN setting: MMSC is empty");
118        }
119    }
120
121    /**
122     * Constructor that overrides the default settings of the MMS Client.
123     *
124     * @param mmscUrl The MMSC URL
125     * @param proxyAddr The proxy address
126     * @param proxyPort The port used by the proxy address
127     * immediately start a SendTransaction upon completion of a NotificationTransaction,
128     * false otherwise.
129     */
130    public TransactionSettings(String mmscUrl, String proxyAddr, int proxyPort) {
131        mServiceCenter = mmscUrl != null ? mmscUrl.trim() : null;
132        mProxyAddress = proxyAddr;
133        mProxyPort = proxyPort;
134
135        if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
136            Log.v(TAG, "TransactionSettings: " + mServiceCenter +
137                    " proxyAddress: " + mProxyAddress +
138                    " proxyPort: " + mProxyPort);
139        }
140   }
141
142    public String getMmscUrl() {
143        return mServiceCenter;
144    }
145
146    public String getProxyAddress() {
147        return mProxyAddress;
148    }
149
150    public int getProxyPort() {
151        return mProxyPort;
152    }
153
154    public boolean isProxySet() {
155        return (mProxyAddress != null) && (mProxyAddress.trim().length() != 0);
156    }
157
158    static private boolean isValidApnType(String types, String requestType) {
159        // If APN type is unspecified, assume APN_TYPE_ALL.
160        if (TextUtils.isEmpty(types)) {
161            return true;
162        }
163
164        for (String t : types.split(",")) {
165            if (t.equals(requestType) || t.equals(PhoneConstants.APN_TYPE_ALL)) {
166                return true;
167            }
168        }
169        return false;
170    }
171}
172