release-request-8325b49d-08a0-4f74-8369-14adb3ef880c-for-git_oc-mr1-release-4042783 snap-temp-L88300000067732062

Change-Id: I7a27facb53d00db8381a34983b560696436fa4c0
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 1ca6c9a..5ac7fab 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -91,6 +91,13 @@
                   android:singleUser="true"
                   android:readPermission="android.permission.READ_SMS" />
 
+        <provider android:name="CarrierProvider"
+                  android:authorities="carrier_information"
+                  android:exported="true"
+                  android:singleUser="true"
+                  android:multiprocess="false"
+                  android:writePermission="android.permission.MODIFY_PHONE_STATE" />
+
         <provider android:name="HbpcdLookupProvider"
                   android:authorities="hbpcd_lookup"
                   android:exported="true"
diff --git a/src/com/android/providers/telephony/CarrierDatabaseHelper.java b/src/com/android/providers/telephony/CarrierDatabaseHelper.java
new file mode 100644
index 0000000..5236b89
--- /dev/null
+++ b/src/com/android/providers/telephony/CarrierDatabaseHelper.java
@@ -0,0 +1,85 @@
+/*
+**
+** Copyright (C) 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package com.android.providers.telephony;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.text.TextUtils;
+import java.util.ArrayList;
+import java.util.List;
+
+public class CarrierDatabaseHelper extends SQLiteOpenHelper {
+    private static final String TAG = "CarrierDatabaseHelper";
+    private static final boolean DBG = true;
+
+    private static final String DATABASE_NAME = "CarrierInformation.db";
+    public static final String CARRIER_KEY_TABLE = "carrier_key";
+    private static final int DATABASE_VERSION = 1;
+
+    /**
+     * CarrierDatabaseHelper carrier database helper class.
+     * @param context of the user.
+     */
+    public CarrierDatabaseHelper(Context context) {
+        super(context, DATABASE_NAME, null, DATABASE_VERSION);
+    }
+
+    static final String KEY_TYPE = "key_type";
+    static final String KEY = "key";
+    static final String MCC = "mcc";
+    static final String MNC = "mnc";
+    static final String MVNO_TYPE = "mvno_type";
+    static final String MVNO_MATCH_DATA = "mvno_match_data";
+    static final String PUBLIC_CERTIFICATE = "public_certificate";
+    static final String LAST_MODIFIED = "last_modified";
+
+    private static final List<String> CARRIERS_UNIQUE_FIELDS = new ArrayList<String>();
+
+    static {
+        CARRIERS_UNIQUE_FIELDS.add(MCC);
+        CARRIERS_UNIQUE_FIELDS.add(MNC);
+        CARRIERS_UNIQUE_FIELDS.add(KEY_TYPE);
+        CARRIERS_UNIQUE_FIELDS.add(MVNO_TYPE);
+        CARRIERS_UNIQUE_FIELDS.add(MVNO_MATCH_DATA);
+    }
+
+    public static String getStringForCarrierKeyTableCreation(String tableName) {
+        return "CREATE TABLE " + tableName +
+                "(_id INTEGER PRIMARY KEY," +
+                MCC + " TEXT DEFAULT ''," +
+                MNC + " TEXT DEFAULT ''," +
+                MVNO_TYPE + " TEXT DEFAULT ''," +
+                MVNO_MATCH_DATA + " TEXT DEFAULT ''," +
+                KEY_TYPE + " TEXT DEFAULT ''," +
+                KEY + " TEXT DEFAULT ''," +
+                PUBLIC_CERTIFICATE + " TEXT DEFAULT ''," +
+                LAST_MODIFIED + " INTEGER DEFAULT 0," +
+                "UNIQUE (" + TextUtils.join(", ", CARRIERS_UNIQUE_FIELDS) + "));";
+    }
+
+    @Override
+    public void onCreate(SQLiteDatabase db) {
+        db.execSQL(getStringForCarrierKeyTableCreation(CARRIER_KEY_TABLE));
+    }
+
+    @Override
+    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+        // do nothing
+    }
+}
diff --git a/src/com/android/providers/telephony/CarrierProvider.java b/src/com/android/providers/telephony/CarrierProvider.java
new file mode 100644
index 0000000..1c85806
--- /dev/null
+++ b/src/com/android/providers/telephony/CarrierProvider.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.providers.telephony;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.net.Uri;
+import android.util.Log;
+
+import android.content.ContentUris;
+import android.database.SQLException;
+
+import java.util.Arrays;
+
+/**
+ * The class to provide base facility to access Carrier related content,
+ * which is stored in a SQLite database.
+ */
+public class CarrierProvider extends ContentProvider {
+
+    private static final boolean VDBG = false; // STOPSHIP if true
+    private static final String TAG = "CarrierProvider";
+
+    private CarrierDatabaseHelper mDbHelper;
+    private SQLiteDatabase mDatabase;
+
+    static final String PROVIDER_NAME = "carrier_information";
+    static final String URL = "content://" + PROVIDER_NAME + "/carrier";
+    static final Uri CONTENT_URI = Uri.parse(URL);
+
+    @Override
+    public boolean onCreate() {
+        Log.d(TAG, "onCreate");
+        mDbHelper = new CarrierDatabaseHelper(getContext());
+        return (mDatabase == null ? false : true);
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        return null;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projectionIn, String selection,
+                        String[] selectionArgs, String sortOrder) {
+        if (VDBG) {
+            Log.d(TAG, "query:"
+                    + " uri=" + uri
+                    + " values=" + Arrays.toString(projectionIn)
+                    + " selection=" + selection
+                    + " selectionArgs=" + Arrays.toString(selectionArgs));
+        }
+        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+        qb.setTables(CarrierDatabaseHelper.CARRIER_KEY_TABLE);
+
+        SQLiteDatabase db = getReadableDatabase();
+        Cursor c = qb.query(db, projectionIn, selection, selectionArgs, null, null, sortOrder);
+        return c;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        values.put(CarrierDatabaseHelper.LAST_MODIFIED, System.currentTimeMillis());
+        long row = getWritableDatabase().insert(CarrierDatabaseHelper.CARRIER_KEY_TABLE,
+                null, values);
+        if (row > 0) {
+            Uri newUri = ContentUris.withAppendedId(CONTENT_URI, row);
+            getContext().getContentResolver().notifyChange(newUri, null);
+            return newUri;
+        }
+        throw new SQLException("Fail to add a new record into " + uri);
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException("Cannot delete URL: " + uri);
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+
+        if (VDBG) {
+            Log.d(TAG, "update:"
+                    + " uri=" + uri
+                    + " values={" + values + "}"
+                    + " selection=" + selection
+                    + " selectionArgs=" + Arrays.toString(selectionArgs));
+        }
+        final int count = getWritableDatabase().update(CarrierDatabaseHelper.CARRIER_KEY_TABLE,
+                values, selection, selectionArgs);
+        Log.d(TAG, "  update.count=" + count);
+        return count;
+    }
+
+    /**
+     * These methods can be overridden in a subclass for testing TelephonyProvider using an
+     * in-memory database.
+     */
+    SQLiteDatabase getReadableDatabase() {
+        return mDbHelper.getReadableDatabase();
+    }
+    SQLiteDatabase getWritableDatabase() {
+        return mDbHelper.getWritableDatabase();
+    }
+}
diff --git a/tests/src/com/android/providers/telephony/CarrierProviderTest.java b/tests/src/com/android/providers/telephony/CarrierProviderTest.java
new file mode 100644
index 0000000..6a56343
--- /dev/null
+++ b/tests/src/com/android/providers/telephony/CarrierProviderTest.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.providers.telephony;
+
+import android.content.ContentValues;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.test.mock.MockContentResolver;
+import android.test.mock.MockContext;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.providers.telephony.CarrierProvider;
+
+import junit.framework.TestCase;
+
+import org.junit.Test;
+
+
+/**
+ * Tests for testing CRUD operations of CarrierProvider.
+ * Uses TelephonyProviderTestable to set up in-memory database
+ *
+ * Build, install and run the tests by running the commands below:
+ *     runtest --path <dir or file>
+ *     runtest --path <dir or file> --test-method <testMethodName>
+ *     e.g.)
+ *         runtest --path tests/src/com/android/providers/telephony/CarrierProviderTest.java \
+ *                 --test-method testInsertCarriers
+ */
+public class CarrierProviderTest extends TestCase {
+
+    private static final String TAG = "CarrierProviderTest";
+
+    private MockContextWithProvider mContext;
+    private MockContentResolver mContentResolver;
+    private CarrierProviderTestable mCarrierProviderTestable;
+
+    public static final String dummy_type = "TYPE5";
+    public static final String dummy_mnc = "MNC001";
+    public static final String dummy_mnc2 = "MNC002";
+    public static final String dummy_mcc = "MCC005";
+    public static final String dummy_key1 = "PUBKEY1";
+    public static final String dummy_key2 = "PUBKEY2";
+    public static final String dummy_mvno_type = "100";
+    public static final String dummy_mvno_match_data = "101";
+
+
+    /**
+     * This is used to give the CarrierProviderTest a mocked context which takes a
+     * CarrierProvider and attaches it to the ContentResolver.
+     */
+    private class MockContextWithProvider extends MockContext {
+        private final MockContentResolver mResolver;
+
+        public MockContextWithProvider(CarrierProvider carrierProvider) {
+            mResolver = new MockContentResolver();
+
+            ProviderInfo providerInfo = new ProviderInfo();
+            providerInfo.authority = CarrierProvider.PROVIDER_NAME;
+
+            // Add context to given telephonyProvider
+            carrierProvider.attachInfoForTesting(this, providerInfo);
+            Log.d(TAG, "MockContextWithProvider: carrierProvider.getContext(): "
+                    + carrierProvider.getContext());
+
+            // Add given telephonyProvider to mResolver, so that mResolver can send queries
+            // to the provider.
+            mResolver.addProvider(CarrierProvider.PROVIDER_NAME, carrierProvider);
+            Log.d(TAG, "MockContextWithProvider: Add carrierProvider to mResolver");
+        }
+
+        @Override
+        public Object getSystemService(String name) {
+            Log.d(TAG, "getSystemService: returning null");
+            return null;
+        }
+
+        @Override
+        public Resources getResources() {
+            Log.d(TAG, "getResources: returning null");
+            return null;
+        }
+
+        @Override
+        public MockContentResolver getContentResolver() {
+            return mResolver;
+        }
+
+        // Gives permission to write to the APN table within the MockContext
+        @Override
+        public int checkCallingOrSelfPermission(String permission) {
+            if (TextUtils.equals(permission, "android.permission.WRITE_APN_SETTINGS")) {
+                Log.d(TAG, "checkCallingOrSelfPermission: permission=" + permission
+                        + ", returning PackageManager.PERMISSION_GRANTED");
+                return PackageManager.PERMISSION_GRANTED;
+            } else {
+                Log.d(TAG, "checkCallingOrSelfPermission: permission=" + permission
+                        + ", returning PackageManager.PERMISSION_DENIED");
+                return PackageManager.PERMISSION_DENIED;
+            }
+        }
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mCarrierProviderTestable = new CarrierProviderTestable();
+        mContext = new MockContextWithProvider(mCarrierProviderTestable);
+        mContentResolver = (MockContentResolver) mContext.getContentResolver();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mCarrierProviderTestable.closeDatabase();
+    }
+
+    /**
+     * Test inserting values in carrier key table.
+     */
+    @Test
+    @SmallTest
+    public void testInsertCertificates() {
+        int count = -1;
+        ContentValues contentValues = new ContentValues();
+        contentValues.put(CarrierDatabaseHelper.KEY_TYPE, dummy_type);
+        contentValues.put(CarrierDatabaseHelper.MCC, dummy_mcc);
+        contentValues.put(CarrierDatabaseHelper.MNC, dummy_mnc);
+        contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, dummy_mvno_type);
+        contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, dummy_mvno_match_data);
+        contentValues.put(CarrierDatabaseHelper.PUBLIC_CERTIFICATE, dummy_key1);
+
+        try {
+            mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
+        } catch (Exception e) {
+            Log.d(TAG, "Error inserting certificates:" + e);
+        }
+        try {
+            Cursor countCursor = mContentResolver.query(CarrierProvider.CONTENT_URI,
+                    new String[]{"count(*) AS count"},
+                    null,
+                    null,
+                    null);
+            countCursor.moveToFirst();
+            count = countCursor.getInt(0);
+        } catch (Exception e) {
+            Log.d(TAG, "Exception in getting count:" + e);
+        }
+        assertEquals(1, count);
+    }
+
+    /**
+     * Test update & query.
+     */
+    @Test
+    @SmallTest
+    public void testUpdateCertificates() {
+        String key = null;
+        ContentValues contentValues = new ContentValues();
+        contentValues.put(CarrierDatabaseHelper.KEY_TYPE, dummy_type);
+        contentValues.put(CarrierDatabaseHelper.MCC, dummy_mcc);
+        contentValues.put(CarrierDatabaseHelper.MNC, dummy_mnc);
+        contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, dummy_mvno_type);
+        contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, dummy_mvno_match_data);
+        contentValues.put(CarrierDatabaseHelper.PUBLIC_CERTIFICATE, dummy_key1);
+
+        try {
+            mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
+        } catch (Exception e) {
+            Log.d(TAG, "Error inserting certificates:" + e);
+        }
+
+        try {
+            ContentValues updatedValues = new ContentValues();
+            updatedValues.put(CarrierDatabaseHelper.PUBLIC_CERTIFICATE, dummy_key2);
+            mContentResolver.update(CarrierProvider.CONTENT_URI, updatedValues,
+                    "mcc=? and mnc=? and key_type=?", new String[] { dummy_mcc, dummy_mnc, dummy_type });
+        } catch (Exception e) {
+            Log.d(TAG, "Error updating values:" + e);
+        }
+
+        try {
+            String[] columns ={CarrierDatabaseHelper.PUBLIC_CERTIFICATE};
+            Cursor findEntry = mContentResolver.query(CarrierProvider.CONTENT_URI, columns,
+                    "mcc=? and mnc=? and key_type=?",
+                    new String[] { dummy_mcc, dummy_mnc, dummy_type }, null);
+            findEntry.moveToFirst();
+            key = findEntry.getString(0);
+        } catch (Exception e) {
+            Log.d(TAG, "Query failed:" + e);
+        }
+        assertEquals(key, dummy_key2);
+    }
+
+    /**
+     * Test inserting multiple certs
+     */
+    @Test
+    @SmallTest
+    public void testMultipleCertificates() {
+        int count = -1;
+        ContentValues contentValues = new ContentValues();
+        contentValues.put(CarrierDatabaseHelper.KEY_TYPE, dummy_type);
+        contentValues.put(CarrierDatabaseHelper.MCC, dummy_mcc);
+        contentValues.put(CarrierDatabaseHelper.MNC, dummy_mnc);
+        contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, dummy_mvno_type);
+        contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, dummy_mvno_match_data);
+        contentValues.put(CarrierDatabaseHelper.PUBLIC_CERTIFICATE, dummy_key1);
+
+        ContentValues contentValuesNew = new ContentValues();
+        contentValuesNew.put(CarrierDatabaseHelper.KEY_TYPE, dummy_type);
+        contentValuesNew.put(CarrierDatabaseHelper.MCC, dummy_mcc);
+        contentValuesNew.put(CarrierDatabaseHelper.MNC, dummy_mnc2);
+        contentValuesNew.put(CarrierDatabaseHelper.MVNO_TYPE, dummy_mvno_type);
+        contentValuesNew.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, dummy_mvno_match_data);
+        contentValuesNew.put(CarrierDatabaseHelper.PUBLIC_CERTIFICATE, dummy_key2);
+
+        try {
+            mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
+            mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValuesNew);
+        } catch (Exception e) {
+            System.out.println("Error inserting certificates:: " + e);
+        }
+
+        try {
+            Cursor countCursor = mContentResolver.query(CarrierProvider.CONTENT_URI,
+                    new String[]{"count(*) AS count"},
+                    null,
+                    null,
+                    null);
+            countCursor.moveToFirst();
+            count = countCursor.getInt(0);
+        } catch (Exception e) {
+            Log.d(TAG, "Exception in getting count:" + e);
+        }
+        assertEquals(2, count);
+    }
+
+    /**
+     * Test inserting duplicate values in carrier key table. Ensure that a SQLException is thrown.
+     */
+    @Test(expected = SQLException.class)
+    public void testDuplicateFailure() {
+        ContentValues contentValues = new ContentValues();
+        contentValues.put(CarrierDatabaseHelper.KEY_TYPE, dummy_type);
+        contentValues.put(CarrierDatabaseHelper.MCC, dummy_mcc);
+        contentValues.put(CarrierDatabaseHelper.MNC, dummy_mnc);
+        contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, dummy_mvno_type);
+        contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, dummy_mvno_match_data);
+        contentValues.put(CarrierDatabaseHelper.PUBLIC_CERTIFICATE, dummy_key1);
+
+        try {
+            mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
+        } catch (Exception e) {
+            Log.d(TAG, "Error inserting certificates:: " + e);
+        }
+        try {
+            mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
+        } catch (Exception e) {
+            Log.d(TAG, "Error inserting certificates:: " + e);
+        }
+    }
+}
diff --git a/tests/src/com/android/providers/telephony/CarrierProviderTestable.java b/tests/src/com/android/providers/telephony/CarrierProviderTestable.java
new file mode 100644
index 0000000..87d6c5f
--- /dev/null
+++ b/tests/src/com/android/providers/telephony/CarrierProviderTestable.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.providers.telephony;
+
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
+
+import com.android.providers.telephony.CarrierProvider;
+import static com.android.providers.telephony.CarrierDatabaseHelper.*;
+
+/**
+ * A subclass of TelephonyProvider used for testing on an in-memory database
+ */
+public class CarrierProviderTestable extends CarrierProvider {
+    private static final String TAG = "CarrierProviderTestable";
+
+    private InMemoryCarrierProviderDbHelper mDbHelper;
+
+    @Override
+    public boolean onCreate() {
+        Log.d(TAG, "onCreate called: mDbHelper = new InMemoryCarrierProviderDbHelper()");
+        mDbHelper = new InMemoryCarrierProviderDbHelper();
+        return true;
+    }
+
+    // close mDbHelper database object
+    protected void closeDatabase() {
+        mDbHelper.close();
+    }
+
+    @Override
+    SQLiteDatabase getReadableDatabase() {
+        Log.d(TAG, "getReadableDatabase called" + mDbHelper.getReadableDatabase());
+        return mDbHelper.getReadableDatabase();
+    }
+
+    @Override
+    SQLiteDatabase getWritableDatabase() {
+        Log.d(TAG, "getWritableDatabase called" + mDbHelper.getWritableDatabase());
+        return mDbHelper.getWritableDatabase();
+    }
+
+    /**
+     * An in memory DB for CarrierProviderTestable to use
+     */
+    public static class InMemoryCarrierProviderDbHelper extends SQLiteOpenHelper {
+
+
+        public InMemoryCarrierProviderDbHelper() {
+            super(null,      // no context is needed for in-memory db
+                    null,    // db file name is null for in-memory db
+                    null,    // CursorFactory is null by default
+                    1);      // db version is no-op for tests
+            Log.d(TAG, "InMemoryCarrierProviderDbHelper creating in-memory database");
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+
+            //set up the Carrier key table
+            Log.d(TAG, "InMemoryCarrierProviderDbHelper onCreate creating the carrier key table");
+            db.execSQL(getStringForCarrierKeyTableCreation(CARRIER_KEY_TABLE));
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            Log.d(TAG, "InMemoryCarrierProviderDbHelper onUpgrade doing nothing");
+            return;
+        }
+    }
+}