Merge "support carrierid provider update from OTA"
diff --git a/src/com/android/providers/telephony/CarrierIdProvider.java b/src/com/android/providers/telephony/CarrierIdProvider.java
index 91fdf21..7acea68 100644
--- a/src/com/android/providers/telephony/CarrierIdProvider.java
+++ b/src/com/android/providers/telephony/CarrierIdProvider.java
@@ -21,13 +21,13 @@
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
+import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
-import android.os.FileUtils;
-import android.os.UserHandle;
+import android.os.Environment;
import android.provider.Telephony.CarrierIdentification;
import android.text.TextUtils;
import android.util.Log;
@@ -38,11 +38,8 @@
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -73,9 +70,13 @@
private static final int DATABASE_VERSION = 3;
private static final String ASSETS_PB_FILE = "carrier_list.pb";
- private static final String ASSETS_FILE_CHECKSUM_PREF_KEY = "assets_checksum";
+ private static final String VERSION_PREF_KEY = "version";
+ private static final String OTA_UPDATED_PB_PATH = "misc/carrierid/" + ASSETS_PB_FILE;
private static final String PREF_FILE = CarrierIdProvider.class.getSimpleName();
+ private static final UriMatcher s_urlMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+ private static final int URL_UPDATE_FROM_PB = 1;
+
/**
* index 0: {@link CarrierIdentification#MCCMNC}
*/
@@ -160,7 +161,8 @@
Log.d(TAG, "onCreate");
mDbHelper = new CarrierIdDatabaseHelper(getContext());
mDbHelper.getReadableDatabase();
- updateFromAssetsIfNeeded(mDbHelper.getWritableDatabase());
+ s_urlMatcher.addURI(AUTHORITY, "update_db", URL_UPDATE_FROM_PB);
+ initDatabaseFromPb(mDbHelper.getWritableDatabase());
return true;
}
@@ -224,13 +226,21 @@
+ " selection=" + selection
+ " selectionArgs=" + Arrays.toString(selectionArgs));
}
- final int count = getWritableDatabase().update(CARRIER_ID_TABLE, values, selection,
- selectionArgs);
- Log.d(TAG, " update.count=" + count);
- if (count > 0) {
- getContext().getContentResolver().notifyChange(CarrierIdentification.CONTENT_URI, null);
+
+ final int match = s_urlMatcher.match(uri);
+ switch (match) {
+ case URL_UPDATE_FROM_PB:
+ return initDatabaseFromPb(getWritableDatabase());
+ default:
+ final int count = getWritableDatabase().update(CARRIER_ID_TABLE, values, selection,
+ selectionArgs);
+ Log.d(TAG, " update.count=" + count);
+ if (count > 0) {
+ getContext().getContentResolver().notifyChange(
+ CarrierIdentification.CONTENT_URI, null);
+ }
+ return count;
}
- return count;
}
/**
@@ -282,74 +292,40 @@
}
/**
- * use check sum to detect assets file update.
- * update database with data from assets only if checksum has been changed
- * and OTA update is unavailable.
+ * Parse and persist pb file as database default values.
+ * Use version number to detect file update.
+ * Update database with data from assets or ota only if version jumps.
*/
- private void updateFromAssetsIfNeeded(SQLiteDatabase db) {
- //TODO skip update from assets if OTA update is available.
- final File assets;
- OutputStream outputStream = null;
- InputStream inputStream = null;
- try {
- // create a temp file to compute check sum.
- assets = new File(getContext().getCacheDir(), ASSETS_PB_FILE);
- outputStream = new FileOutputStream(assets);
- inputStream = getContext().getAssets().open(ASSETS_PB_FILE);
- outputStream.write(readInputStreamToByteArray(inputStream));
- } catch (IOException ex) {
- Log.e(TAG, "assets file not found: " + ex);
- return;
- } finally {
- IoUtils.closeQuietly(outputStream);
- IoUtils.closeQuietly(inputStream);
- }
- long checkSum = getChecksum(assets);
- if (checkSum != getAssetsChecksum()) {
- initDatabaseFromPb(assets, db);
- setAssetsChecksum(checkSum);
- }
- }
-
- /**
- * parse and persist pb file as database default values.
- */
- private void initDatabaseFromPb(File pb, SQLiteDatabase db) {
+ private int initDatabaseFromPb(SQLiteDatabase db) {
Log.d(TAG, "init database from pb file");
- InputStream inputStream = null;
- try {
- inputStream = new FileInputStream(pb);
- byte[] bytes = readInputStreamToByteArray(inputStream);
- CarrierIdProto.CarrierList carrierList = CarrierIdProto.CarrierList.parseFrom(bytes);
- List<ContentValues> cvs = new ArrayList<>();
- for (CarrierIdProto.CarrierId id : carrierList.carrierId) {
- for (CarrierIdProto.CarrierAttribute attr: id.carrierAttribute) {
- ContentValues cv = new ContentValues();
- cv.put(CarrierIdentification.CID, id.canonicalId);
- cv.put(CarrierIdentification.NAME, id.carrierName);
- convertCarrierAttrToContentValues(cv, cvs, attr, 0);
- }
+ int rows = 0;
+ CarrierIdProto.CarrierList carrierList = getUpdateCarrierList();
+ if (carrierList == null) return rows;
+ setAppliedVersion(carrierList.version);
+ List<ContentValues> cvs = new ArrayList<>();
+ for (CarrierIdProto.CarrierId id : carrierList.carrierId) {
+ for (CarrierIdProto.CarrierAttribute attr : id.carrierAttribute) {
+ ContentValues cv = new ContentValues();
+ cv.put(CarrierIdentification.CID, id.canonicalId);
+ cv.put(CarrierIdentification.NAME, id.carrierName);
+ convertCarrierAttrToContentValues(cv, cvs, attr, 0);
}
- db.delete(CARRIER_ID_TABLE, null, null);
- int rows = 0;
- for (ContentValues cv : cvs) {
- if (db.insertOrThrow(CARRIER_ID_TABLE, null, cv) > 0) rows++;
- }
- Log.d(TAG, "init database from pb. inserted rows = " + rows);
- if (rows > 0) {
- // Notify listener of DB change
- getContext().getContentResolver().notifyChange(CarrierIdentification.CONTENT_URI,
- null);
- }
- } catch (IOException ex) {
- Log.e(TAG, "init database from pb failure: " + ex);
- } finally {
- IoUtils.closeQuietly(inputStream);
}
+ db.delete(CARRIER_ID_TABLE, null, null);
+ for (ContentValues cv : cvs) {
+ if (db.insertOrThrow(CARRIER_ID_TABLE, null, cv) > 0) rows++;
+ }
+ Log.d(TAG, "init database from pb. inserted rows = " + rows);
+ if (rows > 0) {
+ // Notify listener of DB change
+ getContext().getContentResolver().notifyChange(CarrierIdentification.CONTENT_URI,
+ null);
+ }
+ return rows;
}
/**
- * recursively loop through carrier attribute list to get all combinations.
+ * Recursively loop through carrier attribute list to get all combinations.
*/
private void convertCarrierAttrToContentValues(ContentValues cv, List<ContentValues> cvs,
CarrierIdProto.CarrierAttribute attr, int index) {
@@ -358,7 +334,7 @@
return;
}
boolean found = false;
- switch(index) {
+ switch (index) {
case MCCMNC_INDEX:
for (String str : attr.mccmncTuple) {
cv.put(CarrierIdentification.MCCMNC, str);
@@ -417,10 +393,10 @@
break;
case ICCID_PREFIX_INDEX:
for (String str : attr.iccidPrefix) {
- cv.put(CarrierIdentification.ICCID_PREFIX, str);
- convertCarrierAttrToContentValues(cv, cvs, attr, index + 1);
- cv.remove(CarrierIdentification.ICCID_PREFIX);
- found = true;
+ cv.put(CarrierIdentification.ICCID_PREFIX, str);
+ convertCarrierAttrToContentValues(cv, cvs, attr, index + 1);
+ cv.remove(CarrierIdentification.ICCID_PREFIX);
+ found = true;
}
break;
default:
@@ -434,7 +410,62 @@
}
/**
- * util function to convert inputStream to byte array before parsing proto data.
+ * Return the update carrierList.
+ * Get the latest version from the last applied, assets and ota file. if the latest version
+ * is newer than the last applied, update is required. Otherwise no update is required and
+ * the returned carrierList will be null.
+ */
+ private CarrierIdProto.CarrierList getUpdateCarrierList() {
+ int version = getAppliedVersion();
+ CarrierIdProto.CarrierList carrierList = null;
+ CarrierIdProto.CarrierList assets = null;
+ CarrierIdProto.CarrierList ota = null;
+ InputStream is = null;
+
+ try {
+ is = getContext().getAssets().open(ASSETS_PB_FILE);
+ assets = CarrierIdProto.CarrierList.parseFrom(readInputStreamToByteArray(is));
+ } catch (IOException ex) {
+ Log.e(TAG, "read carrier list from assets pb failure: " + ex);
+ } finally {
+ IoUtils.closeQuietly(is);
+ }
+ try {
+ is = new FileInputStream(new File(Environment.getDataDirectory(), OTA_UPDATED_PB_PATH));
+ ota = CarrierIdProto.CarrierList.parseFrom(readInputStreamToByteArray(is));
+ } catch (IOException ex) {
+ Log.e(TAG, "read carrier list from ota pb failure: " + ex);
+ } finally {
+ IoUtils.closeQuietly(is);
+ }
+
+ // compare version
+ if (assets != null && assets.version > version) {
+ carrierList = assets;
+ version = assets.version;
+ }
+ if (ota != null && ota.version > version) {
+ carrierList = ota;
+ version = ota.version;
+ }
+ Log.d(TAG, "latest version: " + version + " need update: " + (carrierList != null));
+ return carrierList;
+ }
+
+ private int getAppliedVersion() {
+ final SharedPreferences sp = getContext().getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE);
+ return sp.getInt(VERSION_PREF_KEY, -1);
+ }
+
+ private void setAppliedVersion(int version) {
+ final SharedPreferences sp = getContext().getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sp.edit();
+ editor.putInt(VERSION_PREF_KEY, version);
+ editor.apply();
+ }
+
+ /**
+ * Util function to convert inputStream to byte array before parsing proto data.
*/
private static byte[] readInputStreamToByteArray(InputStream inputStream) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
@@ -447,32 +478,4 @@
buffer.flush();
return buffer.toByteArray();
}
-
- /**
- * util function to calculate checksum of a file
- */
- private long getChecksum(File file) {
- long checksum = -1;
- try {
- checksum = FileUtils.checksumCrc32(file);
- if (VDBG) Log.d(TAG, "Checksum for " + file.getAbsolutePath() + " is " + checksum);
- } catch (FileNotFoundException e) {
- Log.e(TAG, "FileNotFoundException for " + file.getAbsolutePath() + ":" + e);
- } catch (IOException e) {
- Log.e(TAG, "IOException for " + file.getAbsolutePath() + ":" + e);
- }
- return checksum;
- }
-
- private long getAssetsChecksum() {
- SharedPreferences sp = getContext().getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE);
- return sp.getLong(ASSETS_FILE_CHECKSUM_PREF_KEY, -1);
- }
-
- private void setAssetsChecksum(long checksum) {
- SharedPreferences sp = getContext().getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE);
- SharedPreferences.Editor editor = sp.edit();
- editor.putLong(ASSETS_FILE_CHECKSUM_PREF_KEY, checksum);
- editor.apply();
- }
}
\ No newline at end of file