2020import com .google .android .mms .ContentType ;
2121import com .google .android .mms .InvalidHeaderValueException ;
2222import com .google .android .mms .MmsException ;
23+ import com .google .android .mms .util .DownloadDrmHelper ;
24+ import com .google .android .mms .util .DrmConvertSession ;
2325import com .google .android .mms .util .PduCache ;
2426import com .google .android .mms .util .PduCacheEntry ;
2527import com .google .android .mms .util .SqliteWrapper ;
3032import android .content .Context ;
3133import android .database .Cursor ;
3234import android .database .DatabaseUtils ;
35+ import android .database .sqlite .SQLiteException ;
36+ import android .drm .DrmManagerClient ;
3337import android .net .Uri ;
38+ import android .os .FileUtils ;
39+ import android .provider .MediaStore ;
3440import android .provider .Telephony ;
3541import android .provider .Telephony .Mms ;
3642import android .provider .Telephony .MmsSms ;
4248import android .util .Log ;
4349
4450import java .io .ByteArrayOutputStream ;
51+ import java .io .File ;
4552import java .io .FileNotFoundException ;
4653import java .io .IOException ;
4754import java .io .InputStream ;
@@ -271,10 +278,12 @@ public class PduPersister {
271278
272279 private final Context mContext ;
273280 private final ContentResolver mContentResolver ;
281+ private final DrmManagerClient mDrmManagerClient ;
274282
275283 private PduPersister (Context context ) {
276284 mContext = context ;
277285 mContentResolver = context .getContentResolver ();
286+ mDrmManagerClient = new DrmManagerClient (context );
278287 }
279288
280289 /** Get(or create if not exist) an instance of PduPersister */
@@ -761,6 +770,9 @@ private void persistData(PduPart part, Uri uri,
761770 throws MmsException {
762771 OutputStream os = null ;
763772 InputStream is = null ;
773+ DrmConvertSession drmConvertSession = null ;
774+ Uri dataUri = null ;
775+ String path = null ;
764776
765777 try {
766778 byte [] data = part .getData ();
@@ -773,9 +785,38 @@ private void persistData(PduPart part, Uri uri,
773785 throw new MmsException ("unable to update " + uri .toString ());
774786 }
775787 } else {
788+ boolean isDrm = DownloadDrmHelper .isDrmConvertNeeded (contentType );
789+ if (isDrm ) {
790+ if (uri != null ) {
791+ try {
792+ path = convertUriToPath (mContext , uri );
793+ if (LOCAL_LOGV ) {
794+ Log .v (TAG , "drm uri: " + uri + " path: " + path );
795+ }
796+ File f = new File (path );
797+ long len = f .length ();
798+ if (LOCAL_LOGV ) {
799+ Log .v (TAG , "drm path: " + path + " len: " + len );
800+ }
801+ if (len > 0 ) {
802+ // we're not going to re-persist and re-encrypt an already
803+ // converted drm file
804+ return ;
805+ }
806+ } catch (Exception e ) {
807+ Log .e (TAG , "Can't get file info for: " + part .getDataUri (), e );
808+ }
809+ }
810+ // We haven't converted the file yet, start the conversion
811+ drmConvertSession = DrmConvertSession .open (mContext , contentType );
812+ if (drmConvertSession == null ) {
813+ throw new MmsException ("Mimetype " + contentType +
814+ " can not be converted." );
815+ }
816+ }
776817 os = mContentResolver .openOutputStream (uri );
777818 if (data == null ) {
778- Uri dataUri = part .getDataUri ();
819+ dataUri = part .getDataUri ();
779820 if ((dataUri == null ) || (dataUri == uri )) {
780821 Log .w (TAG , "Can't find data for this part." );
781822 return ;
@@ -788,13 +829,32 @@ private void persistData(PduPart part, Uri uri,
788829
789830 byte [] buffer = new byte [8192 ];
790831 for (int len = 0 ; (len = is .read (buffer )) != -1 ; ) {
791- os .write (buffer , 0 , len );
832+ if (!isDrm ) {
833+ os .write (buffer , 0 , len );
834+ } else {
835+ byte [] convertedData = drmConvertSession .convert (buffer , len );
836+ if (convertedData != null ) {
837+ os .write (convertedData , 0 , convertedData .length );
838+ } else {
839+ throw new MmsException ("Error converting drm data." );
840+ }
841+ }
792842 }
793843 } else {
794844 if (LOCAL_LOGV ) {
795845 Log .v (TAG , "Saving data to: " + uri );
796846 }
797- os .write (data );
847+ if (!isDrm ) {
848+ os .write (data );
849+ } else {
850+ dataUri = uri ;
851+ byte [] convertedData = drmConvertSession .convert (data , data .length );
852+ if (convertedData != null ) {
853+ os .write (convertedData , 0 , convertedData .length );
854+ } else {
855+ throw new MmsException ("Error converting drm data." );
856+ }
857+ }
798858 }
799859 }
800860 } catch (FileNotFoundException e ) {
@@ -818,7 +878,65 @@ private void persistData(PduPart part, Uri uri,
818878 Log .e (TAG , "IOException while closing: " + is , e );
819879 } // Ignore
820880 }
881+ if (drmConvertSession != null ) {
882+ drmConvertSession .close (path );
883+
884+ // Reset the permissions on the encrypted part file so everyone has only read
885+ // permission.
886+ File f = new File (path );
887+ ContentValues values = new ContentValues (0 );
888+ SqliteWrapper .update (mContext , mContentResolver ,
889+ Uri .parse ("content://mms/resetFilePerm/" + f .getName ()),
890+ values , null , null );
891+ }
892+ }
893+ }
894+
895+ /**
896+ * This method expects uri in the following format
897+ * content://media/<table_name>/<row_index> (or)
898+ * file://sdcard/test.mp4
899+ * http://test.com/test.mp4
900+ *
901+ * Here <table_name> shall be "video" or "audio" or "images"
902+ * <row_index> the index of the content in given table
903+ */
904+ static public String convertUriToPath (Context context , Uri uri ) {
905+ String path = null ;
906+ if (null != uri ) {
907+ String scheme = uri .getScheme ();
908+ if (null == scheme || scheme .equals ("" ) ||
909+ scheme .equals (ContentResolver .SCHEME_FILE )) {
910+ path = uri .getPath ();
911+
912+ } else if (scheme .equals ("http" )) {
913+ path = uri .toString ();
914+
915+ } else if (scheme .equals (ContentResolver .SCHEME_CONTENT )) {
916+ String [] projection = new String [] {MediaStore .MediaColumns .DATA };
917+ Cursor cursor = null ;
918+ try {
919+ cursor = context .getContentResolver ().query (uri , projection , null ,
920+ null , null );
921+ if (null == cursor || 0 == cursor .getCount () || !cursor .moveToFirst ()) {
922+ throw new IllegalArgumentException ("Given Uri could not be found" +
923+ " in media store" );
924+ }
925+ int pathIndex = cursor .getColumnIndexOrThrow (MediaStore .MediaColumns .DATA );
926+ path = cursor .getString (pathIndex );
927+ } catch (SQLiteException e ) {
928+ throw new IllegalArgumentException ("Given Uri is not formatted in a way " +
929+ "so that it can be found in media store." );
930+ } finally {
931+ if (null != cursor ) {
932+ cursor .close ();
933+ }
934+ }
935+ } else {
936+ throw new IllegalArgumentException ("Given Uri scheme is not supported" );
937+ }
821938 }
939+ return path ;
822940 }
823941
824942 private void updateAddress (
0 commit comments