diff --git a/emailcommon/src/com/android/emailcommon/provider/EmailContent.java b/emailcommon/src/com/android/emailcommon/provider/EmailContent.java
index 867c12dbc..bc5d44b41 100644
--- a/emailcommon/src/com/android/emailcommon/provider/EmailContent.java
+++ b/emailcommon/src/com/android/emailcommon/provider/EmailContent.java
@@ -631,6 +631,10 @@ public abstract class EmailContent {
public static final String ALL_UNREAD_SELECTION =
MessageColumns.FLAG_READ + "=0 AND " + ALL_INBOX_SELECTION;
+ /** Selection to retrieve unread messages in "inbox" for one account */
+ public static final String PER_ACCOUNT_UNREAD_SELECTION =
+ ACCOUNT_KEY_SELECTION + " AND " + ALL_UNREAD_SELECTION;
+
/** Selection to retrieve all messages in "inbox" for one account */
public static final String PER_ACCOUNT_INBOX_SELECTION =
ACCOUNT_KEY_SELECTION + " AND " + ALL_INBOX_SELECTION;
diff --git a/emailcommon/src/com/android/emailcommon/provider/Mailbox.java b/emailcommon/src/com/android/emailcommon/provider/Mailbox.java
index 97f8195dc..3e007014a 100644
--- a/emailcommon/src/com/android/emailcommon/provider/Mailbox.java
+++ b/emailcommon/src/com/android/emailcommon/provider/Mailbox.java
@@ -531,4 +531,4 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns
return new Mailbox[size];
}
};
-}
\ No newline at end of file
+}
diff --git a/src/com/android/email/provider/WidgetProvider.java b/src/com/android/email/provider/WidgetProvider.java
index 0e20a76a1..12f7b3ce3 100644
--- a/src/com/android/email/provider/WidgetProvider.java
+++ b/src/com/android/email/provider/WidgetProvider.java
@@ -55,7 +55,7 @@ public class WidgetProvider extends AppWidgetProvider {
Log.d(EmailWidget.TAG, "onUpdate");
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
- WidgetManager.getInstance().getOrCreateWidgets(context, appWidgetIds);
+ WidgetManager.getInstance().createWidgets(context, appWidgetIds);
}
@Override
diff --git a/src/com/android/email/service/EmailBroadcastProcessorService.java b/src/com/android/email/service/EmailBroadcastProcessorService.java
index 24963fb55..07e10d89e 100644
--- a/src/com/android/email/service/EmailBroadcastProcessorService.java
+++ b/src/com/android/email/service/EmailBroadcastProcessorService.java
@@ -225,8 +225,5 @@ public class EmailBroadcastProcessorService extends IntentService {
// If the exchange service wasn't already running, starting it will cause exchange account
// reconciliation to be performed. The service stops itself it there are no EAS accounts.
ExchangeUtils.startExchangeService(this);
-
- // Let all of the widgets update
- WidgetManager.getInstance().updateAllWidgets();
}
}
diff --git a/src/com/android/email/widget/EmailWidget.java b/src/com/android/email/widget/EmailWidget.java
index 18f028e1a..47045c19c 100644
--- a/src/com/android/email/widget/EmailWidget.java
+++ b/src/com/android/email/widget/EmailWidget.java
@@ -23,15 +23,16 @@ import com.android.email.activity.MessageCompose;
import com.android.email.activity.UiUtilities;
import com.android.email.activity.Welcome;
import com.android.email.provider.WidgetProvider.WidgetService;
+import com.android.emailcommon.provider.EmailContent.Account;
+import com.android.emailcommon.provider.EmailContent.AccountColumns;
import com.android.emailcommon.provider.EmailContent.Message;
import com.android.emailcommon.provider.Mailbox;
import com.android.emailcommon.utility.EmailAsyncTask;
-import com.android.emailcommon.utility.Utility;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
-import android.content.ContentUris;
import android.content.Context;
+import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
import android.content.Loader.OnLoadCompleteListener;
@@ -57,11 +58,8 @@ import java.util.List;
/**
* The email widget.
- *
- * Threading notes:
- * - All methods must be called on the UI thread, except for {@link WidgetUpdater#doInBackground}.
- * - {@link WidgetUpdater#doInBackground} must not read/write any members of {@link EmailWidget}.
- * - (So no synchronizations are required in this class)
+ *
NOTE: All methods must be called on the UI thread so synchronization is NOT required
+ * in this class)
*/
public class EmailWidget implements RemoteViewsService.RemoteViewsFactory,
OnLoadCompleteListener {
@@ -90,16 +88,22 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory,
private static final Uri COMMAND_URI = Uri.parse("widget://command");
// Command names and Uri's built upon COMMAND_URI
- private static final String COMMAND_NAME_SWITCH_LIST_VIEW = "switch_list_view";
- private static final Uri COMMAND_URI_SWITCH_LIST_VIEW =
- COMMAND_URI.buildUpon().appendPath(COMMAND_NAME_SWITCH_LIST_VIEW).build();
private static final String COMMAND_NAME_VIEW_MESSAGE = "view_message";
private static final Uri COMMAND_URI_VIEW_MESSAGE =
COMMAND_URI.buildUpon().appendPath(COMMAND_NAME_VIEW_MESSAGE).build();
private static final int MAX_MESSAGE_LIST_COUNT = 25;
+ // TODO Temporary selection / projection to pick the first account defined. Remove once the
+ // account / mailbox picker activity is added
+ private static final String SORT_ID_ASCENDING = AccountColumns.ID + " ASC";
+ private static final String[] ID_NAME_PROJECTION =
+ { AccountColumns.ID, AccountColumns.DISPLAY_NAME };
+ private static final int ID_NAME_COLUMN_ID = 0;
+ private static final int ID_NAME_COLUMN_NAME = 1;
+
private static String sSubjectSnippetDivider;
+ @SuppressWarnings("unused")
private static String sConfigureText;
private static int sSenderFontSize;
private static int sSubjectFontSize;
@@ -117,6 +121,10 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory,
private final EmailWidgetLoader mLoader;
private final ResourceHelper mResourceHelper;
+ private long mAccountId = Account.NO_ACCOUNT;
+ private long mMailboxId = Mailbox.NO_MAILBOX;
+ private String mAccountName;
+
/**
* The cursor for the messages, with some extra info such as the number of accounts.
*
@@ -125,9 +133,6 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory,
*/
private EmailWidgetLoader.CursorWithCounts mCursor;
- /** The current view type */
- /* package */ WidgetView mWidgetView = WidgetView.UNINITIALIZED_VIEW;
-
private final EmailAsyncTask.Tracker mTaskTracker = new EmailAsyncTask.Tracker();
public EmailWidget(Context context, int _widgetId) {
@@ -158,9 +163,23 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory,
}
public void start() {
- // The default view is UNINITIALIZED_VIEW, and we switch to the next one, which should
- // be the initial view. (the first view shown to the user.)
- switchView();
+ // TODO By default, pick an account to display the widget for. This should all be removed
+ // once the widget configuration activity is hooked up.
+ CursorLoader accountLoader = new CursorLoader(
+ mContext, Account.CONTENT_URI, ID_NAME_PROJECTION, null, null, SORT_ID_ASCENDING);
+ accountLoader.registerListener(1, new OnLoadCompleteListener() {
+ @Override
+ public void onLoadComplete(android.content.Loader loader, Cursor data) {
+ long accountId = Account.NO_ACCOUNT;
+ String accountName = null;
+ if (data != null && data.moveToFirst()) {
+ accountId = data.getLong(ID_NAME_COLUMN_ID);
+ accountName = data.getString(ID_NAME_COLUMN_NAME);
+ }
+ loadView(accountId, accountName);
+ }
+ });
+ accountLoader.startLoading();
}
private boolean isCursorValid() {
@@ -174,7 +193,6 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory,
public void onLoadComplete(Loader loader, Cursor cursor) {
// Save away the cursor
mCursor = (EmailWidgetLoader.CursorWithCounts) cursor;
- mWidgetView = mLoader.getLoadingWidgetView();
RemoteViews views = new RemoteViews(mContext.getPackageName(), R.layout.widget);
updateHeader();
@@ -187,25 +205,10 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory,
* Start loading the data. At this point nothing on the widget changes -- the current view
* will remain valid until the loader loads the latest data.
*/
- private void loadView(WidgetView view) {
- mLoader.load(view);
- }
-
- /**
- * Convenience method for creating an onClickPendingIntent that executes a command via
- * our command Uri. Used for the "next view" command; appends the widget id to the command
- * Uri.
- *
- * @param views The RemoteViews we're inflating
- * @param buttonId the id of the button view
- * @param data the command Uri
- */
- private void setCommandIntent(RemoteViews views, int buttonId, Uri data) {
- Intent intent = new Intent(mContext, WidgetService.class);
- intent.setDataAndType(ContentUris.withAppendedId(data, mWidgetId), WIDGET_DATA_MIME_TYPE);
- PendingIntent pendingIntent = PendingIntent.getService(mContext, 0, intent,
- PendingIntent.FLAG_UPDATE_CURRENT);
- views.setOnClickPendingIntent(buttonId, pendingIntent);
+ private void loadView(long accountId, String accountName) {
+ mAccountId = accountId;
+ mAccountName = accountName;
+ mLoader.load(mAccountId, mMailboxId);
}
/**
@@ -263,12 +266,6 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory,
if (EmailWidget.COMMAND_NAME_VIEW_MESSAGE.equals(command)) {
// "view", ,
openMessage(context, Long.parseLong(pathSegments.get(2)), arg1);
- } else if (EmailWidget.COMMAND_NAME_SWITCH_LIST_VIEW.equals(command)) {
- // "next_view",
- EmailWidget widget = WidgetManager.getInstance().get((int)arg1);
- if (widget != null) {
- widget.switchView();
- }
}
} catch (NumberFormatException e) {
// Shouldn't happen as we construct all of the Uri's
@@ -279,7 +276,7 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory,
private static void openMessage(final Context context, final long mailboxId,
final long messageId) {
- Utility.runAsync(new Runnable() {
+ EmailAsyncTask.runAsyncParallel(new Runnable() {
@Override
public void run() {
Mailbox mailbox = Mailbox.restoreMailboxWithId(context, mailboxId);
@@ -292,8 +289,10 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory,
private void setupTitleAndCount(RemoteViews views) {
// Set up the title (view type + count of messages)
- views.setTextViewText(R.id.widget_title, mWidgetView.getTitle(mContext));
- views.setTextViewText(R.id.widget_tap, sConfigureText);
+ views.setTextViewText(R.id.widget_title, mAccountName);
+ // TODO Temporary UX; need to make this visible and create the correct UX
+ //views.setTextViewText(R.id.widget_tap, sConfigureText);
+ views.setViewVisibility(R.id.widget_tap, View.INVISIBLE);
String count = "";
if (isCursorValid()) {
count = UiUtilities.getMessageCountForUi(mContext, mCursor.getMessageCount(), false);
@@ -317,11 +316,11 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory,
Intent intent = new Intent(mContext, WidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mWidgetId);
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
- views.setRemoteAdapter(mWidgetId, R.id.message_list, intent);
+ views.setRemoteAdapter(R.id.message_list, intent);
setupTitleAndCount(views);
- if (!isCursorValid() || mCursor.getAccountCount() == 0) {
+ if (!isCursorValid() || mAccountId == Account.NO_ACCOUNT) {
// Hide compose icon & show "touch to configure" text
views.setViewVisibility(R.id.widget_compose, View.INVISIBLE);
views.setViewVisibility(R.id.message_list, View.GONE);
@@ -338,8 +337,6 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory,
intent = MessageCompose.getMessageComposeIntent(mContext, -1);
setActivityIntent(views, R.id.widget_compose, intent);
}
- // Create click intent for "view rotation" target
- setCommandIntent(views, R.id.widget_logo, COMMAND_URI_SWITCH_LIST_VIEW);
// Use a bare intent for our template; we need to fill everything in
intent = new Intent(mContext, WidgetService.class);
@@ -452,7 +449,7 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory,
views.setViewVisibility(R.id.widget_attachment,
hasAttachment ? View.VISIBLE : View.GONE);
- if (mCursor.getAccountCount() <= 1 || mWidgetView.isPerAccount()) {
+ if (mAccountId != Account.ACCOUNT_ID_COMBINED_VIEW) {
views.setViewVisibility(R.id.color_chip, View.INVISIBLE);
} else {
long accountId = mCursor.getLong(EmailWidgetLoader.WIDGET_COLUMN_ACCOUNT_KEY);
@@ -513,7 +510,6 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory,
if (mLoader != null) {
mLoader.reset();
}
- WidgetManager.getInstance().remove(mWidgetId);
}
@Override
@@ -522,57 +518,14 @@ public class EmailWidget implements RemoteViewsService.RemoteViewsFactory,
mLoader.reset();
}
mTaskTracker.cancellAllInterrupt();
- WidgetManager.getInstance().remove(mWidgetId);
}
@Override
public void onCreate() {
}
- /**
- * Update the widget. If the current view is invalid, switch to the next view, then update.
- */
- /* package */ void validateAndUpdate() {
- new WidgetUpdater(this, false).cancelPreviousAndExecuteParallel();
- }
-
- /**
- * Switch to the next view.
- */
- /* package */ void switchView() {
- new WidgetUpdater(this, true).cancelPreviousAndExecuteParallel();
- }
-
- /**
- * Update the widget. If {@code switchToNextView} is set true, or the current view is invalid,
- * switch to the next view.
- */
- private static class WidgetUpdater extends EmailAsyncTask {
- private final EmailWidget mParent;
- private final WidgetView mCurrentView;
- private final boolean mSwitchToNextView;
-
- public WidgetUpdater(EmailWidget parent, boolean switchToNextView) {
- super(parent.mTaskTracker);
- mParent = parent;
- mCurrentView = mParent.mWidgetView;
- mSwitchToNextView = switchToNextView;
- }
-
- @Override
- protected WidgetView doInBackground(Void... params) {
- if (mSwitchToNextView || !mCurrentView.isValid(mParent.mContext)) {
- return mCurrentView.getNext(mParent.mContext);
- } else {
- return mCurrentView; // Reload the same view.
- }
- }
-
- @Override
- protected void onPostExecute(WidgetView nextView) {
- if (nextView != null) {
- mParent.loadView(nextView);
- }
- }
+ @Override
+ public String toString() {
+ return "View=" + mAccountName;
}
}
diff --git a/src/com/android/email/widget/EmailWidgetLoader.java b/src/com/android/email/widget/EmailWidgetLoader.java
index b145f910b..ca818496f 100644
--- a/src/com/android/email/widget/EmailWidgetLoader.java
+++ b/src/com/android/email/widget/EmailWidgetLoader.java
@@ -18,9 +18,9 @@ package com.android.email.widget;
import com.android.email.data.ThrottlingCursorLoader;
import com.android.emailcommon.provider.EmailContent;
-import com.android.emailcommon.provider.EmailContent.Account;
import com.android.emailcommon.provider.EmailContent.Message;
import com.android.emailcommon.provider.EmailContent.MessageColumns;
+import com.android.emailcommon.provider.Mailbox;
import android.content.Context;
import android.database.Cursor;
@@ -35,7 +35,7 @@ import android.database.CursorWrapper;
* It's currently just the same as the message count, but this will be updated to the unread
* counts for inboxes.
*/
-/* package */ class EmailWidgetLoader extends ThrottlingCursorLoader {
+class EmailWidgetLoader extends ThrottlingCursorLoader {
private static final String SORT_TIMESTAMP_DESCENDING = MessageColumns.TIMESTAMP + " DESC";
// The projection to be used by the WidgetLoader
@@ -57,23 +57,20 @@ import android.database.CursorWrapper;
public static final int WIDGET_COLUMN_ACCOUNT_KEY = 9;
public static final int WIDGET_COLUMN_FLAGS = 10;
+ private long mAccountId;
+ private long mMailboxId;
+
/**
* The actual data returned by this loader.
*/
- public static class CursorWithCounts extends CursorWrapper {
- private final int mAccountCount;
+ static class CursorWithCounts extends CursorWrapper {
private final int mMessageCount;
- public CursorWithCounts(Cursor cursor, int accountCount, int messageCount) {
+ public CursorWithCounts(Cursor cursor, int messageCount) {
super(cursor);
- mAccountCount = accountCount;
mMessageCount = messageCount;
}
- public int getAccountCount() {
- return mAccountCount;
- }
-
/**
* @return The count that should be shown on the widget header.
* Note depending on the view, it may be the unread count, which is different from
@@ -86,9 +83,7 @@ import android.database.CursorWrapper;
private final Context mContext;
- private WidgetView mLoadingWidgetView;
-
- public EmailWidgetLoader(Context context) {
+ EmailWidgetLoader(Context context) {
super(context, Message.CONTENT_URI, WIDGET_PROJECTION, null,
null, SORT_TIMESTAMP_DESCENDING);
mContext = context;
@@ -101,17 +96,17 @@ import android.database.CursorWrapper;
// Reset the notification Uri to our Message table notifier URI
messagesCursor.setNotificationUri(mContext.getContentResolver(), Message.NOTIFIER_URI);
- final int accountCount = EmailContent.count(mContext, Account.CONTENT_URI);
-
final int messageCount;
- if (mLoadingWidgetView.useUnreadCount()) {
- messageCount = mLoadingWidgetView.getUnreadCount(mContext);
+ if (mMailboxId != Mailbox.QUERY_ALL_FAVORITES) {
+ String selection = "(" + getSelection() + " ) AND " + MessageColumns.FLAG_READ + " = 0";
+ messageCount = EmailContent.count(mContext, Message.CONTENT_URI, selection,
+ getSelectionArgs());
} else {
// Just use the number of all messages shown.
messageCount = messagesCursor.getCount();
}
- return new CursorWithCounts(messagesCursor, accountCount, messageCount);
+ return new CursorWithCounts(messagesCursor, messageCount);
}
/**
@@ -119,22 +114,15 @@ import android.database.CursorWrapper;
*
* Must be called from the UI thread
*
- * @param view the current ViewType
+ * @param accountId
+ * @param mailboxId
*/
- public void load(WidgetView view) {
+ void load(long accountId, long mailboxId) {
reset();
- mLoadingWidgetView = view;
- setSelection(view.getSelection());
- setSelectionArgs(view.getSelectionArgs());
+ mAccountId = accountId;
+ mMailboxId = mailboxId;
+ setSelection(Message.PER_ACCOUNT_UNREAD_SELECTION);
+ setSelectionArgs(new String[]{ Long.toString(mAccountId) });
startLoading();
}
-
- /**
- * @return the {@link WidgetView} that is (being) loaded.
- *
- * Must be called from the UI thread
- */
- public WidgetView getLoadingWidgetView() {
- return mLoadingWidgetView;
- }
}
diff --git a/src/com/android/email/widget/WidgetManager.java b/src/com/android/email/widget/WidgetManager.java
index 20a890db6..fefa89394 100644
--- a/src/com/android/email/widget/WidgetManager.java
+++ b/src/com/android/email/widget/WidgetManager.java
@@ -43,19 +43,9 @@ public class WidgetManager {
return sInstance;
}
- /**
- * Updates all active widgets. If no widgets are active, does nothing.
- */
- public synchronized void updateAllWidgets() {
- for (EmailWidget widget: mWidgets.values()) {
- // Anything could have changed; update widget & validate the current view
- widget.validateAndUpdate();
- }
- }
-
- public synchronized void getOrCreateWidgets(Context context, int[] widgetIds) {
+ public synchronized void createWidgets(Context context, int[] widgetIds) {
for (int widgetId : widgetIds) {
- getOrCreateWidget(context, widgetId).validateAndUpdate();
+ getOrCreateWidget(context, widgetId);
}
}
@@ -67,10 +57,11 @@ public class WidgetManager {
// Stop loading and remove the widget from the map
widget.onDeleted();
}
+ remove(widgetId);
}
}
- public EmailWidget getOrCreateWidget(Context context, int widgetId) {
+ public synchronized EmailWidget getOrCreateWidget(Context context, int widgetId) {
EmailWidget widget = WidgetManager.getInstance().get(widgetId);
if (widget == null) {
if (Email.DEBUG) {
@@ -83,15 +74,15 @@ public class WidgetManager {
return widget;
}
- public EmailWidget get(int widgetId) {
+ private EmailWidget get(int widgetId) {
return mWidgets.get(widgetId);
}
- /* package */ void put(int widgetId, EmailWidget widget) {
+ private void put(int widgetId, EmailWidget widget) {
mWidgets.put(widgetId, widget);
}
- /* package */ void remove(int widgetId) {
+ private void remove(int widgetId) {
mWidgets.remove(widgetId);
}
@@ -99,7 +90,7 @@ public class WidgetManager {
int n = 0;
for (EmailWidget widget : mWidgets.values()) {
writer.println("Widget #" + (++n));
- writer.println(" View=" + widget.mWidgetView);
+ writer.println(" " + widget.toString());
}
}
}
diff --git a/src/com/android/email/widget/WidgetView.java b/src/com/android/email/widget/WidgetView.java
deleted file mode 100644
index b913680da..000000000
--- a/src/com/android/email/widget/WidgetView.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * 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.widget;
-
-import com.android.email.R;
-import com.android.emailcommon.provider.EmailContent;
-import com.android.emailcommon.provider.EmailContent.Account;
-import com.android.emailcommon.provider.EmailContent.AccountColumns;
-import com.android.emailcommon.provider.EmailContent.Message;
-import com.android.emailcommon.provider.EmailContent.MessageColumns;
-import com.android.emailcommon.utility.Utility;
-
-import android.content.ContentUris;
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-
-/**
- * Represents the "view" of the widget.
- *
- * It's a {@link ViewType} + mutable fields. (e.g. account id/name)
- */
-/* package */ class WidgetView {
- private static final String SORT_ID_ASCENDING = AccountColumns.ID + " ASC";
- private static final String[] ID_NAME_PROJECTION = {Account.RECORD_ID, Account.DISPLAY_NAME};
- private static final int ID_NAME_COLUMN_ID = 0;
- private static final int ID_NAME_COLUMN_NAME = 1;
-
- private static enum ViewType {
- TYPE_ALL_UNREAD(false, Message.ALL_UNREAD_SELECTION, R.string.widget_unread, false),
- TYPE_ALL_STARRED(false, Message.ALL_FAVORITE_SELECTION, R.string.widget_starred, false),
- TYPE_ALL_INBOX(false, Message.ALL_INBOX_SELECTION, R.string.widget_all_mail, true),
- TYPE_ACCOUNT_INBOX(true, Message.PER_ACCOUNT_INBOX_SELECTION, 0, true) {
- @Override public String getTitle(Context context, String accountName) {
- return accountName;
- }
-
- @Override public String[] getSelectionArgs(long accountId) {
- return new String[]{Long.toString(accountId)};
- }
- };
-
- private final boolean mIsPerAccount;
- private final String mSelection;
- private final int mTitleResource;
- private final boolean mUseUnreadCount;
-
- ViewType(boolean isPerAccount, String selection, int titleResource,
- boolean useUnreadCount) {
- mIsPerAccount = isPerAccount;
- mSelection = selection;
- mTitleResource = titleResource;
- mUseUnreadCount = useUnreadCount;
- }
-
- public String getTitle(Context context, String accountName) {
- return context.getString(mTitleResource);
- }
-
- public String getSelection() {
- return mSelection;
- }
-
- public String[] getSelectionArgs(long accountId) {
- return null;
- }
- }
-
- /* package */ static final WidgetView ALL_UNREAD = new WidgetView(ViewType.TYPE_ALL_UNREAD);
- /* package */ static final WidgetView ALL_STARRED = new WidgetView(ViewType.TYPE_ALL_STARRED);
- /* package */ static final WidgetView ALL_INBOX = new WidgetView(ViewType.TYPE_ALL_INBOX);
-
- /**
- * The initial view will be the *next* of ALL_STARRED -- see {@link #getNext}.
- */
- public static final WidgetView UNINITIALIZED_VIEW = ALL_STARRED;
-
- private final ViewType mViewType;
- /** Account ID -- set only when isPerAccount */
- private final long mAccountId;
- /** Account name -- set only when isPerAccount */
- private final String mAccountName;
-
- private WidgetView(ViewType viewType) {
- this(viewType, 0, null);
- }
-
- private WidgetView(ViewType viewType, long accountId, String accountName) {
- mViewType = viewType;
- mAccountId = accountId;
- mAccountName = accountName;
- }
-
- public boolean isPerAccount() {
- return mViewType.mIsPerAccount;
- }
-
- public String getTitle(Context context) {
- return mViewType.getTitle(context, mAccountName);
- }
-
- public boolean useUnreadCount() {
- return mViewType.mUseUnreadCount;
- }
-
- public String getSelection() {
- return mViewType.getSelection();
- }
-
- public String[] getSelectionArgs() {
- return mViewType.getSelectionArgs(mAccountId);
- }
-
- /**
- * Switch to the "next" view.
- *
- * Views rotate in this order:
- * - {@link #ALL_STARRED}
- * - {@link #ALL_INBOX} -- this will be skipped if # of accounts <= 1
- * - Inbox for account 1
- * - Inbox for account 2
- * - :
- * - {@link #ALL_UNREAD}
- * - Go back to {@link #ALL_STARRED}.
- *
- * Note the initial view is always the next of {@link #ALL_STARRED}.
- */
- public WidgetView getNext(Context context) {
- if (mViewType == ViewType.TYPE_ALL_UNREAD) {
- return ALL_STARRED;
- }
- if (mViewType == ViewType.TYPE_ALL_STARRED) {
- // If we're in starred and there is more than one account, go to "all mail"
- // Otherwise, fall through to the accounts themselves
- if (EmailContent.count(context, Account.CONTENT_URI) > 1) {
- return ALL_INBOX;
- }
- }
- final long nextAccountIdStart;
- if (mViewType == ViewType.TYPE_ALL_INBOX) {
- nextAccountIdStart = -1;
- } else { // TYPE_ACCOUNT_INBOX
- nextAccountIdStart = mAccountId + 1;
- }
- Cursor c = context.getContentResolver().query(Account.CONTENT_URI, ID_NAME_PROJECTION,
- "_id>=?", new String[] {Long.toString(nextAccountIdStart)}, SORT_ID_ASCENDING);
-
- final long nextAccountId;
- final String nextAccountName;
- try {
- if (c.moveToFirst()) {
- return new WidgetView(ViewType.TYPE_ACCOUNT_INBOX, c.getLong(ID_NAME_COLUMN_ID),
- c.getString(ID_NAME_COLUMN_NAME));
- } else {
- return ALL_UNREAD;
- }
- } finally {
- c.close();
- }
- }
-
- /**
- * Returns whether the current view is valid. The following rules determine if a view is
- * considered valid:
- * 1. {@link ViewType#TYPE_ALL_STARRED} and {@link ViewType#TYPE_ALL_UNREAD} are always
- * valid.
- * 2. If the view is {@link ViewType#TYPE_ALL_INBOX}, returns true
if more than
- * one account is defined. Otherwise, returns false
.
- * 3. If the view is {@link ViewType#TYPE_ACCOUNT_INBOX}, returns true
if the
- * account is defined. Otherwise, returns false
.
- */
- public boolean isValid(Context context) {
- switch(mViewType) {
- case TYPE_ALL_INBOX:
- // "all inbox" is valid only if there is more than one account
- return (EmailContent.count(context, Account.CONTENT_URI) > 1);
- case TYPE_ACCOUNT_INBOX:
- // Ensure current account still exists
- Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, mAccountId);
- return Utility.getFirstRowLong(context, uri,
- EmailContent.ID_PROJECTION, null, null, null,
- EmailContent.ID_PROJECTION_COLUMN, null) != null;
- }
- return true;
- }
-
- /**
- * @return unread message count using the selection.
- */
- public int getUnreadCount(Context context) {
- String selection = "(" + getSelection() + " ) AND " + MessageColumns.FLAG_READ + " = 0";
- return EmailContent.count(context, Message.CONTENT_URI, selection,
- getSelectionArgs());
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("WidgetView:type=");
- sb.append(mViewType);
- sb.append(" account=");
- sb.append(mAccountId);
-
- return sb.toString();
- }
-}
diff --git a/tests/src/com/android/email/widget/WidgetViewTests.java b/tests/src/com/android/email/widget/WidgetViewTests.java
deleted file mode 100644
index 6caec9042..000000000
--- a/tests/src/com/android/email/widget/WidgetViewTests.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/* 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.widget;
-
-import com.android.email.provider.EmailProvider;
-import com.android.email.provider.ProviderTestUtils;
-import com.android.emailcommon.provider.EmailContent;
-import com.android.emailcommon.provider.EmailContent.Account;
-import com.android.emailcommon.provider.EmailContent.Message;
-import com.android.emailcommon.provider.Mailbox;
-
-import android.content.Context;
-import android.test.ProviderTestCase2;
-
-/**
- * Tests of EmailWidget
- *
- * You can run this entire test case with:
- * runtest -c com.android.email.widget.WidgetView email
- */
-public class WidgetViewTests extends ProviderTestCase2 {
- private Context mMockContext;
-
- public WidgetViewTests() {
- super(EmailProvider.class, EmailContent.AUTHORITY);
- }
-
- @Override
- public void setUp() throws Exception {
- super.setUp();
- mMockContext = getMockContext();
- }
-
- @Override
- public void tearDown() throws Exception {
- super.tearDown();
- }
-
- private int getMessageCount(WidgetView view) {
- return EmailContent.count(mMockContext, Message.CONTENT_URI,
- view.getSelection(), view.getSelectionArgs());
- }
-
- private int getUnreadCount(WidgetView view) {
- return view.getUnreadCount(mMockContext);
- }
-
- private static Message createMessage(Context c, Mailbox b, boolean starred, boolean read,
- int flagLoaded) {
- Message message = ProviderTestUtils.setupMessage(
- "1", b.mAccountKey, b.mId, true, false, c, starred, read);
- message.mFlagLoaded = flagLoaded;
- message.save(c);
- return message;
- }
-
- public void testGetNext() {
- // Test with 1 account.
- final Account a1 = ProviderTestUtils.setupAccount("account1", true, mMockContext);
-
- WidgetView view = WidgetView.ALL_UNREAD;
-
- // all unread -> all starred
- view = view.getNext(mMockContext);
- assertEquals(WidgetView.ALL_STARRED, view);
-
- // all starred -> account 1 inbox
- view = view.getNext(mMockContext);
- assertTrue(view.isPerAccount());
- assertEquals(Long.toString(a1.mId), view.getSelectionArgs()[0]);
-
- // account 1 inbox -> all unread
- view = view.getNext(mMockContext);
- assertEquals(WidgetView.ALL_UNREAD, view);
-
- // Next, test with 2 accounts.
- final Account a2 = ProviderTestUtils.setupAccount("account2", true, mMockContext);
-
- // Still all unread
- assertEquals(WidgetView.ALL_UNREAD, view);
-
- // all unread -> all starred
- view = view.getNext(mMockContext);
- assertEquals(WidgetView.ALL_STARRED, view);
-
- // all starred -> all inboxes, as there are more than 1 account.
- view = view.getNext(mMockContext);
- assertEquals(WidgetView.ALL_INBOX, view);
-
- // all inbox -> account 1 inbox
- view = view.getNext(mMockContext);
- assertTrue(view.isPerAccount());
- assertEquals(Long.toString(a1.mId), view.getSelectionArgs()[0]);
-
- // account 1 inbox -> account 2 inbox
- view = view.getNext(mMockContext);
- assertTrue(view.isPerAccount());
- assertEquals(Long.toString(a2.mId), view.getSelectionArgs()[0]);
-
- // account 2 inbox -> all unread
- view = view.getNext(mMockContext);
- assertEquals(WidgetView.ALL_UNREAD, view);
- }
-
- public void testIsValid() {
- // with 0 accounts
- assertTrue(WidgetView.ALL_UNREAD.isValid(mMockContext));
- assertTrue(WidgetView.ALL_STARRED.isValid(mMockContext));
- assertFalse(WidgetView.ALL_INBOX.isValid(mMockContext));
-
- // Test with 1 account.
- final Account a1 = ProviderTestUtils.setupAccount("account1", true, mMockContext);
- assertTrue(WidgetView.ALL_UNREAD.isValid(mMockContext));
- assertTrue(WidgetView.ALL_STARRED.isValid(mMockContext));
- assertFalse(WidgetView.ALL_INBOX.isValid(mMockContext)); // only 1 account -- still invalid
-
- final WidgetView account1View = WidgetView.ALL_INBOX.getNext(mMockContext);
- assertEquals(Long.toString(a1.mId), account1View.getSelectionArgs()[0]);
- assertTrue(account1View.isValid(mMockContext));
-
- // Test with 2 accounts.
- final Account a2 = ProviderTestUtils.setupAccount("account2", true, mMockContext);
- assertTrue(WidgetView.ALL_UNREAD.isValid(mMockContext));
- assertTrue(WidgetView.ALL_STARRED.isValid(mMockContext));
- assertTrue(WidgetView.ALL_INBOX.isValid(mMockContext)); // now it's valid
-
- final WidgetView account2View = account1View.getNext(mMockContext);
- assertEquals(Long.toString(a2.mId), account2View.getSelectionArgs()[0]);
- assertTrue(account2View.isValid(mMockContext));
-
- // Remove account 1
- ProviderTestUtils.deleteAccount(mMockContext, a1.mId);
-
- assertTrue(WidgetView.ALL_UNREAD.isValid(mMockContext));
- assertTrue(WidgetView.ALL_STARRED.isValid(mMockContext));
- assertFalse(WidgetView.ALL_INBOX.isValid(mMockContext)); // only 1 account -- now invalid
-
- assertFalse(account1View.isValid(mMockContext));
- assertTrue(account2View.isValid(mMockContext));
-
- // Remove account 2
- ProviderTestUtils.deleteAccount(mMockContext, a2.mId);
-
- assertTrue(WidgetView.ALL_UNREAD.isValid(mMockContext));
- assertTrue(WidgetView.ALL_STARRED.isValid(mMockContext));
- assertFalse(WidgetView.ALL_INBOX.isValid(mMockContext)); // still invalid
-
- assertFalse(account1View.isValid(mMockContext));
- assertFalse(account2View.isValid(mMockContext));
- }
-
- /**
- * Test the message counts returned by the ViewType selectors.
- */
- public void testCursorCount() {
- // Create 2 accounts
- Account a1 = ProviderTestUtils.setupAccount("account1", true, mMockContext);
- Account a2 = ProviderTestUtils.setupAccount("account2", true, mMockContext);
-
- // Create 2 mailboxes for each account
- Mailbox b11 = ProviderTestUtils.setupMailbox(
- "box11", a1.mId, true, mMockContext, Mailbox.TYPE_INBOX);
- Mailbox b12 = ProviderTestUtils.setupMailbox(
- "box12", a1.mId, true, mMockContext, Mailbox.TYPE_OUTBOX);
- Mailbox b21 = ProviderTestUtils.setupMailbox(
- "box21", a2.mId, true, mMockContext, Mailbox.TYPE_INBOX);
- Mailbox b22 = ProviderTestUtils.setupMailbox(
- "box22", a2.mId, true, mMockContext, Mailbox.TYPE_OUTBOX);
- Mailbox b2t = ProviderTestUtils.setupMailbox(
- "box2T", a2.mId, true, mMockContext, Mailbox.TYPE_TRASH);
-
- // Create some messages
- // b11 (account 1, inbox): 2 messages
- // star read
- Message m11a = createMessage(mMockContext, b11, true, false, Message.FLAG_LOADED_COMPLETE);
- Message m11b = createMessage(mMockContext, b11, false, false, Message.FLAG_LOADED_UNLOADED);
-
- // b12 (account 1, outbox): 2 messages
- Message m12a = createMessage(mMockContext, b12, false, false, Message.FLAG_LOADED_COMPLETE);
- Message m12b = createMessage(mMockContext, b12, true, true, Message.FLAG_LOADED_COMPLETE);
-
- // b21 (account 2, inbox): 4 messages
- Message m21a = createMessage(mMockContext, b21, false, false, Message.FLAG_LOADED_COMPLETE);
- Message m21b = createMessage(mMockContext, b21, false, true, Message.FLAG_LOADED_COMPLETE);
- Message m21c = createMessage(mMockContext, b21, true, true, Message.FLAG_LOADED_COMPLETE);
- Message m21d = createMessage(mMockContext, b21, true, true, Message.FLAG_LOADED_UNLOADED);
-
- // b22 (account 2, outbox) has no messages.
-
- // bt (account 2, trash): 3 messages
- Message mt1 = createMessage(mMockContext, b2t, true, false, Message.FLAG_LOADED_COMPLETE);
- Message mt2 = createMessage(mMockContext, b2t, true, true, Message.FLAG_LOADED_COMPLETE);
- Message mt3 = createMessage(mMockContext, b2t, false, false, Message.FLAG_LOADED_COMPLETE);
-
- assertEquals(4, getMessageCount(WidgetView.ALL_INBOX));
- assertEquals(2, getUnreadCount(WidgetView.ALL_INBOX));
-
- assertEquals(3, getMessageCount(WidgetView.ALL_STARRED));
- assertEquals(1, getUnreadCount(WidgetView.ALL_STARRED));
-
- assertEquals(2, getMessageCount(WidgetView.ALL_UNREAD));
- assertEquals(2, getUnreadCount(WidgetView.ALL_UNREAD));
-
- final WidgetView account1View = WidgetView.ALL_INBOX.getNext(mMockContext);
- assertEquals(Long.toString(a1.mId), account1View.getSelectionArgs()[0]);
- assertEquals(1, getMessageCount(account1View));
- assertEquals(1, getUnreadCount(account1View));
-
- final WidgetView account2View = account1View.getNext(mMockContext);
- assertEquals(Long.toString(a2.mId), account2View.getSelectionArgs()[0]);
- assertEquals(3, getMessageCount(account2View));
- assertEquals(1, getUnreadCount(account2View));
- }
-}