1 /* 2 * Copyright (C) 2010 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 android.drm; 18 19 import java.io.BufferedInputStream; 20 import java.io.Closeable; 21 import java.io.File; 22 import java.io.FileInputStream; 23 import java.io.FileOutputStream; 24 import java.io.IOException; 25 import java.io.InputStream; 26 import java.io.OutputStream; 27 import java.util.HashMap; 28 import java.util.Iterator; 29 30 /** 31 * A utility class that provides operations for parsing extended metadata embedded in 32 * DRM constraint information. If a DRM scheme has specific constraints beyond the standard 33 * constraints, the constraints will show up in the 34 * {@link DrmStore.ConstraintsColumns#EXTENDED_METADATA} key. You can use 35 * {@link DrmUtils.ExtendedMetadataParser} to iterate over those values. 36 * @deprecated Please use {@link android.media.MediaDrm} 37 */ 38 @Deprecated 39 public class DrmUtils { 40 /* Should be used when we need to read from local file */ readBytes(String path)41 /* package */ static byte[] readBytes(String path) throws IOException { 42 File file = new File(path); 43 return readBytes(file); 44 } 45 46 /* Should be used when we need to read from local file */ readBytes(File file)47 /* package */ static byte[] readBytes(File file) throws IOException { 48 FileInputStream inputStream = new FileInputStream(file); 49 BufferedInputStream bufferedStream = new BufferedInputStream(inputStream); 50 byte[] data = null; 51 52 try { 53 int length = bufferedStream.available(); 54 if (length > 0) { 55 data = new byte[length]; 56 // read the entire data 57 bufferedStream.read(data); 58 } 59 } finally { 60 quietlyDispose(bufferedStream); 61 quietlyDispose(inputStream); 62 } 63 return data; 64 } 65 writeToFile(final String path, byte[] data)66 /* package */ static void writeToFile(final String path, byte[] data) throws IOException { 67 /* check for invalid inputs */ 68 FileOutputStream outputStream = null; 69 70 if (null != path && null != data) { 71 try { 72 outputStream = new FileOutputStream(path); 73 outputStream.write(data); 74 } finally { 75 quietlyDispose(outputStream); 76 } 77 } 78 } 79 removeFile(String path)80 /* package */ static void removeFile(String path) throws IOException { 81 File file = new File(path); 82 file.delete(); 83 } 84 quietlyDispose(Closeable closable)85 private static void quietlyDispose(Closeable closable) { 86 try { 87 if (null != closable) { 88 closable.close(); 89 } 90 } catch (IOException e) { 91 // no need to care, at least as of now 92 } 93 } 94 95 /** 96 * Gets an instance of {@link DrmUtils.ExtendedMetadataParser}, which can be used to parse 97 * extended metadata embedded in DRM constraint information. 98 * 99 * @param extendedMetadata Object in which key-value pairs of extended metadata are embedded. 100 * 101 */ getExtendedMetadataParser(byte[] extendedMetadata)102 public static ExtendedMetadataParser getExtendedMetadataParser(byte[] extendedMetadata) { 103 return new ExtendedMetadataParser(extendedMetadata); 104 } 105 106 /** 107 * Utility that parses extended metadata embedded in DRM constraint information. 108 *<p> 109 * Usage example: 110 *<p> 111 * byte[] extendedMetadata<br> 112 * = 113 * constraints.getAsByteArray(DrmStore.ConstraintsColumns.EXTENDED_METADATA);<br> 114 * ExtendedMetadataParser parser = getExtendedMetadataParser(extendedMetadata);<br> 115 * Iterator keyIterator = parser.keyIterator();<br> 116 * while (keyIterator.hasNext()) {<br> 117 * String extendedMetadataKey = keyIterator.next();<br> 118 * String extendedMetadataValue = 119 * parser.get(extendedMetadataKey);<br> 120 * } 121 */ 122 public static class ExtendedMetadataParser { 123 HashMap<String, String> mMap = new HashMap<String, String>(); 124 readByte(byte[] constraintData, int arrayIndex)125 private int readByte(byte[] constraintData, int arrayIndex) { 126 //Convert byte[] into int. 127 return (int)constraintData[arrayIndex]; 128 } 129 readMultipleBytes( byte[] constraintData, int numberOfBytes, int arrayIndex)130 private String readMultipleBytes( 131 byte[] constraintData, int numberOfBytes, int arrayIndex) { 132 byte[] returnBytes = new byte[numberOfBytes]; 133 for (int j = arrayIndex, i = 0; j < arrayIndex + numberOfBytes; j++,i++) { 134 returnBytes[i] = constraintData[j]; 135 } 136 return new String(returnBytes); 137 } 138 139 /* 140 * This will parse the following format 141 * KeyLengthValueLengthKeyValueKeyLength1ValueLength1Key1Value1..\0 142 */ ExtendedMetadataParser(byte[] constraintData)143 private ExtendedMetadataParser(byte[] constraintData) { 144 //Extract KeyValue Pair Info, till terminator occurs. 145 int index = 0; 146 147 while (index < constraintData.length) { 148 //Parse Key Length 149 int keyLength = readByte(constraintData, index); 150 index++; 151 152 //Parse Value Length 153 int valueLength = readByte(constraintData, index); 154 index++; 155 156 //Fetch key 157 String strKey = readMultipleBytes(constraintData, keyLength, index); 158 index += keyLength; 159 160 //Fetch Value 161 String strValue = readMultipleBytes(constraintData, valueLength, index); 162 if (strValue.equals(" ")) { 163 strValue = ""; 164 } 165 index += valueLength; 166 mMap.put(strKey, strValue); 167 } 168 } 169 170 /** 171 * This method returns an iterator object that can be used to iterate over 172 * all values of the metadata. 173 * 174 * @return The iterator object. 175 */ iterator()176 public Iterator<String> iterator() { 177 return mMap.values().iterator(); 178 } 179 180 /** 181 * This method returns an iterator object that can be used to iterate over 182 * all keys of the metadata. 183 * 184 * @return The iterator object. 185 */ keyIterator()186 public Iterator<String> keyIterator() { 187 return mMap.keySet().iterator(); 188 } 189 190 /** 191 * This method retrieves the metadata value associated with a given key. 192 * 193 * @param key The key whose value is being retrieved. 194 * 195 * @return The metadata value associated with the given key. Returns null 196 * if the key is not found. 197 */ get(String key)198 public String get(String key) { 199 return mMap.get(key); 200 } 201 } 202 } 203 204