1526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen/* 2526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Copyright (C) 2012 The Android Open Source Project 3526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 4526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Licensed under the Apache License, Version 2.0 (the "License"); 5526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * you may not use this file except in compliance with the License. 6526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * You may obtain a copy of the License at 7526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 8526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * http://www.apache.org/licenses/LICENSE-2.0 9526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 10526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Unless required by applicable law or agreed to in writing, software 11526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * distributed under the License is distributed on an "AS IS" BASIS, 12526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * See the License for the specific language governing permissions and 14526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * limitations under the License. 15526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 16526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 17526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenpackage com.google.android.mms.util; 18526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 19526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.content.Context; 20526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.drm.DrmConvertedStatus; 21526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.drm.DrmManagerClient; 22526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.util.Log; 23526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.provider.Downloads; 24526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 25526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.io.FileNotFoundException; 26526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.io.IOException; 27526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.io.RandomAccessFile; 28526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 29526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 30526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenpublic class DrmConvertSession { 31526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private DrmManagerClient mDrmClient; 32526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private int mConvertSessionId; 33526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final String TAG = "DrmConvertSession"; 34526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 35526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private DrmConvertSession(DrmManagerClient drmClient, int convertSessionId) { 36526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen mDrmClient = drmClient; 37526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen mConvertSessionId = convertSessionId; 38526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 39526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 40526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 41526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Start of converting a file. 42526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 43526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param context The context of the application running the convert session. 44526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param mimeType Mimetype of content that shall be converted. 45526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return A convert session or null in case an error occurs. 46526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 47526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen public static DrmConvertSession open(Context context, String mimeType) { 48526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen DrmManagerClient drmClient = null; 49526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int convertSessionId = -1; 50526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (context != null && mimeType != null && !mimeType.equals("")) { 51526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 52526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen drmClient = new DrmManagerClient(context); 53526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 54526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen convertSessionId = drmClient.openConvertSession(mimeType); 55526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (IllegalArgumentException e) { 56526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.w(TAG, "Conversion of Mimetype: " + mimeType 57526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen + " is not supported.", e); 58526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (IllegalStateException e) { 59526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.w(TAG, "Could not access Open DrmFramework.", e); 60526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 61526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (IllegalArgumentException e) { 62526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.w(TAG, 63526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen "DrmManagerClient instance could not be created, context is Illegal."); 64526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (IllegalStateException e) { 65526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.w(TAG, "DrmManagerClient didn't initialize properly."); 66526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 67526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 68526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 69526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (drmClient == null || convertSessionId < 0) { 70526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 71526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 72526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return new DrmConvertSession(drmClient, convertSessionId); 73526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 74526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 75526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 76526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Convert a buffer of data to protected format. 77526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 78526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param buffer Buffer filled with data to convert. 79526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param size The number of bytes that shall be converted. 80526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return A Buffer filled with converted data, if execution is ok, in all 81526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * other case null. 82526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 83526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen public byte [] convert(byte[] inBuffer, int size) { 84526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] result = null; 85526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (inBuffer != null) { 86526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen DrmConvertedStatus convertedStatus = null; 87526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 88526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (size != inBuffer.length) { 89526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] buf = new byte[size]; 90526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen System.arraycopy(inBuffer, 0, buf, 0, size); 91526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen convertedStatus = mDrmClient.convertData(mConvertSessionId, buf); 92526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 93526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen convertedStatus = mDrmClient.convertData(mConvertSessionId, inBuffer); 94526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 95526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 96526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (convertedStatus != null && 97526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen convertedStatus.statusCode == DrmConvertedStatus.STATUS_OK && 98526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen convertedStatus.convertedData != null) { 99526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen result = convertedStatus.convertedData; 100526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 101526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (IllegalArgumentException e) { 102526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.w(TAG, "Buffer with data to convert is illegal. Convertsession: " 103526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen + mConvertSessionId, e); 104526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (IllegalStateException e) { 105526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.w(TAG, "Could not convert data. Convertsession: " + 106526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen mConvertSessionId, e); 107526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 108526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 109526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new IllegalArgumentException("Parameter inBuffer is null"); 110526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 111526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return result; 112526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 113526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 114526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 115526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Ends a conversion session of a file. 116526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 117526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param fileName The filename of the converted file. 118526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return Downloads.Impl.STATUS_SUCCESS if execution is ok. 119526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Downloads.Impl.STATUS_FILE_ERROR in case converted file can not 120526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * be accessed. Downloads.Impl.STATUS_NOT_ACCEPTABLE if a problem 121526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * occurs when accessing drm framework. 122526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Downloads.Impl.STATUS_UNKNOWN_ERROR if a general error occurred. 123526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 124526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen public int close(String filename) { 125526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen DrmConvertedStatus convertedStatus = null; 126526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int result = Downloads.Impl.STATUS_UNKNOWN_ERROR; 127526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (mDrmClient != null && mConvertSessionId >= 0) { 128526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 129526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen convertedStatus = mDrmClient.closeConvertSession(mConvertSessionId); 130526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (convertedStatus == null || 131526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen convertedStatus.statusCode != DrmConvertedStatus.STATUS_OK || 132526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen convertedStatus.convertedData == null) { 133526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen result = Downloads.Impl.STATUS_NOT_ACCEPTABLE; 134526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 135526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen RandomAccessFile rndAccessFile = null; 136526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 137526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen rndAccessFile = new RandomAccessFile(filename, "rw"); 138526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen rndAccessFile.seek(convertedStatus.offset); 139526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen rndAccessFile.write(convertedStatus.convertedData); 140526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen result = Downloads.Impl.STATUS_SUCCESS; 141526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (FileNotFoundException e) { 142526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen result = Downloads.Impl.STATUS_FILE_ERROR; 143526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.w(TAG, "File: " + filename + " could not be found.", e); 144526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (IOException e) { 145526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen result = Downloads.Impl.STATUS_FILE_ERROR; 146526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.w(TAG, "Could not access File: " + filename + " .", e); 147526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (IllegalArgumentException e) { 148526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen result = Downloads.Impl.STATUS_FILE_ERROR; 149526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.w(TAG, "Could not open file in mode: rw", e); 150526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (SecurityException e) { 151526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.w(TAG, "Access to File: " + filename + 152526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen " was denied denied by SecurityManager.", e); 153526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } finally { 154526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (rndAccessFile != null) { 155526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 156526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen rndAccessFile.close(); 157526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (IOException e) { 158526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen result = Downloads.Impl.STATUS_FILE_ERROR; 159526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.w(TAG, "Failed to close File:" + filename 160526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen + ".", e); 161526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 162526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 163526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 164526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 165526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (IllegalStateException e) { 166526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.w(TAG, "Could not close convertsession. Convertsession: " + 167526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen mConvertSessionId, e); 168526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 169526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 170526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return result; 171526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 172526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen} 173