• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.email.widget;
18 
19 import com.android.email.R;
20 import com.android.email.data.ThrottlingCursorLoader;
21 import com.android.emailcommon.provider.Account;
22 import com.android.emailcommon.provider.EmailContent;
23 import com.android.emailcommon.provider.EmailContent.Message;
24 import com.android.emailcommon.provider.EmailContent.MessageColumns;
25 import com.android.emailcommon.provider.Mailbox;
26 
27 import android.content.Context;
28 import android.content.res.Resources;
29 import android.database.Cursor;
30 import android.database.CursorWrapper;
31 
32 /**
33  * Loader for {@link EmailWidget}.
34  *
35  * This loader not only loads the messages, but also:
36  * - The number of accounts.
37  * - The message count shown in the widget header.
38  *   It's currently just the same as the message count, but this will be updated to the unread
39  *   counts for inboxes.
40  */
41 class EmailWidgetLoader extends ThrottlingCursorLoader {
42     private static final String SORT_TIMESTAMP_DESCENDING = MessageColumns.TIMESTAMP + " DESC";
43 
44     // The projection to be used by the WidgetLoader
45     private static final String[] WIDGET_PROJECTION = new String[] {
46             EmailContent.RECORD_ID, MessageColumns.DISPLAY_NAME, MessageColumns.TIMESTAMP,
47             MessageColumns.SUBJECT, MessageColumns.FLAG_READ, MessageColumns.FLAG_FAVORITE,
48             MessageColumns.FLAG_ATTACHMENT, MessageColumns.MAILBOX_KEY, MessageColumns.SNIPPET,
49             MessageColumns.ACCOUNT_KEY, MessageColumns.FLAGS
50             };
51     public static final int WIDGET_COLUMN_ID = 0;
52     public static final int WIDGET_COLUMN_DISPLAY_NAME = 1;
53     public static final int WIDGET_COLUMN_TIMESTAMP = 2;
54     public static final int WIDGET_COLUMN_SUBJECT = 3;
55     public static final int WIDGET_COLUMN_FLAG_READ = 4;
56     public static final int WIDGET_COLUMN_FLAG_FAVORITE = 5;
57     public static final int WIDGET_COLUMN_FLAG_ATTACHMENT = 6;
58     public static final int WIDGET_COLUMN_MAILBOX_KEY = 7;
59     public static final int WIDGET_COLUMN_SNIPPET = 8;
60     public static final int WIDGET_COLUMN_ACCOUNT_KEY = 9;
61     public static final int WIDGET_COLUMN_FLAGS = 10;
62 
63     private long mAccountId;
64     private long mMailboxId;
65 
66     /**
67      * Cursor data specifically for use by the Email widget. Contains a cursor of messages in
68      * addition to a message count and account name. The later elements were opportunistically
69      * placed in this cursor. We could have defined multiple loaders for these items.
70      */
71     static class WidgetCursor extends CursorWrapper {
72         private final int mMessageCount;
73         private final String mAccountName;
74         private final String mMailboxName;
75 
WidgetCursor(Cursor cursor, int messageCount, String accountName, String mailboxName)76         public WidgetCursor(Cursor cursor, int messageCount, String accountName,
77                 String mailboxName) {
78             super(cursor);
79             mMessageCount = messageCount;
80             mAccountName = accountName;
81             mMailboxName = mailboxName;
82         }
83 
84         /**
85          * Gets the count to be shown on the widget header. If the currently viewed mailbox ID is
86          * not {@link Mailbox#QUERY_ALL_FAVORITES}, it is the unread count, which is different from
87          * number of records returned by {@link #getCount()}.
88          */
getMessageCount()89         public int getMessageCount() {
90             return mMessageCount;
91         }
92         /** Gets the display name of the account */
getAccountName()93         public String getAccountName() {
94             return mAccountName;
95         }
96         /** Gets the display name of the mailbox */
getMailboxName()97         public String getMailboxName() {
98             return mMailboxName;
99         }
100     }
101 
102     private final Context mContext;
103 
EmailWidgetLoader(Context context)104     EmailWidgetLoader(Context context) {
105         super(context, Message.CONTENT_URI, WIDGET_PROJECTION, null,
106                 null, SORT_TIMESTAMP_DESCENDING);
107         mContext = context;
108     }
109 
110     @Override
loadInBackground()111     public Cursor loadInBackground() {
112         final Cursor messagesCursor = super.loadInBackground();
113 
114         // Reset the notification Uri to our Message table notifier URI
115         messagesCursor.setNotificationUri(mContext.getContentResolver(), Message.NOTIFIER_URI);
116 
117         final int messageCount;
118         if (mMailboxId != Mailbox.QUERY_ALL_FAVORITES) {
119             String selection = "(" + getSelection() + " ) AND " + MessageColumns.FLAG_READ + " = 0";
120             messageCount = EmailContent.count(mContext, Message.CONTENT_URI, selection,
121                     getSelectionArgs());
122         } else {
123             // Just use the number of all messages shown.
124             messageCount = messagesCursor.getCount();
125         }
126         Account account = Account.restoreAccountWithId(mContext, mAccountId);
127         final String accountName;
128         if (account != null) {
129             accountName = account.mDisplayName;
130         } else {
131             if (mAccountId == Account.ACCOUNT_ID_COMBINED_VIEW) {
132                 int accountCount = EmailContent.count(mContext, Account.CONTENT_URI);
133                 Resources res = mContext.getResources();
134                 String countString =
135                         res.getQuantityString(R.plurals.picker_combined_view_account_count,
136                         accountCount, accountCount);
137                 accountName = res.getString(R.string.picker_combined_view_fmt, countString);
138             } else {
139                 // TODO What to use here? "unknown"? Account is real, but, doesn't exist.
140                 accountName = null;
141             }
142         }
143         final String mailboxName;
144         if (mMailboxId > 0) {
145             Mailbox mailbox = Mailbox.restoreMailboxWithId(mContext, mMailboxId);
146             if (mailbox != null) {
147                 mailboxName = mailbox.mDisplayName;    // regular mailbox
148             } else {
149                 // TODO What use here? "unknown"? Mailbox is "real", but, doesn't exist.
150                 mailboxName = null;
151             }
152         } else {
153             if (mMailboxId == Mailbox.QUERY_ALL_INBOXES) {
154                 mailboxName = mContext.getString(R.string.picker_mailbox_name_all_inbox);
155             } else { // default to all unread for the account's inbox
156                 mailboxName = mContext.getString(R.string.picker_mailbox_name_all_unread);
157             }
158         }
159 
160         return new WidgetCursor(messagesCursor, messageCount, accountName, mailboxName);
161     }
162 
163     /**
164      * Stop any pending load, reset selection parameters, and start loading.
165      *
166      * Must be called from the UI thread
167      *
168      * @param accountId The ID of the account. May be {@link Account#ACCOUNT_ID_COMBINED_VIEW}.
169      * @param mailboxId The mailbox to load; may either be a real mailbox or the pseudo mailbox
170      *          {@link Mailbox#QUERY_ALL_INBOXES} or {@link Mailbox#QUERY_ALL_UNREAD}. If it's
171      *          neither of these pseudo mailboxes, {@link Mailbox#QUERY_ALL_UNREAD} will be used.
172      */
load(long accountId, long mailboxId)173     void load(long accountId, long mailboxId) {
174         reset();
175         mAccountId = accountId;
176         mMailboxId = mailboxId;
177         setSelectionAndArgs();
178         startLoading();
179     }
180 
181     /** Sets the loader's selection and arguments depending upon the account and mailbox */
setSelectionAndArgs()182     private void setSelectionAndArgs() {
183         if (mAccountId == Account.ACCOUNT_ID_COMBINED_VIEW) {
184             if (mMailboxId == Mailbox.QUERY_ALL_INBOXES) {
185                 setSelection(Message.ALL_INBOX_SELECTION);
186             } else { // default to all unread
187                 setSelection(Message.ALL_UNREAD_SELECTION);
188             }
189             setSelectionArgs(null);
190         } else {
191             if (mMailboxId > 0L) {
192                 // Simple mailbox selection
193                 setSelection(
194                     MessageColumns.ACCOUNT_KEY + "=? AND " +
195                     MessageColumns.MAILBOX_KEY + "=?");
196                 setSelectionArgs(
197                         new String[] { Long.toString(mAccountId), Long.toString(mMailboxId) });
198             } else {
199                 if (mMailboxId == Mailbox.QUERY_ALL_INBOXES) {
200                     setSelection(Message.PER_ACCOUNT_INBOX_SELECTION);
201                 } else { // default to all unread for the account's inbox
202                     setSelection(Message.PER_ACCOUNT_UNREAD_SELECTION);
203                 }
204                 setSelectionArgs(new String[] { Long.toString(mAccountId) });
205             }
206         }
207     }
208 }
209