diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 4ae9acf..f558bb8 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -107,6 +107,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);
+    }
+}
