Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 27d08270 authored by Ajay Panicker's avatar Ajay Panicker
Browse files

Protect against SQLiteException crash in MAP init

Bug: 32717472
Test: runtest bluetooth
Change-Id: I533d7ca0b281291f931f4aca271ea9ff3214bdf2
parent 87250c76
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.content.IntentFilter.MalformedMimeTypeException;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
@@ -1195,8 +1196,15 @@ public class BluetoothMapContentObserver {
        if (mEnableSmsMms) {
            HashMap<Long, Msg> msgListSms = new HashMap<Long, Msg>();

            Cursor c = mResolver.query(Sms.CONTENT_URI,
            Cursor c;
            try {
                c = mResolver.query(Sms.CONTENT_URI,
                    SMS_PROJECTION_SHORT, null, null, null);
            } catch (SQLiteException e) {
                Log.e(TAG, "Failed to initialize the list of messages: " + e.toString());
                return;
            }

            try {
                if (c != null && c.moveToFirst()) {
                    do {
+68 −0
Original line number Diff line number Diff line
package com.android.bluetooth.map;

import android.content.Context;
import android.content.ContentResolver;
import android.content.ContentProvider;
import android.database.sqlite.SQLiteException;
import android.database.Cursor;
import android.net.Uri;
import android.os.Looper;
import android.os.RemoteException;
import android.os.UserManager;
import android.provider.Telephony.Sms;
import android.test.AndroidTestCase;
import android.test.mock.MockContentResolver;
import android.test.mock.MockContentProvider;
import android.telephony.TelephonyManager;
import android.util.Log;

import junit.framework.Assert;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class BluetoothMapContentObserverTest extends AndroidTestCase {

    class ExceptionTestProvider extends MockContentProvider {
        public ExceptionTestProvider(Context context) {
            super(context);
        }

        @Override
        public Cursor query(Uri uri, String[] b, String s, String[] c, String d) {
            throw new SQLiteException();
        }
    }

    public void testInitMsgList() {
        Looper.prepare();

        Context mockContext = mock(Context.class);
        MockContentResolver mockResolver = new MockContentResolver(mockContext);
        ExceptionTestProvider mockProvider = new ExceptionTestProvider(mockContext);
        mockResolver.addProvider("sms", mockProvider);

        TelephonyManager mockTelephony = mock(TelephonyManager.class);
        UserManager mockUserService = mock(UserManager.class);
        BluetoothMapMasInstance mockMas = mock(BluetoothMapMasInstance.class);

        // Functions that get called when BluetoothMapContentObserver is created
        when(mockUserService.isUserUnlocked()).thenReturn(true);
        when(mockContext.getContentResolver()).thenReturn(mockResolver);
        when(mockContext.getSystemService(Context.TELEPHONY_SERVICE))
            .thenReturn(mockTelephony);
        when(mockContext.getSystemService(Context.USER_SERVICE))
            .thenReturn(mockUserService);

        BluetoothMapContentObserver observer;
        try {
            // The constructor of BluetoothMapContentObserver calls initMsgList
            observer = new BluetoothMapContentObserver(mockContext, null,
                                                       mockMas, null, true);
        } catch(RemoteException e) {
            fail("Failed to created BluetoothMapContentObserver object");
        } catch(SQLiteException e) {
            fail("Threw SQLiteException instead of failing cleanly");
        }
    }
}