summaryrefslogtreecommitdiffstats
path: root/src/com/android/providers/telephony/TelephonyProvider.java
diff options
context:
space:
mode:
authorAmit Mahajan <amitmahajan@google.com>2015-04-16 10:02:52 -0700
committerAmit Mahajan <amitmahajan@google.com>2015-05-01 16:41:32 +0000
commitb80f7335ebde67951eed8fe6a37958eeb9e6cc78 (patch)
tree4602df47afb0f88f3f6cfcb85d2db905aa1dbad7 /src/com/android/providers/telephony/TelephonyProvider.java
parenta2f40df899ffeb07368ec5559116583da45cd546 (diff)
downloadandroid_packages_providers_TelephonyProvider-b80f7335ebde67951eed8fe6a37958eeb9e6cc78.tar.gz
android_packages_providers_TelephonyProvider-b80f7335ebde67951eed8fe6a37958eeb9e6cc78.tar.bz2
android_packages_providers_TelephonyProvider-b80f7335ebde67951eed8fe6a37958eeb9e6cc78.zip
Add bearer_bitmask field (in addition to bearer).
The db is recreated to rename user_edited to edited as that is a more apt name (otherwise just adding column for bearer_bitmask could work going from version 14 to 15). Table anyway had to be recreated going from version < 14 to 15 due to addition of unique constraint. Usage of bearer field is replaced by bearer_bitmask in all modules where possible. Other modules now use both bearer and bearer_bitmask. Other CLs under same topic have those changes. Change-Id: Ibe2968f59f1c82917ff916acdabcc17f34b20d3c
Diffstat (limited to 'src/com/android/providers/telephony/TelephonyProvider.java')
-rw-r--r--src/com/android/providers/telephony/TelephonyProvider.java506
1 files changed, 365 insertions, 141 deletions
diff --git a/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index 3a930ea..12430de 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -38,6 +38,7 @@ import android.os.Environment;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Telephony;
+import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -45,6 +46,7 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.Xml;
+import com.android.internal.telephony.RILConstants;
import com.android.internal.util.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
@@ -57,6 +59,7 @@ import java.io.IOException;
import java.lang.NumberFormatException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
public class TelephonyProvider extends ContentProvider
@@ -65,7 +68,7 @@ public class TelephonyProvider extends ContentProvider
private static final boolean DBG = true;
private static final boolean VDBG = false; // STOPSHIP if true
- private static final int DATABASE_VERSION = 14 << 16;
+ private static final int DATABASE_VERSION = 15 << 16;
private static final int URL_UNKNOWN = 0;
private static final int URL_TELEPHONY = 1;
private static final int URL_CURRENT = 2;
@@ -95,6 +98,7 @@ public class TelephonyProvider extends ContentProvider
private static final String PARTNER_APNS_PATH = "etc/apns-conf.xml";
private static final String OEM_APNS_PATH = "telephony/apns-conf.xml";
+ private static final String OTA_UPDATED_APNS_PATH = "misc/apns-conf.xml";
private static final UriMatcher s_urlMatcher = new UriMatcher(UriMatcher.NO_MATCH);
@@ -239,6 +243,7 @@ public class TelephonyProvider extends ContentProvider
"roaming_protocol TEXT DEFAULT 'IP'," +
"carrier_enabled BOOLEAN DEFAULT 1," +
"bearer INTEGER DEFAULT 0," +
+ "bearer_bitmask INTEGER DEFAULT 0," +
"mvno_type TEXT DEFAULT ''," +
"mvno_match_data TEXT DEFAULT ''," +
"sub_id INTEGER DEFAULT " + SubscriptionManager.INVALID_SUBSCRIPTION_ID + "," +
@@ -248,12 +253,12 @@ public class TelephonyProvider extends ContentProvider
"wait_time INTEGER DEFAULT 0," +
"max_conns_time INTEGER DEFAULT 0," +
"mtu INTEGER DEFAULT 0," +
- "user_edited INTEGER DEFAULT " + Telephony.Carriers.UNEDITED + "," +
+ "edited INTEGER DEFAULT " + Telephony.Carriers.UNEDITED + "," +
// Uniqueness collisions are used to trigger merge code so if a field is listed
// here it means we will accept both (user edited + new apn_conf definition)
- // Columns not included in UNIQUE constraint: name, current, user_edited,
+ // Columns not included in UNIQUE constraint: name, current, edited,
// user, server, password, authtype, type, protocol, roaming_protocol, sub_id,
- // modem_cognitive, max_conns, wait_time, max_conns_time, mtu
+ // modem_cognitive, max_conns, wait_time, max_conns_time, mtu, bearer_bitmask
"UNIQUE (numeric, mcc, mnc, apn, proxy, port, mmsproxy, mmsport, mmsc," +
"carrier_enabled, bearer, mvno_type, mvno_match_data, profile_id));");
if (DBG) log("dbh.createCarriersTable:-");
@@ -284,23 +289,9 @@ public class TelephonyProvider extends ContentProvider
// Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system".
File confFile = new File(Environment.getRootDirectory(), PARTNER_APNS_PATH);
File oemConfFile = new File(Environment.getOemDirectory(), OEM_APNS_PATH);
- if (oemConfFile.exists()) {
- // OEM image exist APN xml, get the timestamp from OEM & System image for comparison
- long oemApnTime = oemConfFile.lastModified();
- long sysApnTime = confFile.lastModified();
- if (DBG) log("APNs Timestamp: oemTime = " + oemApnTime + " sysTime = "
- + sysApnTime);
-
- // To get the latest version from OEM or System image
- if (oemApnTime > sysApnTime) {
- if (DBG) log("APNs Timestamp: OEM image is greater than System image");
- confFile = oemConfFile;
- }
- } else {
- // No Apn in OEM image, so load it from system image.
- if (DBG) log("No APNs in OEM image = " + oemConfFile.getPath() +
- " Load APNs from system image");
- }
+ File updatedConfFile = new File(Environment.getDataDirectory(), OTA_UPDATED_APNS_PATH);
+ confFile = getNewerFile(confFile, oemConfFile);
+ confFile = getNewerFile(confFile, updatedConfFile);
FileReader confreader = null;
if (DBG) log("confFile = " + confFile);
@@ -327,26 +318,26 @@ public class TelephonyProvider extends ContentProvider
e);
} finally {
// Get rid of user/carrier deleted entries that are not present in apn xml file.
- // Those entries have user_edited value USER_DELETED/CARRIER_DELETED.
+ // Those entries have edited value USER_DELETED/CARRIER_DELETED.
if (VDBG) {
log("initDatabase: deleting USER_DELETED and replacing "
+ "DELETED_BUT_PRESENT_IN_XML with DELETED");
}
// Delete USER_DELETED
- db.delete(CARRIERS_TABLE, "user_edited=" + Telephony.Carriers.USER_DELETED + " or " +
- "user_edited=" + Telephony.Carriers.CARRIER_DELETED, null);
+ db.delete(CARRIERS_TABLE, "edited=" + Telephony.Carriers.USER_DELETED + " or " +
+ "edited=" + Telephony.Carriers.CARRIER_DELETED, null);
// Change USER_DELETED_BUT_PRESENT_IN_XML to USER_DELETED
ContentValues cv = new ContentValues();
cv.put(Telephony.Carriers.EDITED, Telephony.Carriers.USER_DELETED);
- db.update(CARRIERS_TABLE, cv, "user_edited=" + Telephony.Carriers.USER_DELETED_BUT_PRESENT_IN_XML,
+ db.update(CARRIERS_TABLE, cv, "edited=" + Telephony.Carriers.USER_DELETED_BUT_PRESENT_IN_XML,
null);
// Change CARRIER_DELETED_BUT_PRESENT_IN_XML to CARRIER_DELETED
cv = new ContentValues();
cv.put(Telephony.Carriers.EDITED, Telephony.Carriers.CARRIER_DELETED);
- db.update(CARRIERS_TABLE, cv, "user_edited=" + Telephony.Carriers.CARRIER_DELETED_BUT_PRESENT_IN_XML,
+ db.update(CARRIERS_TABLE, cv, "edited=" + Telephony.Carriers.CARRIER_DELETED_BUT_PRESENT_IN_XML,
null);
if (confreader != null) {
@@ -361,6 +352,28 @@ public class TelephonyProvider extends ContentProvider
}
+ private File getNewerFile(File sysApnFile, File altApnFile) {
+ if (altApnFile.exists()) {
+ // Alternate file exists. Use the newer one.
+ long altFileTime = altApnFile.lastModified();
+ long currFileTime = sysApnFile.lastModified();
+ if (DBG) log("APNs Timestamp: altFileTime = " + altFileTime + " currFileTime = "
+ + currFileTime);
+
+ // To get the latest version from OEM or System image
+ if (altFileTime > currFileTime) {
+ if (DBG) log("APNs Timestamp: Alternate image " + altApnFile.getPath() +
+ " is greater than System image");
+ return altApnFile;
+ }
+ } else {
+ // No Apn in alternate image, so load it from system image.
+ if (DBG) log("No APNs in OEM image = " + altApnFile.getPath() +
+ " Load APNs from system image");
+ }
+ return sysApnFile;
+ }
+
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (DBG) {
@@ -463,122 +476,160 @@ public class TelephonyProvider extends ContentProvider
oldVersion = 13 << 16 | 6;
}
if (oldVersion < (14 << 16 | 6)) {
+ // Do nothing. This is to avoid recreating table twice. Table is anyway recreated
+ // for next version and that takes care of updates for this version as well.
+ // This version added a new column user_edited to carriers db.
+ }
+ if (oldVersion < (15 << 16 | 6)) {
Cursor c = db.query(CARRIERS_TABLE, null, null, null, null, null, null);
if (VDBG) {
log("dbh.onUpgrade:- before upgrading total number of rows: " + c.getCount());
}
-
createCarriersTable(db, CARRIERS_TABLE_TMP);
- populateNewTable(db, c);
+ if (oldVersion < (14 << 16 | 6)) {
+ populateNewTable(db, c, 13);
+ } else {
+ populateNewTable(db, c, 14);
+ }
db.execSQL("DROP TABLE IF EXISTS " + CARRIERS_TABLE);
db.execSQL("ALTER TABLE " + CARRIERS_TABLE_TMP + " rename to " + CARRIERS_TABLE +
";");
- oldVersion = 14 << 16 | 6;
-
if (VDBG) {
String[] proj = {"_id"};
c = db.query(CARRIERS_TABLE, proj, null, null, null, null, null);
log("dbh.onUpgrade:- after upgrading total number of rows: " + c.getCount());
c.close();
- c = db.query(CARRIERS_TABLE, proj, "user_edited=" + Telephony.Carriers.UNEDITED, null,
- null, null, null);
- log("dbh.onUpgrade:- after upgrading total number of rows with user_edited="
+ c = db.query(CARRIERS_TABLE, proj, "edited=" + Telephony.Carriers.UNEDITED,
+ null, null, null, null);
+ log("dbh.onUpgrade:- after upgrading total number of rows with edited="
+ Telephony.Carriers.UNEDITED + ": " + c.getCount());
c.close();
- c = db.query(CARRIERS_TABLE, proj, "user_edited!=" + Telephony.Carriers.UNEDITED,
+ c = db.query(CARRIERS_TABLE, proj, "edited!=" + Telephony.Carriers.UNEDITED,
null, null, null, null);
- log("dbh.onUpgrade:- after upgrading total number of rows with user_edited!="
+ log("dbh.onUpgrade:- after upgrading total number of rows with edited!="
+ Telephony.Carriers.UNEDITED + ": " + c.getCount());
- c.close();
}
+ c.close();
+
+ oldVersion = 15 << 16 | 6;
}
if (DBG) {
log("dbh.onUpgrade:- db=" + db + " oldV=" + oldVersion + " newV=" + newVersion);
}
}
- private void populateNewTable(SQLiteDatabase db, Cursor c) {
+ private void populateNewTable(SQLiteDatabase db, Cursor c, int oldVersion) {
// Move entries from CARRIERS_TABLE to CARRIERS_TABLE_TMP
if (c != null) {
String[] persistApnsForPlmns = mContext.getResources().getStringArray(
R.array.persist_apns_for_plmn);
while (c.moveToNext()) {
- ContentValues cv = new ContentValues();
- String val;
-
- // Include only non-null values in cv so that null values can be replaced
- // with default if there's a default value for the field
-
- // String vals
- getStringValueFromCursor(cv, c, Telephony.Carriers.NAME);
- getStringValueFromCursor(cv, c, Telephony.Carriers.NUMERIC);
- getStringValueFromCursor(cv, c, Telephony.Carriers.MCC);
- getStringValueFromCursor(cv, c, Telephony.Carriers.MNC);
- getStringValueFromCursor(cv, c, Telephony.Carriers.APN);
- getStringValueFromCursor(cv, c, Telephony.Carriers.USER);
- getStringValueFromCursor(cv, c, Telephony.Carriers.SERVER);
- getStringValueFromCursor(cv, c, Telephony.Carriers.PASSWORD);
- getStringValueFromCursor(cv, c, Telephony.Carriers.PROXY);
- getStringValueFromCursor(cv, c, Telephony.Carriers.PORT);
- getStringValueFromCursor(cv, c, Telephony.Carriers.MMSPROXY);
- getStringValueFromCursor(cv, c, Telephony.Carriers.MMSPORT);
- getStringValueFromCursor(cv, c, Telephony.Carriers.MMSC);
- getStringValueFromCursor(cv, c, Telephony.Carriers.TYPE);
- getStringValueFromCursor(cv, c, Telephony.Carriers.PROTOCOL);
- getStringValueFromCursor(cv, c, Telephony.Carriers.ROAMING_PROTOCOL);
- getStringValueFromCursor(cv, c, Telephony.Carriers.MVNO_TYPE);
- getStringValueFromCursor(cv, c, Telephony.Carriers.MVNO_MATCH_DATA);
-
- // bool/int vals
- getIntValueFromCursor(cv, c, Telephony.Carriers.AUTH_TYPE);
- getIntValueFromCursor(cv, c, Telephony.Carriers.CURRENT);
- getIntValueFromCursor(cv, c, Telephony.Carriers.CARRIER_ENABLED);
- getIntValueFromCursor(cv, c, Telephony.Carriers.BEARER);
- getIntValueFromCursor(cv, c, Telephony.Carriers.SUBSCRIPTION_ID);
- getIntValueFromCursor(cv, c, Telephony.Carriers.PROFILE_ID);
- getIntValueFromCursor(cv, c, Telephony.Carriers.MODEM_COGNITIVE);
- getIntValueFromCursor(cv, c, Telephony.Carriers.MAX_CONNS);
- getIntValueFromCursor(cv, c, Telephony.Carriers.WAIT_TIME);
- getIntValueFromCursor(cv, c, Telephony.Carriers.MAX_CONNS_TIME);
- getIntValueFromCursor(cv, c, Telephony.Carriers.MTU);
-
- // New EDITED column. Default value (Telephony.Carriers.UNEDITED) will
- // be used for all rows except for non-mvno entries for plmns indicated
- // by resource: those will be set to CARRIER_EDITED to preserve
- // their current values
- val = c.getString(c.getColumnIndex(Telephony.Carriers.NUMERIC));
- for (String s : persistApnsForPlmns) {
- if (!TextUtils.isEmpty(val) && val.equals(s) &&
- (!cv.containsKey(Telephony.Carriers.MVNO_TYPE) ||
- TextUtils.isEmpty(cv.getAsString(Telephony.Carriers.
- MVNO_TYPE)))) {
- cv.put(Telephony.Carriers.EDITED, Telephony.Carriers.CARRIER_EDITED);
- break;
+ // only add those rows that will not be deleted as part of upgrade
+ if (rowPersistedAfterUpgrade(c, oldVersion)) {
+ ContentValues cv = new ContentValues();
+ String val;
+
+ // Include only non-null values in cv so that null values can be replaced
+ // with default if there's a default value for the field
+
+ // String vals
+ getStringValueFromCursor(cv, c, Telephony.Carriers.NAME);
+ getStringValueFromCursor(cv, c, Telephony.Carriers.NUMERIC);
+ getStringValueFromCursor(cv, c, Telephony.Carriers.MCC);
+ getStringValueFromCursor(cv, c, Telephony.Carriers.MNC);
+ getStringValueFromCursor(cv, c, Telephony.Carriers.APN);
+ getStringValueFromCursor(cv, c, Telephony.Carriers.USER);
+ getStringValueFromCursor(cv, c, Telephony.Carriers.SERVER);
+ getStringValueFromCursor(cv, c, Telephony.Carriers.PASSWORD);
+ getStringValueFromCursor(cv, c, Telephony.Carriers.PROXY);
+ getStringValueFromCursor(cv, c, Telephony.Carriers.PORT);
+ getStringValueFromCursor(cv, c, Telephony.Carriers.MMSPROXY);
+ getStringValueFromCursor(cv, c, Telephony.Carriers.MMSPORT);
+ getStringValueFromCursor(cv, c, Telephony.Carriers.MMSC);
+ getStringValueFromCursor(cv, c, Telephony.Carriers.TYPE);
+ getStringValueFromCursor(cv, c, Telephony.Carriers.PROTOCOL);
+ getStringValueFromCursor(cv, c, Telephony.Carriers.ROAMING_PROTOCOL);
+ getStringValueFromCursor(cv, c, Telephony.Carriers.MVNO_TYPE);
+ getStringValueFromCursor(cv, c, Telephony.Carriers.MVNO_MATCH_DATA);
+
+ // bool/int vals
+ getIntValueFromCursor(cv, c, Telephony.Carriers.AUTH_TYPE);
+ getIntValueFromCursor(cv, c, Telephony.Carriers.CURRENT);
+ getIntValueFromCursor(cv, c, Telephony.Carriers.CARRIER_ENABLED);
+ getIntValueFromCursor(cv, c, Telephony.Carriers.BEARER);
+ getIntValueFromCursor(cv, c, Telephony.Carriers.SUBSCRIPTION_ID);
+ getIntValueFromCursor(cv, c, Telephony.Carriers.PROFILE_ID);
+ getIntValueFromCursor(cv, c, Telephony.Carriers.MODEM_COGNITIVE);
+ getIntValueFromCursor(cv, c, Telephony.Carriers.MAX_CONNS);
+ getIntValueFromCursor(cv, c, Telephony.Carriers.WAIT_TIME);
+ getIntValueFromCursor(cv, c, Telephony.Carriers.MAX_CONNS_TIME);
+ getIntValueFromCursor(cv, c, Telephony.Carriers.MTU);
+
+ // Change bearer to a bitmask
+ String bearerStr = c.getString(c.getColumnIndex(Telephony.Carriers.BEARER));
+ if (!TextUtils.isEmpty(bearerStr)) {
+ int bearer_bitmask = ServiceState.getBitmaskForTech(
+ Integer.parseInt(bearerStr));
+ cv.put(Telephony.Carriers.BEARER_BITMASK, bearer_bitmask);
}
- }
- try {
- db.insertWithOnConflict(CARRIERS_TABLE_TMP, null, cv,
- SQLiteDatabase.CONFLICT_ABORT);
- if (VDBG) {
- log("dbh.populateNewTable: db.insert returned >= 0; insert "
- + "successful for cv " + cv);
+ if (oldVersion == 14) {
+ String user_edited = c.getString(c.getColumnIndex("user_edited"));
+ if (!TextUtils.isEmpty(user_edited)) {
+ cv.put(Telephony.Carriers.EDITED, new Integer(user_edited));
+ }
}
- } catch (SQLException e) {
- if (VDBG) log("dbh.populateNewTable insertWithOnConflict exception " + e);
- // Insertion failed which could be due to a conflict. Check if that is
- // the case and merge the entries
- Cursor oldRow = DatabaseHelper.selectConflictingRow(db,
- CARRIERS_TABLE_TMP, cv);
- if (oldRow != null) {
- ContentValues mergedValues = new ContentValues();
- mergeFieldsAndUpdateDb(db, CARRIERS_TABLE_TMP, oldRow, cv,
- mergedValues, true);
- oldRow.close();
+
+ // New EDITED column. Default value (Telephony.Carriers.UNEDITED) will
+ // be used for all rows except for non-mvno entries for plmns indicated
+ // by resource: those will be set to CARRIER_EDITED to preserve
+ // their current values
+ val = c.getString(c.getColumnIndex(Telephony.Carriers.NUMERIC));
+ for (String s : persistApnsForPlmns) {
+ if (!TextUtils.isEmpty(val) && val.equals(s) &&
+ (!cv.containsKey(Telephony.Carriers.MVNO_TYPE) ||
+ TextUtils.isEmpty(cv.getAsString(Telephony.Carriers.
+ MVNO_TYPE)))) {
+ if (oldVersion == 13) {
+ cv.put(Telephony.Carriers.EDITED,
+ Telephony.Carriers.CARRIER_EDITED);
+ } else { // if (oldVersion == 14)
+ if (cv.getAsInteger(Telephony.Carriers.EDITED) ==
+ Telephony.Carriers.USER_EDITED) {
+ cv.put(Telephony.Carriers.EDITED,
+ Telephony.Carriers.CARRIER_EDITED);
+ }
+ }
+
+ break;
+ }
+ }
+
+ try {
+ db.insertWithOnConflict(CARRIERS_TABLE_TMP, null, cv,
+ SQLiteDatabase.CONFLICT_ABORT);
+ if (VDBG) {
+ log("dbh.populateNewTable: db.insert returned >= 0; insert "
+ + "successful for cv " + cv);
+ }
+ } catch (SQLException e) {
+ if (VDBG)
+ log("dbh.populateNewTable insertWithOnConflict exception " + e +
+ " for cv " + cv);
+ // Insertion failed which could be due to a conflict. Check if that is
+ // the case and merge the entries
+ Cursor oldRow = DatabaseHelper.selectConflictingRow(db,
+ CARRIERS_TABLE_TMP, cv);
+ if (oldRow != null) {
+ ContentValues mergedValues = new ContentValues();
+ mergeFieldsAndUpdateDb(db, CARRIERS_TABLE_TMP, oldRow, cv,
+ mergedValues, true, mContext);
+ oldRow.close();
+ }
}
}
}
@@ -586,6 +637,33 @@ public class TelephonyProvider extends ContentProvider
}
}
+ private boolean rowPersistedAfterUpgrade(Cursor c, int oldVersion) {
+ if (c != null) {
+ if (oldVersion == 14) {
+ String user_edited = c.getString(c.getColumnIndex("user_edited"));
+ if (!TextUtils.isEmpty(user_edited) &&
+ Integer.parseInt(user_edited) != Telephony.Carriers.UNEDITED) {
+
+ return true;
+ }
+ } else { // coming from an older version
+ String[] persistApnsForPlmns = mContext.getResources().getStringArray(
+ R.array.persist_apns_for_plmn);
+ String plmn = c.getString(c.getColumnIndex(Telephony.Carriers.NUMERIC));
+ if (!TextUtils.isEmpty(plmn)) {
+ for (String s : persistApnsForPlmns) {
+ if (plmn.equals(s) &&
+ TextUtils.isEmpty(c.getString(c.getColumnIndex(
+ Telephony.Carriers.MVNO_TYPE)))) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
private void getStringValueFromCursor(ContentValues cv, Cursor c, String key) {
String fromCursor = c.getString(c.getColumnIndex(key));
if (!TextUtils.isEmpty(fromCursor)) {
@@ -651,6 +729,12 @@ public class TelephonyProvider extends ContentProvider
addBoolAttribute(parser, "carrier_enabled", map, Telephony.Carriers.CARRIER_ENABLED);
addBoolAttribute(parser, "modem_cognitive", map, Telephony.Carriers.MODEM_COGNITIVE);
+ String bearerList = parser.getAttributeValue(null, "bearer_bitmask");
+ if (bearerList != null) {
+ int bearerBitmask = ServiceState.getBitmaskFromString(bearerList);
+ map.put(Telephony.Carriers.BEARER_BITMASK, bearerBitmask);
+ }
+
String mvno_type = parser.getAttributeValue(null, "mvno_type");
if (mvno_type != null) {
String mvno_match_data = parser.getAttributeValue(null, "mvno_match_data");
@@ -739,56 +823,74 @@ public class TelephonyProvider extends ContentProvider
} catch (SQLException e) {
if (VDBG) log("dbh.insertAddingDefaults: exception " + e);
// Insertion failed which could be due to a conflict. Check if that is the case and
- // update user_edited field accordingly.
- // Search for the exact same entry and update user_edited field.
+ // update edited field accordingly.
+ // Search for the exact same entry and update edited field.
// If it is USER_EDITED/CARRIER_EDITED change it to UNEDITED,
// and if USER/CARRIER_DELETED change it to USER/CARRIER_DELETED_BUT_PRESENT_IN_XML.
Cursor oldRow = selectConflictingRow(db, CARRIERS_TABLE, row);
if (oldRow != null) {
// Update the row
ContentValues mergedValues = new ContentValues();
- int user_edited = oldRow.getInt(oldRow.getColumnIndex(
+ int edited = oldRow.getInt(oldRow.getColumnIndex(
Telephony.Carriers.EDITED));
- int old_user_edited = user_edited;
- if (user_edited != Telephony.Carriers.UNEDITED) {
- if (user_edited == Telephony.Carriers.USER_EDITED || user_edited == Telephony.Carriers.CARRIER_EDITED) {
- user_edited = Telephony.Carriers.UNEDITED;
- } else if (user_edited == Telephony.Carriers.USER_DELETED) {
+ int old_edited = edited;
+ if (edited != Telephony.Carriers.UNEDITED) {
+ if (edited == Telephony.Carriers.USER_DELETED) {
// USER_DELETED_BUT_PRESENT_IN_XML indicates entry has been deleted
// by user but present in apn xml file.
- user_edited = Telephony.Carriers.USER_DELETED_BUT_PRESENT_IN_XML;
- } else if (user_edited == Telephony.Carriers.CARRIER_DELETED) {
+ edited = Telephony.Carriers.USER_DELETED_BUT_PRESENT_IN_XML;
+ } else if (edited == Telephony.Carriers.CARRIER_DELETED) {
// CARRIER_DELETED_BUT_PRESENT_IN_XML indicates entry has been deleted
// by user but present in apn xml file.
- user_edited = Telephony.Carriers.CARRIER_DELETED_BUT_PRESENT_IN_XML;
+ edited = Telephony.Carriers.CARRIER_DELETED_BUT_PRESENT_IN_XML;
}
- mergedValues.put(Telephony.Carriers.EDITED, user_edited);
+ mergedValues.put(Telephony.Carriers.EDITED, edited);
}
- mergeFieldsAndUpdateDb(db, CARRIERS_TABLE, oldRow, row, mergedValues, false);
+ mergeFieldsAndUpdateDb(db, CARRIERS_TABLE, oldRow, row, mergedValues, false,
+ mContext);
- if (VDBG) log("dbh.insertAddingDefaults: old user_edited = " + old_user_edited
- + " new user_edited = " + user_edited);
+ if (VDBG) log("dbh.insertAddingDefaults: old edited = " + old_edited
+ + " new edited = " + edited);
oldRow.close();
}
}
}
- static public void mergeFieldsAndUpdateDb(SQLiteDatabase db, String table, Cursor oldRow,
+ public static void mergeFieldsAndUpdateDb(SQLiteDatabase db, String table, Cursor oldRow,
ContentValues newRow, ContentValues mergedValues,
- boolean useOld) {
+ boolean onUpgrade, Context context) {
if (newRow.containsKey(Telephony.Carriers.TYPE)) {
// Merge the types
String oldType = oldRow.getString(oldRow.getColumnIndex(Telephony.Carriers.TYPE));
String newType = newRow.getAsString(Telephony.Carriers.TYPE);
+
if (!oldType.equalsIgnoreCase(newType)) {
if (oldType.equals("") || newType.equals("")) {
newRow.put(Telephony.Carriers.TYPE, "");
} else {
- // Merge the 2 types
String[] oldTypes = oldType.toLowerCase().split(",");
String[] newTypes = newType.toLowerCase().split(",");
+
+ if (VDBG) {
+ log("mergeFieldsAndUpdateDb: Calling separateRowsNeeded() oldType=" +
+ oldType + " old bearer=" + oldRow.getInt(oldRow.getColumnIndex(
+ Telephony.Carriers.BEARER_BITMASK)) +
+ " old profile_id=" + oldRow.getInt(oldRow.getColumnIndex(
+ Telephony.Carriers.PROFILE_ID)) +
+ " newRow " + newRow);
+ }
+
+ // If separate rows are needed, do not need to merge any further
+ if (separateRowsNeeded(db, table, oldRow, newRow, context, oldTypes,
+ newTypes)) {
+ if (VDBG) log("mergeFieldsAndUpdateDb: separateRowsNeeded() returned " +
+ "true");
+ return;
+ }
+
+ // Merge the 2 types
ArrayList<String> mergedTypes = new ArrayList<String>();
mergedTypes.addAll(Arrays.asList(oldTypes));
for (String s : newTypes) {
@@ -807,7 +909,22 @@ public class TelephonyProvider extends ContentProvider
Telephony.Carriers.TYPE));
}
- if (!useOld) {
+ if (newRow.containsKey(Telephony.Carriers.BEARER_BITMASK)) {
+ int oldBearer = oldRow.getInt(oldRow.getColumnIndex(Telephony.Carriers.
+ BEARER_BITMASK));
+ int newBearer = newRow.getAsInteger(Telephony.Carriers.BEARER_BITMASK);
+ if (oldBearer != newBearer) {
+ if (oldBearer == 0 || newBearer == 0) {
+ newRow.put(Telephony.Carriers.BEARER_BITMASK, 0);
+ } else {
+ newRow.put(Telephony.Carriers.BEARER_BITMASK, (oldBearer | newBearer));
+ }
+ }
+ mergedValues.put(Telephony.Carriers.BEARER_BITMASK, newRow.getAsInteger(
+ Telephony.Carriers.BEARER_BITMASK));
+ }
+
+ if (!onUpgrade) {
mergedValues.putAll(newRow);
}
@@ -820,7 +937,110 @@ public class TelephonyProvider extends ContentProvider
}
}
- static public Cursor selectConflictingRow(SQLiteDatabase db, String table,
+ private static boolean separateRowsNeeded(SQLiteDatabase db, String table, Cursor oldRow,
+ ContentValues newRow, Context context,
+ String[] oldTypes, String[] newTypes) {
+ // If this APN falls under persist_apns_for_plmn, and the
+ // only difference between old type and new type is that one has dun, and
+ // the APNs have profile_id 0 or not set, then set the profile_id to 1 for
+ // the dun APN/remove dun from type. This will ensure both oldRow and newRow exist
+ // separately in db.
+
+ boolean match = false;
+
+ // Check if APN falls under persist_apns_for_plmn
+ String[] persistApnsForPlmns = context.getResources().getStringArray(
+ R.array.persist_apns_for_plmn);
+ for (String s : persistApnsForPlmns) {
+ if (s.equalsIgnoreCase(newRow.getAsString(Telephony.Carriers.
+ NUMERIC))) {
+ match = true;
+ break;
+ }
+ }
+
+ if (!match) return false;
+
+ // APN falls under persist_apns_for_plmn
+ // Check if only difference between old type and new type is that
+ // one has dun
+ ArrayList<String> oldTypesAl = new ArrayList<String>(
+ Arrays.asList(oldTypes));
+ ArrayList<String> newTypesAl = new ArrayList<String>(
+ Arrays.asList(newTypes));
+ ArrayList<String> listWithDun = null;
+ ArrayList<String> listWithoutDun = null;
+ boolean dunInOld = false;
+ if (oldTypesAl.size() == newTypesAl.size() + 1) {
+ listWithDun = oldTypesAl;
+ listWithoutDun = newTypesAl;
+ dunInOld = true;
+ } else if (oldTypesAl.size() + 1 == newTypesAl.size()) {
+ listWithDun = newTypesAl;
+ listWithoutDun = oldTypesAl;
+ } else {
+ return false;
+ }
+
+ if (listWithDun.contains("dun") &&
+ !listWithoutDun.contains("dun")) {
+ listWithoutDun.add("dun");
+ if (!listWithDun.containsAll(listWithoutDun)) {
+ return false;
+ }
+
+ // Only difference between old type and new type is that
+ // one has dun
+ // Check if profile_id is 0/not set
+ if (oldRow.getInt(oldRow.getColumnIndex(Telephony.Carriers.
+ PROFILE_ID)) == 0) {
+ if (dunInOld) {
+ // Update oldRow to remove dun from its type field
+ ContentValues updateOldRow = new ContentValues();
+ StringBuilder sb = new StringBuilder();
+ boolean first = true;
+ for (String s : listWithDun) {
+ if (!s.equalsIgnoreCase("dun")) {
+ sb.append(first ? s : "," + s);
+ first = false;
+ }
+ }
+ String updatedType = sb.toString();
+ if (VDBG) {
+ log("separateRowsNeeded: updating type in oldRow to " +
+ updatedType);
+ }
+ updateOldRow.put(Telephony.Carriers.TYPE, updatedType);
+ db.update(table, updateOldRow,
+ "_id=" + oldRow.getInt(oldRow.getColumnIndex("_id")), null);
+ return true;
+ } else {
+ if (VDBG) log("separateRowsNeeded: adding profile id 1 to newRow");
+ // Update newRow to set profile_id to 1
+ newRow.put(Telephony.Carriers.PROFILE_ID,
+ new Integer(1));
+ }
+ } else {
+ return false;
+ }
+
+ // If match was found, both oldRow and newRow need to exist
+ // separately in db. Add newRow to db.
+ try {
+ db.insertWithOnConflict(table, null, newRow,
+ SQLiteDatabase.CONFLICT_REPLACE);
+ if (VDBG) log("separateRowsNeeded: added newRow with profile id 1 to db");
+ return true;
+ } catch (SQLException e) {
+ loge("Exception on trying to add new row after " +
+ "updating profile_id");
+ }
+ }
+
+ return false;
+ }
+
+ public static Cursor selectConflictingRow(SQLiteDatabase db, String table,
ContentValues row) {
// Conflict is possible only when numeric, mcc, mnc (fields without any default value)
// are set in the new row
@@ -831,7 +1051,11 @@ public class TelephonyProvider extends ContentProvider
return null;
}
- String[] columns = { "_id", Telephony.Carriers.TYPE, Telephony.Carriers.EDITED };
+ String[] columns = { "_id",
+ Telephony.Carriers.TYPE,
+ Telephony.Carriers.EDITED,
+ Telephony.Carriers.BEARER_BITMASK,
+ Telephony.Carriers.PROFILE_ID };
String selection = "numeric=? AND mcc=? AND mnc=? AND apn=? AND proxy=? AND port=? "
+ "AND mmsproxy=? AND mmsport=? AND mmsc=? AND carrier_enabled=? AND bearer=? "
+ "AND mvno_type=? AND mvno_match_data=? AND profile_id=?";
@@ -1077,9 +1301,9 @@ public class TelephonyProvider extends ContentProvider
} else {
selection += " and ";
}
- selection += "user_edited!=" + Telephony.Carriers.USER_DELETED + " and user_edited!="
- + Telephony.Carriers.USER_DELETED_BUT_PRESENT_IN_XML + " and user_edited!="
- + Telephony.Carriers.CARRIER_DELETED + " and user_edited!="
+ selection += "edited!=" + Telephony.Carriers.USER_DELETED + " and edited!="
+ + Telephony.Carriers.USER_DELETED_BUT_PRESENT_IN_XML + " and edited!="
+ + Telephony.Carriers.CARRIER_DELETED + " and edited!="
+ Telephony.Carriers.CARRIER_DELETED_BUT_PRESENT_IN_XML;
if (VDBG) log("query: selection modified to " + selection);
}
@@ -1155,9 +1379,9 @@ public class TelephonyProvider extends ContentProvider
}
try {
- // Replace on conflict so that if same APN is present in db with user_edited
+ // Replace on conflict so that if same APN is present in db with edited
// as Telephony.Carriers.UNEDITED or USER/CARRIER_DELETED, it is replaced with
- // user_edited USER/CARRIER_EDITED
+ // edited USER/CARRIER_EDITED
long rowID = db.insertWithOnConflict(CARRIERS_TABLE, null, values,
SQLiteDatabase.CONFLICT_REPLACE);
if (rowID >= 0) {
@@ -1173,7 +1397,7 @@ public class TelephonyProvider extends ContentProvider
if (oldRow != null) {
ContentValues mergedValues = new ContentValues();
DatabaseHelper.mergeFieldsAndUpdateDb(db, CARRIERS_TABLE, oldRow, values,
- mergedValues, false);
+ mergedValues, false, getContext());
oldRow.close();
notify = true;
}
@@ -1414,9 +1638,9 @@ public class TelephonyProvider extends ContentProvider
values.put(Telephony.Carriers.EDITED, Telephony.Carriers.USER_EDITED);
}
- // Replace on conflict so that if same APN is present in db with user_edited
+ // Replace on conflict so that if same APN is present in db with edited
// as Telephony.Carriers.UNEDITED or USER/CARRIER_DELETED, it is replaced with
- // user_edited USER/CARRIER_EDITED
+ // edited USER/CARRIER_EDITED
count = db.updateWithOnConflict(CARRIERS_TABLE, values, where, whereArgs,
SQLiteDatabase.CONFLICT_REPLACE);
break;
@@ -1441,9 +1665,9 @@ public class TelephonyProvider extends ContentProvider
if (!values.containsKey(Telephony.Carriers.EDITED)) {
values.put(Telephony.Carriers.EDITED, Telephony.Carriers.USER_EDITED);
}
- // Replace on conflict so that if same APN is present in db with user_edited
+ // Replace on conflict so that if same APN is present in db with edited
// as Telephony.Carriers.UNEDITED or USER/CARRIER_DELETED, it is replaced with
- // user_edited USER/CARRIER_EDITED
+ // edited USER/CARRIER_EDITED
count = db.updateWithOnConflict(CARRIERS_TABLE, values, where, whereArgs,
SQLiteDatabase.CONFLICT_REPLACE);
break;
@@ -1458,9 +1682,9 @@ public class TelephonyProvider extends ContentProvider
if (!values.containsKey(Telephony.Carriers.EDITED)) {
values.put(Telephony.Carriers.EDITED, Telephony.Carriers.USER_EDITED);
}
- // Replace on conflict so that if same APN is present in db with user_edited
+ // Replace on conflict so that if same APN is present in db with edited
// as Telephony.Carriers.UNEDITED or USER/CARRIER_DELETED, it is replaced with
- // user_edited USER/CARRIER_EDITED
+ // edited USER/CARRIER_EDITED
count = db.updateWithOnConflict(CARRIERS_TABLE, values,
Telephony.Carriers._ID + "=?", new String[] { url.getLastPathSegment() },
SQLiteDatabase.CONFLICT_REPLACE);
@@ -1564,8 +1788,8 @@ public class TelephonyProvider extends ContentProvider
// Delete entries in db
try {
- if (VDBG) log("updateApnDb: deleting user_edited=Telephony.Carriers.UNEDITED entries");
- db.delete(CARRIERS_TABLE, "user_edited=" + Telephony.Carriers.UNEDITED, null);
+ if (VDBG) log("updateApnDb: deleting edited=Telephony.Carriers.UNEDITED entries");
+ db.delete(CARRIERS_TABLE, "edited=" + Telephony.Carriers.UNEDITED, null);
} catch (SQLException e) {
loge("got exception when deleting to update: " + e);
}