blob: 66a60cf90f119a2c8673864ff138bbc460aec719 [file] [log] [blame]
aimitakeshid074e302010-07-29 10:12:27 +09001/*
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
17package android.drm;
18
19import java.io.BufferedInputStream;
isaid21d71a42017-06-02 20:07:01 -040020import java.io.Closeable;
aimitakeshid074e302010-07-29 10:12:27 +090021import java.io.File;
22import java.io.FileInputStream;
aimitakeshid074e302010-07-29 10:12:27 +090023import java.io.FileOutputStream;
24import java.io.IOException;
25import java.io.InputStream;
26import java.io.OutputStream;
27import java.util.HashMap;
28import java.util.Iterator;
29
30/**
Bill Gruber0e092f82011-03-17 16:04:18 -070031 * 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.
Robert Shihea42f762020-01-21 14:00:04 -080036 * @deprecated Please use {@link android.media.MediaDrm}
aimitakeshid074e302010-07-29 10:12:27 +090037 */
Robert Shihea42f762020-01-21 14:00:04 -080038@Deprecated
aimitakeshid074e302010-07-29 10:12:27 +090039public class DrmUtils {
40 /* Should be used when we need to read from local file */
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 */
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 {
James Dongf7a68fc2012-02-27 22:43:30 -080060 quietlyDispose(bufferedStream);
61 quietlyDispose(inputStream);
aimitakeshid074e302010-07-29 10:12:27 +090062 }
63 return data;
64 }
65
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 {
James Dongf7a68fc2012-02-27 22:43:30 -080075 quietlyDispose(outputStream);
aimitakeshid074e302010-07-29 10:12:27 +090076 }
77 }
78 }
79
80 /* package */ static void removeFile(String path) throws IOException {
81 File file = new File(path);
82 file.delete();
83 }
84
isaid21d71a42017-06-02 20:07:01 -040085 private static void quietlyDispose(Closeable closable) {
aimitakeshid074e302010-07-29 10:12:27 +090086 try {
isaid21d71a42017-06-02 20:07:01 -040087 if (null != closable) {
88 closable.close();
aimitakeshid074e302010-07-29 10:12:27 +090089 }
90 } catch (IOException e) {
91 // no need to care, at least as of now
92 }
93 }
94
aimitakeshid074e302010-07-29 10:12:27 +090095 /**
Bill Gruber0e092f82011-03-17 16:04:18 -070096 * Gets an instance of {@link DrmUtils.ExtendedMetadataParser}, which can be used to parse
97 * extended metadata embedded in DRM constraint information.
aimitakeshid074e302010-07-29 10:12:27 +090098 *
Bill Gruber0e092f82011-03-17 16:04:18 -070099 * @param extendedMetadata Object in which key-value pairs of extended metadata are embedded.
aimitakeshid074e302010-07-29 10:12:27 +0900100 *
101 */
102 public static ExtendedMetadataParser getExtendedMetadataParser(byte[] extendedMetadata) {
103 return new ExtendedMetadataParser(extendedMetadata);
104 }
105
106 /**
Bill Gruber0e092f82011-03-17 16:04:18 -0700107 * Utility that parses extended metadata embedded in DRM constraint information.
108 *<p>
109 * Usage example:
110 *<p>
aimitakeshid074e302010-07-29 10:12:27 +0900111 * byte[] extendedMetadata<br>
112 * &nbsp;&nbsp;&nbsp;&nbsp; =
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 * &nbsp;&nbsp;&nbsp;&nbsp;String extendedMetadataKey = keyIterator.next();<br>
118 * &nbsp;&nbsp;&nbsp;&nbsp;String extendedMetadataValue =
119 * parser.get(extendedMetadataKey);<br>
120 * }
121 */
122 public static class ExtendedMetadataParser {
123 HashMap<String, String> mMap = new HashMap<String, String>();
124
125 private int readByte(byte[] constraintData, int arrayIndex) {
126 //Convert byte[] into int.
127 return (int)constraintData[arrayIndex];
128 }
129
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 */
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);
Takeshi Aimic7b3ccc2010-10-08 23:05:49 +0900162 if (strValue.equals(" ")) {
163 strValue = "";
164 }
aimitakeshid074e302010-07-29 10:12:27 +0900165 index += valueLength;
166 mMap.put(strKey, strValue);
167 }
168 }
169
James Dongf7a68fc2012-02-27 22:43:30 -0800170 /**
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 */
aimitakeshid074e302010-07-29 10:12:27 +0900176 public Iterator<String> iterator() {
177 return mMap.values().iterator();
178 }
179
James Dongf7a68fc2012-02-27 22:43:30 -0800180 /**
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 */
aimitakeshid074e302010-07-29 10:12:27 +0900186 public Iterator<String> keyIterator() {
187 return mMap.keySet().iterator();
188 }
189
James Dongf7a68fc2012-02-27 22:43:30 -0800190 /**
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 */
aimitakeshid074e302010-07-29 10:12:27 +0900198 public String get(String key) {
199 return mMap.get(key);
200 }
201 }
202}
203