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

Commit e8875634 authored by Kim Schulz's avatar Kim Schulz Committed by Andre Eisenbach
Browse files

Prevent Cursor leakage in Bluetooth MAP

Bug: 18415378
Change-Id: Id513ee848dd21c641d77be38bdc6be85b5ef87a8
parent c85043e2
Loading
Loading
Loading
Loading
+264 −415

File changed.

Preview size limit exceeded, changes collapsed.

+203 −177
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
*/
package com.android.bluetooth.map;

import java.io.Closeable;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -116,6 +117,13 @@ public class BluetoothMapContentObserver {

    private TYPE mSmsType;

    private static void close(Closeable c) {
        try {
            if (c != null) c.close();
        } catch (IOException e) {
        }
    }

    static final String[] SMS_PROJECTION = new String[] {
        Sms._ID,
        Sms.THREAD_ID,
@@ -452,17 +460,19 @@ public class BluetoothMapContentObserver {
            Cursor c = mResolver.query(Sms.CONTENT_URI,
                SMS_PROJECTION_SHORT, null, null, null);

            if (c != null && c.moveToFirst()) {
                do {
            try {
                while (c != null && c.moveToNext()) {
                    long id = c.getLong(c.getColumnIndex(Sms._ID));
                    int type = c.getInt(c.getColumnIndex(Sms.TYPE));
                    int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID));

                    Msg msg = new Msg(id, type, threadId);
                    msgListSms.put(id, msg);
                } while (c.moveToNext());
                c.close();
                }
            } finally {
                close(c);
            }

            synchronized(mMsgListSms) {
                mMsgListSms.clear();
                mMsgListSms = msgListSms;
@@ -472,17 +482,19 @@ public class BluetoothMapContentObserver {

            c = mResolver.query(Mms.CONTENT_URI, MMS_PROJECTION_SHORT, null, null, null);

            if (c != null && c.moveToFirst()) {
                do {
            try {
                while (c != null && c.moveToNext()) {
                    long id = c.getLong(c.getColumnIndex(Mms._ID));
                    int type = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX));
                    int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID));

                    Msg msg = new Msg(id, type, threadId);
                    msgListMms.put(id, msg);
                } while (c.moveToNext());
                c.close();
                }
            } finally {
                close(c);
            }

            synchronized(mMsgListMms) {
                mMsgListMms.clear();
                mMsgListMms = msgListMms;
@@ -494,16 +506,18 @@ public class BluetoothMapContentObserver {
            Uri uri = mMessageUri;
            Cursor c = mProviderClient.query(uri, EMAIL_PROJECTION_SHORT, null, null, null);

            if (c != null && c.moveToFirst()) {
                do {
            try {
                while (c != null && c.moveToNext()) {
                    long id = c.getLong(c.getColumnIndex(MessageColumns._ID));
                    long folderId = c.getInt(c.getColumnIndex(BluetoothMapContract.MessageColumns.FOLDER_ID));

                    Msg msg = new Msg(id, folderId);
                    msgListEmail.put(id, msg);
                } while (c.moveToNext());
                c.close();
                }
            } finally {
                close(c);
            }

            synchronized(mMsgListEmail) {
                mMsgListEmail.clear();
                mMsgListEmail = msgListEmail;
@@ -520,8 +534,8 @@ public class BluetoothMapContentObserver {
            SMS_PROJECTION_SHORT, null, null, null);

        synchronized(mMsgListSms) {
            if (c != null && c.moveToFirst()) {
                do {
            try {
                while (c != null && c.moveToNext()) {
                    long id = c.getLong(c.getColumnIndex(Sms._ID));
                    int type = c.getInt(c.getColumnIndex(Sms.TYPE));
                    int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID));
@@ -570,8 +584,9 @@ public class BluetoothMapContentObserver {
                        }
                        msgListSms.put(id, msg);
                    }
                } while (c.moveToNext());
                c.close();
                }
            } finally {
                close(c);
            }

            for (Msg msg : mMsgListSms.values()) {
@@ -594,8 +609,8 @@ public class BluetoothMapContentObserver {
            MMS_PROJECTION_SHORT, null, null, null);

        synchronized(mMsgListMms) {
            if (c != null && c.moveToFirst()) {
                do {
            try {
                while (c != null && c.moveToNext()) {
                    long id = c.getLong(c.getColumnIndex(Mms._ID));
                    int type = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX));
                    int mtype = c.getInt(c.getColumnIndex(Mms.MESSAGE_TYPE));
@@ -657,8 +672,9 @@ public class BluetoothMapContentObserver {
                        }
                        msgListMms.put(id, msg);
                    }
                } while (c.moveToNext());
                c.close();
                }
            } finally {
                close(c);
            }

            for (Msg msg : mMsgListMms.values()) {
@@ -681,8 +697,8 @@ public class BluetoothMapContentObserver {
        Cursor c = mProviderClient.query(mMessageUri, EMAIL_PROJECTION_SHORT, null, null, null);

        synchronized(mMsgListEmail) {
            if (c != null && c.moveToFirst()) {
                do {
            try {
                while (c != null && c.moveToNext()) {
                    long id = c.getLong(c.getColumnIndex(BluetoothMapContract.MessageColumns._ID));
                    int folderId = c.getInt(c.getColumnIndex(
                            BluetoothMapContract.MessageColumns.FOLDER_ID));
@@ -750,8 +766,9 @@ public class BluetoothMapContentObserver {
                        }
                        msgListEmail.put(id, msg);
                    }
                } while (c.moveToNext());
                c.close();
                }
            } finally {
                close(c);
            }

            // For all messages no longer in the database send a delete notification
@@ -893,6 +910,8 @@ public class BluetoothMapContentObserver {
        boolean res = false;
        Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle);
        Cursor c = mResolver.query(uri, null, null, null, null);

        try {
            if (c != null && c.moveToFirst()) {
                /* Move to deleted folder, or delete if already in deleted folder */
                int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID));
@@ -915,9 +934,10 @@ public class BluetoothMapContentObserver {
                }
                res = true;
            }
        if (c != null) {
            c.close();
        } finally {
            close(c);
        }

        return res;
    }

@@ -926,6 +946,7 @@ public class BluetoothMapContentObserver {
        Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle);
        Cursor c = mResolver.query(uri, null, null, null, null);

        try {
            if (c != null && c.moveToFirst()) {
                int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID));
                if (threadId == DELETED_THREAD_ID) {
@@ -957,9 +978,10 @@ public class BluetoothMapContentObserver {
                }
                res = true;
            }
        if (c != null) {
            c.close();
        } finally {
            close(c);
        }

        return res;
    }

@@ -968,6 +990,7 @@ public class BluetoothMapContentObserver {
        Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle);
        Cursor c = mResolver.query(uri, null, null, null, null);

        try {
            if (c != null && c.moveToFirst()) {
                /* Move to deleted folder, or delete if already in deleted folder */
                int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID));
@@ -990,9 +1013,10 @@ public class BluetoothMapContentObserver {
                }
                res = true;
            }
        if (c != null) {
            c.close();
        } finally {
            close(c);
        }

        return res;
    }

@@ -1001,6 +1025,7 @@ public class BluetoothMapContentObserver {
        Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle);
        Cursor c = mResolver.query(uri, null, null, null, null);

        try {
            if (c != null && c.moveToFirst()) {
                int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID));
                if (threadId == DELETED_THREAD_ID) {
@@ -1021,9 +1046,10 @@ public class BluetoothMapContentObserver {
                }
                res = true;
            }
        if (c != null) {
            c.close();
        } finally {
            close(c);
        }

        return res;
    }

@@ -1073,7 +1099,6 @@ public class BluetoothMapContentObserver {

        if (type == TYPE.SMS_GSM || type == TYPE.SMS_CDMA) {
            Uri uri = Sms.Inbox.CONTENT_URI;//ContentUris.withAppendedId(Sms.CONTENT_URI, handle);
            Cursor c = mResolver.query(uri, null, null, null, null);
            ContentValues contentValues = new ContentValues();
            contentValues.put(Sms.READ, statusValue);
            contentValues.put(Sms.SEEN, statusValue);
@@ -1082,15 +1107,15 @@ public class BluetoothMapContentObserver {
            if (D) Log.d(TAG, " -> SMS Uri: " + uri.toString() + " Where " + where + " values " + values);
            count = mResolver.update(uri, contentValues, where, null);
            if (D) Log.d(TAG, " -> "+count +" rows updated!");

        } else if (type == TYPE.MMS) {
            Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle);
            Cursor c = mResolver.query(uri, null, null, null, null);
            if (D) Log.d(TAG, " -> MMS Uri: " + uri.toString());
            ContentValues contentValues = new ContentValues();
            contentValues.put(Mms.READ, statusValue);
            count = mResolver.update(uri, contentValues, null, null);

            if (D) Log.d(TAG, " -> "+count +" rows updated!");

        } if (type == TYPE.EMAIL) {
            Uri uri = mMessageUri;
            ContentValues contentValues = new ContentValues();
@@ -1098,10 +1123,8 @@ public class BluetoothMapContentObserver {
            contentValues.put(BluetoothMapContract.MessageColumns._ID, handle);
            count = mProviderClient.update(uri, contentValues, null, null);
        }
        if(count < 1) {
            return false;
        }
        return true;

        return (count > 0);
    }

    private class PushMsgInfo {
@@ -1267,7 +1290,7 @@ public class BluetoothMapContentObserver {
                                return -1;
                            }
                            Cursor c = mResolver.query(uri, SMS_PROJECTION_SHORT, null, null, null);

                            try {
                                /* Extract the data for the inserted message, and store in local mirror, to
                                * avoid sending a NewMessage Event. */
                                if (c != null && c.moveToFirst()) {
@@ -1276,10 +1299,12 @@ public class BluetoothMapContentObserver {
                                    int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID));
                                    Msg newMsg = new Msg(id, type, threadId);
                                    mMsgListSms.put(id, newMsg);
                                c.close();
                                } else {
                                    return -1; // This can only happen, if the message is deleted just as it is added
                                }
                            } finally {
                                close(c);
                            }

                            handle = Long.parseLong(uri.getLastPathSegment());

@@ -1335,28 +1360,28 @@ public class BluetoothMapContentObserver {
        }
    }


    private void moveDraftToOutbox(long handle) {
        /*Move message by changing the msg_box value in the content provider database */
        if (handle != -1) {
        if (handle != -1) return;

        String whereClause = " _id= " + handle;
        Uri uri = Mms.CONTENT_URI;
        Cursor queryResult = mResolver.query(uri, null, whereClause, null, null);
            if (queryResult != null) {
                if (queryResult.getCount() > 0) {
                    queryResult.moveToFirst();
        try {
            if (queryResult != null && queryResult.moveToFirst()) {
                ContentValues data = new ContentValues();
                /* set folder to be outbox */
                data.put(Mms.MESSAGE_BOX, Mms.MESSAGE_BOX_OUTBOX);
                mResolver.update(uri, data, whereClause, null);
                    if (D) Log.d(TAG, "moved draft MMS to outbox");
                }
                queryResult.close();
                if (D) Log.d(TAG, "Moved draft MMS to outbox");
            } else {
                if (D) Log.d(TAG, "Could not move draft to outbox ");
            }
        } finally {
            queryResult.close();
        }
    }

    private long pushMmsToFolder(int folder, String to_address, BluetoothMapbMessageMms msg) {
        /**
         * strategy:
@@ -1400,7 +1425,6 @@ public class BluetoothMapContentObserver {
        Uri uri = Mms.CONTENT_URI;

        synchronized (mMsgListMms) {

            uri = mResolver.insert(uri, values);

            if (uri == null) {
@@ -1412,7 +1436,7 @@ public class BluetoothMapContentObserver {
               doing the query ensures we get any changes made by the content provider
               at insert. */
            Cursor c = mResolver.query(uri, MMS_PROJECTION_SHORT, null, null, null);

            try {
                if (c != null && c.moveToFirst()) {
                    long id = c.getLong(c.getColumnIndex(Mms._ID));
                    int type = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX));
@@ -1424,7 +1448,9 @@ public class BluetoothMapContentObserver {
                    Msg newMsg = new Msg(id, type, threadId);
                    newMsg.localInitiatedSend = true;
                    mMsgListMms.put(id, newMsg);
                c.close();
                }
            } finally {
                close(c);
            }
        } // Done adding changes, unlock access to mMsgListMms to allow sending MMS events again

@@ -1437,9 +1463,9 @@ public class BluetoothMapContentObserver {
                Log.w(TAG, "No MMS parts present...");
            } else {
                if(V) Log.v(TAG, "Adding " + msg.getMimeParts().size() + " parts to the data base.");
                for(MimePart part : msg.getMimeParts()) {
                int count = 0;
                    count++;
                for(MimePart part : msg.getMimeParts()) {
                    ++count;
                    values.clear();
                    if(part.mContentType != null &&  part.mContentType.toUpperCase().contains("TEXT")) {
                        values.put(Mms.Part.CONTENT_TYPE, "text/plain");
@@ -1912,11 +1938,10 @@ public class BluetoothMapContentObserver {
    private void resendPendingMessages() {
        /* Send pending messages in outbox */
        String where = "type = " + Sms.MESSAGE_TYPE_OUTBOX;
        Cursor c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION, where, null,
            null);
        Cursor c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION, where, null, null);

        if (c != null && c.moveToFirst()) {
            do {
        try {
            while (c!= null && c.moveToNext()) {
                long id = c.getLong(c.getColumnIndex(Sms._ID));
                String msgBody = c.getString(c.getColumnIndex(Sms.BODY));
                PushMsgInfo msgInfo = mPushMsgList.get(id);
@@ -1925,19 +1950,20 @@ public class BluetoothMapContentObserver {
                }
                msgInfo.sendInProgress = true;
                sendMessage(msgInfo, msgBody);
            } while (c.moveToNext());
            c.close();
            }
        } finally {
            close(c);
        }
    }

    private void failPendingMessages() {
        /* Move pending messages from outbox to failed */
        String where = "type = " + Sms.MESSAGE_TYPE_OUTBOX;
        Cursor c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION, where, null,
            null);
        Cursor c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION, where, null, null);
        if (c == null) return;

        if (c != null && c.moveToFirst()) {
            do {
        try {
            while (c!= null && c.moveToNext()) {
                long id = c.getLong(c.getColumnIndex(Sms._ID));
                String msgBody = c.getString(c.getColumnIndex(Sms.BODY));
                PushMsgInfo msgInfo = mPushMsgList.get(id);
@@ -1946,9 +1972,10 @@ public class BluetoothMapContentObserver {
                }
                Sms.moveMessageToFolder(mContext, msgInfo.uri,
                    Sms.MESSAGE_TYPE_FAILED, 0);
            } while (c.moveToNext());
            }
        if (c != null) c.close();
        } finally {
            close(c);
        }
    }

    private void removeDeletedMessages() {
@@ -1989,5 +2016,4 @@ public class BluetoothMapContentObserver {
        }
        return false;
    }

}
+14 −25
Original line number Diff line number Diff line
@@ -151,28 +151,16 @@ public class BluetoothMapEmailSettingsLoader {
             }
             mProviderClient.setDetectNotResponding(PROVIDER_ANR_TIMEOUT);


            Uri uri = Uri.parse(app.mBase_uri_no_account + "/" + BluetoothMapContract.TABLE_ACCOUNT);

             c = mProviderClient.query(uri, BluetoothMapContract.BT_ACCOUNT_PROJECTION, null, null, BluetoothMapContract.AccountColumns._ID+" DESC");
        } catch (RemoteException e){
            if(D)Log.d(TAG,"Could not establish ContentProviderClient for "+app.getPackageName()+
                    " - returning empty account list" );
            return children;
        }

        if (c != null) {
            c.moveToPosition(-1);
            while (c.moveToNext()) {
                if(D)Log.d(TAG,"Adding account " +c.getString(c.getColumnIndex(BluetoothMapContract.AccountColumns.ACCOUNT_DISPLAY_NAME))+
                        " with ID "+String.valueOf((c.getInt(c.getColumnIndex(BluetoothMapContract.AccountColumns._ID)))));

            c = mProviderClient.query(uri, BluetoothMapContract.BT_ACCOUNT_PROJECTION, null, null,
                    BluetoothMapContract.AccountColumns._ID+" DESC");
            while (c != null && c.moveToNext()) {
                BluetoothMapEmailSettingsItem child = new BluetoothMapEmailSettingsItem(
                        /*id*/           String.valueOf((c.getInt(c.getColumnIndex(BluetoothMapContract.AccountColumns._ID)))),
                        /*name*/         c.getString(c.getColumnIndex(BluetoothMapContract.AccountColumns.ACCOUNT_DISPLAY_NAME)) ,
                        /*package name*/ app.getPackageName(),
                        /*providerMeta*/ app.getProviderAuthority(),
                        /*icon*/         null);
                    String.valueOf((c.getInt(c.getColumnIndex(BluetoothMapContract.AccountColumns._ID)))),
                    c.getString(c.getColumnIndex(BluetoothMapContract.AccountColumns.ACCOUNT_DISPLAY_NAME)) ,
                    app.getPackageName(),
                    app.getProviderAuthority(),
                    null);

                child.mIsChecked = (c.getInt(c.getColumnIndex(BluetoothMapContract.AccountColumns.FLAG_EXPOSE))!=0);
                /*update the account counter so we can make sure that not to many accounts are checked. */
@@ -182,9 +170,11 @@ public class BluetoothMapEmailSettingsLoader {
                }
                children.add(child);
            }
            c.close();
        } else {
            if(D)Log.d(TAG, "query failed");
        } catch (RemoteException e){
            if(D)Log.d(TAG,"Could not establish ContentProviderClient for "+app.getPackageName()+
                    " - returning empty account list" );
        } finally {
            if (c != null) c.close();
        }
        return children;
    }
@@ -198,5 +188,4 @@ public class BluetoothMapEmailSettingsLoader {
        if(D)Log.d(TAG,"Enabled Accounts count:"+ mAccountsEnabledCount);
        return mAccountsEnabledCount;
    }

}
+4 −6
Original line number Diff line number Diff line
@@ -212,17 +212,15 @@ public class BluetoothMapObexServer extends ServerRequestHandler {
                        " = " + parentFolder.getEmailFolderId();
        Cursor c = mProviderClient.query(mEmailFolderUri,
                        BluetoothMapContract.BT_FOLDER_PROJECTION, where, null, null);
        if (c != null) {
            c.moveToPosition(-1);
            while (c.moveToNext()) {
        try {
            while (c != null && c.moveToNext()) {
                String name = c.getString(c.getColumnIndex(BluetoothMapContract.FolderColumns.NAME));
                long id = c.getLong(c.getColumnIndex(BluetoothMapContract.FolderColumns._ID));
                newFolder = parentFolder.addEmailFolder(name, id);
                addEmailFolders(newFolder); // Use recursion to add any sub folders
            }
            c.close();
        } else {
            if (D) Log.d(TAG, "addEmailFolders(): no elements found");
        } finally {
            if (c != null) c.close();
        }
    }