Merge "Menu items to spec + cleanup" into jb-ub-mail-ur9
diff --git a/res/drawable-hdpi/ic_star_off.png b/res/drawable-hdpi/ic_star_off.png
index 4476f91..cf1cd90 100644
--- a/res/drawable-hdpi/ic_star_off.png
+++ b/res/drawable-hdpi/ic_star_off.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_star_on.png b/res/drawable-hdpi/ic_star_on.png
index b4e7ceb..b694bbb 100644
--- a/res/drawable-hdpi/ic_star_on.png
+++ b/res/drawable-hdpi/ic_star_on.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_star_off.png b/res/drawable-mdpi/ic_star_off.png
index 3d959ef..522b5ab 100644
--- a/res/drawable-mdpi/ic_star_off.png
+++ b/res/drawable-mdpi/ic_star_off.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_star_on.png b/res/drawable-mdpi/ic_star_on.png
index 9f4318f..50dd679 100644
--- a/res/drawable-mdpi/ic_star_on.png
+++ b/res/drawable-mdpi/ic_star_on.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_star_off.png b/res/drawable-xhdpi/ic_star_off.png
index 72c50b7..a611a1f 100644
--- a/res/drawable-xhdpi/ic_star_off.png
+++ b/res/drawable-xhdpi/ic_star_off.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_star_on.png b/res/drawable-xhdpi/ic_star_on.png
index 31551a2..f77acd7 100644
--- a/res/drawable-xhdpi/ic_star_on.png
+++ b/res/drawable-xhdpi/ic_star_on.png
Binary files differ
diff --git a/res/layout/conversation_item_view_normal.xml b/res/layout/conversation_item_view_normal.xml
index 350afd7..25eabe4 100644
--- a/res/layout/conversation_item_view_normal.xml
+++ b/res/layout/conversation_item_view_normal.xml
@@ -145,7 +145,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
- android:layout_marginTop="-6dp"
+ android:layout_marginTop="-1dp"
android:src="@drawable/ic_star_off" />
<!-- we assume the star asset is less than 48dp wide -->
diff --git a/res/layout/conversation_item_view_normal_spacious.xml b/res/layout/conversation_item_view_normal_spacious.xml
index b8bb2af..7bc05d3 100644
--- a/res/layout/conversation_item_view_normal_spacious.xml
+++ b/res/layout/conversation_item_view_normal_spacious.xml
@@ -145,7 +145,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
- android:layout_marginTop="-6dp"
+ android:layout_marginTop="-1dp"
android:src="@drawable/ic_star_off" />
<!-- we assume the star asset is less than 48dp wide -->
diff --git a/res/layout/conversation_item_view_wide.xml b/res/layout/conversation_item_view_wide.xml
index 949e964..3acda63 100644
--- a/res/layout/conversation_item_view_wide.xml
+++ b/res/layout/conversation_item_view_wide.xml
@@ -140,7 +140,7 @@
android:id="@+id/star"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginTop="-12dp"
+ android:layout_marginTop="-1dp"
android:layout_marginLeft="32dp"
android:src="@drawable/ic_star_off" />
diff --git a/res/layout/swipe_to_refresh.xml b/res/layout/swipe_to_refresh.xml
index 35dd7ee..6ea9f4b 100644
--- a/res/layout/swipe_to_refresh.xml
+++ b/res/layout/swipe_to_refresh.xml
@@ -26,7 +26,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
- android:textColor="#0099cc"
+ android:textColor="@color/swipe_to_refresh_text_color"
android:textSize="17sp" />
</FrameLayout>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index ccc40d9..6f077bc 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -112,8 +112,10 @@
<!-- Teaser colors -->
-
<!-- The color of the section name text in the teaser -->
<color name="teaser_main_text">#58585b</color>
+ <!-- swipe to refresh text color, this matches the color in
+ progressbar_solid_holo.png -->
+ <color name="swipe_to_refresh_text_color">#0099cc</color>
</resources>
diff --git a/res/values/dimen.xml b/res/values/dimen.xml
index 11d12a4..3c826ea 100644
--- a/res/values/dimen.xml
+++ b/res/values/dimen.xml
@@ -31,7 +31,8 @@
<dimen name="compose_scrollview_width">700dp</dimen>
<dimen name="color_block_width">32dip</dimen>
<dimen name="color_block_height">6dip</dimen>
- <dimen name="star_touch_slop">4dip</dimen>
+ <!-- The star is pretty small and does not have padding anymore, so the slop needs to be bigger-->
+ <dimen name="star_touch_slop">16dip</dimen>
<dimen name="sender_image_touch_slop">8dip</dimen>
<dimen name="move_slop">4dip</dimen>
<dimen name="standard_scaled_dimen">100sp</dimen>
diff --git a/src/com/android/mail/browse/MessageCursor.java b/src/com/android/mail/browse/MessageCursor.java
index ff6016a..0858448 100644
--- a/src/com/android/mail/browse/MessageCursor.java
+++ b/src/com/android/mail/browse/MessageCursor.java
@@ -18,34 +18,30 @@
package com.android.mail.browse;
import android.database.Cursor;
-import android.database.CursorWrapper;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
+import com.android.mail.content.CursorCreator;
+import com.android.mail.content.ObjectCursor;
import com.android.mail.providers.Account;
import com.android.mail.providers.Attachment;
import com.android.mail.providers.Conversation;
import com.android.mail.providers.Message;
-import com.android.mail.providers.UIProvider;
import com.android.mail.providers.UIProvider.CursorExtraKeys;
import com.android.mail.providers.UIProvider.CursorStatus;
import com.android.mail.ui.ConversationUpdater;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
import java.util.List;
-import java.util.Map;
/**
* MessageCursor contains the messages within a conversation; the public methods within should
* only be called by the UI thread, as cursor position isn't guaranteed to be maintained
*/
-public class MessageCursor extends CursorWrapper {
-
- private final Map<Long, ConversationMessage> mCache = Maps.newHashMap();
+public class MessageCursor extends ObjectCursor<MessageCursor.ConversationMessage> {
/**
* The current controller that this cursor can use to reference the owning {@link Conversation},
* and a current {@link ConversationUpdater}. Since this cursor will survive a rotation, but
@@ -79,7 +75,7 @@
private transient ConversationController mController;
- private ConversationMessage(MessageCursor cursor) {
+ private ConversationMessage(Cursor cursor) {
super(cursor);
}
@@ -122,10 +118,26 @@
}
}
+ /**
+ * Public object that knows how to construct Messages given Cursors.
+ */
+ public static final CursorCreator<ConversationMessage> FACTORY =
+ new CursorCreator<ConversationMessage>() {
+ @Override
+ public ConversationMessage createFromCursor(Cursor c) {
+ return new ConversationMessage(c);
+ }
+
+ @Override
+ public String toString() {
+ return "ConversationMessage CursorCreator";
+ }
+ };
+
}
public MessageCursor(Cursor inner) {
- super(inner);
+ super(inner, ConversationMessage.FACTORY);
}
public void setController(ConversationController controller) {
@@ -133,12 +145,7 @@
}
public ConversationMessage getMessage() {
- final long id = getWrappedCursor().getLong(UIProvider.MESSAGE_ID_COLUMN);
- ConversationMessage m = mCache.get(id);
- if (m == null) {
- m = new ConversationMessage(this);
- mCache.put(id, m);
- }
+ final ConversationMessage m = getModel();
// ALWAYS set up each ConversationMessage with the latest controller.
// Rotation invalidates everything except this Cursor, its Loader and the cached Messages,
// so if we want to continue using them after rotate, we have to ensure their controller
diff --git a/src/com/android/mail/content/ObjectCursorLoader.java b/src/com/android/mail/content/ObjectCursorLoader.java
index 3184524..dbb93bb 100644
--- a/src/com/android/mail/content/ObjectCursorLoader.java
+++ b/src/com/android/mail/content/ObjectCursorLoader.java
@@ -36,7 +36,7 @@
final ForceLoadContentObserver mObserver;
protected static final String LOG_TAG = LogTag.getLogTag();
- final Uri mUri;
+ private Uri mUri;
final String[] mProjection;
// Copied over from CursorLoader, but none of our uses specify this. So these are hardcoded to
// null right here.
@@ -60,15 +60,12 @@
* If these are null, it's going to crash anyway in loadInBackground(), but this stack trace
* is much more useful.
*/
- if (uri == null) {
- throw new NullPointerException("The uri cannot be null");
- }
if (factory == null) {
throw new NullPointerException("The factory cannot be null");
}
mObserver = new ForceLoadContentObserver();
- mUri = uri;
+ setUri(uri);
mProjection = projection;
mFactory = factory;
}
@@ -84,7 +81,7 @@
inner.registerContentObserver(mObserver);
}
// Modifications to the ObjectCursor, create an Object Cursor and fill the cache.
- final ObjectCursor<T> cursor = new ObjectCursor<T>(inner, mFactory);
+ final ObjectCursor<T> cursor = getObjectCursor(inner);
cursor.fillCache();
try {
@@ -96,6 +93,10 @@
return cursor;
}
+ protected ObjectCursor<T> getObjectCursor(Cursor inner) {
+ return new ObjectCursor<T>(inner, mFactory);
+ }
+
/* Runs on the UI thread */
@Override
public void deliverResult(ObjectCursor<T> cursor) {
@@ -188,4 +189,15 @@
mDebugDelayMs = delayMs;
return this;
}
+
+ protected final Uri getUri() {
+ return mUri;
+ }
+
+ protected final void setUri(Uri uri) {
+ if (uri == null) {
+ throw new NullPointerException("The uri cannot be null");
+ }
+ mUri = uri;
+ }
}
diff --git a/src/com/android/mail/photomanager/ContactPhotoManager.java b/src/com/android/mail/photomanager/ContactPhotoManager.java
index 2cf23bb..580d67a 100644
--- a/src/com/android/mail/photomanager/ContactPhotoManager.java
+++ b/src/com/android/mail/photomanager/ContactPhotoManager.java
@@ -225,9 +225,13 @@
SenderInfoLoader.loadContactPhotos(
getResolver(), addresses, false /* decodeBitmaps */);
- // put all entries into photos map: mapping of email addresses to photoBytes
- for(Map.Entry<String, ContactInfo> entry : emailAddressToContactInfoMap.entrySet()) {
- photos.put(entry.getKey(), entry.getValue().photoBytes);
+ // Put all entries into photos map: a mapping of email addresses to photoBytes.
+ // If there is no ContactInfo, it means we couldn't get a photo for this
+ // address so just put null in for the bytes so that the crazy caching
+ // works properly and we don't get an infinite loop of GC churn.
+ for (final String address : addresses) {
+ final ContactInfo info = emailAddressToContactInfoMap.get(address);
+ photos.put(address, info != null ? info.photoBytes : null);
}
return photos;
diff --git a/src/com/android/mail/providers/Account.java b/src/com/android/mail/providers/Account.java
index 0595db7..391ffe0 100644
--- a/src/com/android/mail/providers/Account.java
+++ b/src/com/android/mail/providers/Account.java
@@ -172,6 +172,10 @@
public final Uri updateSettingsUri;
/**
+ * Whether message transforms (HTML DOM manipulation) feature is enabled.
+ */
+ public final int enableMessageTransforms;
+ /**
* Transient cache of parsed {@link #accountFromAddresses}, plus an entry for the main account
* address.
*/
@@ -214,6 +218,7 @@
viewIntentProxyUri);
json.put(UIProvider.AccountColumns.ACCOUNT_COOKIE_QUERY_URI, accoutCookieQueryUri);
json.put(UIProvider.AccountColumns.UPDATE_SETTINGS_URI, updateSettingsUri);
+ json.put(UIProvider.AccountColumns.ENABLE_MESSAGE_TRANSFORMS, enableMessageTransforms);
if (settings != null) {
json.put(SETTINGS_KEY, settings.toJSON());
}
@@ -301,6 +306,7 @@
json.optString(UIProvider.AccountColumns.ACCOUNT_COOKIE_QUERY_URI));
updateSettingsUri = Utils.getValidUri(
json.optString(UIProvider.AccountColumns.UPDATE_SETTINGS_URI));
+ enableMessageTransforms = json.optInt(AccountColumns.ENABLE_MESSAGE_TRANSFORMS);
final Settings jsonSettings = Settings.newInstance(json.optJSONObject(SETTINGS_KEY));
if (jsonSettings != null) {
@@ -337,6 +343,7 @@
viewIntentProxyUri = in.readParcelable(null);
accoutCookieQueryUri = in.readParcelable(null);
updateSettingsUri = in.readParcelable(null);
+ enableMessageTransforms = in.readInt();
final String serializedSettings = in.readString();
final Settings parcelSettings = Settings.newInstance(serializedSettings);
if (parcelSettings != null) {
@@ -399,6 +406,8 @@
cursor.getColumnIndex(UIProvider.AccountColumns.ACCOUNT_COOKIE_QUERY_URI)));
updateSettingsUri = Utils.getValidUri(cursor.getString(
cursor.getColumnIndex(UIProvider.AccountColumns.UPDATE_SETTINGS_URI)));
+ enableMessageTransforms = cursor.getInt(
+ cursor.getColumnIndex(AccountColumns.ENABLE_MESSAGE_TRANSFORMS));
settings = new Settings(cursor);
}
@@ -472,6 +481,7 @@
dest.writeParcelable(viewIntentProxyUri, 0);
dest.writeParcelable(accoutCookieQueryUri, 0);
dest.writeParcelable(updateSettingsUri, 0);
+ dest.writeInt(enableMessageTransforms);
if (settings == null) {
LogUtils.e(LOG_TAG, "unexpected null settings object in writeToParcel");
}
@@ -562,6 +572,7 @@
Objects.equal(viewIntentProxyUri, other.viewIntentProxyUri) &&
Objects.equal(accoutCookieQueryUri, other.accoutCookieQueryUri) &&
Objects.equal(updateSettingsUri, other.updateSettingsUri) &&
+ Objects.equal(enableMessageTransforms, other.enableMessageTransforms) &&
Objects.equal(settings, other.settings);
}
@@ -591,7 +602,7 @@
undoUri, settingsIntentUri, helpIntentUri, sendFeedbackIntentUri,
reauthenticationIntentUri, syncStatus, composeIntentUri, mimeType,
recentFolderListUri, color, defaultRecentFolderListUri, viewIntentProxyUri,
- accoutCookieQueryUri, updateSettingsUri);
+ accoutCookieQueryUri, updateSettingsUri, enableMessageTransforms);
}
/**
@@ -721,6 +732,7 @@
map.put(UIProvider.AccountColumns.ACCOUNT_COOKIE_QUERY_URI, accoutCookieQueryUri);
map.put(UIProvider.AccountColumns.COLOR, color);
map.put(UIProvider.AccountColumns.UPDATE_SETTINGS_URI, updateSettingsUri);
+ map.put(UIProvider.AccountColumns.ENABLE_MESSAGE_TRANSFORMS, enableMessageTransforms);
map.put(AccountColumns.SettingsColumns.SIGNATURE, settings.signature);
map.put(AccountColumns.SettingsColumns.AUTO_ADVANCE, settings.getAutoAdvanceSetting());
map.put(AccountColumns.SettingsColumns.MESSAGE_TEXT_SIZE, settings.messageTextSize);
diff --git a/src/com/android/mail/providers/UIProvider.java b/src/com/android/mail/providers/UIProvider.java
index f3ca8be..2014557 100644
--- a/src/com/android/mail/providers/UIProvider.java
+++ b/src/com/android/mail/providers/UIProvider.java
@@ -166,6 +166,7 @@
.put(AccountColumns.SettingsColumns.CONVERSATION_VIEW_MODE, Integer.class)
.put(AccountColumns.SettingsColumns.VEILED_ADDRESS_PATTERN, String.class)
.put(AccountColumns.UPDATE_SETTINGS_URI, String.class)
+ .put(AccountColumns.ENABLE_MESSAGE_TRANSFORMS, Integer.class)
.build();
public static final Map<String, Class<?>> ACCOUNTS_COLUMNS =
@@ -449,6 +450,10 @@
* the new values.
*/
public static final String UPDATE_SETTINGS_URI = "updateSettingsUri";
+ /**
+ * Whether message transforms (HTML DOM manipulation) should be enabled.
+ */
+ public static final String ENABLE_MESSAGE_TRANSFORMS = "enableMessageTransforms";
public static final class SettingsColumns {
/**
diff --git a/src/com/android/mail/ui/AbstractActivityController.java b/src/com/android/mail/ui/AbstractActivityController.java
index b0bcd5b..4eb9de1 100644
--- a/src/com/android/mail/ui/AbstractActivityController.java
+++ b/src/com/android/mail/ui/AbstractActivityController.java
@@ -352,7 +352,8 @@
protected ActionBarDrawerToggle mDrawerToggle;
protected ListView mListViewForAnimating;
protected boolean mHasNewAccountOrFolder;
- protected final MailDrawerListener mDrawerListener = new MailDrawerListener();
+ private boolean mConversationListLoadFinishedIgnored;
+ protected MailDrawerListener mDrawerListener;
public static final String SYNC_ERROR_DIALOG_FRAGMENT_TAG = "SyncErrorDialogFragment";
@@ -383,6 +384,7 @@
mShowUndoBarDelay = r.getInteger(R.integer.show_undo_bar_delay_ms);
mVeiledMatcher = VeiledAddressMatcher.newInstance(activity.getResources());
mIsTablet = Utils.useTabletUI(r);
+ mConversationListLoadFinishedIgnored = false;
}
@Override
@@ -1004,7 +1006,8 @@
mDrawerToggle = new ActionBarDrawerToggle((Activity) mActivity, mDrawerContainer,
R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close);
- mDrawerContainer.setDrawerListener(new MailDrawerListener());
+ mDrawerListener = new MailDrawerListener();
+ mDrawerContainer.setDrawerListener(mDrawerListener);
mDrawerContainer.setDrawerShadow(
mContext.getResources().getDrawable(R.drawable.drawer_shadow), Gravity.START);
@@ -3059,8 +3062,9 @@
public void onLoadFinished(Loader<ConversationCursor> loader, ConversationCursor data) {
LogUtils.d(LOG_TAG, "IN AAC.ConversationCursor.onLoadFinished, data=%s loader=%s",
data, loader);
- if (isDrawerEnabled() && mDrawerContainer.isDrawerOpen(mDrawerPullout)) {
+ if (isDrawerEnabled() && mDrawerListener.getDrawerState() != DrawerLayout.STATE_IDLE) {
LogUtils.d(LOG_TAG, "ConversationListLoaderCallbacks.onLoadFinished: ignoring.");
+ mConversationListLoadFinishedIgnored = true;
return;
}
// Clear our all pending destructive actions before swapping the conversation cursor
@@ -3825,6 +3829,12 @@
}
private class MailDrawerListener implements DrawerLayout.DrawerListener {
+ private int mDrawerState;
+
+ public MailDrawerListener() {
+ mDrawerState = DrawerLayout.STATE_IDLE;
+ }
+
@Override
public void onDrawerOpened(View drawerView) {
mDrawerToggle.onDrawerOpened(drawerView);
@@ -3858,9 +3868,20 @@
*/
@Override
public void onDrawerStateChanged(int newState) {
- mDrawerToggle.onDrawerStateChanged(newState);
- if (mHasNewAccountOrFolder && newState == DrawerLayout.STATE_IDLE) {
- refreshDrawer();
+ mDrawerState = newState;
+ mDrawerToggle.onDrawerStateChanged(mDrawerState);
+ if (mDrawerState == DrawerLayout.STATE_IDLE) {
+ if (mHasNewAccountOrFolder) {
+ refreshDrawer();
+ }
+ if (mConversationListLoadFinishedIgnored) {
+ mConversationListLoadFinishedIgnored = false;
+ final Bundle args = new Bundle();
+ args.putParcelable(BUNDLE_ACCOUNT_KEY, mAccount);
+ args.putParcelable(BUNDLE_FOLDER_KEY, mFolder);
+ mActivity.getLoaderManager().initLoader(
+ LOADER_CONVERSATION_LIST, args, mListCursorCallbacks);
+ }
}
}
@@ -3878,6 +3899,17 @@
}
mDrawerObservers.notifyChanged();
}
+
+ /**
+ * Returns the most recent update of the {@link DrawerLayout}'s state provided
+ * by {@link #onDrawerStateChanged(int)}.
+ * @return The {@link DrawerLayout}'s current state. One of
+ * {@link DrawerLayout#STATE_DRAGGING}, {@link DrawerLayout#STATE_IDLE},
+ * or {@link DrawerLayout#STATE_SETTLING}.
+ */
+ public int getDrawerState() {
+ return mDrawerState;
+ }
}
@Override
diff --git a/src/com/android/mail/ui/AbstractConversationViewFragment.java b/src/com/android/mail/ui/AbstractConversationViewFragment.java
index 82b00b5..642a9f3 100644
--- a/src/com/android/mail/ui/AbstractConversationViewFragment.java
+++ b/src/com/android/mail/ui/AbstractConversationViewFragment.java
@@ -25,7 +25,6 @@
import android.app.LoaderManager;
import android.content.ActivityNotFoundException;
import android.content.Context;
-import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
import android.content.pm.ActivityInfo;
@@ -56,7 +55,10 @@
import com.android.mail.browse.ConversationViewHeader.ConversationViewHeaderCallbacks;
import com.android.mail.browse.MessageCursor;
import com.android.mail.browse.MessageCursor.ConversationController;
+import com.android.mail.browse.MessageCursor.ConversationMessage;
import com.android.mail.browse.MessageHeaderView.MessageHeaderViewCallbacks;
+import com.android.mail.content.ObjectCursor;
+import com.android.mail.content.ObjectCursorLoader;
import com.android.mail.providers.Account;
import com.android.mail.providers.AccountObserver;
import com.android.mail.providers.Address;
@@ -193,7 +195,8 @@
* Subclasses must override this, since they may want to display a single or
* many messages related to this conversation.
*/
- protected abstract void onMessageCursorLoadFinished(Loader<Cursor> loader,
+ protected abstract void onMessageCursorLoadFinished(
+ Loader<ObjectCursor<ConversationMessage>> loader,
MessageCursor newCursor, MessageCursor oldCursor);
/**
@@ -502,15 +505,17 @@
}
}
- private class MessageLoaderCallbacks implements LoaderManager.LoaderCallbacks<Cursor> {
+ private class MessageLoaderCallbacks
+ implements LoaderManager.LoaderCallbacks<ObjectCursor<ConversationMessage>> {
@Override
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ public Loader<ObjectCursor<ConversationMessage>> onCreateLoader(int id, Bundle args) {
return new MessageLoader(mActivity.getActivityContext(), mConversation.messageListUri);
}
@Override
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ public void onLoadFinished(Loader<ObjectCursor<ConversationMessage>> loader,
+ ObjectCursor<ConversationMessage> data) {
// ignore truly duplicate results
// this can happen when restoring after rotation
if (mCursor == data) {
@@ -538,7 +543,8 @@
// message list update fires first. nothing to do
// because we expect to be torn down soon.)
LogUtils.i(LOG_TAG, "CVF: offscreen conv has no messages, ignoring update"
- + " in anticipation of conv cursor update. c=%s", mConversation.uri);
+ + " in anticipation of conv cursor update. c=%s",
+ mConversation.uri);
}
// existing mCursor will imminently be closed, must stop referencing it
// since we expect to be kicked out soon, it doesn't matter what mCursor
@@ -563,7 +569,7 @@
}
@Override
- public void onLoaderReset(Loader<Cursor> loader) {
+ public void onLoaderReset(Loader<ObjectCursor<ConversationMessage>> loader) {
mCursor = null;
}
@@ -641,20 +647,15 @@
return new ConversationViewState();
}
- private static class MessageLoader extends CursorLoader {
+ private static class MessageLoader extends ObjectCursorLoader<ConversationMessage> {
private boolean mDeliveredFirstResults = false;
public MessageLoader(Context c, Uri messageListUri) {
- super(c, messageListUri, UIProvider.MESSAGE_PROJECTION, null, null, null);
+ super(c, messageListUri, UIProvider.MESSAGE_PROJECTION, ConversationMessage.FACTORY);
}
@Override
- public Cursor loadInBackground() {
- return new MessageCursor(super.loadInBackground());
- }
-
- @Override
- public void deliverResult(Cursor result) {
+ public void deliverResult(ObjectCursor<ConversationMessage> result) {
// We want to deliver these results, and then we want to make sure
// that any subsequent
// queries do not hit the network
@@ -677,6 +678,11 @@
setUri(uri);
}
}
+
+ @Override
+ protected ObjectCursor<ConversationMessage> getObjectCursor(Cursor inner) {
+ return new MessageCursor(inner);
+ }
}
/**
@@ -870,6 +876,7 @@
* @return {@code true} if the conversation should be transformed. {@code false}, otherwise.
*/
public boolean shouldApplyTransforms() {
- return !mHasConversationTransformBeenReverted;
+ return (mAccount.enableMessageTransforms > 0) &&
+ !mHasConversationTransformBeenReverted;
}
}
diff --git a/src/com/android/mail/ui/ConversationViewFragment.java b/src/com/android/mail/ui/ConversationViewFragment.java
index b67b538..c119861 100644
--- a/src/com/android/mail/ui/ConversationViewFragment.java
+++ b/src/com/android/mail/ui/ConversationViewFragment.java
@@ -63,6 +63,7 @@
import com.android.mail.browse.ScrollIndicatorsView;
import com.android.mail.browse.SuperCollapsedBlock;
import com.android.mail.browse.WebViewContextMenu;
+import com.android.mail.content.ObjectCursor;
import com.android.mail.preferences.MailPrefs;
import com.android.mail.providers.Account;
import com.android.mail.providers.Address;
@@ -1202,8 +1203,8 @@
}
@Override
- public void onMessageCursorLoadFinished(Loader<Cursor> loader, MessageCursor newCursor,
- MessageCursor oldCursor) {
+ public void onMessageCursorLoadFinished(Loader<ObjectCursor<ConversationMessage>> loader,
+ MessageCursor newCursor, MessageCursor oldCursor) {
/*
* what kind of changes affect the MessageCursor? 1. new message(s) 2.
* read/unread state change 3. deleted message, either regular or draft
diff --git a/src/com/android/mail/ui/MailActionBarView.java b/src/com/android/mail/ui/MailActionBarView.java
index 637c03b..da73346 100644
--- a/src/com/android/mail/ui/MailActionBarView.java
+++ b/src/com/android/mail/ui/MailActionBarView.java
@@ -731,7 +731,7 @@
if (ViewMode.isWaitingForSync(mMode)) {
// Account is not synced: clear title and update the subtitle.
setTitle("");
- removeUnreadCount();
+ removeUnreadCount(true);
return;
}
// Check if we should be changing the actionbar at all, and back off if not.
@@ -757,27 +757,31 @@
final int toDisplay = (folderUnreadCount > UNREAD_LIMIT)
? (UNREAD_LIMIT + 1) : folderUnreadCount;
if ((mUnreadCount != toDisplay || folderChanged) && toDisplay != 0) {
- setSubtitle(Utils.getUnreadMessageString(
- mActivity.getApplicationContext(), toDisplay));
- // This is a new update, remove previous messages, if any.
- mHandler.removeMessages(SubtitleHandler.EMAIL);
- // In a short while, show the account name in its place.
- mHandler.sendEmptyMessageDelayed(SubtitleHandler.EMAIL, ACCOUNT_DELAY_MS);
- } else {
- removeUnreadCount();
+ setSubtitle(Utils.getUnreadMessageString(mActivity.getApplicationContext(), toDisplay));
}
+ // Schedule a removal of unread count for the future, if there isn't one already.
+ removeUnreadCount(false);
// Remember the new value for the next run
mUnreadCount = toDisplay;
}
/**
* Remove the unread count and show the account name, if required.
+ * @param now true if you want the change to happen immediately. False if you want to enforce
+ * it happens later.
*/
- private void removeUnreadCount() {
- // Remove all previous messages which might change the subtitle
- mHandler.removeMessages(SubtitleHandler.EMAIL);
- // Update the subtitle: clear it or show account name.
- mHandler.sendEmptyMessage(SubtitleHandler.EMAIL);
+ private void removeUnreadCount(boolean now) {
+ if (now) {
+ // Remove all previous messages which might change the subtitle
+ mHandler.removeMessages(SubtitleHandler.EMAIL);
+ // Update the subtitle: clear it or show account name.
+ mHandler.sendEmptyMessage(SubtitleHandler.EMAIL);
+ } else {
+ if (!mHandler.hasMessages(SubtitleHandler.EMAIL)) {
+ // In a short while, show the account name in its place.
+ mHandler.sendEmptyMessageDelayed(SubtitleHandler.EMAIL, ACCOUNT_DELAY_MS);
+ }
+ }
}
/**
diff --git a/src/com/android/mail/ui/SecureConversationViewFragment.java b/src/com/android/mail/ui/SecureConversationViewFragment.java
index d2eac38..3a74d35 100644
--- a/src/com/android/mail/ui/SecureConversationViewFragment.java
+++ b/src/com/android/mail/ui/SecureConversationViewFragment.java
@@ -40,6 +40,7 @@
import com.android.mail.browse.MessageHeaderView.MessageHeaderViewCallbacks;
import com.android.mail.browse.MessageScrollView;
import com.android.mail.browse.MessageWebView;
+import com.android.mail.content.ObjectCursor;
import com.android.mail.providers.Account;
import com.android.mail.providers.Conversation;
import com.android.mail.providers.Message;
@@ -213,8 +214,8 @@
}
@Override
- protected void onMessageCursorLoadFinished(Loader<Cursor> loader, MessageCursor newCursor,
- MessageCursor oldCursor) {
+ protected void onMessageCursorLoadFinished(Loader<ObjectCursor<ConversationMessage>> loader,
+ MessageCursor newCursor, MessageCursor oldCursor) {
// ignore cursors that are still loading results
if (newCursor == null || !newCursor.isLoaded()) {
LogUtils.i(LOG_TAG, "CONV RENDER: existing cursor is null, rendering from scratch");