1d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/* 2d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2015 The Android Open Source Project 3d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 4d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Licensed under the Apache License, Version 2.0 (the "License"); 5d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * you may not use this file except in compliance with the License. 6d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * You may obtain a copy of the License at 7d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 8d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * http://www.apache.org/licenses/LICENSE-2.0 9d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 10d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Unless required by applicable law or agreed to in writing, software 11d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * distributed under the License is distributed on an "AS IS" BASIS, 12d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * See the License for the specific language governing permissions and 14d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * limitations under the License. 15d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 16d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 17d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpackage com.android.messaging.sms; 18d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 19d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.ContentValues; 20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.Context; 21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.database.Cursor; 22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.database.sqlite.SQLiteDatabase; 23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.database.sqlite.SQLiteException; 24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.net.Uri; 25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.provider.Telephony; 26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.support.v7.mms.ApnSettingsLoader; 27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.support.v7.mms.MmsManager; 28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.text.TextUtils; 29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.util.SparseArray; 30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.ParticipantData; 32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.mmslib.SqliteWrapper; 33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.BugleGservices; 34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.BugleGservicesKeys; 35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.LogUtil; 36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.OsUtil; 37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.PhoneUtils; 38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.net.URI; 40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.net.URISyntaxException; 41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.ArrayList; 42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.List; 43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/** 45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * APN loader for default SMS SIM 46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * This loader tries to load APNs from 3 sources in order: 48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 1. Gservices setting 49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 2. System APN table 50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 3. Local APN table 51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpublic class BugleApnSettingsLoader implements ApnSettingsLoader { 53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * The base implementation of an APN 55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static class BaseApn implements Apn { 57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Create a base APN from parameters 59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param typesIn the APN type field 61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param mmscIn the APN mmsc field 62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param proxyIn the APN mmsproxy field 63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param portIn the APN mmsport field 64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return an instance of base APN, or null if any of the parameter is invalid 65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static BaseApn from(final String typesIn, final String mmscIn, final String proxyIn, 67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String portIn) { 68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (!isValidApnType(trimWithNullCheck(typesIn), APN_TYPE_MMS)) { 69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd String mmsc = trimWithNullCheck(mmscIn); 72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (TextUtils.isEmpty(mmsc)) { 73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mmsc = trimV4AddrZeros(mmsc); 76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd new URI(mmsc); 78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (final URISyntaxException e) { 79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd String mmsProxy = trimWithNullCheck(proxyIn); 82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int mmsProxyPort = 80; 83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (!TextUtils.isEmpty(mmsProxy)) { 84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mmsProxy = trimV4AddrZeros(mmsProxy); 85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String portString = trimWithNullCheck(portIn); 86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (portString != null) { 87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mmsProxyPort = Integer.parseInt(portString); 89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (final NumberFormatException e) { 90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Ignore, just use 80 to try 91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 94d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return new BaseApn(mmsc, mmsProxy, mmsProxyPort); 95d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 96d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 97d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private final String mMmsc; 98d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private final String mMmsProxy; 99d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private final int mMmsProxyPort; 100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public BaseApn(final String mmsc, final String proxy, final int port) { 102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mMmsc = mmsc; 103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mMmsProxy = proxy; 104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mMmsProxyPort = port; 105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getMmsc() { 109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mMmsc; 110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getMmsProxy() { 114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mMmsProxy; 115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int getMmsProxyPort() { 119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mMmsProxyPort; 120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void setSuccess() { 124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Do nothing 125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean equals(final BaseApn other) { 128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return TextUtils.equals(mMmsc, other.getMmsc()) && 129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd TextUtils.equals(mMmsProxy, other.getMmsProxy()) && 130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mMmsProxyPort == other.getMmsProxyPort(); 131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * The APN represented by the local APN table row 136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static class DatabaseApn implements Apn { 138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final ContentValues CURRENT_NULL_VALUE; 139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final ContentValues CURRENT_SET_VALUE; 140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd static { 141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd CURRENT_NULL_VALUE = new ContentValues(1); 142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd CURRENT_NULL_VALUE.putNull(Telephony.Carriers.CURRENT); 143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd CURRENT_SET_VALUE = new ContentValues(1); 144d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd CURRENT_SET_VALUE.put(Telephony.Carriers.CURRENT, "1"); // 1 for auto selected APN 145d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 146d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String CLEAR_UPDATE_SELECTION = Telephony.Carriers.CURRENT + " =?"; 147d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String[] CLEAR_UPDATE_SELECTION_ARGS = new String[] { "1" }; 148d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String SET_UPDATE_SELECTION = Telephony.Carriers._ID + " =?"; 149d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 150d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 151d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Create an APN loaded from local database 152d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 153d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param apns the in-memory APN list 154d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param typesIn the APN type field 155d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param mmscIn the APN mmsc field 156d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param proxyIn the APN mmsproxy field 157d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param portIn the APN mmsport field 158d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param rowId the APN's row ID in database 159d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param current the value of CURRENT column in database 160d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return an in-memory APN instance for database APN row, null if parameter invalid 161d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 162d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static DatabaseApn from(final List<Apn> apns, final String typesIn, 163d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String mmscIn, final String proxyIn, final String portIn, 164d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final long rowId, final int current) { 165d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (apns == null) { 166d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 167d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 168d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final BaseApn base = BaseApn.from(typesIn, mmscIn, proxyIn, portIn); 169d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (base == null) { 170d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 171d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 172d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (final ApnSettingsLoader.Apn apn : apns) { 173d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (apn instanceof DatabaseApn && ((DatabaseApn) apn).equals(base)) { 174d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 175d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 176d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 177d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return new DatabaseApn(apns, base, rowId, current); 178d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 179d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 180d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private final List<Apn> mApns; 181d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private final BaseApn mBase; 182d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private final long mRowId; 183d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private int mCurrent; 184d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 185d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public DatabaseApn(final List<Apn> apns, final BaseApn base, final long rowId, 186d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int current) { 187d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mApns = apns; 188d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mBase = base; 189d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mRowId = rowId; 190d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mCurrent = current; 191d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 192d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 193d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 194d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getMmsc() { 195d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mBase.getMmsc(); 196d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 197d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 198d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 199d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public String getMmsProxy() { 200d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mBase.getMmsProxy(); 201d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 202d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 203d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 204d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public int getMmsProxyPort() { 205d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mBase.getMmsProxyPort(); 206d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 207d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 208d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 209d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void setSuccess() { 210d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd moveToListHead(); 211d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd setCurrentInDatabase(); 212d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 213d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 214d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 215d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Try to move this APN to the head of in-memory list 216d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 217d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private void moveToListHead() { 218d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // If this is being marked as a successful APN, move it to the top of the list so 219d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // next time it will be tried first 220d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd boolean moved = false; 221d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd synchronized (mApns) { 222d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mApns.get(0) != this) { 223d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mApns.remove(this); 224d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mApns.add(0, this); 225d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd moved = true; 226d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 227d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 228d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (moved) { 229d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.d(LogUtil.BUGLE_TAG, "Set APN [" 230d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + "MMSC=" + getMmsc() + ", " 231d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + "PROXY=" + getMmsProxy() + ", " 232d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + "PORT=" + getMmsProxyPort() + "] to be first"); 233d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 234d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 235d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 236d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 237d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Try to set the APN to be CURRENT in its database table 238d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 239d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private void setCurrentInDatabase() { 240d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd synchronized (this) { 241d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mCurrent > 0) { 242d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Already current 243d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return; 244d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 245d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mCurrent = 1; 246d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 247d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.d(LogUtil.BUGLE_TAG, "Set APN @" + mRowId + " to be CURRENT in local db"); 248d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final SQLiteDatabase database = ApnDatabase.getApnDatabase().getWritableDatabase(); 249d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd database.beginTransaction(); 250d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 251d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // clear the previous current=1 apn 252d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // we don't clear current=2 apn since it is manually selected by user 253d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // and we should not override it. 254d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd database.update(ApnDatabase.APN_TABLE, CURRENT_NULL_VALUE, 255d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd CLEAR_UPDATE_SELECTION, CLEAR_UPDATE_SELECTION_ARGS); 256d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // set this one to be current (1) 257d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd database.update(ApnDatabase.APN_TABLE, CURRENT_SET_VALUE, SET_UPDATE_SELECTION, 258d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd new String[] { Long.toString(mRowId) }); 259d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd database.setTransactionSuccessful(); 260d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } finally { 261d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd database.endTransaction(); 262d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 263d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 264d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 265d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public boolean equals(final BaseApn other) { 266d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (other == null) { 267d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 268d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 269d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mBase.equals(other); 270d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 271d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 272d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 273d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 274d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * APN_TYPE_ALL is a special type to indicate that this APN entry can 275d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * service all data connections. 276d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 277d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String APN_TYPE_ALL = "*"; 278d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** APN type for MMS traffic */ 279d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String APN_TYPE_MMS = "mms"; 280d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 281d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String[] APN_PROJECTION_SYSTEM = { 282d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Telephony.Carriers.TYPE, 283d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Telephony.Carriers.MMSC, 284d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Telephony.Carriers.MMSPROXY, 285d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Telephony.Carriers.MMSPORT, 286d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }; 287d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String[] APN_PROJECTION_LOCAL = { 288d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Telephony.Carriers.TYPE, 289d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Telephony.Carriers.MMSC, 290d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Telephony.Carriers.MMSPROXY, 291d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Telephony.Carriers.MMSPORT, 292d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Telephony.Carriers.CURRENT, 293d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Telephony.Carriers._ID, 294d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }; 295d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int COLUMN_TYPE = 0; 296d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int COLUMN_MMSC = 1; 297d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int COLUMN_MMSPROXY = 2; 298d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int COLUMN_MMSPORT = 3; 299d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int COLUMN_CURRENT = 4; 300d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final int COLUMN_ID = 5; 301d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 302d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String SELECTION_APN = Telephony.Carriers.APN + "=?"; 303d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String SELECTION_CURRENT = Telephony.Carriers.CURRENT + " IS NOT NULL"; 304d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String SELECTION_NUMERIC = Telephony.Carriers.NUMERIC + "=?"; 305d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String ORDER_BY = Telephony.Carriers.CURRENT + " DESC"; 306d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 307d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private final Context mContext; 308d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 309d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Cached APNs for subIds 310d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private final SparseArray<List<ApnSettingsLoader.Apn>> mApnsCache; 311d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 312d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public BugleApnSettingsLoader(final Context context) { 313d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mContext = context; 314d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mApnsCache = new SparseArray<>(); 315d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 316d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 317d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 318d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public List<ApnSettingsLoader.Apn> get(final String apnName) { 319d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int subId = PhoneUtils.getDefault().getEffectiveSubId( 320d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ParticipantData.DEFAULT_SELF_SUB_ID); 321d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd List<ApnSettingsLoader.Apn> apns; 322d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd boolean didLoad = false; 323d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd synchronized (this) { 324d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd apns = mApnsCache.get(subId); 325d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (apns == null) { 326d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd apns = new ArrayList<>(); 327d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mApnsCache.put(subId, apns); 328d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd loadLocked(subId, apnName, apns); 329d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd didLoad = true; 330d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 331d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 332d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (didLoad) { 333d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.i(LogUtil.BUGLE_TAG, "Loaded " + apns.size() + " APNs"); 334d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 335d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return apns; 336d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 337d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 338d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private void loadLocked(final int subId, final String apnName, final List<Apn> apns) { 339d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Try Gservices first 340d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd loadFromGservices(apns); 341d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (apns.size() > 0) { 342d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return; 343d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 344d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Try system APN table 345d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd loadFromSystem(subId, apnName, apns); 346d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (apns.size() > 0) { 347d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return; 348d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 349d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Try local APN table 350d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd loadFromLocalDatabase(apnName, apns); 351d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (apns.size() <= 0) { 352d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.w(LogUtil.BUGLE_TAG, "Failed to load any APN"); 353d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 354d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 355d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 356d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 357d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Load from Gservices if APN setting is set in Gservices 358d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 359d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param apns the list used to return results 360d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 361d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private void loadFromGservices(final List<Apn> apns) { 362d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final BugleGservices gservices = BugleGservices.get(); 363d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String mmsc = gservices.getString(BugleGservicesKeys.MMS_MMSC, null); 364d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (TextUtils.isEmpty(mmsc)) { 365d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return; 366d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 367d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.i(LogUtil.BUGLE_TAG, "Loading APNs from gservices"); 368d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String proxy = gservices.getString(BugleGservicesKeys.MMS_PROXY_ADDRESS, null); 369d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int port = gservices.getInt(BugleGservicesKeys.MMS_PROXY_PORT, -1); 370d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Apn apn = BaseApn.from("mms", mmsc, proxy, Integer.toString(port)); 371d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (apn != null) { 372d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd apns.add(apn); 373d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 374d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 375d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 376d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 377d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Load matching APNs from telephony provider. 378d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * We try different combinations of the query to work around some platform quirks. 379d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 380d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param subId the SIM subId 381d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param apnName the APN name to match 382d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param apns the list used to return results 383d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 384d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private void loadFromSystem(final int subId, final String apnName, final List<Apn> apns) { 385d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Uri uri; 386d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (OsUtil.isAtLeastL_MR1() && subId != MmsManager.DEFAULT_SUB_ID) { 387d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "/subId/" + subId); 388d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 389d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd uri = Telephony.Carriers.CONTENT_URI; 390d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 391d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Cursor cursor = null; 392d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 393d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (; ; ) { 394d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Try different combinations of queries. Some would work on some platforms. 395d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // So we query each combination until we find one returns non-empty result. 396d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor = querySystem(uri, true/*checkCurrent*/, apnName); 397d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (cursor != null) { 398d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 399d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 400d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor = querySystem(uri, false/*checkCurrent*/, apnName); 401d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (cursor != null) { 402d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 403d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 404d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor = querySystem(uri, true/*checkCurrent*/, null/*apnName*/); 405d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (cursor != null) { 406d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 407d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 408d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor = querySystem(uri, false/*checkCurrent*/, null/*apnName*/); 409d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 410d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 411d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (final SecurityException e) { 412d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Can't access platform APN table, return directly 413d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return; 414d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 415d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (cursor == null) { 416d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return; 417d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 418d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 419d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (cursor.moveToFirst()) { 420d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final ApnSettingsLoader.Apn apn = BaseApn.from( 421d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor.getString(COLUMN_TYPE), 422d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor.getString(COLUMN_MMSC), 423d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor.getString(COLUMN_MMSPROXY), 424d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor.getString(COLUMN_MMSPORT)); 425d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (apn != null) { 426d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd apns.add(apn); 427d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 428d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 429d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } finally { 430d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor.close(); 431d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 432d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 433d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 434d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 435d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Query system APN table 436d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 437d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param uri The APN query URL to use 438d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param checkCurrent If add "CURRENT IS NOT NULL" condition 439d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param apnName The optional APN name for query condition 440d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return A cursor of the query result. If a cursor is returned as not null, it is 441d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * guaranteed to contain at least one row. 442d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 443d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private Cursor querySystem(final Uri uri, final boolean checkCurrent, String apnName) { 444d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.i(LogUtil.BUGLE_TAG, "Loading APNs from system, " 445d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + "checkCurrent=" + checkCurrent + " apnName=" + apnName); 446d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final StringBuilder selectionBuilder = new StringBuilder(); 447d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd String[] selectionArgs = null; 448d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (checkCurrent) { 449d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd selectionBuilder.append(SELECTION_CURRENT); 450d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 451d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd apnName = trimWithNullCheck(apnName); 452d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (!TextUtils.isEmpty(apnName)) { 453d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (selectionBuilder.length() > 0) { 454d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd selectionBuilder.append(" AND "); 455d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 456d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd selectionBuilder.append(SELECTION_APN); 457d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd selectionArgs = new String[] { apnName }; 458d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 459d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 460d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Cursor cursor = SqliteWrapper.query( 461d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mContext, 462d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mContext.getContentResolver(), 463d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd uri, 464d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd APN_PROJECTION_SYSTEM, 465d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd selectionBuilder.toString(), 466d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd selectionArgs, 467d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd null/*sortOrder*/); 468d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (cursor == null || cursor.getCount() < 1) { 469d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (cursor != null) { 470d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor.close(); 471d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 472d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.w(LogUtil.BUGLE_TAG, "Query " + uri + " with apn " + apnName + " and " 473d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + (checkCurrent ? "checking CURRENT" : "not checking CURRENT") 474d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + " returned empty"); 475d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 476d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 477d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return cursor; 478d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (final SQLiteException e) { 479d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.w(LogUtil.BUGLE_TAG, "APN table query exception: " + e); 480d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (final SecurityException e) { 481d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.w(LogUtil.BUGLE_TAG, "Platform restricts APN table access: " + e); 482d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw e; 483d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 484d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 485d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 486d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 487d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 488d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Load matching APNs from local APN table. 489d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * We try both using the APN name and not using the APN name. 490d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 491d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param apnName the APN name 492d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param apns the list of results to return 493d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 494d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private void loadFromLocalDatabase(final String apnName, final List<Apn> apns) { 495d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.i(LogUtil.BUGLE_TAG, "Loading APNs from local APN table"); 496d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final SQLiteDatabase database = ApnDatabase.getApnDatabase().getWritableDatabase(); 497d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String mccMnc = PhoneUtils.getMccMncString(PhoneUtils.getDefault().getMccMnc()); 498d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Cursor cursor = null; 499d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor = queryLocalDatabase(database, mccMnc, apnName); 500d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (cursor == null) { 501d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor = queryLocalDatabase(database, mccMnc, null/*apnName*/); 502d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 503d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (cursor == null) { 504d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.w(LogUtil.BUGLE_TAG, "Could not find any APN in local table"); 505d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return; 506d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 507d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 508d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd while (cursor.moveToNext()) { 509d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Apn apn = DatabaseApn.from(apns, 510d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor.getString(COLUMN_TYPE), 511d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor.getString(COLUMN_MMSC), 512d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor.getString(COLUMN_MMSPROXY), 513d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor.getString(COLUMN_MMSPORT), 514d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor.getLong(COLUMN_ID), 515d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor.getInt(COLUMN_CURRENT)); 516d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (apn != null) { 517d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd apns.add(apn); 518d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 519d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 520d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } finally { 521d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor.close(); 522d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 523d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 524d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 525d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 526d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Make a query of local APN table based on MCC/MNC and APN name, sorted by CURRENT 527d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * column in descending order 528d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 529d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param db the local database 530d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param numeric the MCC/MNC string 531d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param apnName the optional APN name to match 532d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the cursor of the query, null if no result 533d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 534d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static Cursor queryLocalDatabase(final SQLiteDatabase db, final String numeric, 535d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String apnName) { 536d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String selection; 537d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String[] selectionArgs; 538d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (TextUtils.isEmpty(apnName)) { 539d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd selection = SELECTION_NUMERIC; 540d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd selectionArgs = new String[] { numeric }; 541d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 542d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd selection = SELECTION_NUMERIC + " AND " + SELECTION_APN; 543d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd selectionArgs = new String[] { numeric, apnName }; 544d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 545d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Cursor cursor = null; 546d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 547d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor = db.query(ApnDatabase.APN_TABLE, APN_PROJECTION_LOCAL, selection, selectionArgs, 548d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd null/*groupBy*/, null/*having*/, ORDER_BY, null/*limit*/); 549d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (final SQLiteException e) { 550d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.w(LogUtil.BUGLE_TAG, "Local APN table does not exist. Try rebuilding.", e); 551d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ApnDatabase.forceBuildAndLoadApnTables(); 552d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor = db.query(ApnDatabase.APN_TABLE, APN_PROJECTION_LOCAL, selection, selectionArgs, 553d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd null/*groupBy*/, null/*having*/, ORDER_BY, null/*limit*/); 554d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 555d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (cursor == null || cursor.getCount() < 1) { 556d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (cursor != null) { 557d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor.close(); 558d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 559d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.w(LogUtil.BUGLE_TAG, "Query local APNs with apn " + apnName 560d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + " returned empty"); 561d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 562d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 563d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return cursor; 564d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 565d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 566d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static String trimWithNullCheck(final String value) { 567d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return value != null ? value.trim() : null; 568d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 569d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 570d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 571d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Trim leading zeros from IPv4 address strings 572d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Our base libraries will interpret that as octel.. 573d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Must leave non v4 addresses and host names alone. 574d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * For example, 192.168.000.010 -> 192.168.0.10 575d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 576d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param addr a string representing an ip addr 577d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return a string propertly trimmed 578d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 579d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static String trimV4AddrZeros(final String addr) { 580d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (addr == null) { 581d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 582d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 583d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String[] octets = addr.split("\\."); 584d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (octets.length != 4) { 585d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return addr; 586d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 587d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final StringBuilder builder = new StringBuilder(16); 588d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd String result = null; 589d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (int i = 0; i < 4; i++) { 590d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 591d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (octets[i].length() > 3) { 592d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return addr; 593d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 594d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd builder.append(Integer.parseInt(octets[i])); 595d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (final NumberFormatException e) { 596d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return addr; 597d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 598d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (i < 3) { 599d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd builder.append('.'); 600d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 601d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 602d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd result = builder.toString(); 603d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return result; 604d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 605d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 606d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 607d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Check if the APN contains the APN type we want 608d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 609d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param types The string encodes a list of supported types 610d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param requestType The type we want 611d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return true if the input types string contains the requestType 612d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 613d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static boolean isValidApnType(final String types, final String requestType) { 614d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // If APN type is unspecified, assume APN_TYPE_ALL. 615d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (TextUtils.isEmpty(types)) { 616d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return true; 617d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 618d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (final String t : types.split(",")) { 619d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (t.equals(requestType) || t.equals(APN_TYPE_ALL)) { 620d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return true; 621d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 622d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 623d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 624d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 625d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 626d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 627d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get the ID of first APN to try 628d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 629d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static String getFirstTryApn(final SQLiteDatabase database, final String mccMnc) { 630d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd String key = null; 631d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Cursor cursor = null; 632d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 633d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor = queryLocalDatabase(database, mccMnc, null/*apnName*/); 634d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (cursor.moveToFirst()) { 635d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd key = cursor.getString(ApnDatabase.COLUMN_ID); 636d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 637d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (final Exception e) { 638d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Nothing to do 639d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } finally { 640d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (cursor != null) { 641d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd cursor.close(); 642d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 643d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 644d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return key; 645d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 646d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd} 647