use of com.fsck.k9.mail.Body in project k-9 by k9mail.
the class MessageViewInfoExtractorTest method testSimpleHtmlMessage.
@Test
public void testSimpleHtmlMessage() throws MessagingException {
String bodyText = "<strong>K-9 Mail</strong> rocks :>";
// Create text/plain body
TextBody body = new TextBody(bodyText);
// Create message
MimeMessage message = new MimeMessage();
message.setHeader(MimeHeader.HEADER_CONTENT_TYPE, "text/html");
MimeMessageHelper.setBody(message, body);
// Extract text
ArrayList<Viewable> outputViewableParts = new ArrayList<>();
MessageExtractor.findViewablesAndAttachments(message, outputViewableParts, null);
assertEquals(outputViewableParts.size(), 1);
ViewableExtractedText container = messageViewInfoExtractor.extractTextFromViewables(outputViewableParts);
assertEquals(BODY_TEXT, container.text);
assertEquals(bodyText, container.html);
}
use of com.fsck.k9.mail.Body in project k-9 by k9mail.
the class MessageCreationHelper method createMessage.
private static Message createMessage(String mimeType, Body body) {
MimeMessage message = new MimeMessage();
message.setBody(body);
message.setHeader(MimeHeader.HEADER_CONTENT_TYPE, mimeType);
return message;
}
use of com.fsck.k9.mail.Body in project k-9 by k9mail.
the class MessageCompose method initFromIntent.
/**
* Handle external intents that trigger the message compose activity.
*
* <p>
* Supported external intents:
* <ul>
* <li>{@link Intent#ACTION_VIEW}</li>
* <li>{@link Intent#ACTION_SENDTO}</li>
* <li>{@link Intent#ACTION_SEND}</li>
* <li>{@link Intent#ACTION_SEND_MULTIPLE}</li>
* </ul>
* </p>
*
* @param intent
* The (external) intent that started the activity.
*
* @return {@code true}, if this activity was started by an external intent. {@code false},
* otherwise.
*/
private boolean initFromIntent(final Intent intent) {
boolean startedByExternalIntent = false;
final String action = intent.getAction();
if (Intent.ACTION_VIEW.equals(action) || Intent.ACTION_SENDTO.equals(action)) {
/*
* Someone has clicked a mailto: link. The address is in the URI.
*/
if (intent.getData() != null) {
Uri uri = intent.getData();
if (MailTo.isMailTo(uri)) {
MailTo mailTo = MailTo.parse(uri);
initializeFromMailto(mailTo);
}
}
/*
* Note: According to the documentation ACTION_VIEW and ACTION_SENDTO don't accept
* EXTRA_* parameters.
* And previously we didn't process these EXTRAs. But it looks like nobody bothers to
* read the official documentation and just copies wrong sample code that happens to
* work with the AOSP Email application. And because even big players get this wrong,
* we're now finally giving in and read the EXTRAs for those actions (below).
*/
}
if (Intent.ACTION_SEND.equals(action) || Intent.ACTION_SEND_MULTIPLE.equals(action) || Intent.ACTION_SENDTO.equals(action) || Intent.ACTION_VIEW.equals(action)) {
startedByExternalIntent = true;
/*
* Note: Here we allow a slight deviation from the documented behavior.
* EXTRA_TEXT is used as message body (if available) regardless of the MIME
* type of the intent. In addition one or multiple attachments can be added
* using EXTRA_STREAM.
*/
CharSequence text = intent.getCharSequenceExtra(Intent.EXTRA_TEXT);
// Only use EXTRA_TEXT if the body hasn't already been set by the mailto URI
if (text != null && messageContentView.getText().length() == 0) {
messageContentView.setText(CrLfConverter.toLf(text));
}
String type = intent.getType();
if (Intent.ACTION_SEND.equals(action)) {
Uri stream = intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (stream != null) {
attachmentPresenter.addExternalAttachment(stream, type);
}
} else {
List<Parcelable> list = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
if (list != null) {
for (Parcelable parcelable : list) {
Uri stream = (Uri) parcelable;
if (stream != null) {
attachmentPresenter.addExternalAttachment(stream, type);
}
}
}
}
String subject = intent.getStringExtra(Intent.EXTRA_SUBJECT);
// Only use EXTRA_SUBJECT if the subject hasn't already been set by the mailto URI
if (subject != null && subjectView.getText().length() == 0) {
subjectView.setText(subject);
}
recipientPresenter.initFromSendOrViewIntent(intent);
}
if (ACTION_AUTOCRYPT_PEER.equals(action)) {
String trustId = intent.getStringExtra(OpenPgpApi.EXTRA_AUTOCRYPT_PEER_ID);
if (trustId != null) {
recipientPresenter.initFromTrustIdAction(trustId);
startedByExternalIntent = true;
}
}
return startedByExternalIntent;
}
use of com.fsck.k9.mail.Body in project k-9 by k9mail.
the class MessageCompose method onCreate.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (UpgradeDatabases.actionUpgradeDatabases(this, getIntent())) {
finish();
return;
}
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setLayout(R.layout.message_compose);
ViewStub contentContainer = findViewById(R.id.message_compose_content);
sizeFormatter = new SizeFormatter(getResources());
ThemeManager themeManager = getThemeManager();
int messageComposeThemeResourceId = themeManager.getMessageComposeThemeResourceId();
ContextThemeWrapper themeContext = new ContextThemeWrapper(this, messageComposeThemeResourceId);
LayoutInflater themedLayoutInflater = LayoutInflater.from(themeContext);
contentContainer.setLayoutInflater(themedLayoutInflater);
View contentView = contentContainer.inflate();
// background color needs to be forced
// TODO: Change themes to use appropriate background colors that don't need overriding.
TypedValue outValue = new TypedValue();
themeContext.getTheme().resolveAttribute(R.attr.messageViewBackgroundColor, outValue, true);
contentView.setBackgroundColor(outValue.data);
initializeActionBar();
// on api level 15, setContentView() shows the progress bar for some reason...
setProgressBarIndeterminateVisibility(false);
final Intent intent = getIntent();
String messageReferenceString = intent.getStringExtra(EXTRA_MESSAGE_REFERENCE);
relatedMessageReference = MessageReference.parse(messageReferenceString);
final String accountUuid = (relatedMessageReference != null) ? relatedMessageReference.getAccountUuid() : intent.getStringExtra(EXTRA_ACCOUNT);
if (accountUuid != null) {
account = preferences.getAccount(accountUuid);
}
if (account == null) {
account = preferences.getDefaultAccount();
}
if (account == null) {
/*
* There are no accounts set up. This should not have happened. Prompt the
* user to set up an account as an acceptable bailout.
*/
MessageList.launch(this);
changesMadeSinceLastSave = false;
finish();
return;
}
contacts = Contacts.getInstance(MessageCompose.this);
chooseIdentityButton = findViewById(R.id.identity);
chooseIdentityButton.setOnClickListener(this);
ReplyToView replyToView = new ReplyToView(this);
replyToPresenter = new ReplyToPresenter(replyToView);
RecipientMvpView recipientMvpView = new RecipientMvpView(this);
ComposePgpInlineDecider composePgpInlineDecider = new ComposePgpInlineDecider();
ComposePgpEnableByDefaultDecider composePgpEnableByDefaultDecider = new ComposePgpEnableByDefaultDecider();
OpenPgpApiManager openPgpApiManager = new OpenPgpApiManager(getApplicationContext(), this);
recipientPresenter = new RecipientPresenter(getApplicationContext(), getSupportLoaderManager(), openPgpApiManager, recipientMvpView, account, composePgpInlineDecider, composePgpEnableByDefaultDecider, AutocryptStatusInteractor.getInstance(), new ReplyToParser(), DI.get(AutocryptDraftStateHeaderParser.class));
recipientPresenter.asyncUpdateCryptoStatus();
subjectView = findViewById(R.id.subject);
subjectView.getInputExtras(true).putBoolean("allowEmoji", true);
EditText upperSignature = findViewById(R.id.upper_signature);
EditText lowerSignature = findViewById(R.id.lower_signature);
QuotedMessageMvpView quotedMessageMvpView = new QuotedMessageMvpView(this);
quotedMessagePresenter = new QuotedMessagePresenter(this, quotedMessageMvpView, account);
attachmentPresenter = new AttachmentPresenter(getApplicationContext(), attachmentMvpView, getSupportLoaderManager(), this);
messageContentView = findViewById(R.id.message_content);
messageContentView.getInputExtras(true).putBoolean("allowEmoji", true);
attachmentsView = findViewById(R.id.attachments);
TextWatcher draftNeedsChangingTextWatcher = new SimpleTextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
changesMadeSinceLastSave = true;
}
};
TextWatcher signTextWatcher = new SimpleTextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
changesMadeSinceLastSave = true;
signatureChanged = true;
}
};
replyToView.addTextChangedListener(draftNeedsChangingTextWatcher);
recipientMvpView.addTextChangedListener(draftNeedsChangingTextWatcher);
quotedMessageMvpView.addTextChangedListener(draftNeedsChangingTextWatcher);
subjectView.addTextChangedListener(draftNeedsChangingTextWatcher);
messageContentView.addTextChangedListener(draftNeedsChangingTextWatcher);
/*
* We set this to invisible by default. Other methods will turn it back on if it's
* needed.
*/
quotedMessagePresenter.showOrHideQuotedText(QuotedTextMode.NONE);
subjectView.setOnFocusChangeListener(this);
messageContentView.setOnFocusChangeListener(this);
if (savedInstanceState != null) {
/*
* This data gets used in onCreate, so grab it here instead of onRestoreInstanceState
*/
relatedMessageProcessed = savedInstanceState.getBoolean(STATE_KEY_SOURCE_MESSAGE_PROCED, false);
}
if (initFromIntent(intent)) {
action = Action.COMPOSE;
changesMadeSinceLastSave = true;
} else {
String action = intent.getAction();
if (ACTION_COMPOSE.equals(action)) {
this.action = Action.COMPOSE;
} else if (ACTION_REPLY.equals(action)) {
this.action = Action.REPLY;
} else if (ACTION_REPLY_ALL.equals(action)) {
this.action = Action.REPLY_ALL;
} else if (ACTION_FORWARD.equals(action)) {
this.action = Action.FORWARD;
} else if (ACTION_FORWARD_AS_ATTACHMENT.equals(action)) {
this.action = Action.FORWARD_AS_ATTACHMENT;
} else if (ACTION_EDIT_DRAFT.equals(action)) {
this.action = Action.EDIT_DRAFT;
} else {
// This shouldn't happen
Timber.w("MessageCompose was started with an unsupported action");
this.action = Action.COMPOSE;
}
}
if (identity == null) {
identity = account.getIdentity(0);
}
if (account.isSignatureBeforeQuotedText()) {
signatureView = upperSignature;
lowerSignature.setVisibility(View.GONE);
} else {
signatureView = lowerSignature;
upperSignature.setVisibility(View.GONE);
}
updateSignature();
signatureView.addTextChangedListener(signTextWatcher);
if (!identity.getSignatureUse()) {
signatureView.setVisibility(View.GONE);
}
requestReadReceipt = account.isMessageReadReceipt();
updateFrom();
replyToPresenter.setIdentity(identity);
if (!relatedMessageProcessed) {
if (action == Action.REPLY || action == Action.REPLY_ALL || action == Action.FORWARD || action == Action.FORWARD_AS_ATTACHMENT || action == Action.EDIT_DRAFT) {
messageLoaderHelper = messageLoaderHelperFactory.createForMessageCompose(this, getSupportLoaderManager(), getSupportFragmentManager(), messageLoaderCallbacks);
internalMessageHandler.sendEmptyMessage(MSG_PROGRESS_ON);
if (action == Action.FORWARD_AS_ATTACHMENT) {
messageLoaderHelper.asyncStartOrResumeLoadingMessageMetadata(relatedMessageReference);
} else {
Parcelable cachedDecryptionResult = intent.getParcelableExtra(EXTRA_MESSAGE_DECRYPTION_RESULT);
messageLoaderHelper.asyncStartOrResumeLoadingMessage(relatedMessageReference, cachedDecryptionResult);
}
}
}
if (action == Action.REPLY || action == Action.REPLY_ALL) {
relatedFlag = Flag.ANSWERED;
} else if (action == Action.FORWARD || action == Action.FORWARD_AS_ATTACHMENT) {
relatedFlag = Flag.FORWARDED;
}
if (action == Action.REPLY || action == Action.REPLY_ALL || action == Action.EDIT_DRAFT) {
// change focus to message body.
messageContentView.requestFocus();
} else {
// Explicitly set focus to "To:" input field (see issue 2998)
recipientMvpView.requestFocusOnToField();
}
updateMessageFormat();
// Set font size of input controls
int fontSize = K9.getFontSizes().getMessageComposeInput();
replyToView.setFontSizes(K9.getFontSizes(), fontSize);
recipientMvpView.setFontSizes(K9.getFontSizes(), fontSize);
quotedMessageMvpView.setFontSizes(K9.getFontSizes(), fontSize);
K9.getFontSizes().setViewTextSize(subjectView, fontSize);
K9.getFontSizes().setViewTextSize(messageContentView, fontSize);
K9.getFontSizes().setViewTextSize(signatureView, fontSize);
updateMessageFormat();
setTitle();
currentMessageBuilder = (MessageBuilder) getLastCustomNonConfigurationInstance();
if (currentMessageBuilder != null) {
setProgressBarIndeterminateVisibility(true);
currentMessageBuilder.reattachCallback(this);
}
if (savedInstanceState == null) {
checkAndRequestPermissions();
}
}
use of com.fsck.k9.mail.Body in project k-9 by k9mail.
the class AttachmentInfoExtractorTest method extractInfo__withDeferredFileBody.
@Test
public void extractInfo__withDeferredFileBody() throws Exception {
attachmentInfoExtractor = new AttachmentInfoExtractor(context) {
@Nullable
@Override
protected Uri getDecryptedFileProviderUri(DeferredFileBody decryptedTempFileBody, String mimeType) {
return TEST_URI;
}
};
DeferredFileBody body = mock(DeferredFileBody.class);
when(body.getSize()).thenReturn(TEST_SIZE);
MimeBodyPart part = new MimeBodyPart();
part.setBody(body);
part.setHeader(MimeHeader.HEADER_CONTENT_TYPE, TEST_MIME_TYPE);
AttachmentViewInfo attachmentViewInfo = attachmentInfoExtractor.extractAttachmentInfo(part);
assertEquals(TEST_URI, attachmentViewInfo.internalUri);
assertEquals(TEST_SIZE, attachmentViewInfo.size);
assertEquals(TEST_MIME_TYPE, attachmentViewInfo.mimeType);
assertFalse(attachmentViewInfo.inlineAttachment);
assertTrue(attachmentViewInfo.isContentAvailable());
}
Aggregations