OSDN Git Service

Protect against SQLiteException crash in MAP init
authorAjay Panicker <apanicke@google.com>
Thu, 10 Nov 2016 01:11:40 +0000 (17:11 -0800)
committerAjay Panicker <apanicke@google.com>
Tue, 15 Nov 2016 18:31:29 +0000 (10:31 -0800)
Bug: 32717472
Test: runtest bluetooth
Change-Id: I533d7ca0b281291f931f4aca271ea9ff3214bdf2

src/com/android/bluetooth/map/BluetoothMapContentObserver.java
tests/src/com/android/bluetooth/tests/map/BluetoothMapContentObserverTest.java [new file with mode: 0644]

index f4e58e8..113f0d3 100644 (file)
@@ -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 {
diff --git a/tests/src/com/android/bluetooth/tests/map/BluetoothMapContentObserverTest.java b/tests/src/com/android/bluetooth/tests/map/BluetoothMapContentObserverTest.java
new file mode 100644 (file)
index 0000000..6fa6c2c
--- /dev/null
@@ -0,0 +1,68 @@
+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");
+        }
+    }
+}