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.Config; 28 import android.util.Log; 29 30 import java.io.ByteArrayInputStream; 31 import java.io.ByteArrayOutputStream; 32 import java.io.IOException; 33 import java.io.InputStream; 34 35 /** 36 * The Drm Wrapper. 37 */ 38 public class DrmWrapper { 39 /** 40 * The DRM right object. 41 */ 42 private DrmRights mRight; 43 44 /** 45 * The DrmRawContent. 46 */ 47 private final DrmRawContent mDrmObject; 48 49 private final Uri mDataUri; 50 private final byte[] mData; 51 /** 52 * The decrypted data. 53 */ 54 private byte[] mDecryptedData; 55 56 /** 57 * The log tag. 58 */ 59 private static final String LOG_TAG = "DrmWrapper"; 60 private static final boolean DEBUG = false; 61 private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV; 62 63 /** 64 * Constructor. 65 * @param uri 66 */ DrmWrapper(String drmContentType, Uri uri, byte[] drmData)67 public DrmWrapper(String drmContentType, Uri uri, byte[] drmData) 68 throws DrmException, IOException { 69 if ((drmContentType == null) || (drmData == null)) { 70 throw new IllegalArgumentException( 71 "Content-Type or data may not be null."); 72 } 73 74 mDataUri = uri; 75 mData = drmData; 76 77 ByteArrayInputStream drmDataStream = new ByteArrayInputStream(drmData); 78 mDrmObject = new DrmRawContent(drmDataStream, drmDataStream.available(), 79 drmContentType); 80 // Install rights if necessary. 81 if (!isRightsInstalled()) { 82 if (LOCAL_LOGV) { 83 Log.v(LOG_TAG, "DRM rights not installed yet."); 84 } 85 installRights(drmData); 86 } 87 } 88 89 /** 90 * Get permission type for the decrypted content-type. 91 * 92 * @return the permission 93 */ getPermission()94 private int getPermission() { 95 String contentType = mDrmObject.getContentType(); 96 97 if (ContentType.isAudioType(contentType) || 98 ContentType.isVideoType(contentType)) { 99 return DrmRights.DRM_PERMISSION_PLAY; 100 } 101 return DrmRights.DRM_PERMISSION_DISPLAY; 102 } 103 104 /** 105 * Get decrypted data. 106 * 107 * @return the decrypted content if decryption was successful. 108 * @throws IOException 109 */ getDecryptedData()110 public byte[] getDecryptedData() throws IOException { 111 if ((mDecryptedData == null) && (mRight != null)) { 112 // Decrypt it. 113 InputStream decryptedDataStream = mDrmObject.getContentInputStream(mRight); 114 try { 115 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 116 byte[] buffer = new byte[256]; 117 int len; 118 while ((len = decryptedDataStream.read(buffer)) > 0) { 119 baos.write(buffer, 0, len); 120 } 121 mDecryptedData = baos.toByteArray(); 122 } finally { 123 try { 124 decryptedDataStream.close(); 125 } catch (IOException e) { 126 Log.e(LOG_TAG, e.getMessage(), e); 127 } 128 } 129 } 130 131 if (mDecryptedData != null) { 132 byte[] decryptedData = new byte[mDecryptedData.length]; 133 System.arraycopy(mDecryptedData, 0, decryptedData, 0, mDecryptedData.length); 134 return decryptedData; 135 } 136 return null; 137 } 138 139 /** 140 * Consume the rights. 141 * 142 * @return true if consume success 143 * false if consume failure 144 */ consumeRights()145 public boolean consumeRights() { 146 if (mRight == null) { 147 return false; 148 } 149 150 return mRight.consumeRights(getPermission()); 151 } 152 153 /** 154 * Install Right. 155 * 156 * @param rightData right's data 157 * @throws IOException 158 * @throws DrmException 159 */ installRights(byte[] rightData)160 public void installRights(byte[] rightData) throws DrmException, IOException { 161 if (rightData == null) { 162 throw new DrmException("Right data may not be null."); 163 } 164 165 if (LOCAL_LOGV) { 166 Log.v(LOG_TAG, "Installing DRM rights."); 167 } 168 169 ByteArrayInputStream rightDataStream = new ByteArrayInputStream(rightData); 170 mRight = DrmRightsManager.getInstance().installRights( 171 rightDataStream, rightData.length, 172 DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING); 173 } 174 175 /** 176 * Check whether the DRM object's right is existed. If not, we should 177 * download it. 178 * 179 * @return true if it is existed 180 * false if not 181 */ isRightsInstalled()182 public boolean isRightsInstalled() { 183 if (mRight != null) { 184 return true; 185 } 186 187 mRight = DrmRightsManager.getInstance().queryRights(mDrmObject); 188 return mRight != null ? true : false; 189 } 190 191 /** 192 * Check whether this DRM object can be forwarded. 193 * 194 * @return true if this object can be forwarded 195 * false if not 196 */ isAllowedToForward()197 public boolean isAllowedToForward() { 198 if (DrmRawContent.DRM_SEPARATE_DELIVERY != mDrmObject.getRawType()) { 199 return false; 200 } 201 return true; 202 } 203 204 /** 205 * Get URL of right. 206 * 207 * @return the right's URL 208 */ getRightsAddress()209 public String getRightsAddress() { 210 if (mDrmObject == null) { 211 return null; 212 } 213 return mDrmObject.getRightsAddress(); 214 } 215 216 /** 217 * Get the decrypted object's content-type. 218 * 219 * @return the content-type 220 */ getContentType()221 public String getContentType() { 222 return mDrmObject.getContentType(); 223 } 224 getOriginalUri()225 public Uri getOriginalUri() { 226 return mDataUri; 227 } 228 getOriginalData()229 public byte[] getOriginalData() { 230 return mData; 231 } 232 } 233