Exemple #1
0
 void insertParts(MasterSecret masterSecret, long mmsId, PduBody body) throws MmsException {
   for (int i = 0; i < body.getPartsNum(); i++) {
     PduPart part = body.getPart(i);
     PartId partId = insertPart(masterSecret, part, mmsId, part.getThumbnail());
     Log.w(TAG, "Inserted part at ID: " + partId);
   }
 }
  private static PduPart constructPartFromUri(Context context, Uri uri)
      throws IOException, MediaTooLargeException {
    PduPart part = new PduPart();
    ContentResolver resolver = context.getContentResolver();
    Cursor cursor = null;

    try {
      cursor =
          resolver.query(uri, new String[] {MediaStore.Video.Media.MIME_TYPE}, null, null, null);
      if (cursor != null && cursor.moveToFirst()) {
        Log.w("VideoSlide", "Setting mime type: " + cursor.getString(0));
        part.setContentType(cursor.getString(0).getBytes());
      }
    } finally {
      if (cursor != null) cursor.close();
    }

    if (getMediaSize(context, uri) > MAX_MESSAGE_SIZE)
      throw new MediaTooLargeException("Video exceeds maximum message size.");

    part.setDataUri(uri);
    part.setContentId((System.currentTimeMillis() + "").getBytes());
    part.setName(("Video" + System.currentTimeMillis()).getBytes());

    return part;
  }
  public static PduPart constructPartFromUri(Context context, Uri uri)
      throws IOException, MediaTooLargeException {
    PduPart part = new PduPart();

    assertMediaSize(context, uri, MmsMediaConstraints.MAX_MESSAGE_SIZE);

    Cursor cursor = null;

    try {
      cursor =
          context
              .getContentResolver()
              .query(uri, new String[] {Audio.Media.MIME_TYPE}, null, null, null);

      if (cursor != null && cursor.moveToFirst())
        part.setContentType(cursor.getString(0).getBytes());
      else throw new IOException("Unable to query content type.");
    } finally {
      if (cursor != null) cursor.close();
    }

    part.setDataUri(uri);
    part.setContentId((System.currentTimeMillis() + "").getBytes());
    part.setName(("Audio" + System.currentTimeMillis()).getBytes());

    return part;
  }
Exemple #4
0
  private PartId insertPart(MasterSecret masterSecret, PduPart part, long mmsId, Bitmap thumbnail)
      throws MmsException {
    Log.w(TAG, "inserting part to mms " + mmsId);
    SQLiteDatabase database = databaseHelper.getWritableDatabase();
    Pair<File, Long> partData = null;

    if (!part.isPendingPush()) {
      partData = writePartData(masterSecret, part);
      Log.w(TAG, "Wrote part to file: " + partData.first.getAbsolutePath());
    }

    ContentValues contentValues = getContentValuesForPart(part);
    contentValues.put(MMS_ID, mmsId);

    if (partData != null) {
      contentValues.put(DATA, partData.first.getAbsolutePath());
      contentValues.put(SIZE, partData.second);
    }

    long partRowId = database.insert(TABLE_NAME, null, contentValues);
    PartId partId = new PartId(partRowId, part.getUniqueId());

    if (thumbnail != null) {
      Log.w(TAG, "inserting pre-generated thumbnail");
      ThumbnailData data = new ThumbnailData(thumbnail);
      updatePartThumbnail(masterSecret, partId, part, data.toDataStream(), data.getAspectRatio());
    } else if (!part.isPendingPush()) {
      thumbnailExecutor.submit(new ThumbnailFetchCallable(masterSecret, partId));
    }

    return partId;
  }
Exemple #5
0
  private PduPart getPart(Cursor cursor) {
    PduPart part = new PduPart();

    getPartValues(part, cursor);

    part.setDataUri(PartAuthority.getPartUri(part.getPartId()));

    return part;
  }
  @Override
  public void onCanceled() {
    PartDatabase database = DatabaseFactory.getPartDatabase(context);
    List<PduPart> parts = database.getParts(messageId);

    for (PduPart part : parts) {
      markFailed(messageId, part, part.getPartId());
    }
  }
  private static PduPart constructPartFromUri(Uri uri) throws IOException, BitmapDecodingException {
    PduPart part = new PduPart();

    part.setDataUri(uri);
    part.setContentType(ContentType.IMAGE_JPEG.getBytes());
    part.setContentId((System.currentTimeMillis() + "").getBytes());
    part.setName(("Image" + System.currentTimeMillis()).getBytes());

    return part;
  }
  @Override
  public void onRun(MasterSecret masterSecret) throws IOException {
    PartDatabase database = DatabaseFactory.getPartDatabase(context);

    Log.w(TAG, "Downloading push parts for: " + messageId);

    List<PduPart> parts = database.getParts(messageId);

    for (PduPart part : parts) {
      retrievePart(masterSecret, part, messageId);
      Log.w(TAG, "Got part: " + part.getPartId());
    }
  }
Exemple #9
0
  public void updateFailedDownloadedPart(long messageId, PartId partId, PduPart part)
      throws MmsException {
    SQLiteDatabase database = databaseHelper.getWritableDatabase();

    part.setContentDisposition(new byte[0]);
    part.setPendingPush(false);

    ContentValues values = getContentValuesForPart(part);

    values.put(DATA, (String) null);

    database.update(TABLE_NAME, values, PART_ID_WHERE, partId.toStrings());
    notifyConversationListeners(
        DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageId));
  }
Exemple #10
0
 private Pair<File, Long> writePartData(MasterSecret masterSecret, PduPart part)
     throws MmsException {
   try {
     if (part.getData() != null) {
       Log.w(TAG, "Writing part data from buffer");
       return writePartData(masterSecret, part, new ByteArrayInputStream(part.getData()));
     } else if (part.getDataUri() != null) {
       Log.w(TAG, "Writing part data from URI");
       InputStream in = PartAuthority.getPartStream(context, masterSecret, part.getDataUri());
       return writePartData(masterSecret, part, in);
     } else {
       throw new MmsException("Part is empty!");
     }
   } catch (IOException e) {
     throw new MmsException(e);
   }
 }
  private TextSecureAttachmentPointer createAttachmentPointer(
      MasterSecret masterSecret, PduPart part) throws InvalidPartException {
    try {
      MasterCipher masterCipher = new MasterCipher(masterSecret);
      long id = Long.parseLong(Util.toIsoString(part.getContentLocation()));
      byte[] key =
          masterCipher.decryptBytes(Base64.decode(Util.toIsoString(part.getContentDisposition())));
      String relay = null;

      if (part.getName() != null) {
        relay = Util.toIsoString(part.getName());
      }

      return new TextSecureAttachmentPointer(id, null, key, relay);
    } catch (InvalidMessageException | IOException e) {
      Log.w(TAG, e);
      throw new InvalidPartException(e);
    }
  }
  private static PduBody pduBodyFor(
      MasterSecret masterSecret, List<TextSecureAttachment> attachments) {
    PduBody body = new PduBody();

    for (TextSecureAttachment attachment : attachments) {
      if (attachment.isPointer()) {
        PduPart media = new PduPart();
        byte[] encryptedKey =
            new MasterCipher(masterSecret).encryptBytes(attachment.asPointer().getKey());

        media.setContentType(Util.toIsoBytes(attachment.getContentType()));
        media.setContentLocation(Util.toIsoBytes(String.valueOf(attachment.asPointer().getId())));
        media.setContentDisposition(Util.toIsoBytes(Base64.encodeBytes(encryptedKey)));
        media.setPendingPush(true);

        body.addPart(media);
      }
    }

    return body;
  }
Exemple #13
0
    @Override
    public InputStream call() throws Exception {
      final InputStream stream = getDataStream(masterSecret, partId, THUMBNAIL);
      if (stream != null) {
        return stream;
      }

      try {
        PduPart part = getPart(partId);
        ThumbnailData data =
            MediaUtil.generateThumbnail(
                context, masterSecret, part.getDataUri(), Util.toIsoString(part.getContentType()));
        if (data == null) {
          return null;
        }
        updatePartThumbnail(masterSecret, partId, part, data.toDataStream(), data.getAspectRatio());
      } catch (BitmapDecodingException bde) {
        throw new IOException(bde);
      }

      return getDataStream(masterSecret, partId, THUMBNAIL);
    }
Exemple #14
0
  public void updateDownloadedPart(
      MasterSecret masterSecret, long messageId, PartId partId, PduPart part, InputStream data)
      throws MmsException {
    SQLiteDatabase database = databaseHelper.getWritableDatabase();
    Pair<File, Long> partData = writePartData(masterSecret, part, data);

    part.setContentDisposition(new byte[0]);
    part.setPendingPush(false);

    ContentValues values = getContentValuesForPart(part);

    if (partData != null) {
      values.put(DATA, partData.first.getAbsolutePath());
      values.put(SIZE, partData.second);
    }

    database.update(TABLE_NAME, values, PART_ID_WHERE, partId.toStrings());

    thumbnailExecutor.submit(new ThumbnailFetchCallable(masterSecret, partId));

    notifyConversationListeners(
        DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageId));
  }
Exemple #15
0
  public void updatePartData(MasterSecret masterSecret, PduPart part, InputStream data)
      throws MmsException {
    SQLiteDatabase database = databaseHelper.getWritableDatabase();
    Pair<File, Long> partData = writePartData(masterSecret, part, data);

    if (partData == null) throw new MmsException("couldn't update part data");

    Cursor cursor = null;
    try {
      cursor =
          database.query(
              TABLE_NAME,
              new String[] {DATA},
              PART_ID_WHERE,
              part.getPartId().toStrings(),
              null,
              null,
              null);

      if (cursor != null && cursor.moveToFirst()) {
        int dataColumn = cursor.getColumnIndexOrThrow(DATA);
        if (!cursor.isNull(dataColumn) && !new File(cursor.getString(dataColumn)).delete()) {
          Log.w(TAG, "Couldn't delete old part file");
        }
      }
    } finally {
      if (cursor != null) cursor.close();
    }
    ContentValues values = new ContentValues(2);
    values.put(DATA, partData.first.getAbsolutePath());
    values.put(SIZE, partData.second);

    part.setDataSize(partData.second);

    database.update(TABLE_NAME, values, PART_ID_WHERE, part.getPartId().toStrings());
    Log.w(TAG, "updated data for part #" + part.getPartId());
  }
  private void retrievePart(MasterSecret masterSecret, PduPart part, long messageId)
      throws IOException {
    PartDatabase database = DatabaseFactory.getPartDatabase(context);
    File attachmentFile = null;
    PartDatabase.PartId partId = part.getPartId();

    try {
      attachmentFile = createTempFile();

      TextSecureAttachmentPointer pointer = createAttachmentPointer(masterSecret, part);
      InputStream attachment = messageReceiver.retrieveAttachment(pointer, attachmentFile);

      database.updateDownloadedPart(masterSecret, messageId, partId, part, attachment);
    } catch (InvalidPartException
        | NonSuccessfulResponseCodeException
        | InvalidMessageException
        | MmsException e) {
      Log.w(TAG, e);
      markFailed(messageId, part, partId);
    } finally {
      if (attachmentFile != null) attachmentFile.delete();
    }
  }
Exemple #17
0
 @Override
 public boolean onResourceReady(
     GlideDrawable resource,
     Object model,
     Target<GlideDrawable> target,
     boolean isFromMemoryCache,
     boolean isFirstResource) {
   if (resource instanceof GlideBitmapDrawable) {
     Log.w(TAG, "onResourceReady() for a Bitmap. Saving.");
     part.setThumbnail(((GlideBitmapDrawable) resource).getBitmap());
   }
   LayoutParams layoutParams = (LayoutParams) getRemoveButton().getLayoutParams();
   if (resource.getIntrinsicWidth() < getWidth()) {
     layoutParams.topMargin = 0;
     layoutParams.rightMargin =
         Math.max(0, (getWidth() - image.getPaddingRight() - resource.getIntrinsicWidth()) / 2);
   } else {
     layoutParams.topMargin =
         Math.max(0, (getHeight() - image.getPaddingTop() - resource.getIntrinsicHeight()) / 2);
     layoutParams.rightMargin = 0;
   }
   getRemoveButton().setLayoutParams(layoutParams);
   return false;
 }
Exemple #18
0
  private void getPartValues(PduPart part, Cursor cursor) {

    part.setRowId(cursor.getLong(cursor.getColumnIndexOrThrow(ROW_ID)));
    part.setUniqueId(cursor.getLong(cursor.getColumnIndexOrThrow(UNIQUE_ID)));

    int charsetColumn = cursor.getColumnIndexOrThrow(CHARSET);

    if (!cursor.isNull(charsetColumn)) part.setCharset(cursor.getInt(charsetColumn));

    int contentTypeColumn = cursor.getColumnIndexOrThrow(CONTENT_TYPE);

    if (!cursor.isNull(contentTypeColumn))
      part.setContentType(Util.toIsoBytes(cursor.getString(contentTypeColumn)));

    int nameColumn = cursor.getColumnIndexOrThrow(NAME);

    if (!cursor.isNull(nameColumn)) part.setName(Util.toIsoBytes(cursor.getString(nameColumn)));

    int fileNameColumn = cursor.getColumnIndexOrThrow(FILENAME);

    if (!cursor.isNull(fileNameColumn))
      part.setFilename(Util.toIsoBytes(cursor.getString(fileNameColumn)));

    int contentDispositionColumn = cursor.getColumnIndexOrThrow(CONTENT_DISPOSITION);

    if (!cursor.isNull(contentDispositionColumn))
      part.setContentDisposition(Util.toIsoBytes(cursor.getString(contentDispositionColumn)));

    int contentIdColumn = cursor.getColumnIndexOrThrow(CONTENT_ID);

    if (!cursor.isNull(contentIdColumn))
      part.setContentId(Util.toIsoBytes(cursor.getString(contentIdColumn)));

    int contentLocationColumn = cursor.getColumnIndexOrThrow(CONTENT_LOCATION);

    if (!cursor.isNull(contentLocationColumn))
      part.setContentLocation(Util.toIsoBytes(cursor.getString(contentLocationColumn)));

    int encryptedColumn = cursor.getColumnIndexOrThrow(ENCRYPTED);

    if (!cursor.isNull(encryptedColumn)) part.setEncrypted(cursor.getInt(encryptedColumn) == 1);

    int pendingPushColumn = cursor.getColumnIndexOrThrow(PENDING_PUSH_ATTACHMENT);

    if (!cursor.isNull(pendingPushColumn))
      part.setPendingPush(cursor.getInt(pendingPushColumn) == 1);

    int sizeColumn = cursor.getColumnIndexOrThrow(SIZE);

    if (!cursor.isNull(sizeColumn))
      part.setDataSize(cursor.getLong(cursor.getColumnIndexOrThrow(SIZE)));
  }
Exemple #19
0
  private ContentValues getContentValuesForPart(PduPart part) throws MmsException {
    ContentValues contentValues = new ContentValues();

    if (part.getCharset() != 0) {
      contentValues.put(CHARSET, part.getCharset());
    }

    if (part.getContentType() != null) {
      contentValues.put(CONTENT_TYPE, Util.toIsoString(part.getContentType()));

      if (Util.toIsoString(part.getContentType()).equals(ContentType.APP_SMIL)) {
        contentValues.put(SEQUENCE, -1);
      }
    } else {
      throw new MmsException("There is no content type for this part.");
    }

    if (part.getName() != null) {
      contentValues.put(NAME, new String(part.getName()));
    }

    if (part.getFilename() != null) {
      contentValues.put(FILENAME, new String(part.getFilename()));
    }

    if (part.getContentDisposition() != null) {
      contentValues.put(CONTENT_DISPOSITION, Util.toIsoString(part.getContentDisposition()));
    }

    if (part.getContentId() != null) {
      contentValues.put(CONTENT_ID, Util.toIsoString(part.getContentId()));
    }

    if (part.getContentLocation() != null) {
      contentValues.put(CONTENT_LOCATION, Util.toIsoString(part.getContentLocation()));
    }

    contentValues.put(ENCRYPTED, part.getEncrypted() ? 1 : 0);
    contentValues.put(PENDING_PUSH_ATTACHMENT, part.isPendingPush() ? 1 : 0);
    contentValues.put(UNIQUE_ID, part.getUniqueId());

    return contentValues;
  }
Exemple #20
0
 protected OutputStream getPartOutputStream(MasterSecret masterSecret, File path, PduPart part)
     throws FileNotFoundException {
   Log.w(TAG, "Writing part to: " + path.getAbsolutePath());
   part.setEncrypted(true);
   return new EncryptingPartOutputStream(path, masterSecret);
 }