1 /*
2  * Copyright (C) 2016 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 package com.google.android.exoplayer2.drm;
17 
18 import android.annotation.TargetApi;
19 import android.media.DeniedByServerException;
20 import android.media.MediaCrypto;
21 import android.media.MediaCryptoException;
22 import android.media.MediaDrm;
23 import android.media.NotProvisionedException;
24 import android.media.ResourceBusyException;
25 import android.media.UnsupportedSchemeException;
26 import android.support.annotation.NonNull;
27 import com.google.android.exoplayer2.util.Assertions;
28 import java.util.HashMap;
29 import java.util.Map;
30 import java.util.UUID;
31 
32 /**
33  * An {@link ExoMediaDrm} implementation that wraps the framework {@link MediaDrm}.
34  */
35 @TargetApi(18)
36 public final class FrameworkMediaDrm implements ExoMediaDrm<FrameworkMediaCrypto> {
37 
38   private final MediaDrm mediaDrm;
39 
40   /**
41    * Creates an instance for the specified scheme UUID.
42    *
43    * @param uuid The scheme uuid.
44    * @return The created instance.
45    * @throws UnsupportedDrmException If the DRM scheme is unsupported or cannot be instantiated.
46    */
newInstance(UUID uuid)47   public static FrameworkMediaDrm newInstance(UUID uuid) throws UnsupportedDrmException {
48     try {
49       return new FrameworkMediaDrm(uuid);
50     } catch (UnsupportedSchemeException e) {
51       throw new UnsupportedDrmException(UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME, e);
52     } catch (Exception e) {
53       throw new UnsupportedDrmException(UnsupportedDrmException.REASON_INSTANTIATION_ERROR, e);
54     }
55   }
56 
FrameworkMediaDrm(UUID uuid)57   private FrameworkMediaDrm(UUID uuid) throws UnsupportedSchemeException {
58     this.mediaDrm = new MediaDrm(Assertions.checkNotNull(uuid));
59   }
60 
61   @Override
setOnEventListener( final ExoMediaDrm.OnEventListener<? super FrameworkMediaCrypto> listener)62   public void setOnEventListener(
63       final ExoMediaDrm.OnEventListener<? super FrameworkMediaCrypto> listener) {
64     mediaDrm.setOnEventListener(listener == null ? null : new MediaDrm.OnEventListener() {
65       @Override
66       public void onEvent(@NonNull MediaDrm md, byte[] sessionId, int event, int extra,
67           byte[] data) {
68         listener.onEvent(FrameworkMediaDrm.this, sessionId, event, extra, data);
69       }
70     });
71   }
72 
73   @Override
openSession()74   public byte[] openSession() throws NotProvisionedException, ResourceBusyException {
75     return mediaDrm.openSession();
76   }
77 
78   @Override
closeSession(byte[] sessionId)79   public void closeSession(byte[] sessionId) {
80     mediaDrm.closeSession(sessionId);
81   }
82 
83   @Override
getKeyRequest(byte[] scope, byte[] init, String mimeType, int keyType, HashMap<String, String> optionalParameters)84   public KeyRequest getKeyRequest(byte[] scope, byte[] init, String mimeType, int keyType,
85       HashMap<String, String> optionalParameters) throws NotProvisionedException {
86     final MediaDrm.KeyRequest request = mediaDrm.getKeyRequest(scope, init, mimeType, keyType,
87         optionalParameters);
88     return new KeyRequest() {
89       @Override
90       public byte[] getData() {
91         return request.getData();
92       }
93 
94       @Override
95       public String getDefaultUrl() {
96         return request.getDefaultUrl();
97       }
98     };
99   }
100 
101   @Override
102   public byte[] provideKeyResponse(byte[] scope, byte[] response)
103       throws NotProvisionedException, DeniedByServerException {
104     return mediaDrm.provideKeyResponse(scope, response);
105   }
106 
107   @Override
108   public ProvisionRequest getProvisionRequest() {
109     final MediaDrm.ProvisionRequest provisionRequest = mediaDrm.getProvisionRequest();
110     return new ProvisionRequest() {
111       @Override
112       public byte[] getData() {
113         return provisionRequest.getData();
114       }
115 
116       @Override
117       public String getDefaultUrl() {
118         return provisionRequest.getDefaultUrl();
119       }
120     };
121   }
122 
123   @Override
124   public void provideProvisionResponse(byte[] response) throws DeniedByServerException {
125     mediaDrm.provideProvisionResponse(response);
126   }
127 
128   @Override
129   public Map<String, String> queryKeyStatus(byte[] sessionId) {
130     return mediaDrm.queryKeyStatus(sessionId);
131   }
132 
133   @Override
134   public void release() {
135     mediaDrm.release();
136   }
137 
138   @Override
139   public void restoreKeys(byte[] sessionId, byte[] keySetId) {
140     mediaDrm.restoreKeys(sessionId, keySetId);
141   }
142 
143   @Override
144   public String getPropertyString(String propertyName) {
145     return mediaDrm.getPropertyString(propertyName);
146   }
147 
148   @Override
149   public byte[] getPropertyByteArray(String propertyName) {
150     return mediaDrm.getPropertyByteArray(propertyName);
151   }
152 
153   @Override
154   public void setPropertyString(String propertyName, String value) {
155     mediaDrm.setPropertyString(propertyName, value);
156   }
157 
158   @Override
159   public void setPropertyByteArray(String propertyName, byte[] value) {
160     mediaDrm.setPropertyByteArray(propertyName, value);
161   }
162 
163   @Override
164   public FrameworkMediaCrypto createMediaCrypto(UUID uuid, byte[] initData)
165       throws MediaCryptoException {
166     return new FrameworkMediaCrypto(new MediaCrypto(uuid, initData));
167   }
168 
169 }
170