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.google.android.mms.util; 18 19 import android.compat.annotation.UnsupportedAppUsage; 20 import android.content.Context; 21 import android.drm.DrmConvertedStatus; 22 import android.drm.DrmManagerClient; 23 import android.util.Log; 24 25 import java.io.FileNotFoundException; 26 import java.io.IOException; 27 import java.io.RandomAccessFile; 28 29 30 public class DrmConvertSession { 31 private DrmManagerClient mDrmClient; 32 private int mConvertSessionId; 33 private static final String TAG = "DrmConvertSession"; 34 35 // These values are copied from Downloads.Impl.* for backward compatibility since 36 // {@link #close()} that uses it is marked @UnsupportedAppUsage. 37 public static final int STATUS_SUCCESS = 200; 38 public static final int STATUS_NOT_ACCEPTABLE = 406; 39 public static final int STATUS_UNKNOWN_ERROR = 491; 40 public static final int STATUS_FILE_ERROR = 492; 41 DrmConvertSession(DrmManagerClient drmClient, int convertSessionId)42 private DrmConvertSession(DrmManagerClient drmClient, int convertSessionId) { 43 mDrmClient = drmClient; 44 mConvertSessionId = convertSessionId; 45 } 46 47 /** 48 * Start of converting a file. 49 * 50 * @param context The context of the application running the convert session. 51 * @param mimeType Mimetype of content that shall be converted. 52 * @return A convert session or null in case an error occurs. 53 */ 54 @UnsupportedAppUsage open(Context context, String mimeType)55 public static DrmConvertSession open(Context context, String mimeType) { 56 DrmManagerClient drmClient = null; 57 int convertSessionId = -1; 58 if (context != null && mimeType != null && !mimeType.equals("")) { 59 try { 60 drmClient = new DrmManagerClient(context); 61 try { 62 convertSessionId = drmClient.openConvertSession(mimeType); 63 } catch (IllegalArgumentException e) { 64 Log.w(TAG, "Conversion of Mimetype: " + mimeType 65 + " is not supported.", e); 66 } catch (IllegalStateException e) { 67 Log.w(TAG, "Could not access Open DrmFramework.", e); 68 } 69 } catch (IllegalArgumentException e) { 70 Log.w(TAG, 71 "DrmManagerClient instance could not be created, context is Illegal."); 72 } catch (IllegalStateException e) { 73 Log.w(TAG, "DrmManagerClient didn't initialize properly."); 74 } 75 } 76 77 if (drmClient == null || convertSessionId < 0) { 78 return null; 79 } else { 80 return new DrmConvertSession(drmClient, convertSessionId); 81 } 82 } 83 /** 84 * Convert a buffer of data to protected format. 85 * 86 * @param buffer Buffer filled with data to convert. 87 * @param size The number of bytes that shall be converted. 88 * @return A Buffer filled with converted data, if execution is ok, in all 89 * other case null. 90 */ 91 @UnsupportedAppUsage convert(byte[] inBuffer, int size)92 public byte [] convert(byte[] inBuffer, int size) { 93 byte[] result = null; 94 if (inBuffer != null) { 95 DrmConvertedStatus convertedStatus = null; 96 try { 97 if (size != inBuffer.length) { 98 byte[] buf = new byte[size]; 99 System.arraycopy(inBuffer, 0, buf, 0, size); 100 convertedStatus = mDrmClient.convertData(mConvertSessionId, buf); 101 } else { 102 convertedStatus = mDrmClient.convertData(mConvertSessionId, inBuffer); 103 } 104 105 if (convertedStatus != null && 106 convertedStatus.statusCode == DrmConvertedStatus.STATUS_OK && 107 convertedStatus.convertedData != null) { 108 result = convertedStatus.convertedData; 109 } 110 } catch (IllegalArgumentException e) { 111 Log.w(TAG, "Buffer with data to convert is illegal. Convertsession: " 112 + mConvertSessionId, e); 113 } catch (IllegalStateException e) { 114 Log.w(TAG, "Could not convert data. Convertsession: " + 115 mConvertSessionId, e); 116 } 117 } else { 118 throw new IllegalArgumentException("Parameter inBuffer is null"); 119 } 120 return result; 121 } 122 123 /** 124 * Ends a conversion session of a file. 125 * 126 * @param fileName The filename of the converted file. 127 * @return STATUS_SUCCESS if execution is ok. 128 * STATUS_FILE_ERROR in case converted file can not 129 * be accessed. STATUS_NOT_ACCEPTABLE if a problem 130 * occurs when accessing drm framework. 131 * STATUS_UNKNOWN_ERROR if a general error occurred. 132 */ 133 @UnsupportedAppUsage close(String filename)134 public int close(String filename) { 135 DrmConvertedStatus convertedStatus = null; 136 int result = STATUS_UNKNOWN_ERROR; 137 if (mDrmClient != null && mConvertSessionId >= 0) { 138 try { 139 convertedStatus = mDrmClient.closeConvertSession(mConvertSessionId); 140 if (convertedStatus == null || 141 convertedStatus.statusCode != DrmConvertedStatus.STATUS_OK || 142 convertedStatus.convertedData == null) { 143 result = STATUS_NOT_ACCEPTABLE; 144 } else { 145 RandomAccessFile rndAccessFile = null; 146 try { 147 rndAccessFile = new RandomAccessFile(filename, "rw"); 148 rndAccessFile.seek(convertedStatus.offset); 149 rndAccessFile.write(convertedStatus.convertedData); 150 result = STATUS_SUCCESS; 151 } catch (FileNotFoundException e) { 152 result = STATUS_FILE_ERROR; 153 Log.w(TAG, "File: " + filename + " could not be found.", e); 154 } catch (IOException e) { 155 result = STATUS_FILE_ERROR; 156 Log.w(TAG, "Could not access File: " + filename + " .", e); 157 } catch (IllegalArgumentException e) { 158 result = STATUS_FILE_ERROR; 159 Log.w(TAG, "Could not open file in mode: rw", e); 160 } catch (SecurityException e) { 161 Log.w(TAG, "Access to File: " + filename + 162 " was denied denied by SecurityManager.", e); 163 } finally { 164 if (rndAccessFile != null) { 165 try { 166 rndAccessFile.close(); 167 } catch (IOException e) { 168 result = STATUS_FILE_ERROR; 169 Log.w(TAG, "Failed to close File:" + filename 170 + ".", e); 171 } 172 } 173 } 174 } 175 } catch (IllegalStateException e) { 176 Log.w(TAG, "Could not close convertsession. Convertsession: " + 177 mConvertSessionId, e); 178 } 179 } 180 return result; 181 } 182 } 183