diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 4a56852..10ea098 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -99,6 +99,13 @@
                   android:multiprocess="false"
                   android:writePermission="android.permission.MODIFY_PHONE_STATE" />
 
+        <provider android:name="CellBroadcastProvider"
+                  android:authorities="cellbroadcasts"
+                  android:exported="true"
+                  android:singleUser="true"
+                  android:multiprocess="false"
+                  android:readPermission="android.permission.READ_CELL_BROADCASTS" />
+
         <provider android:name="HbpcdLookupProvider"
                   android:authorities="hbpcd_lookup"
                   android:exported="true"
diff --git a/src/com/android/providers/telephony/CellBroadcastProvider.java b/src/com/android/providers/telephony/CellBroadcastProvider.java
new file mode 100644
index 0000000..3c6c51c
--- /dev/null
+++ b/src/com/android/providers/telephony/CellBroadcastProvider.java
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2019 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.app.AppOpsManager;
+import android.content.ContentProvider;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Process;
+import android.provider.Telephony.CellBroadcasts;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Arrays;
+
+/**
+ * The content provider that provides access of cell broadcast message to application.
+ * Permission {@link android.permission.READ_CELL_BROADCASTS} is required for querying the cell
+ * broadcast message. Only phone process has the permission to write/update the database via this
+ * provider.
+ */
+public class CellBroadcastProvider extends ContentProvider {
+    /** Interface for read/write permission check. */
+    public interface PermissionChecker {
+        /** Return {@code True} if the caller has the permission to write/update the database. */
+        boolean hasWritePermission();
+
+        /** Return {@code True} if the caller has the permission to query the database. */
+        boolean hasReadPermission();
+    }
+
+    private static final String TAG = CellBroadcastProvider.class.getSimpleName();
+
+    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
+
+    /** Database name. */
+    private static final String DATABASE_NAME = "cellbroadcasts.db";
+
+    /** Database version. */
+    private static final int DATABASE_VERSION = 1;
+
+    /** URI matcher for ContentProvider queries. */
+    private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+
+    /** URI matcher type to get all cell broadcasts. */
+    private static final int ALL = 0;
+
+    /** MIME type for the list of all cell broadcasts. */
+    private static final String LIST_TYPE = "vnd.android.cursor.dir/cellbroadcast";
+
+    /** Table name of cell broadcast message. */
+    @VisibleForTesting
+    public static final String CELL_BROADCASTS_TABLE_NAME = "cell_broadcasts";
+
+    /** Authority string for content URIs. */
+    @VisibleForTesting
+    public static final String AUTHORITY = "cellbroadcasts";
+
+    @VisibleForTesting
+    public PermissionChecker mPermissionChecker;
+
+    /** The database helper for this content provider. */
+    @VisibleForTesting
+    public SQLiteOpenHelper mDbHelper;
+
+    static {
+        sUriMatcher.addURI(AUTHORITY, null, ALL);
+    }
+
+    public CellBroadcastProvider() {}
+
+    @VisibleForTesting
+    public CellBroadcastProvider(PermissionChecker permissionChecker) {
+        mPermissionChecker = permissionChecker;
+    }
+
+    @Override
+    public boolean onCreate() {
+        mDbHelper = new CellBroadcastDatabaseHelper(getContext());
+        mPermissionChecker = new CellBroadcastPermissionChecker();
+        setAppOps(AppOpsManager.OP_READ_CELL_BROADCASTS, AppOpsManager.OP_NONE);
+        return true;
+    }
+
+    /**
+     * Return the MIME type of the data at the specified URI.
+     *
+     * @param uri the URI to query.
+     * @return a MIME type string, or null if there is no type.
+     */
+    @Override
+    public String getType(Uri uri) {
+        int match = sUriMatcher.match(uri);
+        switch (match) {
+            case ALL:
+                return LIST_TYPE;
+            default:
+                return null;
+        }
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        checkReadPermission();
+
+        if (DBG) {
+            Log.d(TAG, "query:"
+                    + " uri = " + uri
+                    + " projection = " + Arrays.toString(projection)
+                    + " selection = " + selection
+                    + " selectionArgs = " + Arrays.toString(selectionArgs)
+                    + " sortOrder = " + sortOrder);
+        }
+
+        String orderBy;
+        if (!TextUtils.isEmpty(sortOrder)) {
+            orderBy = sortOrder;
+        } else {
+            orderBy = CellBroadcasts.RECEIVED_TIME + " DESC";
+        }
+
+        int match = sUriMatcher.match(uri);
+        switch (match) {
+            case ALL:
+                return getReadableDatabase().query(
+                        CELL_BROADCASTS_TABLE_NAME, projection, selection, selectionArgs,
+                        null /* groupBy */, null /* having */, orderBy);
+            default:
+                throw new IllegalArgumentException(
+                        "Query method doesn't support this uri = " + uri);
+        }
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        checkWritePermission();
+
+        if (DBG) {
+            Log.d(TAG, "insert:"
+                    + " uri = " + uri
+                    + " contentValue = " + values);
+        }
+
+        switch (sUriMatcher.match(uri)) {
+            case ALL:
+                long row = getWritableDatabase().insertOrThrow(CELL_BROADCASTS_TABLE_NAME, null,
+                        values);
+                if (row > 0) {
+                    Uri newUri = ContentUris.withAppendedId(CellBroadcasts.CONTENT_URI, row);
+                    getContext().getContentResolver()
+                            .notifyChange(CellBroadcasts.CONTENT_URI, null /* observer */);
+                    return newUri;
+                } else {
+                    Log.e(TAG, "Insert record failed because of unknown reason, uri = " + uri);
+                    return null;
+                }
+            default:
+                throw new IllegalArgumentException(
+                        "Insert method doesn't support this uri = " + uri);
+        }
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        checkWritePermission();
+
+        if (DBG) {
+            Log.d(TAG, "delete:"
+                    + " uri = " + uri
+                    + " selection = " + selection
+                    + " selectionArgs = " + Arrays.toString(selectionArgs));
+        }
+
+        switch (sUriMatcher.match(uri)) {
+            case ALL:
+                return getWritableDatabase().delete(CELL_BROADCASTS_TABLE_NAME,
+                        selection, selectionArgs);
+            default:
+                throw new IllegalArgumentException(
+                        "Delete method doesn't support this uri = " + uri);
+        }
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        checkWritePermission();
+
+        if (DBG) {
+            Log.d(TAG, "update:"
+                    + " uri = " + uri
+                    + " values = {" + values + "}"
+                    + " selection = " + selection
+                    + " selectionArgs = " + Arrays.toString(selectionArgs));
+        }
+
+        switch (sUriMatcher.match(uri)) {
+            case ALL:
+                int rowCount = getWritableDatabase().update(
+                        CELL_BROADCASTS_TABLE_NAME,
+                        values,
+                        selection,
+                        selectionArgs);
+                if (rowCount > 0) {
+                    getContext().getContentResolver().notifyChange(uri, null /* observer */);
+                }
+                return rowCount;
+            default:
+                throw new IllegalArgumentException(
+                        "Update method doesn't support this uri = " + uri);
+        }
+    }
+
+    @VisibleForTesting
+    public static String getStringForCellBroadcastTableCreation(String tableName) {
+        return "CREATE TABLE " + tableName + " ("
+                + CellBroadcasts._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+                + CellBroadcasts.GEOGRAPHICAL_SCOPE + " INTEGER,"
+                + CellBroadcasts.PLMN + " TEXT,"
+                + CellBroadcasts.LAC + " INTEGER,"
+                + CellBroadcasts.CID + " INTEGER,"
+                + CellBroadcasts.SERIAL_NUMBER + " INTEGER,"
+                + CellBroadcasts.SERVICE_CATEGORY + " INTEGER,"
+                + CellBroadcasts.LANGUAGE_CODE + " TEXT,"
+                + CellBroadcasts.MESSAGE_BODY + " TEXT,"
+                + CellBroadcasts.MESSAGE_FORMAT + " INTEGER,"
+                + CellBroadcasts.MESSAGE_PRIORITY + " INTEGER,"
+                + CellBroadcasts.ETWS_WARNING_TYPE + " INTEGER,"
+                + CellBroadcasts.CMAS_MESSAGE_CLASS + " INTEGER,"
+                + CellBroadcasts.CMAS_CATEGORY + " INTEGER,"
+                + CellBroadcasts.CMAS_RESPONSE_TYPE + " INTEGER,"
+                + CellBroadcasts.CMAS_SEVERITY + " INTEGER,"
+                + CellBroadcasts.CMAS_URGENCY + " INTEGER,"
+                + CellBroadcasts.CMAS_CERTAINTY + " INTEGER,"
+                + CellBroadcasts.RECEIVED_TIME + " BIGINT,"
+                + CellBroadcasts.MESSAGE_BROADCASTED + " BOOLEAN DEFAULT 0,"
+                + CellBroadcasts.GEOMETRIES + " TEXT);";
+    }
+
+    private SQLiteDatabase getWritableDatabase() {
+        return mDbHelper.getWritableDatabase();
+    }
+
+    private SQLiteDatabase getReadableDatabase() {
+        return mDbHelper.getReadableDatabase();
+    }
+
+    private void checkWritePermission() {
+        if (!mPermissionChecker.hasWritePermission()) {
+            throw new SecurityException(
+                    "No permission to write CellBroadcast provider");
+        }
+    }
+
+    private void checkReadPermission() {
+        if (!mPermissionChecker.hasReadPermission()) {
+            throw new SecurityException(
+                    "No permission to read CellBroadcast provider");
+        }
+    }
+
+    private class CellBroadcastDatabaseHelper extends SQLiteOpenHelper {
+        CellBroadcastDatabaseHelper(Context context) {
+            super(context, DATABASE_NAME, null /* factory */, DATABASE_VERSION);
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            db.execSQL(getStringForCellBroadcastTableCreation(CELL_BROADCASTS_TABLE_NAME));
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
+    }
+
+    private class CellBroadcastPermissionChecker implements PermissionChecker {
+        @Override
+        public boolean hasWritePermission() {
+            // Only the phone process has the write permission for CellBroadcast content provider.
+            return Binder.getCallingUid() == Process.PHONE_UID;
+        }
+
+        @Override
+        public boolean hasReadPermission() {
+            return getContext().checkCallingOrSelfPermission(
+                    "android.permission.READ_CELL_BROADCASTS") == PackageManager.PERMISSION_GRANTED;
+        }
+    }
+}
diff --git a/tests/src/com/android/providers/telephony/CellBroadcastProviderTest.java b/tests/src/com/android/providers/telephony/CellBroadcastProviderTest.java
new file mode 100644
index 0000000..517572e
--- /dev/null
+++ b/tests/src/com/android/providers/telephony/CellBroadcastProviderTest.java
@@ -0,0 +1,382 @@
+/*
+ * Copyright (C) 2019 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 static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+
+import junit.framework.TestCase;
+
+import android.content.ContentValues;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.Telephony.CellBroadcasts;
+import android.test.mock.MockContentResolver;
+import android.test.mock.MockContext;
+import android.util.Log;
+
+import com.android.providers.telephony.CellBroadcastProvider.PermissionChecker;
+
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class CellBroadcastProviderTest extends TestCase {
+    private static final String TAG = CellBroadcastProviderTest.class.getSimpleName();
+
+    private static final int GEO_SCOPE = 1;
+    private static final String PLMN = "123456";
+    private static final int LAC = 13;
+    private static final int CID = 123;
+    private static final int SERIAL_NUMBER = 17984;
+    private static final int SERVICE_CATEGORY = 4379;
+    private static final String LANGUAGE_CODE = "en";
+    private static final String MESSAGE_BODY = "AMBER Alert: xxxx";
+    private static final int MESSAGE_FORMAT = 1;
+    private static final int MESSAGE_PRIORITY = 3;
+    private static final int ETWS_WARNING_TYPE = 1;
+    private static final int CMAS_MESSAGE_CLASS = 1;
+    private static final int CMAS_CATEGORY = 6;
+    private static final int CMAS_RESPONSE_TYPE = 1;
+    private static final int CMAS_SEVERITY = 2;
+    private static final int CMAS_URGENCY = 3;
+    private static final int CMAS_CERTAINTY = 4;
+    private static final int RECEIVED_TIME = 1562792637;
+    private static final int MESSAGE_BROADCASTED = 1;
+    private static final String GEOMETRIES_COORDINATES
+            = "polygon|0,0|0,1|1,1|1,0;circle|0,0|100";
+
+    private static final String SELECT_BY_ID = CellBroadcasts._ID + "=?";
+
+    private static final String[] QUERY_COLUMNS = {
+            CellBroadcasts._ID,
+            CellBroadcasts.GEOGRAPHICAL_SCOPE,
+            CellBroadcasts.PLMN,
+            CellBroadcasts.LAC,
+            CellBroadcasts.CID,
+            CellBroadcasts.SERIAL_NUMBER,
+            CellBroadcasts.SERVICE_CATEGORY,
+            CellBroadcasts.LANGUAGE_CODE,
+            CellBroadcasts.MESSAGE_BODY,
+            CellBroadcasts.MESSAGE_FORMAT,
+            CellBroadcasts.MESSAGE_PRIORITY,
+            CellBroadcasts.ETWS_WARNING_TYPE,
+            CellBroadcasts.CMAS_MESSAGE_CLASS,
+            CellBroadcasts.CMAS_CATEGORY,
+            CellBroadcasts.CMAS_RESPONSE_TYPE,
+            CellBroadcasts.CMAS_SEVERITY,
+            CellBroadcasts.CMAS_URGENCY,
+            CellBroadcasts.CMAS_CERTAINTY,
+            CellBroadcasts.RECEIVED_TIME,
+            CellBroadcasts.MESSAGE_BROADCASTED,
+            CellBroadcasts.GEOMETRIES
+    };
+
+    private CellBroadcastProviderTestable mCellBroadcastProviderTestable;
+    private MockContextWithProvider mContext;
+    private MockContentResolver mContentResolver;
+
+    @Mock
+    private PermissionChecker mMockPermissionChecker;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        MockitoAnnotations.initMocks(this);
+        doReturn(true).when(mMockPermissionChecker).hasReadPermission();
+        doReturn(true).when(mMockPermissionChecker).hasWritePermission();
+
+        mCellBroadcastProviderTestable = new CellBroadcastProviderTestable(mMockPermissionChecker);
+        mContext = new MockContextWithProvider(mCellBroadcastProviderTestable);
+        mContentResolver = mContext.getContentResolver();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mCellBroadcastProviderTestable.closeDatabase();
+        super.tearDown();
+    }
+
+    @Test
+    public void testUpdate() {
+        // Insert a cellbroadcast to the database.
+        ContentValues cv = fakeCellBroadcast();
+        Uri uri = mContentResolver.insert(CellBroadcasts.CONTENT_URI, cv);
+        assertThat(uri).isNotNull();
+
+        // Change some fields of this cell broadcast.
+        int messageBroadcasted = 1 - cv.getAsInteger(CellBroadcasts.MESSAGE_BROADCASTED);
+        int receivedTime = 1234555555;
+        cv.put(CellBroadcasts.MESSAGE_BROADCASTED, messageBroadcasted);
+        cv.put(CellBroadcasts.RECEIVED_TIME, receivedTime);
+        mContentResolver.update(CellBroadcasts.CONTENT_URI, cv, SELECT_BY_ID,
+                new String[] { uri.getLastPathSegment() });
+
+        // Query and check if the update is successed.
+        Cursor cursor = mContentResolver.query(CellBroadcasts.CONTENT_URI, QUERY_COLUMNS,
+                SELECT_BY_ID, new String[] { uri.getLastPathSegment() }, null /* orderBy */);
+        cursor.moveToNext();
+
+        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.RECEIVED_TIME)))
+                .isEqualTo(receivedTime);
+        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_BROADCASTED)))
+                .isEqualTo(messageBroadcasted);
+        cursor.close();
+    }
+
+    @Test
+    public void testUpdate_WithoutWritePermission_fail() {
+        ContentValues cv = fakeCellBroadcast();
+        Uri uri = mContentResolver.insert(CellBroadcasts.CONTENT_URI, cv);
+        assertThat(uri).isNotNull();
+
+        // Revoke the write permission
+        doReturn(false).when(mMockPermissionChecker).hasWritePermission();
+
+        try {
+            mContentResolver.update(CellBroadcasts.CONTENT_URI, cv, SELECT_BY_ID,
+                    new String[] { uri.getLastPathSegment() });
+            fail();
+        } catch (SecurityException ex) {
+            // pass the test
+        }
+    }
+
+    @Test
+    public void testGetAllCellBroadcast() {
+        // Insert some cell broadcasts which message_broadcasted is false
+        int messageNotBroadcastedCount = 5;
+        ContentValues cv = fakeCellBroadcast();
+        cv.put(CellBroadcasts.MESSAGE_BROADCASTED, 0);
+        for (int i = 0; i < messageNotBroadcastedCount; i++) {
+            mContentResolver.insert(CellBroadcasts.CONTENT_URI, cv);
+        }
+
+        // Insert some cell broadcasts which message_broadcasted is true
+        int messageBroadcastedCount = 6;
+        cv.put(CellBroadcasts.MESSAGE_BROADCASTED, 1);
+        for (int i = 0; i < messageBroadcastedCount; i++) {
+            mContentResolver.insert(CellBroadcasts.CONTENT_URI, cv);
+        }
+
+        // Query the broadcast with message_broadcasted is false
+        Cursor cursor = mContentResolver.query(
+                CellBroadcasts.CONTENT_URI,
+                QUERY_COLUMNS,
+                String.format("%s=?", CellBroadcasts.MESSAGE_BROADCASTED), /* selection */
+                new String[] {"0"}, /* selectionArgs */
+                null /* sortOrder */);
+        assertThat(cursor.getCount()).isEqualTo(messageNotBroadcastedCount);
+    }
+
+    @Test
+    public void testDelete_withoutWritePermission_throwSecurityException() {
+        Uri uri = mContentResolver.insert(CellBroadcasts.CONTENT_URI, fakeCellBroadcast());
+        assertThat(uri).isNotNull();
+
+        // Revoke the write permission
+        doReturn(false).when(mMockPermissionChecker).hasWritePermission();
+
+        try {
+            mContentResolver.delete(CellBroadcasts.CONTENT_URI, SELECT_BY_ID,
+                    new String[] { uri.getLastPathSegment() });
+            fail();
+        } catch (SecurityException ex) {
+            // pass the test
+        }
+    }
+
+
+    @Test
+    public void testDelete_oneRecord_success() {
+        // Insert a cellbroadcast to the database.
+        ContentValues cv = fakeCellBroadcast();
+        Uri uri = mContentResolver.insert(CellBroadcasts.CONTENT_URI, cv);
+        assertThat(uri).isNotNull();
+
+        String[] selectionArgs = new String[] { uri.getLastPathSegment() };
+
+        // Ensure the cell broadcast is inserted.
+        Cursor cursor = mContentResolver.query(CellBroadcasts.CONTENT_URI, QUERY_COLUMNS,
+                SELECT_BY_ID, selectionArgs, null /* orderBy */);
+        assertThat(cursor.getCount()).isEqualTo(1);
+        cursor.close();
+
+        // Delete the cell broadcast
+        int rowCount = mContentResolver.delete(CellBroadcasts.CONTENT_URI, SELECT_BY_ID,
+                selectionArgs);
+        assertThat(rowCount).isEqualTo(1);
+
+        // Ensure the cell broadcast is deleted.
+        cursor = mContentResolver.query(CellBroadcasts.CONTENT_URI, QUERY_COLUMNS, SELECT_BY_ID,
+                selectionArgs, null /* orderBy */);
+        assertThat(cursor.getCount()).isEqualTo(0);
+        cursor.close();
+    }
+
+    @Test
+    public void testDelete_all_success() {
+        // Insert a cellbroadcast to the database.
+        mContentResolver.insert(CellBroadcasts.CONTENT_URI, fakeCellBroadcast());
+        mContentResolver.insert(CellBroadcasts.CONTENT_URI, fakeCellBroadcast());
+
+        // Ensure the cell broadcast are inserted.
+        Cursor cursor = mContentResolver.query(CellBroadcasts.CONTENT_URI, QUERY_COLUMNS,
+                null /* selection */, null /* selectionArgs */, null /* orderBy */);
+        assertThat(cursor.getCount()).isEqualTo(2);
+        cursor.close();
+
+        // Delete all cell broadcasts.
+        int rowCount = mContentResolver.delete(
+                CellBroadcasts.CONTENT_URI, null /* selection */, null /* selectionArgs */);
+        assertThat(rowCount).isEqualTo(2);
+        cursor.close();
+
+        // Ensure all cell broadcasts are deleted.
+        cursor = mContentResolver.query(CellBroadcasts.CONTENT_URI, QUERY_COLUMNS,
+                null /* selection */, null /* selectionArgs */, null /* orderBy */);
+        assertThat(cursor.getCount()).isEqualTo(0);
+        cursor.close();
+    }
+
+    @Test
+    public void testInsert_withoutWritePermission_fail() {
+        doReturn(false).when(mMockPermissionChecker).hasWritePermission();
+
+        try {
+            mContentResolver.insert(CellBroadcasts.CONTENT_URI, fakeCellBroadcast());
+            fail();
+        } catch (SecurityException ex) {
+            // pass the test
+        }
+    }
+
+    @Test
+    public void testInsertAndQuery() {
+        // Insert a cell broadcast message
+        Uri uri = mContentResolver.insert(CellBroadcasts.CONTENT_URI, fakeCellBroadcast());
+
+        // Verify that the return uri is not null and the record is inserted into the database
+        // correctly.
+        assertThat(uri).isNotNull();
+        Cursor cursor = mContentResolver.query(
+                CellBroadcasts.CONTENT_URI, QUERY_COLUMNS, SELECT_BY_ID,
+                new String[] { uri.getLastPathSegment() }, null /* orderBy */);
+        assertThat(cursor.getCount()).isEqualTo(1);
+
+        cursor.moveToNext();
+        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.GEOGRAPHICAL_SCOPE)))
+                .isEqualTo(GEO_SCOPE);
+        assertThat(cursor.getString(cursor.getColumnIndexOrThrow(CellBroadcasts.PLMN)))
+                .isEqualTo(PLMN);
+        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.LAC))).isEqualTo(LAC);
+        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CID))).isEqualTo(CID);
+        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.SERIAL_NUMBER)))
+                .isEqualTo(SERIAL_NUMBER);
+        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.SERVICE_CATEGORY)))
+                .isEqualTo(SERVICE_CATEGORY);
+        assertThat(cursor.getString(cursor.getColumnIndexOrThrow(CellBroadcasts.LANGUAGE_CODE)))
+                .isEqualTo(LANGUAGE_CODE);
+        assertThat(cursor.getString(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_BODY)))
+                .isEqualTo(MESSAGE_BODY);
+        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_FORMAT)))
+                .isEqualTo(MESSAGE_FORMAT);
+        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_PRIORITY)))
+                .isEqualTo(MESSAGE_PRIORITY);
+        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.ETWS_WARNING_TYPE)))
+                .isEqualTo(ETWS_WARNING_TYPE);
+        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CMAS_MESSAGE_CLASS)))
+                .isEqualTo(CMAS_MESSAGE_CLASS);
+        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CMAS_CATEGORY)))
+                .isEqualTo(CMAS_CATEGORY);
+        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CMAS_RESPONSE_TYPE)))
+                .isEqualTo(CMAS_RESPONSE_TYPE);
+        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CMAS_SEVERITY)))
+                .isEqualTo(CMAS_SEVERITY);
+        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CMAS_URGENCY)))
+                .isEqualTo(CMAS_URGENCY);
+        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.CMAS_CERTAINTY)))
+                .isEqualTo(CMAS_CERTAINTY);
+        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.RECEIVED_TIME)))
+                .isEqualTo(RECEIVED_TIME);
+        assertThat(cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_BROADCASTED)))
+                .isEqualTo(MESSAGE_BROADCASTED);
+        assertThat(cursor.getString(cursor.getColumnIndexOrThrow(
+                CellBroadcasts.GEOMETRIES))).isEqualTo(GEOMETRIES_COORDINATES);
+    }
+
+    /**
+     * This is used to give the CellBroadcastProviderTest a mocked context which takes a
+     * CellBroadcastProvider and attaches it to the ContentResolver.
+     */
+    private class MockContextWithProvider extends MockContext {
+        private final MockContentResolver mResolver;
+
+        public MockContextWithProvider(CellBroadcastProviderTestable cellBroadcastProvider) {
+            mResolver = new MockContentResolver();
+            cellBroadcastProvider.initializeForTesting(this);
+
+            // Add given cellBroadcastProvider to mResolver, so that mResolver can send queries
+            // to the provider.
+            mResolver.addProvider(CellBroadcastProvider.AUTHORITY, cellBroadcastProvider);
+        }
+
+        @Override
+        public MockContentResolver getContentResolver() {
+            return mResolver;
+        }
+
+
+        @Override
+        public Object getSystemService(String name) {
+            Log.d(TAG, "getSystemService: returning null");
+            return null;
+        }
+
+        @Override
+        public int checkCallingOrSelfPermission(String permission) {
+            return PackageManager.PERMISSION_GRANTED;
+        }
+    }
+
+    private static ContentValues fakeCellBroadcast() {
+        ContentValues cv = new ContentValues();
+        cv.put(CellBroadcasts.GEOGRAPHICAL_SCOPE, GEO_SCOPE);
+        cv.put(CellBroadcasts.PLMN, PLMN);
+        cv.put(CellBroadcasts.LAC, LAC);
+        cv.put(CellBroadcasts.CID, CID);
+        cv.put(CellBroadcasts.SERIAL_NUMBER, SERIAL_NUMBER);
+        cv.put(CellBroadcasts.SERVICE_CATEGORY, SERVICE_CATEGORY);
+        cv.put(CellBroadcasts.LANGUAGE_CODE, LANGUAGE_CODE);
+        cv.put(CellBroadcasts.MESSAGE_BODY, MESSAGE_BODY);
+        cv.put(CellBroadcasts.MESSAGE_FORMAT, MESSAGE_FORMAT);
+        cv.put(CellBroadcasts.MESSAGE_PRIORITY, MESSAGE_PRIORITY);
+        cv.put(CellBroadcasts.ETWS_WARNING_TYPE, ETWS_WARNING_TYPE);
+        cv.put(CellBroadcasts.CMAS_MESSAGE_CLASS, CMAS_MESSAGE_CLASS);
+        cv.put(CellBroadcasts.CMAS_CATEGORY, CMAS_CATEGORY);
+        cv.put(CellBroadcasts.CMAS_RESPONSE_TYPE, CMAS_RESPONSE_TYPE);
+        cv.put(CellBroadcasts.CMAS_SEVERITY, CMAS_SEVERITY);
+        cv.put(CellBroadcasts.CMAS_URGENCY, CMAS_URGENCY);
+        cv.put(CellBroadcasts.CMAS_CERTAINTY, CMAS_CERTAINTY);
+        cv.put(CellBroadcasts.RECEIVED_TIME, RECEIVED_TIME);
+        cv.put(CellBroadcasts.MESSAGE_BROADCASTED, MESSAGE_BROADCASTED);
+        cv.put(CellBroadcasts.GEOMETRIES, GEOMETRIES_COORDINATES);
+        return cv;
+    }
+}
diff --git a/tests/src/com/android/providers/telephony/CellBroadcastProviderTestable.java b/tests/src/com/android/providers/telephony/CellBroadcastProviderTestable.java
new file mode 100644
index 0000000..8334312
--- /dev/null
+++ b/tests/src/com/android/providers/telephony/CellBroadcastProviderTestable.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 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.content.pm.ProviderInfo;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
+
+import androidx.test.InstrumentationRegistry;
+
+public class CellBroadcastProviderTestable extends CellBroadcastProvider {
+    private static final String TAG = CellBroadcastProviderTestable.class.getSimpleName();
+
+    public CellBroadcastProviderTestable(PermissionChecker permissionChecker) {
+        super(permissionChecker);
+    }
+
+    @Override
+    public boolean onCreate() {
+        // DO NOT call super.onCreate(), otherwise the permission checker will be override.
+        Log.d(TAG, "CellBroadcastProviderTestable onCreate");
+        mDbHelper = new InMemoryCellBroadcastProviderDbHelper();
+        return true;
+    }
+
+    public void closeDatabase() {
+        mDbHelper.close();
+    }
+
+    public static class InMemoryCellBroadcastProviderDbHelper extends SQLiteOpenHelper {
+        public InMemoryCellBroadcastProviderDbHelper() {
+            super(InstrumentationRegistry.getTargetContext(),
+                    null,    // db file name is null for in-memory db
+                    null,    // CursorFactory is null by default
+                    1);      // db version is no-op for tests
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            Log.d(TAG, "IN MEMORY DB CREATED");
+            db.execSQL(getStringForCellBroadcastTableCreation(CELL_BROADCASTS_TABLE_NAME));
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
+    }
+
+    public void initializeForTesting(Context context) {
+        ProviderInfo providerInfo = new ProviderInfo();
+        providerInfo.authority = CellBroadcastProvider.AUTHORITY;
+
+        // Add context to given carrierIdProvider
+        attachInfoForTesting(context, providerInfo);
+    }
+}
