streaming media

// FREEBIE
This commit is contained in:
Jake McGinty
2014-12-12 01:03:24 -08:00
parent a09e0afbd6
commit 07bb07c342
22 changed files with 423 additions and 395 deletions

View File

@@ -7,7 +7,6 @@ import android.util.Pair;
import org.thoughtcrime.securesms.crypto.MasterCipher;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.EncryptingPartDatabase;
import org.thoughtcrime.securesms.database.PartDatabase;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
@@ -54,11 +53,11 @@ public class AttachmentDownloadJob extends MasterSecretJob implements Injectable
@Override
public void onRun(MasterSecret masterSecret) throws IOException {
PartDatabase database = DatabaseFactory.getEncryptingPartDatabase(context, masterSecret);
PartDatabase database = DatabaseFactory.getPartDatabase(context);
Log.w(TAG, "Downloading push parts for: " + messageId);
List<Pair<Long, PduPart>> parts = database.getParts(messageId, false);
List<Pair<Long, PduPart>> parts = database.getParts(messageId);
for (Pair<Long, PduPart> partPair : parts) {
retrievePart(masterSecret, partPair.second, messageId, partPair.first);
@@ -69,7 +68,7 @@ public class AttachmentDownloadJob extends MasterSecretJob implements Injectable
@Override
public void onCanceled() {
PartDatabase database = DatabaseFactory.getPartDatabase(context);
List<Pair<Long, PduPart>> parts = database.getParts(messageId, false);
List<Pair<Long, PduPart>> parts = database.getParts(messageId);
for (Pair<Long, PduPart> partPair : parts) {
markFailed(messageId, partPair.second, partPair.first);
@@ -78,16 +77,14 @@ public class AttachmentDownloadJob extends MasterSecretJob implements Injectable
@Override
public boolean onShouldRetryThrowable(Exception exception) {
if (exception instanceof PushNetworkException) return true;
return false;
return (exception instanceof PushNetworkException);
}
private void retrievePart(MasterSecret masterSecret, PduPart part, long messageId, long partId)
throws IOException
{
EncryptingPartDatabase database = DatabaseFactory.getEncryptingPartDatabase(context, masterSecret);
File attachmentFile = null;
PartDatabase database = DatabaseFactory.getPartDatabase(context);
File attachmentFile = null;
try {
attachmentFile = createTempFile();
@@ -95,7 +92,7 @@ public class AttachmentDownloadJob extends MasterSecretJob implements Injectable
TextSecureAttachmentPointer pointer = createAttachmentPointer(masterSecret, part);
InputStream attachment = messageReceiver.retrieveAttachment(pointer, attachmentFile);
database.updateDownloadedPart(messageId, partId, part, attachment);
database.updateDownloadedPart(masterSecret, messageId, partId, part, attachment);
} catch (InvalidPartException | NonSuccessfulResponseCodeException | InvalidMessageException | MmsException e) {
Log.w(TAG, e);
markFailed(messageId, part, partId);

View File

@@ -16,6 +16,7 @@ import org.thoughtcrime.securesms.mms.MmsRadio;
import org.thoughtcrime.securesms.mms.MmsRadioException;
import org.thoughtcrime.securesms.mms.MmsSendResult;
import org.thoughtcrime.securesms.mms.OutgoingMmsConnection;
import org.thoughtcrime.securesms.mms.PartAuthority;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
import org.thoughtcrime.securesms.recipients.Recipients;
@@ -23,17 +24,22 @@ import org.thoughtcrime.securesms.transport.InsecureFallbackApprovalException;
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
import org.thoughtcrime.securesms.util.Hex;
import org.thoughtcrime.securesms.util.NumberUtil;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.jobqueue.JobParameters;
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
import org.whispersystems.libaxolotl.NoSessionException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import ws.com.google.android.mms.MmsException;
import ws.com.google.android.mms.pdu.EncodedStringValue;
import ws.com.google.android.mms.pdu.PduBody;
import ws.com.google.android.mms.pdu.PduComposer;
import ws.com.google.android.mms.pdu.PduHeaders;
import ws.com.google.android.mms.pdu.PduPart;
import ws.com.google.android.mms.pdu.SendConf;
import ws.com.google.android.mms.pdu.SendReq;
@@ -60,10 +66,12 @@ public class MmsSendJob extends MasterSecretJob {
}
@Override
public void onRun(MasterSecret masterSecret) throws MmsException, NoSuchMessageException {
public void onRun(MasterSecret masterSecret) throws MmsException, NoSuchMessageException, IOException {
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
SendReq message = database.getOutgoingMessage(masterSecret, messageId);
populatePartData(message.getBody(), masterSecret);
try {
MmsSendResult result = deliver(masterSecret, message);
@@ -94,6 +102,20 @@ public class MmsSendJob extends MasterSecretJob {
notifyMediaMessageDeliveryFailed(context, messageId);
}
private void populatePartData(PduPart part, MasterSecret masterSecret) throws IOException {
ByteArrayOutputStream os = part.getDataSize() > 0 && part.getDataSize() < Integer.MAX_VALUE
? new ByteArrayOutputStream((int)part.getDataSize())
: new ByteArrayOutputStream();
Util.copy(PartAuthority.getPartStream(context, masterSecret, part.getDataUri()), os);
part.setData(os.toByteArray());
}
private void populatePartData(PduBody body, MasterSecret masterSecret) throws IOException {
for (int i=body.getPartsNum()-1; i>=0; i--) {
populatePartData(body.getPart(i), masterSecret);
}
}
public MmsSendResult deliver(MasterSecret masterSecret, SendReq message)
throws UndeliverableMessageException, InsecureFallbackApprovalException
{

View File

@@ -114,7 +114,7 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
byte[] groupId = GroupUtil.getDecodedId(message.getTo()[0].getString());
Recipients recipients = DatabaseFactory.getGroupDatabase(context).getGroupMembers(groupId, false);
List<PushAddress> addresses = getPushAddresses(recipients);
List<TextSecureAttachment> attachments = getAttachments(message);
List<TextSecureAttachment> attachments = getAttachments(masterSecret, message);
if (MmsSmsColumns.Types.isGroupUpdate(message.getDatabaseMessageBox()) ||
MmsSmsColumns.Types.isGroupQuit(message.getDatabaseMessageBox()))

View File

@@ -109,7 +109,7 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
try {
Recipients recipients = RecipientFactory.getRecipientsFromString(context, destination, false);
PushAddress address = getPushAddress(recipients.getPrimaryRecipient());
List<TextSecureAttachment> attachments = getAttachments(message);
List<TextSecureAttachment> attachments = getAttachments(masterSecret, message);
String body = PartParser.getMessageText(message.getBody());
TextSecureMessage mediaMessage = new TextSecureMessage(message.getSentTimestamp(), attachments, body);

View File

@@ -3,8 +3,10 @@ package org.thoughtcrime.securesms.jobs;
import android.content.Context;
import android.util.Log;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
import org.thoughtcrime.securesms.mms.PartAuthority;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.Recipients;
@@ -20,10 +22,13 @@ import org.whispersystems.textsecure.api.push.PushAddress;
import org.whispersystems.textsecure.api.util.InvalidNumberException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;
import ws.com.google.android.mms.ContentType;
import ws.com.google.android.mms.pdu.PduPart;
import ws.com.google.android.mms.pdu.SendReq;
public abstract class PushSendJob extends MasterSecretJob {
@@ -82,18 +87,23 @@ public abstract class PushSendJob extends MasterSecretJob {
return (isSmsFallbackSupported(context, destination, media) && TextSecurePreferences.isFallbackSmsAskRequired(context));
}
protected List<TextSecureAttachment> getAttachments(SendReq message) {
protected List<TextSecureAttachment> getAttachments(final MasterSecret masterSecret, final SendReq message) {
List<TextSecureAttachment> attachments = new LinkedList<>();
for (int i=0;i<message.getBody().getPartsNum();i++) {
String contentType = Util.toIsoString(message.getBody().getPart(i).getContentType());
PduPart part = message.getBody().getPart(i);
String contentType = Util.toIsoString(part.getContentType());
if (ContentType.isImageType(contentType) ||
ContentType.isAudioType(contentType) ||
ContentType.isVideoType(contentType))
{
byte[] data = message.getBody().getPart(i).getData();
Log.w(TAG, "Adding attachment...");
attachments.add(new TextSecureAttachmentStream(new ByteArrayInputStream(data), contentType, data.length));
try {
InputStream is = PartAuthority.getPartStream(context, masterSecret, part.getDataUri());
attachments.add(new TextSecureAttachmentStream(is, contentType, part.getDataSize()));
} catch (IOException ioe) {
Log.w(TAG, "Couldn't open attachment", ioe);
}
}
}