Fix bug where mailbox list won't update in combined view
The problem was that CombinedMailboxesLoader used the cursor returned by super.loadInBackground() (which contains accounts), to build a matrix cursor (which contains special mailboxes and accounts and will be returned), and *it closed the first cursor* after building the matrix cursor. However, because this first cursor is the one that CursorLoader sets an observer, it shouldn't be closed until the returned matix cursor closes. In other words the two cursors should have the same lifecycle. Fixed it by using ClosingMatrixCursor that used by AccountsLoader, which is doing a similar thing, but properly. Bug 3387730 Change-Id: I554ade001dc25afa869eefb4dcf9887495e6753e
This commit is contained in:
parent
b0c0673342
commit
d0ee1e404d
|
@ -16,9 +16,9 @@
|
||||||
|
|
||||||
package com.android.email.activity;
|
package com.android.email.activity;
|
||||||
|
|
||||||
import com.android.email.Email;
|
|
||||||
import com.android.email.R;
|
import com.android.email.R;
|
||||||
import com.android.email.Utility;
|
import com.android.email.Utility;
|
||||||
|
import com.android.email.data.ClosingMatrixCursor;
|
||||||
import com.android.email.data.ThrottlingCursorLoader;
|
import com.android.email.data.ThrottlingCursorLoader;
|
||||||
import com.android.email.provider.EmailContent;
|
import com.android.email.provider.EmailContent;
|
||||||
import com.android.email.provider.EmailContent.Account;
|
import com.android.email.provider.EmailContent.Account;
|
||||||
|
@ -208,23 +208,4 @@ public class AccountSelectorAdapter extends CursorAdapter {
|
||||||
return Utility.CloseTraceCursorWrapper.get(resultCursor);
|
return Utility.CloseTraceCursorWrapper.get(resultCursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link MatrixCursor} which takes an extra {@link Cursor} to the constructor, and close
|
|
||||||
* it when self is closed.
|
|
||||||
*/
|
|
||||||
private static class ClosingMatrixCursor extends MatrixCursor {
|
|
||||||
private final Cursor mInnerCursor;
|
|
||||||
|
|
||||||
public ClosingMatrixCursor(String[] columnNames, Cursor innerCursor) {
|
|
||||||
super(columnNames);
|
|
||||||
mInnerCursor = innerCursor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
mInnerCursor.close();
|
|
||||||
super.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import com.android.email.Email;
|
||||||
import com.android.email.R;
|
import com.android.email.R;
|
||||||
import com.android.email.ResourceHelper;
|
import com.android.email.ResourceHelper;
|
||||||
import com.android.email.Utility;
|
import com.android.email.Utility;
|
||||||
|
import com.android.email.data.ClosingMatrixCursor;
|
||||||
import com.android.email.data.ThrottlingCursorLoader;
|
import com.android.email.data.ThrottlingCursorLoader;
|
||||||
import com.android.email.provider.EmailContent;
|
import com.android.email.provider.EmailContent;
|
||||||
import com.android.email.provider.EmailContent.Account;
|
import com.android.email.provider.EmailContent.Account;
|
||||||
|
@ -423,33 +424,31 @@ import android.widget.TextView;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Cursor loadInBackground() {
|
public Cursor loadInBackground() {
|
||||||
final MatrixCursor combinedWithAccounts = getSpecialMailboxesCursor(mContext);
|
|
||||||
final Cursor accounts = super.loadInBackground();
|
final Cursor accounts = super.loadInBackground();
|
||||||
try {
|
final MatrixCursor combinedWithAccounts = getSpecialMailboxesCursor(mContext, accounts);
|
||||||
accounts.moveToPosition(-1);
|
|
||||||
while (accounts.moveToNext()) {
|
accounts.moveToPosition(-1);
|
||||||
RowBuilder row = combinedWithAccounts.newRow();
|
while (accounts.moveToNext()) {
|
||||||
final long accountId = accounts.getLong(COLUMN_ACCOUND_ID);
|
RowBuilder row = combinedWithAccounts.newRow();
|
||||||
row.add(accountId);
|
final long accountId = accounts.getLong(COLUMN_ACCOUND_ID);
|
||||||
row.add(accountId);
|
row.add(accountId);
|
||||||
row.add(accounts.getString(COLUMN_ACCOUNT_DISPLAY_NAME));
|
row.add(accountId);
|
||||||
row.add(-1); // No mailbox type. Shouldn't really be used.
|
row.add(accounts.getString(COLUMN_ACCOUNT_DISPLAY_NAME));
|
||||||
final int unreadCount = Mailbox.getUnreadCountByAccountAndMailboxType(
|
row.add(-1); // No mailbox type. Shouldn't really be used.
|
||||||
mContext, accountId, Mailbox.TYPE_INBOX);
|
final int unreadCount = Mailbox.getUnreadCountByAccountAndMailboxType(
|
||||||
row.add(unreadCount);
|
mContext, accountId, Mailbox.TYPE_INBOX);
|
||||||
row.add(unreadCount);
|
row.add(unreadCount);
|
||||||
row.add(ROW_TYPE_ACCOUNT);
|
row.add(unreadCount);
|
||||||
}
|
row.add(ROW_TYPE_ACCOUNT);
|
||||||
} finally {
|
|
||||||
accounts.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Utility.CloseTraceCursorWrapper.get(combinedWithAccounts);
|
return Utility.CloseTraceCursorWrapper.get(combinedWithAccounts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ static MatrixCursor getSpecialMailboxesCursor(Context context) {
|
/* package */ static MatrixCursor getSpecialMailboxesCursor(Context context,
|
||||||
MatrixCursor cursor = new MatrixCursor(PROJECTION);
|
Cursor innerCursor) {
|
||||||
|
MatrixCursor cursor = new ClosingMatrixCursor(PROJECTION, innerCursor);
|
||||||
// Combined inbox -- show unread count
|
// Combined inbox -- show unread count
|
||||||
addSummaryMailboxRow(context, cursor,
|
addSummaryMailboxRow(context, cursor,
|
||||||
Mailbox.QUERY_ALL_INBOXES, Mailbox.TYPE_INBOX,
|
Mailbox.QUERY_ALL_INBOXES, Mailbox.TYPE_INBOX,
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011 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.email.data;
|
||||||
|
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.database.MatrixCursor;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link MatrixCursor} which takes an extra {@link Cursor} to the constructor, and close
|
||||||
|
* it when self is closed.
|
||||||
|
*/
|
||||||
|
public class ClosingMatrixCursor extends MatrixCursor {
|
||||||
|
private final Cursor mInnerCursor;
|
||||||
|
|
||||||
|
public ClosingMatrixCursor(String[] columnNames, Cursor innerCursor) {
|
||||||
|
super(columnNames);
|
||||||
|
mInnerCursor = innerCursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
if (mInnerCursor != null) {
|
||||||
|
mInnerCursor.close();
|
||||||
|
}
|
||||||
|
super.close();
|
||||||
|
}
|
||||||
|
}
|
|
@ -73,7 +73,7 @@ public class MailboxesAdapterTest extends ProviderTestCase2<EmailProvider> {
|
||||||
createMessage(c, b2t, true, true); // Starred message in trash; All Starred excludes it.
|
createMessage(c, b2t, true, true); // Starred message in trash; All Starred excludes it.
|
||||||
|
|
||||||
// Kick the method
|
// Kick the method
|
||||||
Cursor cursor = MailboxesAdapter.getSpecialMailboxesCursor(c);
|
Cursor cursor = MailboxesAdapter.getSpecialMailboxesCursor(c, null);
|
||||||
|
|
||||||
// Check the result
|
// Check the result
|
||||||
assertEquals(4, cursor.getCount());
|
assertEquals(4, cursor.getCount());
|
||||||
|
|
Loading…
Reference in New Issue