Fix reply/forward for both SMTP and EAS; fixes #2138725
* Add new introText column in the Body database * Reply/Forward put the appropriate String into this new column * Rfc822Output uses this when required when streaming the message Change-Id: I34602fdb3f91692c46fc8bc31ba0e6f680d445a0
This commit is contained in:
parent
0d00889f83
commit
5fc57eccef
|
@ -642,10 +642,20 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus
|
|||
//message.mHtmlReply = mSource.mHtml;
|
||||
message.mTextReply = mSource.mText;
|
||||
}
|
||||
|
||||
String fromAsString = Address.unpackToString(mSource.mFrom);
|
||||
if (ACTION_FORWARD.equals(action)) {
|
||||
message.mFlags |= Message.FLAG_TYPE_FORWARD;
|
||||
String subject = mSource.mSubject;
|
||||
String to = Address.unpackToString(mSource.mTo);
|
||||
String cc = Address.unpackToString(mSource.mCc);
|
||||
message.mIntroText =
|
||||
getString(R.string.message_compose_fwd_header_fmt, subject, fromAsString,
|
||||
to != null ? to : "", cc != null ? cc : "");
|
||||
} else {
|
||||
message.mFlags |= Message.FLAG_TYPE_REPLY;
|
||||
message.mIntroText =
|
||||
getString(R.string.message_compose_reply_header_fmt, fromAsString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -683,6 +693,7 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus
|
|||
values.put(BodyColumns.TEXT_CONTENT, mDraft.mText);
|
||||
values.put(BodyColumns.TEXT_REPLY, mDraft.mTextReply);
|
||||
values.put(BodyColumns.HTML_REPLY, mDraft.mHtmlReply);
|
||||
values.put(BodyColumns.INTRO_TEXT, mDraft.mIntroText);
|
||||
Body.updateBodyWithMessageId(MessageCompose.this, mDraft.mId, values);
|
||||
} else {
|
||||
// mDraft.mId is set upon return of saveToMailbox()
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package com.android.email.mail.transport;
|
||||
|
||||
import com.android.email.R;
|
||||
import com.android.email.codec.binary.Base64;
|
||||
import com.android.email.codec.binary.Base64OutputStream;
|
||||
import com.android.email.mail.Address;
|
||||
|
@ -67,11 +66,10 @@ public class Rfc822Output {
|
|||
}
|
||||
|
||||
String text = body.mTextContent;
|
||||
String fromAsString = Address.unpackToString(message.mFrom);
|
||||
int flags = message.mFlags;
|
||||
boolean isReply = (flags & Message.FLAG_TYPE_REPLY) != 0;
|
||||
boolean isForward = (flags & Message.FLAG_TYPE_FORWARD) != 0;
|
||||
|
||||
String intro = body.mIntroText == null ? "" : body.mIntroText;
|
||||
if (!appendQuotedText) {
|
||||
// appendQuotedText is set to false for use by SmartReply/SmartForward in EAS.
|
||||
// SmartReply doesn't appear to work properly, so we will still add the header into
|
||||
|
@ -79,7 +77,7 @@ public class Rfc822Output {
|
|||
// SmartForward doesn't put any kind of break between the original and the new text,
|
||||
// so we add a CRLF
|
||||
if (isReply) {
|
||||
text += context.getString(R.string.message_compose_reply_header_fmt, fromAsString);
|
||||
text += intro;
|
||||
} else if (isForward) {
|
||||
text += "\r\n";
|
||||
}
|
||||
|
@ -93,17 +91,13 @@ public class Rfc822Output {
|
|||
quotedText = matcher.replaceAll("\n");
|
||||
}
|
||||
if (isReply) {
|
||||
text += context.getString(R.string.message_compose_reply_header_fmt, fromAsString);
|
||||
text += intro;
|
||||
if (quotedText != null) {
|
||||
Matcher matcher = PATTERN_START_OF_LINE.matcher(quotedText);
|
||||
text += matcher.replaceAll(">");
|
||||
}
|
||||
} else if (isForward) {
|
||||
String subject = message.mSubject;
|
||||
String to = Address.unpackToString(message.mTo);
|
||||
String cc = Address.unpackToString(message.mCc);
|
||||
text += context.getString(R.string.message_compose_fwd_header_fmt, subject,
|
||||
fromAsString, to != null ? to : "", cc != null ? cc : "");
|
||||
text += intro;
|
||||
if (quotedText != null) {
|
||||
text += quotedText;
|
||||
}
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
package com.android.email.provider;
|
||||
|
||||
import com.android.email.R;
|
||||
|
||||
import android.content.ContentProviderOperation;
|
||||
import android.content.ContentProviderResult;
|
||||
import android.content.ContentResolver;
|
||||
|
@ -189,6 +187,8 @@ public abstract class EmailContent {
|
|||
public static final String TEXT_REPLY = "textReply";
|
||||
// Message id of the source (if this is a reply/forward)
|
||||
public static final String SOURCE_MESSAGE_KEY = "sourceMessageKey";
|
||||
// The text to be placed between a reply/forward response and the original message
|
||||
public static final String INTRO_TEXT = "introText";
|
||||
}
|
||||
|
||||
public static final class Body extends EmailContent implements BodyColumns {
|
||||
|
@ -203,9 +203,11 @@ public abstract class EmailContent {
|
|||
public static final int CONTENT_HTML_REPLY_COLUMN = 4;
|
||||
public static final int CONTENT_TEXT_REPLY_COLUMN = 5;
|
||||
public static final int CONTENT_SOURCE_KEY_COLUMN = 6;
|
||||
public static final int CONTENT_INTRO_TEXT_COLUMN = 7;
|
||||
public static final String[] CONTENT_PROJECTION = new String[] {
|
||||
RECORD_ID, BodyColumns.MESSAGE_KEY, BodyColumns.HTML_CONTENT, BodyColumns.TEXT_CONTENT,
|
||||
BodyColumns.HTML_REPLY, BodyColumns.TEXT_REPLY, BodyColumns.SOURCE_MESSAGE_KEY
|
||||
BodyColumns.HTML_REPLY, BodyColumns.TEXT_REPLY, BodyColumns.SOURCE_MESSAGE_KEY,
|
||||
BodyColumns.INTRO_TEXT
|
||||
};
|
||||
|
||||
public static final int TEXT_TEXT_COLUMN = 1;
|
||||
|
@ -226,6 +228,7 @@ public abstract class EmailContent {
|
|||
public String mHtmlReply;
|
||||
public String mTextReply;
|
||||
public long mSourceKey;
|
||||
public String mIntroText;
|
||||
|
||||
public Body() {
|
||||
mBaseUri = CONTENT_URI;
|
||||
|
@ -242,7 +245,7 @@ public abstract class EmailContent {
|
|||
values.put(BodyColumns.HTML_REPLY, mHtmlReply);
|
||||
values.put(BodyColumns.TEXT_REPLY, mTextReply);
|
||||
values.put(BodyColumns.SOURCE_MESSAGE_KEY, mSourceKey);
|
||||
|
||||
values.put(BodyColumns.INTRO_TEXT, mIntroText);
|
||||
return values;
|
||||
}
|
||||
|
||||
|
@ -337,6 +340,7 @@ public abstract class EmailContent {
|
|||
mHtmlReply = c.getString(CONTENT_HTML_REPLY_COLUMN);
|
||||
mTextReply = c.getString(CONTENT_TEXT_REPLY_COLUMN);
|
||||
mSourceKey = c.getLong(CONTENT_SOURCE_KEY_COLUMN);
|
||||
mIntroText = c.getString(CONTENT_INTRO_TEXT_COLUMN);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -501,6 +505,7 @@ public abstract class EmailContent {
|
|||
transient public String mHtmlReply;
|
||||
transient public long mSourceKey;
|
||||
transient public ArrayList<Attachment> mAttachments = null;
|
||||
transient public String mIntroText;
|
||||
|
||||
// Values used in mFlagRead
|
||||
public static final int UNREAD = 0;
|
||||
|
@ -684,6 +689,9 @@ public abstract class EmailContent {
|
|||
if (mSourceKey != 0) {
|
||||
cv.put(Body.SOURCE_MESSAGE_KEY, mSourceKey);
|
||||
}
|
||||
if (mIntroText != null) {
|
||||
cv.put(Body.INTRO_TEXT, mIntroText);
|
||||
}
|
||||
b = ContentProviderOperation.newInsert(Body.CONTENT_URI);
|
||||
b.withValues(cv);
|
||||
ContentValues backValues = new ContentValues();
|
||||
|
|
|
@ -69,7 +69,8 @@ public class EmailProvider extends ContentProvider {
|
|||
// Version 3: Add "sourceKey" column
|
||||
// Version 4: Database wipe required; changing AccountManager interface w/Exchange
|
||||
// Version 5: Database wipe required; changing AccountManager interface w/Exchange
|
||||
public static final int BODY_DATABASE_VERSION = 5;
|
||||
// Version 6: Adding Body.mIntroText column
|
||||
public static final int BODY_DATABASE_VERSION = 6;
|
||||
|
||||
public static final String EMAIL_AUTHORITY = "com.android.email.provider";
|
||||
|
||||
|
@ -494,7 +495,8 @@ public class EmailProvider extends ContentProvider {
|
|||
+ BodyColumns.TEXT_CONTENT + " text, "
|
||||
+ BodyColumns.HTML_REPLY + " text, "
|
||||
+ BodyColumns.TEXT_REPLY + " text, "
|
||||
+ BodyColumns.SOURCE_MESSAGE_KEY + " text"
|
||||
+ BodyColumns.SOURCE_MESSAGE_KEY + " text, "
|
||||
+ BodyColumns.INTRO_TEXT + " text"
|
||||
+ ");";
|
||||
db.execSQL("create table " + Body.TABLE_NAME + s);
|
||||
db.execSQL(createIndex(Body.TABLE_NAME, BodyColumns.MESSAGE_KEY));
|
||||
|
@ -507,6 +509,15 @@ public class EmailProvider extends ContentProvider {
|
|||
createBodyTable(db);
|
||||
} catch (SQLException e) {
|
||||
}
|
||||
} else if (oldVersion == 5) {
|
||||
try {
|
||||
db.execSQL("alter table " + Body.TABLE_NAME
|
||||
+ " add " + BodyColumns.INTRO_TEXT + " text");
|
||||
} catch (SQLException e) {
|
||||
// Shouldn't be needed unless we're debugging and interrupt the process
|
||||
Log.w(TAG, "Exception upgrading EmailProviderBody.db from v5 to v6", e);
|
||||
}
|
||||
oldVersion = 6;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -590,12 +601,17 @@ public class EmailProvider extends ContentProvider {
|
|||
}
|
||||
if (oldVersion == 5) {
|
||||
// Message Tables: Add SyncColumns.SERVER_TIMESTAMP
|
||||
db.execSQL("alter table " + Message.TABLE_NAME
|
||||
+ " add column " + SyncColumns.SERVER_TIMESTAMP + " integer" + ";");
|
||||
db.execSQL("alter table " + Message.UPDATED_TABLE_NAME
|
||||
+ " add column " + SyncColumns.SERVER_TIMESTAMP + " integer" + ";");
|
||||
db.execSQL("alter table " + Message.DELETED_TABLE_NAME
|
||||
+ " add column " + SyncColumns.SERVER_TIMESTAMP + " integer" + ";");
|
||||
try {
|
||||
db.execSQL("alter table " + Message.TABLE_NAME
|
||||
+ " add column " + SyncColumns.SERVER_TIMESTAMP + " integer" + ";");
|
||||
db.execSQL("alter table " + Message.UPDATED_TABLE_NAME
|
||||
+ " add column " + SyncColumns.SERVER_TIMESTAMP + " integer" + ";");
|
||||
db.execSQL("alter table " + Message.DELETED_TABLE_NAME
|
||||
+ " add column " + SyncColumns.SERVER_TIMESTAMP + " integer" + ";");
|
||||
} catch (SQLException e) {
|
||||
// Shouldn't be needed unless we're debugging and interrupt the process
|
||||
Log.w(TAG, "Exception upgrading EmailProvider.db from v5 to v6", e);
|
||||
}
|
||||
oldVersion = 6;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ public class Rfc822OutputTests extends AndroidTestCase {
|
|||
msg.mFrom = SENDER;
|
||||
msg.mFlags = Message.FLAG_TYPE_REPLY;
|
||||
msg.mTextReply = BODY;
|
||||
msg.mIntroText = REPLY_BODY_SHORT;
|
||||
msg.save(getContext());
|
||||
|
||||
String body = Rfc822Output.buildBodyText(getContext(), msg, true);
|
||||
|
@ -87,6 +88,7 @@ public class Rfc822OutputTests extends AndroidTestCase {
|
|||
msg.mFrom = SENDER;
|
||||
msg.mFlags = Message.FLAG_TYPE_REPLY;
|
||||
msg.mTextReply = BODY;
|
||||
msg.mIntroText = REPLY_BODY_SHORT;
|
||||
msg.save(getContext());
|
||||
|
||||
String body = Rfc822Output.buildBodyText(getContext(), msg, false);
|
||||
|
|
|
@ -151,6 +151,7 @@ public class ProviderTestUtils extends Assert {
|
|||
message.mTextReply = "reply text " + name;
|
||||
message.mHtmlReply = "reply html " + name;
|
||||
message.mSourceKey = 400 + name.length();
|
||||
message.mIntroText = "intro text " + name;
|
||||
}
|
||||
|
||||
if (saveIt) {
|
||||
|
@ -314,6 +315,7 @@ public class ProviderTestUtils extends Assert {
|
|||
assertEquals(caller + " mTextReply", expect.mTextReply, actual.mTextReply);
|
||||
assertEquals(caller + " mHtmlReply", expect.mHtmlReply, actual.mHtmlReply);
|
||||
assertEquals(caller + " mSourceKey", expect.mSourceKey, actual.mSourceKey);
|
||||
assertEquals(caller + " mIntroText", expect.mIntroText, actual.mIntroText);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -234,11 +234,13 @@ public class ProviderTests extends ProviderTestCase2<EmailProvider> {
|
|||
String textReply2 = message2.mTextReply;
|
||||
String htmlReply2 = message2.mHtmlReply;
|
||||
long sourceKey2 = message2.mSourceKey;
|
||||
String introText2 = message2.mIntroText;
|
||||
message2.mText = null;
|
||||
message2.mHtml = null;
|
||||
message2.mTextReply = null;
|
||||
message2.mHtmlReply = null;
|
||||
message2.mSourceKey = 0;
|
||||
message2.mIntroText = null;
|
||||
Message message2get = EmailContent.Message.restoreMessageWithId(mMockContext, message2Id);
|
||||
ProviderTestUtils.assertMessageEqual("testMessageSave", message2, message2get);
|
||||
|
||||
|
@ -249,6 +251,7 @@ public class ProviderTests extends ProviderTestCase2<EmailProvider> {
|
|||
assertEquals("reply text", textReply2, body2.mTextReply);
|
||||
assertEquals("reply html", htmlReply2, body2.mHtmlReply);
|
||||
assertEquals("source key", sourceKey2, body2.mSourceKey);
|
||||
assertEquals("intro text", introText2, body2.mIntroText);
|
||||
|
||||
// Message with attachments and body
|
||||
Message message3 = ProviderTestUtils.setupMessage("message3", account1Id, box1Id, true,
|
||||
|
@ -432,6 +435,7 @@ public class ProviderTests extends ProviderTestCase2<EmailProvider> {
|
|||
final String htmlContent = "and some html";
|
||||
final String textReply = "plain text reply";
|
||||
final String htmlReply = "or the html reply";
|
||||
final String introText = "fred wrote:";
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(BodyColumns.TEXT_CONTENT, textContent);
|
||||
|
@ -439,6 +443,7 @@ public class ProviderTests extends ProviderTestCase2<EmailProvider> {
|
|||
values.put(BodyColumns.TEXT_REPLY, textReply);
|
||||
values.put(BodyColumns.HTML_REPLY, htmlReply);
|
||||
values.put(BodyColumns.SOURCE_MESSAGE_KEY, 17);
|
||||
values.put(BodyColumns.INTRO_TEXT, introText);
|
||||
|
||||
// 1
|
||||
Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
|
||||
|
@ -454,6 +459,7 @@ public class ProviderTests extends ProviderTestCase2<EmailProvider> {
|
|||
assertEquals(body1.mTextReply, textReply);
|
||||
assertEquals(body1.mHtmlReply, htmlReply);
|
||||
assertEquals(body1.mSourceKey, 17);
|
||||
assertEquals(body1.mIntroText, introText);
|
||||
|
||||
// 2
|
||||
Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true,
|
||||
|
@ -470,6 +476,7 @@ public class ProviderTests extends ProviderTestCase2<EmailProvider> {
|
|||
assertEquals(body2.mTextReply, textReply);
|
||||
assertEquals(body2.mHtmlReply, htmlReply);
|
||||
assertEquals(body2.mSourceKey, 17);
|
||||
assertEquals(body2.mIntroText, introText);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue