• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 Esmertec AG.
3  * Copyright (C) 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.model;
19 
20 import com.android.mms.UnsupportContentTypeException;
21 import com.android.mms.LogTag;
22 import com.android.mms.MmsConfig;
23 import com.android.mms.drm.DrmWrapper;
24 import com.google.android.mms.ContentType;
25 import com.google.android.mms.MmsException;
26 import com.google.android.mms.pdu.PduBody;
27 import com.google.android.mms.pdu.PduPart;
28 
29 import org.w3c.dom.smil.SMILMediaElement;
30 import org.w3c.dom.smil.SMILRegionElement;
31 import org.w3c.dom.smil.SMILRegionMediaElement;
32 import org.w3c.dom.smil.Time;
33 import org.w3c.dom.smil.TimeList;
34 
35 import android.content.Context;
36 import android.drm.mobile1.DrmException;
37 import android.util.Log;
38 
39 import java.io.IOException;
40 
41 public class MediaModelFactory {
42     private static final String TAG = "Mms:media";
43 
getMediaModel(Context context, SMILMediaElement sme, LayoutModel layouts, PduBody pb)44     public static MediaModel getMediaModel(Context context,
45             SMILMediaElement sme, LayoutModel layouts, PduBody pb)
46             throws DrmException, IOException, IllegalArgumentException, MmsException {
47         String tag = sme.getTagName();
48         String src = sme.getSrc();
49         PduPart part = findPart(pb, src);
50 
51         if (sme instanceof SMILRegionMediaElement) {
52             return getRegionMediaModel(
53                     context, tag, src, (SMILRegionMediaElement) sme, layouts, part);
54         } else {
55             return getGenericMediaModel(
56                     context, tag, src, sme, part, null);
57         }
58     }
59 
findPart(PduBody pb, String src)60     private static PduPart findPart(PduBody pb, String src) {
61         PduPart part = null;
62 
63         if (src != null) {
64             if (src.startsWith("cid:")) {
65                 part = pb.getPartByContentId("<" + src.substring("cid:".length()) + ">");
66             } else {
67                 part = pb.getPartByName(src);
68                 if (part == null) {
69                     part = pb.getPartByFileName(src);
70                     if (part == null) {
71                         part = pb.getPartByContentLocation(src);
72                     }
73                 }
74             }
75         }
76 
77         if (part != null) {
78             return part;
79         }
80 
81         throw new IllegalArgumentException("No part found for the model.");
82     }
83 
getRegionMediaModel(Context context, String tag, String src, SMILRegionMediaElement srme, LayoutModel layouts, PduPart part)84     private static MediaModel getRegionMediaModel(Context context,
85             String tag, String src, SMILRegionMediaElement srme,
86             LayoutModel layouts, PduPart part) throws DrmException, IOException, MmsException {
87         SMILRegionElement sre = srme.getRegion();
88         if (sre != null) {
89             RegionModel region = layouts.findRegionById(sre.getId());
90             if (region != null) {
91                 return getGenericMediaModel(context, tag, src, srme, part, region);
92             }
93         } else {
94             String rId = null;
95 
96             if (tag.equals(SmilHelper.ELEMENT_TAG_TEXT)) {
97                 rId = LayoutModel.TEXT_REGION_ID;
98             } else {
99                 rId = LayoutModel.IMAGE_REGION_ID;
100             }
101 
102             RegionModel region = layouts.findRegionById(rId);
103             if (region != null) {
104                 return getGenericMediaModel(context, tag, src, srme, part, region);
105             }
106         }
107 
108         throw new IllegalArgumentException("Region not found or bad region ID.");
109     }
110 
getGenericMediaModel(Context context, String tag, String src, SMILMediaElement sme, PduPart part, RegionModel regionModel)111     private static MediaModel getGenericMediaModel(Context context,
112             String tag, String src, SMILMediaElement sme, PduPart part,
113             RegionModel regionModel) throws DrmException, IOException, MmsException {
114         byte[] bytes = part.getContentType();
115         if (bytes == null) {
116             throw new IllegalArgumentException(
117                     "Content-Type of the part may not be null.");
118         }
119 
120         String contentType = new String(bytes);
121         MediaModel media = null;
122         if (ContentType.isDrmType(contentType)) {
123             DrmWrapper wrapper = new DrmWrapper(
124                     contentType, part.getDataUri(), part.getData());
125             if (tag.equals(SmilHelper.ELEMENT_TAG_TEXT)) {
126                 media = new TextModel(context, contentType, src,
127                         part.getCharset(), wrapper, regionModel);
128             } else if (tag.equals(SmilHelper.ELEMENT_TAG_IMAGE)) {
129                 media = new ImageModel(context, contentType, src,
130                         wrapper, regionModel);
131             } else if (tag.equals(SmilHelper.ELEMENT_TAG_VIDEO)) {
132                 media = new VideoModel(context, contentType, src,
133                         wrapper, regionModel);
134             } else if (tag.equals(SmilHelper.ELEMENT_TAG_AUDIO)) {
135                 media = new AudioModel(context, contentType, src,
136                         wrapper);
137             } else if (tag.equals(SmilHelper.ELEMENT_TAG_REF)) {
138                 String drmContentType = wrapper.getContentType();
139                 if (ContentType.isTextType(drmContentType)) {
140                     media = new TextModel(context, contentType, src,
141                             part.getCharset(), wrapper, regionModel);
142                 } else if (ContentType.isImageType(drmContentType)) {
143                     media = new ImageModel(context, contentType, src,
144                             wrapper, regionModel);
145                 } else if (ContentType.isVideoType(drmContentType)) {
146                     media = new VideoModel(context, contentType, src,
147                             wrapper, regionModel);
148                 } else if (ContentType.isAudioType(drmContentType)) {
149                     media = new AudioModel(context, contentType, src,
150                             wrapper);
151                 } else {
152                     throw new UnsupportContentTypeException(
153                         "Unsupported Content-Type: " + drmContentType);
154                 }
155             } else {
156                 throw new IllegalArgumentException("Unsupported TAG: " + tag);
157             }
158         } else {
159             if (tag.equals(SmilHelper.ELEMENT_TAG_TEXT)) {
160                 media = new TextModel(context, contentType, src,
161                         part.getCharset(), part.getData(), regionModel);
162             } else if (tag.equals(SmilHelper.ELEMENT_TAG_IMAGE)) {
163                 media = new ImageModel(context, contentType, src,
164                         part.getDataUri(), regionModel);
165             } else if (tag.equals(SmilHelper.ELEMENT_TAG_VIDEO)) {
166                 media = new VideoModel(context, contentType, src,
167                         part.getDataUri(), regionModel);
168             } else if (tag.equals(SmilHelper.ELEMENT_TAG_AUDIO)) {
169                 media = new AudioModel(context, contentType, src,
170                         part.getDataUri());
171             } else if (tag.equals(SmilHelper.ELEMENT_TAG_REF)) {
172                 if (ContentType.isTextType(contentType)) {
173                     media = new TextModel(context, contentType, src,
174                             part.getCharset(), part.getData(), regionModel);
175                 } else if (ContentType.isImageType(contentType)) {
176                     media = new ImageModel(context, contentType, src,
177                             part.getDataUri(), regionModel);
178                 } else if (ContentType.isVideoType(contentType)) {
179                     media = new VideoModel(context, contentType, src,
180                             part.getDataUri(), regionModel);
181                 } else if (ContentType.isAudioType(contentType)) {
182                     media = new AudioModel(context, contentType, src,
183                             part.getDataUri());
184                 } else {
185                     throw new UnsupportContentTypeException(
186                         "Unsupported Content-Type: " + contentType);
187                 }
188             } else {
189                 throw new IllegalArgumentException("Unsupported TAG: " + tag);
190             }
191         }
192 
193         // Set 'begin' property.
194         int begin = 0;
195         TimeList tl = sme.getBegin();
196         if ((tl != null) && (tl.getLength() > 0)) {
197             // We only support a single begin value.
198             Time t = tl.item(0);
199             begin = (int) (t.getResolvedOffset() * 1000);
200         }
201         media.setBegin(begin);
202 
203         // Set 'duration' property.
204         int duration = (int) (sme.getDur() * 1000);
205         if (duration <= 0) {
206             tl = sme.getEnd();
207             if ((tl != null) && (tl.getLength() > 0)) {
208                 // We only support a single end value.
209                 Time t = tl.item(0);
210                 if (t.getTimeType() != Time.SMIL_TIME_INDEFINITE) {
211                     duration = (int) (t.getResolvedOffset() * 1000) - begin;
212 
213                     if (duration == 0 &&
214                             (media instanceof AudioModel || media instanceof VideoModel)) {
215                         duration = MmsConfig.getMinimumSlideElementDuration();
216                         if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
217                             Log.d(TAG, "[MediaModelFactory] compute new duration for " + tag +
218                                     ", duration=" + duration);
219                         }
220                     }
221                 }
222             }
223         }
224 
225         media.setDuration(duration);
226 
227         // Set 'fill' property.
228         media.setFill(sme.getFill());
229         return media;
230     }
231 }
232