1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 package com.android.messaging.mmslib.util;
18 
19 import android.content.Context;
20 import android.drm.DrmConvertedStatus;
21 import android.drm.DrmManagerClient;
22 import android.util.Log;
23 
24 import com.android.messaging.mmslib.Downloads;
25 
26 import java.io.FileNotFoundException;
27 import java.io.IOException;
28 import java.io.RandomAccessFile;
29 
30 
31 public class DrmConvertSession {
32     private DrmManagerClient mDrmClient;
33     private int mConvertSessionId;
34     private static final String TAG = "DrmConvertSession";
35 
DrmConvertSession(DrmManagerClient drmClient, int convertSessionId)36     private DrmConvertSession(DrmManagerClient drmClient, int convertSessionId) {
37         mDrmClient = drmClient;
38         mConvertSessionId = convertSessionId;
39     }
40 
41     /**
42      * Start of converting a file.
43      *
44      * @param context  The context of the application running the convert session.
45      * @param mimeType Mimetype of content that shall be converted.
46      * @return A convert session or null in case an error occurs.
47      */
open(Context context, String mimeType)48     public static DrmConvertSession open(Context context, String mimeType) {
49         DrmManagerClient drmClient = null;
50         int convertSessionId = -1;
51         if (context != null && mimeType != null && !mimeType.equals("")) {
52             try {
53                 drmClient = new DrmManagerClient(context);
54                 try {
55                     convertSessionId = drmClient.openConvertSession(mimeType);
56                 } catch (IllegalArgumentException e) {
57                     Log.w(TAG, "Conversion of Mimetype: " + mimeType
58                             + " is not supported.", e);
59                 } catch (IllegalStateException e) {
60                     Log.w(TAG, "Could not access Open DrmFramework.", e);
61                 }
62             } catch (IllegalArgumentException e) {
63                 Log.w(TAG,
64                         "DrmManagerClient instance could not be created, context is Illegal.");
65             } catch (IllegalStateException e) {
66                 Log.w(TAG, "DrmManagerClient didn't initialize properly.");
67             }
68         }
69 
70         if (drmClient == null || convertSessionId < 0) {
71             return null;
72         } else {
73             return new DrmConvertSession(drmClient, convertSessionId);
74         }
75     }
76 
77     /**
78      * Convert a buffer of data to protected format.
79      *
80      * @param buffer Buffer filled with data to convert.
81      * @param size   The number of bytes that shall be converted.
82      * @return A Buffer filled with converted data, if execution is ok, in all
83      * other case null.
84      */
convert(byte[] inBuffer, int size)85     public byte[] convert(byte[] inBuffer, int size) {
86         byte[] result = null;
87         if (inBuffer != null) {
88             DrmConvertedStatus convertedStatus = null;
89             try {
90                 if (size != inBuffer.length) {
91                     byte[] buf = new byte[size];
92                     System.arraycopy(inBuffer, 0, buf, 0, size);
93                     convertedStatus = mDrmClient.convertData(mConvertSessionId, buf);
94                 } else {
95                     convertedStatus = mDrmClient.convertData(mConvertSessionId, inBuffer);
96                 }
97 
98                 if (convertedStatus != null &&
99                         convertedStatus.statusCode == DrmConvertedStatus.STATUS_OK &&
100                         convertedStatus.convertedData != null) {
101                     result = convertedStatus.convertedData;
102                 }
103             } catch (IllegalArgumentException e) {
104                 Log.w(TAG, "Buffer with data to convert is illegal. Convertsession: "
105                         + mConvertSessionId, e);
106             } catch (IllegalStateException e) {
107                 Log.w(TAG, "Could not convert data. Convertsession: " +
108                         mConvertSessionId, e);
109             }
110         } else {
111             throw new IllegalArgumentException("Parameter inBuffer is null");
112         }
113         return result;
114     }
115 
116     /**
117      * Ends a conversion session of a file.
118      *
119      * @param fileName The filename of the converted file.
120      * @return Downloads.Impl.STATUS_SUCCESS if execution is ok.
121      *         Downloads.Impl.STATUS_FILE_ERROR in case converted file can not
122      *         be accessed. Downloads.Impl.STATUS_NOT_ACCEPTABLE if a problem
123      *         occurs when accessing drm framework.
124      *         Downloads.Impl.STATUS_UNKNOWN_ERROR if a general error occurred.
125      */
close(String filename)126     public int close(String filename) {
127         DrmConvertedStatus convertedStatus = null;
128         int result = Downloads.Impl.STATUS_UNKNOWN_ERROR;
129         if (mDrmClient != null && mConvertSessionId >= 0) {
130             try {
131                 convertedStatus = mDrmClient.closeConvertSession(mConvertSessionId);
132                 if (convertedStatus == null ||
133                         convertedStatus.statusCode != DrmConvertedStatus.STATUS_OK ||
134                         convertedStatus.convertedData == null) {
135                     result = Downloads.Impl.STATUS_NOT_ACCEPTABLE;
136                 } else {
137                     RandomAccessFile rndAccessFile = null;
138                     try {
139                         rndAccessFile = new RandomAccessFile(filename, "rw");
140                         rndAccessFile.seek(convertedStatus.offset);
141                         rndAccessFile.write(convertedStatus.convertedData);
142                         result = Downloads.Impl.STATUS_SUCCESS;
143                     } catch (FileNotFoundException e) {
144                         result = Downloads.Impl.STATUS_FILE_ERROR;
145                         Log.w(TAG, "File: " + filename + " could not be found.", e);
146                     } catch (IOException e) {
147                         result = Downloads.Impl.STATUS_FILE_ERROR;
148                         Log.w(TAG, "Could not access File: " + filename + " .", e);
149                     } catch (IllegalArgumentException e) {
150                         result = Downloads.Impl.STATUS_FILE_ERROR;
151                         Log.w(TAG, "Could not open file in mode: rw", e);
152                     } catch (SecurityException e) {
153                         Log.w(TAG, "Access to File: " + filename +
154                                 " was denied denied by SecurityManager.", e);
155                     } finally {
156                         if (rndAccessFile != null) {
157                             try {
158                                 rndAccessFile.close();
159                             } catch (IOException e) {
160                                 result = Downloads.Impl.STATUS_FILE_ERROR;
161                                 Log.w(TAG, "Failed to close File:" + filename
162                                         + ".", e);
163                             }
164                         }
165                     }
166                 }
167             } catch (IllegalStateException e) {
168                 Log.w(TAG, "Could not close convertsession. Convertsession: " +
169                         mConvertSessionId, e);
170             }
171         }
172         return result;
173     }
174 }
175