@@ -79,6 +79,8 @@ public class PartDatabase extends Database {
7979 private static final String THUMBNAIL = "thumbnail" ;
8080 private static final String ASPECT_RATIO = "aspect_ratio" ;
8181
82+ private static final String ID_CONTENT_WHERE = ID + " = ? AND " + CONTENT_ID + " = ?" ;
83+
8284 public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY, " +
8385 MMS_ID + " INTEGER, " + SEQUENCE + " INTEGER DEFAULT 0, " +
8486 CONTENT_TYPE + " TEXT, " + NAME + " TEXT, " + CHARSET + " INTEGER, " +
@@ -113,10 +115,10 @@ public PartDatabase(Context context, SQLiteOpenHelper databaseHelper) {
113115 super (context , databaseHelper );
114116 }
115117
116- public InputStream getPartStream (MasterSecret masterSecret , long partId )
118+ public InputStream getPartStream (MasterSecret masterSecret , long partId , byte [] contentId )
117119 throws FileNotFoundException
118120 {
119- return getDataStream (masterSecret , partId , DATA );
121+ return getDataStream (masterSecret , partId , contentId , DATA );
120122 }
121123
122124 public void updateFailedDownloadedPart (long messageId , long partId , PduPart part )
@@ -206,7 +208,7 @@ public void deleteParts(long mmsId) {
206208 cursor .close ();
207209 }
208210
209- database .delete (TABLE_NAME , MMS_ID + " = ?" , new String [] {mmsId + "" });
211+ database .delete (TABLE_NAME , MMS_ID + " = ?" , new String [] {mmsId + "" });
210212 }
211213
212214 @ SuppressWarnings ("ResultOfMethodCallIgnored" )
@@ -343,15 +345,17 @@ protected OutputStream getPartOutputStream(MasterSecret masterSecret, File path,
343345 return new EncryptingPartOutputStream (path , masterSecret );
344346 }
345347
346- @ VisibleForTesting InputStream getDataStream (MasterSecret masterSecret , long partId , String dataType )
348+ @ VisibleForTesting InputStream getDataStream (MasterSecret masterSecret , long partId , byte [] contentId , String dataType )
347349 throws FileNotFoundException
348350 {
349351 SQLiteDatabase database = databaseHelper .getReadableDatabase ();
350352 Cursor cursor = null ;
351353
352354 try {
353- cursor = database .query (TABLE_NAME , new String []{dataType }, ID_WHERE ,
354- new String [] {partId +"" }, null , null , null );
355+ cursor = database .query (TABLE_NAME , new String []{dataType }, ID_CONTENT_WHERE ,
356+ new String [] {String .valueOf (partId ),
357+ Util .toIsoString (contentId )},
358+ null , null , null );
355359
356360 if (cursor != null && cursor .moveToFirst ()) {
357361 if (cursor .isNull (0 )) {
@@ -402,15 +406,15 @@ private Pair<File, Long> writePartData(MasterSecret masterSecret, PduPart part)
402406 }
403407 }
404408
405- public InputStream getThumbnailStream (final MasterSecret masterSecret , final long partId ) throws IOException {
409+ public InputStream getThumbnailStream (MasterSecret masterSecret , long partId , byte [] contentId ) throws IOException {
406410 Log .w (TAG , "getThumbnailStream(" + partId + ")" );
407- final InputStream dataStream = getDataStream (masterSecret , partId , THUMBNAIL );
411+ final InputStream dataStream = getDataStream (masterSecret , partId , contentId , THUMBNAIL );
408412 if (dataStream != null ) {
409413 return dataStream ;
410414 }
411415
412416 try {
413- return thumbnailExecutor .submit (new ThumbnailFetchCallable (masterSecret , partId )).get ();
417+ return thumbnailExecutor .submit (new ThumbnailFetchCallable (masterSecret , partId , contentId )).get ();
414418 } catch (InterruptedException ie ) {
415419 throw new AssertionError ("interrupted" );
416420 } catch (ExecutionException ee ) {
@@ -424,7 +428,7 @@ private PduPart getPart(Cursor cursor) {
424428
425429 getPartValues (part , cursor );
426430
427- part .setDataUri (ContentUris . withAppendedId ( PartAuthority . PART_CONTENT_URI , part .getId ()));
431+ part .setDataUri (PartAuthority . getPartUri ( part . getId () , part .getContentId ()));
428432
429433 return part ;
430434 }
@@ -454,7 +458,7 @@ private long insertPart(MasterSecret masterSecret, PduPart part, long mmsId, Bit
454458 ThumbnailData data = new ThumbnailData (thumbnail );
455459 updatePartThumbnail (masterSecret , partId , part , data .toDataStream (), data .getAspectRatio ());
456460 } else if (!part .isPendingPush ()) {
457- thumbnailExecutor .submit (new ThumbnailFetchCallable (masterSecret , partId ));
461+ thumbnailExecutor .submit (new ThumbnailFetchCallable (masterSecret , partId , part . getContentId () ));
458462 }
459463
460464 return partId ;
@@ -479,7 +483,7 @@ public void updateDownloadedPart(MasterSecret masterSecret, long messageId,
479483
480484 database .update (TABLE_NAME , values , ID_WHERE , new String []{partId +"" });
481485
482- thumbnailExecutor .submit (new ThumbnailFetchCallable (masterSecret , partId ));
486+ thumbnailExecutor .submit (new ThumbnailFetchCallable (masterSecret , partId , part . getContentId () ));
483487
484488 notifyConversationListeners (DatabaseFactory .getMmsDatabase (context ).getThreadIdForMessage (messageId ));
485489 }
@@ -534,11 +538,12 @@ public void updatePartThumbnail(MasterSecret masterSecret, long partId, PduPart
534538
535539 public static class ImageRecord {
536540 private long partId ;
541+ private byte [] contentId ;
537542 private String contentType ;
538543 private String address ;
539544 private long date ;
540545
541- private ImageRecord (long partId , String contentType , String address , long date ) {
546+ private ImageRecord (long partId , byte [] contentId , String contentType , String address , long date ) {
542547 this .partId = partId ;
543548 this .contentType = contentType ;
544549 this .address = address ;
@@ -547,6 +552,7 @@ private ImageRecord(long partId, String contentType, String address, long date)
547552
548553 public static ImageRecord from (Cursor cursor ) {
549554 return new ImageRecord (cursor .getLong (cursor .getColumnIndexOrThrow (ID )),
555+ Util .toIsoBytes (cursor .getString (cursor .getColumnIndexOrThrow (CONTENT_ID ))),
550556 cursor .getString (cursor .getColumnIndexOrThrow (CONTENT_TYPE )),
551557 cursor .getString (cursor .getColumnIndexOrThrow (MmsDatabase .ADDRESS )),
552558 cursor .getLong (cursor .getColumnIndexOrThrow (MmsDatabase .NORMALIZED_DATE_RECEIVED )) * 1000 );
@@ -569,22 +575,24 @@ public long getDate() {
569575 }
570576
571577 public Uri getUri () {
572- return ContentUris . withAppendedId ( PartAuthority .PART_CONTENT_URI , getPartId () );
578+ return PartAuthority .getPartUri ( partId , contentId );
573579 }
574580 }
575581
576582 @ VisibleForTesting class ThumbnailFetchCallable implements Callable <InputStream > {
577583 private final MasterSecret masterSecret ;
578584 private final long partId ;
585+ private final byte [] contentId ;
579586
580- public ThumbnailFetchCallable (MasterSecret masterSecret , long partId ) {
587+ public ThumbnailFetchCallable (MasterSecret masterSecret , long partId , byte [] contentId ) {
581588 this .masterSecret = masterSecret ;
582589 this .partId = partId ;
590+ this .contentId = contentId ;
583591 }
584592
585593 @ Override
586594 public InputStream call () throws Exception {
587- final InputStream stream = getDataStream (masterSecret , partId , THUMBNAIL );
595+ final InputStream stream = getDataStream (masterSecret , partId , contentId , THUMBNAIL );
588596 if (stream != null ) {
589597 return stream ;
590598 }
@@ -599,7 +607,8 @@ public InputStream call() throws Exception {
599607 } catch (BitmapDecodingException bde ) {
600608 throw new IOException (bde );
601609 }
602- return getDataStream (masterSecret , partId , THUMBNAIL );
610+
611+ return getDataStream (masterSecret , partId , contentId , THUMBNAIL );
603612 }
604613 }
605614}
0 commit comments