1 /* 2 * Copyright (C) 2007-2008 Esmertec AG. 3 * Copyright (C) 2007-2008 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package com.android.mms.drm; 19 20 import com.google.android.mms.ContentType; 21 22 import android.drm.mobile1.DrmException; 23 import android.drm.mobile1.DrmRawContent; 24 import android.drm.mobile1.DrmRights; 25 import android.drm.mobile1.DrmRightsManager; 26 import android.net.Uri; 27 import android.util.Log; 28 29 import java.io.ByteArrayInputStream; 30 import java.io.ByteArrayOutputStream; 31 import java.io.IOException; 32 import java.io.InputStream; 33 34 /** 35 * The Drm Wrapper. 36 */ 37 public class DrmWrapper { 38 /** 39 * The DRM right object. 40 */ 41 private DrmRights mRight; 42 43 /** 44 * The DrmRawContent. 45 */ 46 private final DrmRawContent mDrmObject; 47 48 private final Uri mDataUri; 49 private final byte[] mData; 50 /** 51 * The decrypted data. 52 */ 53 private byte[] mDecryptedData; 54 55 /** 56 * The log tag. 57 */ 58 private static final String LOG_TAG = "DrmWrapper"; 59 private static final boolean DEBUG = false; 60 private static final boolean LOCAL_LOGV = false; 61 62 /** 63 * Constructor. 64 * @param uri 65 */ 66 public DrmWrapper(String drmContentType, Uri uri, byte[] drmData) 67 throws DrmException, IOException { 68 if ((drmContentType == null) || (drmData == null)) { 69 throw new IllegalArgumentException( 70 "Content-Type or data may not be null."); 71 } 72 73 mDataUri = uri; 74 mData = drmData; 75 76 ByteArrayInputStream drmDataStream = new ByteArrayInputStream(drmData); 77 mDrmObject = new DrmRawContent(drmDataStream, drmDataStream.available(), 78 drmContentType); 79 // Install rights if necessary. 80 if (!isRightsInstalled()) { 81 if (LOCAL_LOGV) { 82 Log.v(LOG_TAG, "DRM rights not installed yet."); 83 } 84 installRights(drmData); 85 } 86 } 87 88 /** 89 * Get permission type for the decrypted content-type. 90 * 91 * @return the permission 92 */ 93 private int getPermission() { 94 String contentType = mDrmObject.getContentType(); 95 96 if (ContentType.isAudioType(contentType) || 97 ContentType.isVideoType(contentType)) { 98 return DrmRights.DRM_PERMISSION_PLAY; 99 } 100 return DrmRights.DRM_PERMISSION_DISPLAY; 101 } 102 103 /** 104 * Get decrypted data. 105 * 106 * @return the decrypted content if decryption was successful. 107 * @throws IOException 108 */ 109 public byte[] getDecryptedData() throws IOException { 110 if ((mDecryptedData == null) && (mRight != null)) { 111 // Decrypt it. 112 InputStream decryptedDataStream = mDrmObject.getContentInputStream(mRight); 113 try { 114 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 115 byte[] buffer = new byte[256]; 116 int len; 117 while ((len = decryptedDataStream.read(buffer)) > 0) { 118 baos.write(buffer, 0, len); 119 } 120 mDecryptedData = baos.toByteArray(); 121 } finally { 122 try { 123 decryptedDataStream.close(); 124 } catch (IOException e) { 125 Log.e(LOG_TAG, e.getMessage(), e); 126 } 127 } 128 } 129 130 if (mDecryptedData != null) { 131 byte[] decryptedData = new byte[mDecryptedData.length]; 132 System.arraycopy(mDecryptedData, 0, decryptedData, 0, mDecryptedData.length); 133 return decryptedData; 134 } 135 return null; 136 } 137 138 /** 139 * Consume the rights. 140 * 141 * @return true if consume success 142 * false if consume failure 143 */ 144 public boolean consumeRights() { 145 if (mRight == null) { 146 return false; 147 } 148 149 return mRight.consumeRights(getPermission()); 150 } 151 152 /** 153 * Install Right. 154 * 155 * @param rightData right's data 156 * @throws IOException 157 * @throws DrmException 158 */ 159 public void installRights(byte[] rightData) throws DrmException, IOException { 160 if (rightData == null) { 161 throw new DrmException("Right data may not be null."); 162 } 163 164 if (LOCAL_LOGV) { 165 Log.v(LOG_TAG, "Installing DRM rights."); 166 } 167 168 ByteArrayInputStream rightDataStream = new ByteArrayInputStream(rightData); 169 mRight = DrmRightsManager.getInstance().installRights( 170 rightDataStream, rightData.length, 171 DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING); 172 } 173 174 /** 175 * Check whether the DRM object's right is existed. If not, we should 176 * download it. 177 * 178 * @return true if it is existed 179 * false if not 180 */ 181 public boolean isRightsInstalled() { 182 if (mRight != null) { 183 return true; 184 } 185 186 mRight = DrmRightsManager.getInstance().queryRights(mDrmObject); 187 return mRight != null ? true : false; 188 } 189 190 /** 191 * Check whether this DRM object can be forwarded. 192 * 193 * @return true if this object can be forwarded 194 * false if not 195 */ 196 public boolean isAllowedToForward() { 197 if (DrmRawContent.DRM_SEPARATE_DELIVERY != mDrmObject.getRawType()) { 198 return false; 199 } 200 return true; 201 } 202 203 /** 204 * Get URL of right. 205 * 206 * @return the right's URL 207 */ 208 public String getRightsAddress() { 209 if (mDrmObject == null) { 210 return null; 211 } 212 return mDrmObject.getRightsAddress(); 213 } 214 215 /** 216 * Get the decrypted object's content-type. 217 * 218 * @return the content-type 219 */ 220 public String getContentType() { 221 return mDrmObject.getContentType(); 222 } 223 224 public Uri getOriginalUri() { 225 return mDataUri; 226 } 227 228 public byte[] getOriginalData() { 229 return mData; 230 } 231 } 232