EmailWidgetLoader.java revision 0b4602b5d926d0cd1a913963497eec674cf1cea3
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.email.widget;
18
19import com.android.email.data.ThrottlingCursorLoader;
20import com.android.emailcommon.provider.EmailContent;
21import com.android.emailcommon.provider.EmailContent.Account;
22import com.android.emailcommon.provider.EmailContent.Message;
23import com.android.emailcommon.provider.EmailContent.MessageColumns;
24import com.android.emailcommon.provider.Mailbox;
25
26import android.content.Context;
27import android.database.Cursor;
28import android.database.CursorWrapper;
29
30/**
31 * Loader for {@link EmailWidget}.
32 *
33 * This loader not only loads the messages, but also:
34 * - The number of accounts.
35 * - The message count shown in the widget header.
36 *   It's currently just the same as the message count, but this will be updated to the unread
37 *   counts for inboxes.
38 */
39class EmailWidgetLoader extends ThrottlingCursorLoader {
40    private static final String SORT_TIMESTAMP_DESCENDING = MessageColumns.TIMESTAMP + " DESC";
41
42    // The projection to be used by the WidgetLoader
43    private static final String[] WIDGET_PROJECTION = new String[] {
44            EmailContent.RECORD_ID, MessageColumns.DISPLAY_NAME, MessageColumns.TIMESTAMP,
45            MessageColumns.SUBJECT, MessageColumns.FLAG_READ, MessageColumns.FLAG_FAVORITE,
46            MessageColumns.FLAG_ATTACHMENT, MessageColumns.MAILBOX_KEY, MessageColumns.SNIPPET,
47            MessageColumns.ACCOUNT_KEY, MessageColumns.FLAGS
48            };
49    public static final int WIDGET_COLUMN_ID = 0;
50    public static final int WIDGET_COLUMN_DISPLAY_NAME = 1;
51    public static final int WIDGET_COLUMN_TIMESTAMP = 2;
52    public static final int WIDGET_COLUMN_SUBJECT = 3;
53    public static final int WIDGET_COLUMN_FLAG_READ = 4;
54    public static final int WIDGET_COLUMN_FLAG_FAVORITE = 5;
55    public static final int WIDGET_COLUMN_FLAG_ATTACHMENT = 6;
56    public static final int WIDGET_COLUMN_MAILBOX_KEY = 7;
57    public static final int WIDGET_COLUMN_SNIPPET = 8;
58    public static final int WIDGET_COLUMN_ACCOUNT_KEY = 9;
59    public static final int WIDGET_COLUMN_FLAGS = 10;
60
61    private long mAccountId;
62    private long mMailboxId;
63
64    /**
65     * Cursor data specifically for use by the Email widget. Contains a cursor of messages in
66     * addition to a message count and account name. The later elements were opportunistically
67     * placed in this cursor. We could have defined multiple loaders for these items.
68     */
69    static class WidgetCursor extends CursorWrapper {
70        private final int mMessageCount;
71        private final String mAccountName;
72
73        public WidgetCursor(Cursor cursor, int messageCount, String accountName) {
74            super(cursor);
75            mMessageCount = messageCount;
76            mAccountName = accountName;
77        }
78
79        /**
80         * Gets the count to be shown on the widget header. If the currently viewed mailbox ID is
81         * not {@link Mailbox#QUERY_ALL_FAVORITES}, it is the unread count, which is different from
82         * number of records returned by {@link #getCount()}.
83         */
84        public int getMessageCount() {
85            return mMessageCount;
86        }
87        /** Gets the display name of the account */
88        public String getAccountName() {
89            return mAccountName;
90        }
91    }
92
93    private final Context mContext;
94
95    EmailWidgetLoader(Context context) {
96        super(context, Message.CONTENT_URI, WIDGET_PROJECTION, null,
97                null, SORT_TIMESTAMP_DESCENDING);
98        mContext = context;
99    }
100
101    @Override
102    public Cursor loadInBackground() {
103        final Cursor messagesCursor = super.loadInBackground();
104
105        // Reset the notification Uri to our Message table notifier URI
106        messagesCursor.setNotificationUri(mContext.getContentResolver(), Message.NOTIFIER_URI);
107
108        final int messageCount;
109        if (mMailboxId != Mailbox.QUERY_ALL_FAVORITES) {
110            String selection = "(" + getSelection() + " ) AND " + MessageColumns.FLAG_READ + " = 0";
111            messageCount = EmailContent.count(mContext, Message.CONTENT_URI, selection,
112                    getSelectionArgs());
113        } else {
114            // Just use the number of all messages shown.
115            messageCount = messagesCursor.getCount();
116        }
117        Account account = Account.restoreAccountWithId(mContext, mAccountId);
118        final String accountName;
119        if (account != null) {
120            accountName = account.mDisplayName;
121        } else {
122            accountName = null;
123        }
124
125        return new WidgetCursor(messagesCursor, messageCount, accountName);
126    }
127
128    /**
129     * Stop any pending load, reset selection parameters, and start loading.
130     *
131     * Must be called from the UI thread
132     *
133     * @param accountId The ID of the account. May be {@link Account#ACCOUNT_ID_COMBINED_VIEW}.
134     * @param mailboxId The mailbox to load; may be one of the special mailbox IDs.
135     */
136    void load(long accountId, long mailboxId) {
137        reset();
138        mAccountId = accountId;
139        mMailboxId = mailboxId;
140        setSelectionAndArgs();
141        startLoading();
142    }
143
144    /** Sets the loader's selection and arguments depending upon the account and mailbox */
145    private void setSelectionAndArgs() {
146        if (mAccountId == Account.ACCOUNT_ID_COMBINED_VIEW) {
147            if (mMailboxId == Mailbox.QUERY_ALL_INBOXES) {
148                setSelection(Message.ALL_INBOX_SELECTION);
149            } else if (mMailboxId == Mailbox.QUERY_ALL_FAVORITES) {
150                setSelection(Message.ALL_FAVORITE_SELECTION);
151            } else { // default to all unread
152                setSelection(Message.ALL_UNREAD_SELECTION);
153            }
154            setSelectionArgs(null);
155        } else {
156            if (mMailboxId > 0L) {
157                // Simple mailbox selection
158                setSelection(
159                    MessageColumns.ACCOUNT_KEY + "=? AND " +
160                    MessageColumns.MAILBOX_KEY + "=?");
161                setSelectionArgs(
162                        new String[] { Long.toString(mAccountId), Long.toString(mMailboxId) });
163            } else {
164                if (mMailboxId == Mailbox.QUERY_ALL_INBOXES) {
165                    setSelection(Message.PER_ACCOUNT_INBOX_SELECTION);
166                } else if (mMailboxId == Mailbox.QUERY_ALL_FAVORITES) {
167                    setSelection(Message.PER_ACCOUNT_FAVORITE_SELECTION);
168                } else { // default to all unread for the account's inbox
169                    setSelection(Message.PER_ACCOUNT_UNREAD_SELECTION);
170                }
171                setSelectionArgs(new String[] { Long.toString(mAccountId) });
172            }
173        }
174    }
175}
176