Merge "Support compose with quoted html." into jb-ub-mail-ur10
diff --git a/res/layout/swipe_leavebehind.xml b/res/layout/swipe_leavebehind.xml
index a0bb4f6..9d0a50d 100644
--- a/res/layout/swipe_leavebehind.xml
+++ b/res/layout/swipe_leavebehind.xml
@@ -19,55 +19,9 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/swiped_bg_color">
- <LinearLayout
+
+ <include
android:id="@+id/swipeable_content"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:clickable="true"
- android:orientation="horizontal">
- <TextView
- android:id="@+id/undo_descriptionview"
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:ellipsize="end"
- android:singleLine="true"
- android:text="@string/no_conversations"
- android:textColor="@android:color/white"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:paddingLeft="16dip"
- android:clickable="true"
- android:gravity="center_vertical"/>
+ layout="@layout/swipe_leavebehind_body" />
- <View
- android:id="@+id/undo_separator"
- android:layout_width="1dip"
- android:layout_height="match_parent"
- android:background="@android:color/white"
- android:layout_marginTop="16dp"
- android:layout_marginBottom="16dp" />
-
- <ImageView
- android:id="@+id/undo_icon"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:paddingLeft="12dip"
- android:paddingRight="8dip"
- android:src="@drawable/ic_menu_revert_holo_dark"
- android:background="?android:attr/selectableItemBackground"
- android:duplicateParentState="true" />
-
- <TextView
- android:id="@+id/undo_text"
- style="@style/UndoTextStyle"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:paddingRight="16dip"
- android:text="@string/undo"
- android:textAllCaps="true"
- android:gravity="center_vertical"
- android:textColor="@android:color/white"
- android:background="?android:attr/selectableItemBackground"
- android:duplicateParentState="true"/>
- </LinearLayout>
</com.android.mail.ui.LeaveBehindItem>
diff --git a/res/layout/swipe_leavebehind_body.xml b/res/layout/swipe_leavebehind_body.xml
new file mode 100644
index 0000000..027d33c
--- /dev/null
+++ b/res/layout/swipe_leavebehind_body.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 Google Inc.
+ Licensed to 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:clickable="true"
+ android:orientation="horizontal">
+ <TextView
+ android:id="@+id/undo_descriptionview"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:ellipsize="end"
+ android:singleLine="true"
+ android:text="@string/no_conversations"
+ android:textColor="@android:color/white"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:paddingLeft="16dip"
+ android:clickable="true"
+ android:gravity="center_vertical"/>
+
+ <View
+ android:id="@+id/undo_separator"
+ android:layout_width="1dip"
+ android:layout_height="match_parent"
+ android:background="@android:color/white"
+ android:layout_marginTop="16dp"
+ android:layout_marginBottom="16dp" />
+
+ <ImageView
+ android:id="@+id/undo_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:paddingLeft="12dip"
+ android:paddingRight="8dip"
+ android:src="@drawable/ic_menu_revert_holo_dark"
+ android:background="?android:attr/selectableItemBackground"
+ android:duplicateParentState="true" />
+
+ <TextView
+ android:id="@+id/undo_text"
+ style="@style/UndoTextStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:paddingRight="16dip"
+ android:text="@string/undo"
+ android:textAllCaps="true"
+ android:gravity="center_vertical"
+ android:textColor="@android:color/white"
+ android:background="?android:attr/selectableItemBackground"
+ android:duplicateParentState="true"/>
+</LinearLayout>
diff --git a/res/menu/photo_view_menu.xml b/res/menu/photo_view_menu.xml
index 5caeca4..d654d40 100644
--- a/res/menu/photo_view_menu.xml
+++ b/res/menu/photo_view_menu.xml
@@ -34,6 +34,10 @@
android:id="@+id/menu_share_all"
android:showAsAction="never"
android:title="@string/menu_photo_share_all"/>
+ <item
+ android:id="@+id/menu_download_again"
+ android:showAsAction="never"
+ android:title="@string/download_again"/>
</group>
</menu>
\ No newline at end of file
diff --git a/src/com/android/bitmap/AltBitmapCache.java b/src/com/android/bitmap/AltBitmapCache.java
index 2ad047f..fb8e915 100644
--- a/src/com/android/bitmap/AltBitmapCache.java
+++ b/src/com/android/bitmap/AltBitmapCache.java
@@ -70,6 +70,7 @@
if (DEBUG) {
LogUtils.d(TAG, "AltBitmapCache: %s waiting", Thread.currentThread().getName());
}
+ Trace.beginSection("sleep");
try {
// block
mLock.wait();
@@ -79,6 +80,7 @@
}
} catch (InterruptedException e) {
}
+ Trace.endSection();
}
}
return bitmap;
diff --git a/src/com/android/bitmap/ContiguousFIFOAggregator.java b/src/com/android/bitmap/ContiguousFIFOAggregator.java
index 018923c..f93503b 100644
--- a/src/com/android/bitmap/ContiguousFIFOAggregator.java
+++ b/src/com/android/bitmap/ContiguousFIFOAggregator.java
@@ -175,7 +175,7 @@
Entry<T, Value> first;
int count = 0;
while (iter.hasNext()) {
- Utils.traceBeginSection("pool maybeExecuteNow");
+ Utils.traceBeginSection("pool maybeExecuteNow loop");
first = iter.next();
if (count > 0) {
// When count == 0, the key is already first.
@@ -183,6 +183,7 @@
}
if (first.getValue().task == null) {
+ Utils.traceEndSection();
break;
}
diff --git a/src/com/android/bitmap/DecodeTask.java b/src/com/android/bitmap/DecodeTask.java
index da87b7d..af4674e 100644
--- a/src/com/android/bitmap/DecodeTask.java
+++ b/src/com/android/bitmap/DecodeTask.java
@@ -94,17 +94,27 @@
AssetFileDescriptor fd = null;
InputStream in = null;
try {
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
+ Trace.beginSection("poll for reusable bitmap");
+ mInBitmap = mCache.poll();
+ Trace.endSection();
+
+ if (isCancelled()) {
+ return null;
+ }
+ }
+
Trace.beginSection("create fd or stream");
fd = mKey.createFd();
if (fd == null) {
in = mKey.createInputStream();
- if (in != null && !in.markSupported()) {
- Trace.endSection();
- throw new IllegalArgumentException("input stream must support reset()");
- }
}
Trace.endSection();
+ if (isCancelled()) {
+ return null;
+ }
+
Trace.beginSection("decodeBounds");
mOpts.inJustDecodeBounds = true;
if (fd != null) {
@@ -117,6 +127,7 @@
if (isCancelled()) {
return null;
}
+
final int srcW = mOpts.outWidth;
final int srcH = mOpts.outHeight;
@@ -124,14 +135,6 @@
mOpts.inMutable = true;
mOpts.inSampleSize = calculateSampleSize(srcW, srcH, mDestW, mDestH);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
- Trace.beginSection("poll for reusable bitmap");
- mInBitmap = mCache.poll();
- Trace.endSection();
-
- if (isCancelled()) {
- return null;
- }
-
if (mInBitmap == null) {
if (DEBUG) System.err.println(
"decode thread wants a bitmap. cache dump:\n" + mCache.toDebugString());
@@ -140,6 +143,11 @@
Bitmap.createBitmap(mDestBufferW, mDestBufferH,
Bitmap.Config.ARGB_8888));
Trace.endSection();
+
+ if (isCancelled()) {
+ return null;
+ }
+
if (DEBUG) System.err.println("*** allocated new bitmap in decode thread: "
+ mInBitmap + " key=" + mKey);
} else {
@@ -150,15 +158,16 @@
mOpts.inBitmap = mInBitmap.bmp;
}
+ Bitmap decodeResult = null;
+
+ if (in != null) {
+ in = mKey.createInputStream();
+ }
+
if (isCancelled()) {
return null;
}
- Bitmap decodeResult = null;
-
- if (in != null) {
- in.reset();
- }
final Rect srcRect = new Rect();
if (CROP_DURING_DECODE) {
try {
@@ -170,6 +179,10 @@
} finally {
Trace.endSection();
}
+
+ if (isCancelled()) {
+ return null;
+ }
}
if (!CROP_DURING_DECODE || (decodeResult == null && !isCancelled())) {
@@ -194,9 +207,13 @@
} finally {
Trace.endSection();
}
+
+ if (isCancelled()) {
+ return null;
+ }
}
- if (!isCancelled() && decodeResult != null) {
+ if (decodeResult != null) {
if (mInBitmap != null) {
result = mInBitmap;
// srcRect is non-empty when using the cropping BitmapRegionDecoder codepath
diff --git a/src/com/android/mail/bitmap/AttachmentDrawable.java b/src/com/android/mail/bitmap/AttachmentDrawable.java
index 96f0eb5..927561a 100644
--- a/src/com/android/mail/bitmap/AttachmentDrawable.java
+++ b/src/com/android/mail/bitmap/AttachmentDrawable.java
@@ -22,6 +22,7 @@
import com.android.bitmap.DecodeTask;
import com.android.bitmap.DecodeTask.Request;
import com.android.bitmap.ReusableBitmap;
+import com.android.bitmap.Trace;
import com.android.mail.R;
import com.android.mail.browse.ConversationItemViewCoordinates;
import com.android.mail.ui.SwipeableListView;
@@ -140,6 +141,7 @@
return;
}
+ Trace.beginSection("set image");
// avoid visual state transitions when the existing request and the new one are just
// requests for different renditions of the same attachment
final boolean onlyRenditionChange = (mCurrKey != null && mCurrKey.matches(key));
@@ -166,6 +168,7 @@
setLoadState(LOAD_STATE_UNINITIALIZED);
if (key == null) {
+ Trace.endSection();
return;
}
@@ -182,6 +185,7 @@
mCurrKey, mCache.toDebugString());
}
}
+ Trace.endSection();
}
@Override
@@ -328,6 +332,7 @@
return;
}
+ Trace.beginSection("decode");
if (LIMIT_BITMAP_DENSITY) {
final float scale =
Math.min(1f, (float) MAX_BITMAP_DENSITY / DisplayMetrics.DENSITY_DEFAULT
@@ -342,6 +347,7 @@
}
if (w == 0 || bufferH == 0) {
+ Trace.endSection();
return;
}
// System.out.println("ITEM " + this + " w=" + w + " h=" + bufferH + " key=" + mCurrKey);
@@ -353,6 +359,7 @@
}
mTask = new DecodeTask(mCurrKey, w, bufferH, bufferW, bufferH, this, mCache);
mTask.executeOnExecutor(EXECUTOR);
+ Trace.endSection();
}
private void setLoadState(int loadState) {
@@ -363,6 +370,7 @@
return;
}
+ Trace.beginSection("set load state");
switch (loadState) {
// This state differs from LOADED in that the subsequent state transition away from
// UNINITIALIZED will not have a fancy transition. This allows list item binds to
@@ -390,6 +398,7 @@
mProgress.setVisible(false);
break;
}
+ Trace.endSection();
mLoadState = loadState;
LogUtils.v(LOG_TAG, "OUT stateful AD.setState. new=%s placeholder=%s progress=%s",
diff --git a/src/com/android/mail/bitmap/CompositeDrawable.java b/src/com/android/mail/bitmap/CompositeDrawable.java
index 45af4ab..e25bfc7 100644
--- a/src/com/android/mail/bitmap/CompositeDrawable.java
+++ b/src/com/android/mail/bitmap/CompositeDrawable.java
@@ -6,6 +6,8 @@
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import com.android.bitmap.Trace;
+
import java.util.ArrayList;
import java.util.List;
@@ -53,12 +55,14 @@
T result = mDrawables.get(i);
if (result == null) {
+ Trace.beginSection("create division drawable");
result = createDivisionDrawable();
mDrawables.set(i, result);
result.setCallback(this);
// Make sure drawables created after the bounds were already set have their bounds
// set initially (the other unaffected drawables basically de-bounce this).
onBoundsChange(getBounds());
+ Trace.endSection();
}
return result;
}
diff --git a/src/com/android/mail/browse/AttachmentActionHandler.java b/src/com/android/mail/browse/AttachmentActionHandler.java
index 40a66db..02cec4a 100644
--- a/src/com/android/mail/browse/AttachmentActionHandler.java
+++ b/src/com/android/mail/browse/AttachmentActionHandler.java
@@ -122,7 +122,6 @@
}
public void startRedownloadingAttachment(Attachment attachment) {
- showDownloadingDialog();
final ContentValues params = new ContentValues(2);
params.put(AttachmentColumns.STATE, AttachmentState.REDOWNLOADING);
params.put(AttachmentColumns.DESTINATION, attachment.destination);
@@ -134,7 +133,7 @@
* Displays a loading dialog to be used for downloading attachments.
* Must be called on the UI thread.
*/
- private void showDownloadingDialog() {
+ public void showDownloadingDialog() {
final FragmentTransaction ft = mFragmentManager.beginTransaction();
final Fragment prev = mFragmentManager.findFragmentByTag(PROGRESS_FRAGMENT_TAG);
if (prev != null) {
diff --git a/src/com/android/mail/browse/ConversationItemView.java b/src/com/android/mail/browse/ConversationItemView.java
index f95f0b6..9bf7c3a 100644
--- a/src/com/android/mail/browse/ConversationItemView.java
+++ b/src/com/android/mail/browse/ConversationItemView.java
@@ -1542,7 +1542,10 @@
mPhotoFlipMatrix.reset();
mPhotoFlipMatrix.postScale(scale, 1);
- canvas.translate(mCoordinates.contactImagesX + xOffset, mCoordinates.contactImagesY);
+ final float x = mCoordinates.contactImagesX + xOffset;
+ final float y = mCoordinates.contactImagesY;
+
+ canvas.translate(x, y);
if (mPhotoBitmap == null) {
mContactImagesHolder.draw(canvas, mPhotoFlipMatrix);
@@ -2263,4 +2266,8 @@
public void setPhotoFlipFraction(final float fraction) {
mPhotoFlipAnimator.setValue(fraction);
}
+
+ public String getAccount() {
+ return mAccount;
+ }
}
diff --git a/src/com/android/mail/browse/ConversationItemViewCoordinates.java b/src/com/android/mail/browse/ConversationItemViewCoordinates.java
index 559d708..7b958d1 100644
--- a/src/com/android/mail/browse/ConversationItemViewCoordinates.java
+++ b/src/com/android/mail/browse/ConversationItemViewCoordinates.java
@@ -161,6 +161,28 @@
}
+ public static class CoordinatesCache {
+ private final SparseArray<ConversationItemViewCoordinates> mCoordinatesCache
+ = new SparseArray<ConversationItemViewCoordinates>();
+ private final SparseArray<View> mViewsCache = new SparseArray<View>();
+
+ public ConversationItemViewCoordinates getCoordinates(final int key) {
+ return mCoordinatesCache.get(key);
+ }
+
+ public View getView(final int layoutId) {
+ return mViewsCache.get(layoutId);
+ }
+
+ public void put(final int key, final ConversationItemViewCoordinates coords) {
+ mCoordinatesCache.put(key, coords);
+ }
+
+ public void put(final int layoutId, final View view) {
+ mViewsCache.put(layoutId, view);
+ }
+ }
+
/**
* One of either NORMAL_MODE or WIDE_MODE.
*/
@@ -268,7 +290,8 @@
private final int mFolderCellWidth;
private final int mFolderMinimumWidth;
- private ConversationItemViewCoordinates(Context context, Config config) {
+ private ConversationItemViewCoordinates(final Context context, final Config config,
+ final CoordinatesCache cache) {
Utils.traceBeginSection("CIV coordinates constructor");
final Resources res = context.getResources();
mFolderCellWidth = res.getDimensionPixelSize(R.dimen.folder_cell_width);
@@ -289,17 +312,23 @@
layoutId = R.layout.conversation_item_view_normal;
}
}
- final ViewGroup view = (ViewGroup) LayoutInflater.from(context).inflate(layoutId, null);
+
+ ViewGroup view = (ViewGroup) cache.getView(layoutId);
+ if (view == null) {
+ view = (ViewGroup) LayoutInflater.from(context).inflate(layoutId, null);
+ cache.put(layoutId, view);
+ }
// Show/hide optional views before measure/layout call
- View attachmentPreviews = null;
+ final View attachmentPreviews = view.findViewById(R.id.attachment_previews);;
if (config.getAttachmentPreviewMode() != ATTACHMENT_PREVIEW_NONE) {
- attachmentPreviews = view.findViewById(R.id.attachment_previews);
- LayoutParams params = attachmentPreviews.getLayoutParams();
+ final LayoutParams params = attachmentPreviews.getLayoutParams();
attachmentPreviews.setVisibility(View.VISIBLE);
params.height = getAttachmentPreviewsHeight(context, config.getAttachmentPreviewMode());
attachmentPreviews.setLayoutParams(params);
+ } else {
+ attachmentPreviews.setVisibility(View.GONE);
}
attachmentPreviewsDecodeHeight = getAttachmentPreviewsHeight(context,
ATTACHMENT_PREVIEW_UNREAD);
@@ -308,7 +337,7 @@
folders.setVisibility(config.areFoldersVisible() ? View.VISIBLE : View.GONE);
// Add margin between attachment previews and folders
- View attachmentPreviewsBottomMargin = view
+ final View attachmentPreviewsBottomMargin = view
.findViewById(R.id.attachment_previews_bottom_margin);
attachmentPreviewsBottomMargin.setVisibility(
attachmentPreviews != null && config.areFoldersVisible() ? View.VISIBLE
@@ -630,15 +659,15 @@
* Returns coordinates for elements inside a conversation header view given
* the view width.
*/
- public static ConversationItemViewCoordinates forConfig(Context context, Config config,
- SparseArray<ConversationItemViewCoordinates> cache) {
+ public static ConversationItemViewCoordinates forConfig(final Context context,
+ final Config config, final CoordinatesCache cache) {
final int cacheKey = config.getCacheKey();
- ConversationItemViewCoordinates coordinates = cache.get(cacheKey);
+ ConversationItemViewCoordinates coordinates = cache.getCoordinates(cacheKey);
if (coordinates != null) {
return coordinates;
}
- coordinates = new ConversationItemViewCoordinates(context, config);
+ coordinates = new ConversationItemViewCoordinates(context, config, cache);
cache.put(cacheKey, coordinates);
return coordinates;
}
diff --git a/src/com/android/mail/browse/MessageAttachmentBar.java b/src/com/android/mail/browse/MessageAttachmentBar.java
index 1bb6d2e..18efa86 100644
--- a/src/com/android/mail/browse/MessageAttachmentBar.java
+++ b/src/com/android/mail/browse/MessageAttachmentBar.java
@@ -176,6 +176,7 @@
}
} else if (res == R.id.download_again) {
if (mAttachment.isPresentLocally()) {
+ mActionHandler.showDownloadingDialog();
mActionHandler.startRedownloadingAttachment(mAttachment);
}
} else if (res == R.id.cancel_attachment) {
diff --git a/src/com/android/mail/compose/ComposeActivity.java b/src/com/android/mail/compose/ComposeActivity.java
index 61360f5..c80799d 100644
--- a/src/com/android/mail/compose/ComposeActivity.java
+++ b/src/com/android/mail/compose/ComposeActivity.java
@@ -69,6 +69,7 @@
import android.widget.Toast;
import com.android.common.Rfc822Validator;
+import com.android.common.contacts.DataUsageStatUpdater;
import com.android.ex.chips.RecipientEditTextView;
import com.android.mail.MailIntentService;
import com.android.mail.R;
@@ -2039,16 +2040,30 @@
sendOrSaveMessage(messageIdToSave, sendOrSaveMessage, selectedAccount);
if (!sendOrSaveMessage.mSave) {
- UIProvider.incrementRecipientsTimesContacted(mContext,
+ incrementRecipientsTimesContacted(mContext,
(String) sendOrSaveMessage.mValues.get(UIProvider.MessageColumns.TO));
- UIProvider.incrementRecipientsTimesContacted(mContext,
+ incrementRecipientsTimesContacted(mContext,
(String) sendOrSaveMessage.mValues.get(UIProvider.MessageColumns.CC));
- UIProvider.incrementRecipientsTimesContacted(mContext,
+ incrementRecipientsTimesContacted(mContext,
(String) sendOrSaveMessage.mValues.get(UIProvider.MessageColumns.BCC));
}
mSendOrSaveCallback.sendOrSaveFinished(SendOrSaveTask.this, true);
}
+ private static void incrementRecipientsTimesContacted(final Context context,
+ final String addressString) {
+ if (TextUtils.isEmpty(addressString)) {
+ return;
+ }
+ final Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(addressString);
+ final ArrayList<String> recipients = new ArrayList<String>(tokens.length);
+ for (int i = 0; i < tokens.length;i++) {
+ recipients.add(tokens[i].getAddress());
+ }
+ final DataUsageStatUpdater statsUpdater = new DataUsageStatUpdater(context);
+ statsUpdater.updateWithAddress(recipients);
+ }
+
/**
* Send or Save a message.
*/
diff --git a/src/com/android/mail/photo/MailPhotoViewActivity.java b/src/com/android/mail/photo/MailPhotoViewActivity.java
index ecceedf..8f4216e 100644
--- a/src/com/android/mail/photo/MailPhotoViewActivity.java
+++ b/src/com/android/mail/photo/MailPhotoViewActivity.java
@@ -58,6 +58,11 @@
private MenuItem mSaveAllItem;
private MenuItem mShareItem;
private MenuItem mShareAllItem;
+ /**
+ * Only for attachments that are currently downloading. Attachments that failed show the
+ * retry button.
+ */
+ private MenuItem mDownloadAgainItem;
private AttachmentActionHandler mActionHandler;
private Menu mMenu;
@@ -121,6 +126,7 @@
mSaveAllItem = mMenu.findItem(R.id.menu_save_all);
mShareItem = mMenu.findItem(R.id.menu_share);
mShareAllItem = mMenu.findItem(R.id.menu_share_all);
+ mDownloadAgainItem = mMenu.findItem(R.id.menu_download_again);
return true;
}
@@ -145,6 +151,7 @@
mSaveItem.setEnabled(!attachment.isDownloading()
&& attachment.canSave() && !attachment.isSavedToExternal());
mShareItem.setEnabled(attachment.canShare());
+ mDownloadAgainItem.setEnabled(attachment.canSave() && attachment.isDownloading());
} else {
if (mMenu != null) {
mMenu.setGroupEnabled(R.id.photo_view_menu_group, false);
@@ -201,6 +208,9 @@
} else if (itemId == R.id.menu_share_all) { // share all of the photos
shareAllAttachments();
return true;
+ } else if (itemId == R.id.menu_download_again) { // redownload the current photo
+ redownloadAttachment();
+ return true;
} else {
return super.onOptionsItemSelected(item);
}
@@ -277,7 +287,7 @@
retryButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- downloadAttachment();
+ redownloadAttachment();
emptyText.setVisibility(View.GONE);
retryButton.setVisibility(View.GONE);
}
@@ -294,13 +304,17 @@
}
/**
- * Downloads the attachment.
+ * Redownloads the attachment.
*/
- private void downloadAttachment() {
+ private void redownloadAttachment() {
final Attachment attachment = getCurrentAttachment();
if (attachment != null && attachment.canSave()) {
+ // REDOWNLOADING command is only for attachments that are finished or failed.
+ // For an attachment that is downloading (or paused in the DownloadManager), we need to
+ // cancel it first.
mActionHandler.setAttachment(attachment);
- mActionHandler.startDownloadingAttachment(AttachmentDestination.CACHE);
+ mActionHandler.cancelAttachment();
+ mActionHandler.startDownloadingAttachment(attachment.destination);
}
}
diff --git a/src/com/android/mail/preferences/MailPrefs.java b/src/com/android/mail/preferences/MailPrefs.java
index bb79652..ac06ced 100644
--- a/src/com/android/mail/preferences/MailPrefs.java
+++ b/src/com/android/mail/preferences/MailPrefs.java
@@ -22,6 +22,7 @@
import com.android.mail.providers.Account;
import com.android.mail.providers.UIProvider;
+import com.android.mail.utils.LogUtils;
import com.android.mail.widget.BaseWidgetProvider;
import com.google.common.collect.ImmutableSet;
@@ -159,6 +160,10 @@
}
public void configureWidget(int appWidgetId, Account account, final String folderUri) {
+ if (account == null) {
+ LogUtils.e(LOG_TAG, "Cannot configure widget with null account");
+ return;
+ }
getEditor().putString(PreferenceKeys.WIDGET_ACCOUNT_PREFIX + appWidgetId,
createWidgetPreferenceValue(account, folderUri)).apply();
}
diff --git a/src/com/android/mail/providers/Folder.java b/src/com/android/mail/providers/Folder.java
index c1ddf00..271aeeb 100644
--- a/src/com/android/mail/providers/Folder.java
+++ b/src/com/android/mail/providers/Folder.java
@@ -193,7 +193,139 @@
/** An immutable, empty conversation list */
public static final Collection<Folder> EMPTY = Collections.emptyList();
- // TODO: we desperately need a Builder here
+ public static final class Builder {
+ private int mId;
+ private String mPersistentId;
+ private Uri mUri;
+ private String mName;
+ private int mCapabilities;
+ private boolean mHasChildren;
+ private int mSyncWindow;
+ private Uri mConversationListUri;
+ private Uri mChildFoldersListUri;
+ private int mUnseenCount;
+ private int mUnreadCount;
+ private int mTotalCount;
+ private Uri mRefreshUri;
+ private int mSyncStatus;
+ private int mLastSyncResult;
+ private int mType;
+ private int mIconResId;
+ private int mNotificationIconResId;
+ private String mBgColor;
+ private String mFgColor;
+ private Uri mLoadMoreUri;
+ private String mHierarchicalDesc;
+ private Uri mParent;
+ private long mLastMessageTimestamp;
+
+ public Folder build() {
+ return new Folder(mId, mPersistentId, mUri, mName, mCapabilities,
+ mHasChildren, mSyncWindow, mConversationListUri, mChildFoldersListUri,
+ mUnseenCount, mUnreadCount, mTotalCount, mRefreshUri, mSyncStatus,
+ mLastSyncResult, mType, mIconResId, mNotificationIconResId, mBgColor,
+ mFgColor, mLoadMoreUri, mHierarchicalDesc, mParent,
+ mLastMessageTimestamp);
+ }
+
+ public Builder setId(final int id) {
+ mId = id;
+ return this;
+ }
+ public Builder setPersistentId(final String persistentId) {
+ mPersistentId = persistentId;
+ return this;
+ }
+ public Builder setUri(final Uri uri) {
+ mUri = uri;
+ return this;
+ }
+ public Builder setName(final String name) {
+ mName = name;
+ return this;
+ }
+ public Builder setCapabilities(final int capabilities) {
+ mCapabilities = capabilities;
+ return this;
+ }
+ public Builder setHasChildren(final boolean hasChildren) {
+ mHasChildren = hasChildren;
+ return this;
+ }
+ public Builder setSyncWindow(final int syncWindow) {
+ mSyncWindow = syncWindow;
+ return this;
+ }
+ public Builder setConversationListUri(final Uri conversationListUri) {
+ mConversationListUri = conversationListUri;
+ return this;
+ }
+ public Builder setChildFoldersListUri(final Uri childFoldersListUri) {
+ mChildFoldersListUri = childFoldersListUri;
+ return this;
+ }
+ public Builder setUnseenCount(final int unseenCount) {
+ mUnseenCount = unseenCount;
+ return this;
+ }
+ public Builder setUnreadCount(final int unreadCount) {
+ mUnreadCount = unreadCount;
+ return this;
+ }
+ public Builder setTotalCount(final int totalCount) {
+ mTotalCount = totalCount;
+ return this;
+ }
+ public Builder setRefreshUri(final Uri refreshUri) {
+ mRefreshUri = refreshUri;
+ return this;
+ }
+ public Builder setSyncStatus(final int syncStatus) {
+ mSyncStatus = syncStatus;
+ return this;
+ }
+ public Builder setLastSyncResult(final int lastSyncResult) {
+ mLastSyncResult = lastSyncResult;
+ return this;
+ }
+ public Builder setType(final int type) {
+ mType = type;
+ return this;
+ }
+ public Builder setIconResId(final int iconResId) {
+ mIconResId = iconResId;
+ return this;
+ }
+ public Builder setNotificationIconResId(final int notificationIconResId) {
+ mNotificationIconResId = notificationIconResId;
+ return this;
+ }
+ public Builder setBgColor(final String bgColor) {
+ mBgColor = bgColor;
+ return this;
+ }
+ public Builder setFgColor(final String fgColor) {
+ mFgColor = fgColor;
+ return this;
+ }
+ public Builder setLoadMoreUri(final Uri loadMoreUri) {
+ mLoadMoreUri = loadMoreUri;
+ return this;
+ }
+ public Builder setHierarchicalDesc(final String hierarchicalDesc) {
+ mHierarchicalDesc = hierarchicalDesc;
+ return this;
+ }
+ public Builder setParent(final Uri parent) {
+ mParent = parent;
+ return this;
+ }
+ public Builder setLastMessageTimestamp(final long lastMessageTimestamp) {
+ mLastMessageTimestamp = lastMessageTimestamp;
+ return this;
+ }
+ }
+
public Folder(int id, String persistentId, Uri uri, String name, int capabilities,
boolean hasChildren, int syncWindow, Uri conversationListUri, Uri childFoldersListUri,
int unseenCount, int unreadCount, int totalCount, Uri refreshUri, int syncStatus,
@@ -361,7 +493,7 @@
public static ObjectCursorLoader<Folder> forSearchResults(Account account, String query,
Context context) {
if (account.searchUri != null) {
- final Builder searchBuilder = account.searchUri.buildUpon();
+ final Uri.Builder searchBuilder = account.searchUri.buildUpon();
searchBuilder.appendQueryParameter(UIProvider.SearchQueryParameters.QUERY, query);
final Uri searchUri = searchBuilder.build();
return new ObjectCursorLoader<Folder>(context, searchUri, UIProvider.FOLDERS_PROJECTION,
diff --git a/src/com/android/mail/providers/UIProvider.java b/src/com/android/mail/providers/UIProvider.java
index e1b2b91..98769e4 100644
--- a/src/com/android/mail/providers/UIProvider.java
+++ b/src/com/android/mail/providers/UIProvider.java
@@ -2020,24 +2020,6 @@
}
}
- public static String getAttachmentTypeSetting() {
- // TODO: query the account to see what kinds of attachments it supports?
- return "com.google.android.gm.allowAddAnyAttachment";
- }
-
- public static void incrementRecipientsTimesContacted(Context context, String addressString) {
- DataUsageStatUpdater statsUpdater = new DataUsageStatUpdater(context);
- ArrayList<String> recipients = new ArrayList<String>();
- if (TextUtils.isEmpty(addressString)) {
- return;
- }
- Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(addressString);
- for (int i = 0; i < tokens.length;i++) {
- recipients.add(tokens[i].getAddress());
- }
- statsUpdater.updateWithAddress(recipients);
- }
-
public static final String[] UNDO_PROJECTION = {
ConversationColumns.MESSAGE_LIST_URI
};
diff --git a/src/com/android/mail/ui/AnimatedAdapter.java b/src/com/android/mail/ui/AnimatedAdapter.java
index 77af447..61a7793 100644
--- a/src/com/android/mail/ui/AnimatedAdapter.java
+++ b/src/com/android/mail/ui/AnimatedAdapter.java
@@ -41,6 +41,7 @@
import com.android.mail.browse.ConversationCursor;
import com.android.mail.browse.ConversationItemView;
import com.android.mail.browse.ConversationItemViewCoordinates;
+import com.android.mail.browse.ConversationItemViewCoordinates.CoordinatesCache;
import com.android.mail.browse.SwipeableConversationItemView;
import com.android.mail.content.ObjectCursor;
import com.android.mail.preferences.MailPrefs;
@@ -198,8 +199,7 @@
*/
private final SparseArray<ConversationSpecialItemView> mSpecialViews;
- private final SparseArray<ConversationItemViewCoordinates> mCoordinatesCache =
- new SparseArray<ConversationItemViewCoordinates>();
+ private final CoordinatesCache mCoordinatesCache = new CoordinatesCache();
/**
* Temporary views insert at specific positions relative to conversations. These can be
@@ -520,6 +520,7 @@
if(isPositionFadeLeaveBehind(conv)) {
LeaveBehindItem fade = getFadeLeaveBehindItem(position, conv);
fade.startShrinkAnimation(mAnimatorListener);
+ Utils.traceEndSection();
return fade;
}
}
@@ -540,6 +541,7 @@
fadeIn.startFadeInTextAnimation(sDismissAllShortDelay /* delay start */);
}
}
+ Utils.traceEndSection();
return fadeIn;
}
}
@@ -649,7 +651,7 @@
}
}
- public SparseArray<ConversationItemViewCoordinates> getCoordinatesCache() {
+ public CoordinatesCache getCoordinatesCache() {
return mCoordinatesCache;
}