/*
* Copyright (C) 2008 Esmertec AG.
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.mms.model;
import com.android.mms.ContentRestrictionException;
import com.android.mms.ExceedMessageSizeException;
import com.android.mms.MmsConfig;
import com.android.mms.R;
import com.android.mms.dom.smil.parser.SmilXmlSerializer;
import android.drm.mobile1.DrmException;
import com.android.mms.drm.DrmWrapper;
import com.android.mms.layout.LayoutManager;
import com.google.android.mms.ContentType;
import com.google.android.mms.MmsException;
import com.google.android.mms.pdu.GenericPdu;
import com.google.android.mms.pdu.MultimediaMessagePdu;
import com.google.android.mms.pdu.PduBody;
import com.google.android.mms.pdu.PduHeaders;
import com.google.android.mms.pdu.PduPart;
import com.google.android.mms.pdu.PduPersister;
import com.google.android.mms.pdu.CharacterSets;
import org.w3c.dom.NodeList;
import org.w3c.dom.events.EventTarget;
import org.w3c.dom.smil.SMILDocument;
import org.w3c.dom.smil.SMILElement;
import org.w3c.dom.smil.SMILLayoutElement;
import org.w3c.dom.smil.SMILMediaElement;
import org.w3c.dom.smil.SMILParElement;
import org.w3c.dom.smil.SMILRegionElement;
import org.w3c.dom.smil.SMILRootLayoutElement;
import android.content.ContentUris;
import android.content.Context;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class SlideshowModel extends Model
implements List<SlideModel>, IModelChangedObserver {
private static final String TAG = "Mms/slideshow";
private final LayoutModel mLayout;
private final List<SlideModel> mSlides;
//===== fixed CR<NEWMS00133151> by luning at 11-10-26 begin =====
public ArrayList<VcardModel> mVcards;
//===== fixed CR<NEWMS00133151> by luning at 11-10-26 end =====
public ArrayList<FileModel> mFiles; /* fixed CR<NEWMS00144166> by luning at 2011.11.28 */
private SMILDocument mDocumentCache;
private PduBody mPduBodyCache;
private int mCurrentMessageSize;
private Context mContext;
private int mSubjectSize;
// amount of space to leave in a slideshow for text and overhead.
public static final int SLIDESHOW_SLOP = MmsConfig.getMaxSingleSlideSize();
private SlideshowModel(Context context) {
mLayout = new LayoutModel();
mSlides = Collections.synchronizedList(new ArrayList<SlideModel>());
mContext = context;
mSubjectSize = 0;
}
private SlideshowModel(LayoutModel layouts, List<SlideModel> slides,
SMILDocument documentCache, PduBody pbCache, Context context) {
mContext = context;
mDocumentCache = documentCache;
mPduBodyCache = pbCache;
/* fixed CR<NEWMS00137442> by luning at 11-11-07 begin */
if (null == slides) {
mSlides = Collections.synchronizedList(new ArrayList<SlideModel>());
} else {
mSlides = slides;
}
if (null == layouts) {
mLayout = new LayoutModel();
} else {
mLayout = layouts;
}
/* fixed CR<NEWMS00137442> by luning at 11-11-07 end */
for (SlideModel slide : mSlides) {
increaseMessageSize(slide.getSlideSize());
slide.setParent(this);
}
mSubjectSize = 0;
}
public static SlideshowModel createNew(Context context) {
return new SlideshowModel(context);
}
public static SlideshowModel createFromMessageUri(
Context context, Uri uri, boolean slideFomatError) throws MmsException {
return createFromPduBody(context, getPduBody(context, uri), slideFomatError);
}
//===== fixed CR<NEWMS00133151> by luning at 11-10-26 begin =====
public boolean hasVcard(){
if(null == mVcards || mVcards.size() == 0){
return false;
}
return true;
}
public boolean hasVcards(){
if(null == mVcards || mVcards.size() > 1){
return false;
}
return true;
}
public void setVcards(ArrayList<VcardModel> vCards){
if(null != vCards){
mVcards = vCards;
}else{
mVcards = new ArrayList<VcardModel>();
}
}
public void addVcard(VcardModel vcard){
if(null == mVcards){
mVcards = new ArrayList<VcardModel>();
}
mVcards.add(vcard);
}
//===== fixed CR<NEWMS00133151> by luning at 11-10-26 end =====
/* fixed CR<NEWMS00144166> by luning at 2011.11.28 begin*/
public boolean hasOtherFile(){
if(null == mFiles || mFiles.size() == 0){
return false;
}
return true;
}
public void setOtherFiles(ArrayList<FileModel> files){
if(null != files){
mFiles = files;
}else{
mFiles = new ArrayList<FileModel>();
}
}
/* fixed CR<NEWMS00144166> by luning at 2011.11.28 end*/
public static SlideshowModel createFromPduBody(Context context, PduBody pb, boolean slideFomatError) throws MmsException {
SMILDocument document = SmilHelper.getDocument(pb);
// Create root-layout model.
SMILLayoutElement sle = document.getLayout();
SMILRootLayoutElement srle = sle.getRootLayout();
int w = srle.getWidth();
int h = srle.getHeight();
if ((w == 0) || (h == 0)) {
w = LayoutManager.getInstance().getLayoutParameters().getWidth();
h = LayoutManager.getInstance().getLayoutParameters().getHeight();
srle.setWidth(w);
srle.setHeight(h);
}
RegionModel rootLayout = new RegionModel(
null, 0, 0, w, h);
// Create region models.
ArrayList<RegionModel> regions = new ArrayList<RegionModel>();
NodeList nlRegions = sle.getRegions();
int regionsNum = nlRegions.getLength();
for (int i = 0; i < regionsNum; i++) {
SMILRegionElement sre = (SMILRegionElement) nlRegions.item(i);
RegionModel r = new RegionModel(sre.getId(), sre.getFit(),
sre.getLeft(), sre.getTop(), sre.getWidth(), sre.getHeight(),
sre.getBackgroundColor());
regions.add(r);
}
LayoutModel layouts = new LayoutModel(rootLayout, regions);
/* fixed CR<NEWMS00133151,NEWMS00144166> by luning at 2011.12.06 end */
ArrayList<VcardModel> vCardsModels = new ArrayList<VcardModel>();
ArrayList<FileModel> fileModels = new ArrayList<FileModel>();
// Create slide models.
SMILElement docBody = document.getBody();
NodeList slideNodes = docBody.getChildNodes();
int slidesNum = slideNodes.getLength();
List<SlideModel> slides = Collections.synchronizedList(new ArrayList<SlideModel>(slidesNum));
for (int i = 0; i < slidesNum; i++) {
// FIXME: This is NOT compatible with the SMILDocument which is
// generated by some other mobile phones.
SMILParElement par = (SMILParElement) slideNodes.item(i);
//======fixed CR<NEWMS00114698> by luning at 11-08-12 begin======
int parDuration = (int) (par.getDur() * 1000);
//======fixed CR<NEWMS00114698> by luning at 11-08-12 end======
// Create media models for each slide.
NodeList mediaNodes = par.getChildNodes();
int mediaNum = mediaNodes.getLength();
ArrayList<MediaModel> mediaSet = new ArrayList<MediaModel>(mediaNum);
for (int j = 0; j < mediaNum; j++) {
SMILMediaElement sme = (SMILMediaElement) mediaNodes.item(j);
try {
MediaModel media = MediaModelFactory.getMediaModel(
context, sme, layouts, pb);
//fix for bug 10852
if(media.isVcard()){
VcardModel vcard = (VcardModel)media;
vCardsModels.add(vcard);
}
if(media.isOtherFile()){
FileModel file = (FileModel)media;
fileModels.add(file);
}
//======fixed CR<NEWMS00114698> by luning at 11-08-12 begin======
if(media.getDuration() > parDuration){
media.setDuration(parDuration);
} else if((media.isImage()||media.isText()) && media.getDuration() < parDuration){
media.setDuration(parDuration);
}
//======fixed CR<NEWMS00114698> by luning at 11-08-12 end======
// context, sme, layouts, pb);
/*
* This is for slide duration value set.
* If mms server does not support slide duration.
*/
if (!MmsConfig.getSlideDurationEnabled()) {
int mediadur = media.getDuration();
float dur = par.getDur();
if (dur == 0) {
mediadur = MmsConfig.getMinimumSlideElementDuration() * 1000;
media.setDuration(mediadur);
}
if ((int)mediadur / 1000 != dur) {
String tag = sme.getTagName();
if (ContentType.isVideoType(media.mContentType)
|| tag.equals(SmilHelper.ELEMENT_TAG_VIDEO)
|| ContentType.isAudioType(media.mContentType)
|| tag.equals(SmilHelper.ELEMENT_TAG_AUDIO)) {
/*
* add 1 sec to release and close audio/video
* for guaranteeing the audio/video playing.
* because the mmsc does not support the slide duration.
*/
par.setDur((float)mediadur / 1000 + 1);
} else {
/*
* If a slide has an image and an audio/video element
* and the audio/video element has longer duration than the image,
* The Image disappear before the slide play done. so have to match
* an image duration to the slide duration.
*/
if ((int)mediadur / 1000 < dur) {
media.setDuration((int)dur * 1000);
} else {
if ((int)dur != 0) {
media.setDuration((int)dur * 1000);
} else {
par.setDur((float)mediadur / 1000);
}
}
}
}
}
SmilHelper.addMediaElementEventListeners(
(EventTarget) sme, media);
mediaSet.add(media);
} catch (DrmException e) {
Log.e(TAG, e.getMessage(), e);
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
} catch (IllegalArgumentException e) {
Log.e(TAG, e.getMessage(), e);
}
}
SlideModel slide = new SlideModel(parDuration, mediaSet, context, slideFomatError);
slide.setFill(par.getFill());
SmilHelper.addParElementEventListeners((EventTarget) par, slide);
slides.add(slide);
}
//for NEWMS00198557
// take notes for bug 19247 --start
for (PduPart part : pb.getParts()) {
if (!part.findBySmil) {
byte[] bytes = part.getContentType();
if (null != bytes) {
String contentType = new String(bytes);
Uri uri = part.getDataUri();
String contentLocation = null;
if (null == part.getContentLocation()) {
contentLocation = "";
} else {
contentLocation = new String(part.getContentLocation());
}
if (ContentType.TEXT_VCARD.equalsIgnoreCase(contentType)) {
if (null != uri) {
VcardModel vCard = new VcardModel(context,
ContentType.TEXT_VCARD, contentLocation, uri);
vCardsModels.add(vCard);
}
} else if (!ContentType.APP_SMIL.equalsIgnoreCase(contentType)) {
if (null != uri) {
try {
FileModel file = new FileModel(context, null,
ContentType.FILE_UNSPECIFIED, contentLocation, uri);
fileModels.add(file);
} catch (MmsException e) {
Log.e(TAG, "MmsException caught while creating FileModel", e);
}
}
}
}
}
}
// take notes for bug 19247 --end
SlideshowModel slideshow = new SlideshowModel(layouts, slides, document, pb, context);
if (null != vCardsModels) {
slideshow.setVcards(vCardsModels);
}
if (null != fileModels) {
slideshow.setOtherFiles(fileModels);
}
/* fixed CR<NEWMS00133151,NEWMS00144166> by luning at 2011.12.06 end */
slideshow.registerModelChangedObserver(slideshow);
return slideshow;
}
public PduBody toPduBody() {
if (mPduBodyCache == null) {
mDocumentCache = SmilHelper.getDocument(this);
mPduBodyCache = makePduBody(mDocumentCache);
}
return mPduBodyCache;
}
private PduBody makePduBody(SMILDocument document) {
return makePduBody(null, document, false);
}
private PduBody makePduBody(Context context, SMILDocument document, boolean isMakingCopy) {
PduBody pb = new PduBody();
boolean hasForwardLock = false;
List<SlideModel> slides = new ArrayList<SlideModel>(Arrays.asList(mSlides.toArray(new SlideModel[mSlides.size()])));
Collections.copy(slides, mSlides);
for (SlideModel slide : slides) {
for (MediaModel media : slide) {
if (isMakingCopy) {
if (media.isDrmProtected() && !media.isAllowedToForward()) {
hasForwardLock = true;
continue;
}
}
PduPart part = new PduPart();
if (media.isText()) {
TextModel text = (TextModel) media;
// Don't create empty text part.
if (TextUtils.isEmpty(text.getText())) {
continue;
}
// Set Charset if it's a text media.
part.setCharset(text.getCharset());
}
// Set Content-Type.
part.setContentType(media.getContentType().getBytes());
String src = media.getSrc();
String location;
boolean startWithContentId = src.startsWith("cid:");
if (startWithContentId) {
location = src.substring("cid:".length());
} else {
location = src;
}
// Set Content-Location.
part.setContentLocation(location.getBytes());
// Set Content-Id.
if (startWithContentId) {
//Keep the original Content-Id.
part.setContentId(location.getBytes());
} else {
int index = location.lastIndexOf(".");
String contentId = (index == -1) ? location
: location.substring(0, index);
part.setContentId(contentId.getBytes());
}
if (media.isDrmProtected()) {
DrmWrapper wrapper = media.getDrmObject();
part.setDataUri(wrapper.getOriginalUri());
part.setData(wrapper.getOriginalData());
} else if (media.isText()) {
part.setData(((TextModel) media).getText().getBytes());
}else if(media.isVcard() || media.isOtherFile()){//2012-03-02 fix for bug 10852 phone02 start
try {
part.setDataUri(media.getUri());
part.setData(media.getData());
} catch (DrmException e) {
Log.e(TAG, "makePduBody hanppened DrmException :"+e.toString(), e);
e.printStackTrace();
}//2012-03-02 fix for bug 10852 phone02 end
} else if (media.isImage() || media.isVideo() || media.isAudio()) {
part.setDataUri(media.getUri());
} else {
Log.w(TAG, "Unsupport media: " + media);
}
pb.addPart(part);
}
}
if (pb.getPartsNum() == 0 && mFiles != null) {
for (FileModel file : mFiles) {
PduPart part = createPduPart(file);
pb.addPart(part);
}
}
if (pb.getPartsNum() == 0 && mVcards != null) {
for (VcardModel vcard : mVcards) {
PduPart part = createPduPart(vcard);
pb.addPart(part);
}
}
if (hasForwardLock && isMakingCopy && context != null) {
Toast.makeText(context, context.getString(R.string.cannot_forward_drm_obj),
Toast.LENGTH_LONG).show();
document = SmilHelper.getDocument(pb);
}
// ===== fixed CR<NEWMS00120798> by luning at 2011.11.08 begin =====
//fix for bug fix for bug 10852 ,cover this code ,the vcard add to slide
// if(hasVcard()){
// for(VcardModel vcardModel :mVcards){
// PduPart part = new PduPart();
// // Set Content-Type.
// part.setContentType(vcardModel.getContentType().getBytes());
// // Set Content-Location.
// part.setContentLocation(vcardModel.getSrc().getBytes());
// // Set Content-Id.
// part.setContentId(vcardModel.getSrc().getBytes());
// // Set Uri
// part.setDataUri(vcardModel.getUri());
// // add vcardPart to body
// pb.addPart(part);
// }
// }
// ===== fixed CR<NEWMS00120798> by luning at 2011.11.08 end =====
// Create and insert SMIL part(as the first part) into the PduBody.
ByteArrayOutputStream out = new ByteArrayOutputStream();
SmilXmlSerializer.serialize(document, out);
PduPart smilPart = new PduPart();
smilPart.setCharset(CharacterSets.DEFAULT_CHARSET);
smilPart.setContentId("smil".getBytes());
smilPart.setContentLocation("smil.xml".getBytes());
smilPart.setContentType(ContentType.APP_SMIL.getBytes());
smilPart.setData(out.toByteArray());
pb.addPart(0, smilPart);
return pb;
}
private PduPart createPduPart(MediaModel media) {
PduPart part = new PduPart();
try {
part.setContentType(media.getContentType().getBytes());
String src = media.getSrc();
String location;
boolean startWithContentId = src.startsWith("cid:");
if (startWithContentId) {
location = src.substring("cid:".length());
} else {
location = src;
}
// Set Content-Id.
if (startWithContentId) {
// Keep the original Content-Id.
part.setContentId(location.getBytes());
} else {
int index = location.lastIndexOf(".");
String contentId = (index == -1) ? location : location.substring(0, index);
part.setContentId(contentId.getBytes());
}
// Set Content-Location.
part.setContentLocation(location.getBytes());
part.setDataUri(media.getUri());
part.setData(media.getData());
} catch (DrmException e) {
Log.e(TAG, "makePduBody hanppened DrmException :" + e.toString(), e);
e.printStackTrace();
}
return part;
}
public PduBody makeCopy(Context context) {
return makePduBody(context, SmilHelper.getDocument(this), true);
}
public SMILDocument toSmilDocument() {
if (mDocumentCache == null) {
mDocumentCache = SmilHelper.getDocument(this);
}
return mDocumentCache;
}
public static PduBody getPduBody(Context context, Uri msg) throws MmsException {
PduPersister p = PduPersister.getPduPersister(context);
GenericPdu pdu = p.load(msg);
int msgType = pdu.getMessageType();
if ((msgType == PduHeaders.MESSAGE_TYPE_SEND_REQ)
|| (msgType == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF)) {
return ((MultimediaMessagePdu) pdu).getBody();
} else {
throw new MmsException();
}
}
public void setCurrentMessageSize(int size) {
mCurrentMessageSize = size;
}
public int getCurrentMessageSize() {
return mCurrentMessageSize;
}
public void increaseMessageSize(int increaseSize) {
if (increaseSize > 0) {
mCurrentMessageSize += increaseSize;
}
}
public void decreaseMessageSize(int decreaseSize) {
if (decreaseSize > 0) {
mCurrentMessageSize -= decreaseSize;
}
}
public LayoutModel getLayout() {
return mLayout;
}
//
// Implement List<E> interface.
//
public boolean add(SlideModel object) {
int increaseSize = object.getSlideSize();
checkMessageSize(increaseSize);
if ((object != null) && mSlides.add(object)) {
increaseMessageSize(increaseSize);
object.registerModelChangedObserver(this);
for (IModelChangedObserver observer : mModelChangedObservers) {
object.registerModelChangedObserver(observer);
}
notifyModelChanged(true);
return true;
}
return false;
}
public boolean addAll(Collection<? extends SlideModel> collection) {
throw new UnsupportedOperationException("Operation not supported.");
}
public void clear() {
if (mSlides.size() > 0) {
for (SlideModel slide : mSlides) {
slide.unregisterModelChangedObserver(this);
for (IModelChangedObserver observer : mModelChangedObservers) {
slide.unregisterModelChangedObserver(observer);
}
}
mCurrentMessageSize = 0;
mSlides.clear();
notifyModelChanged(true);
}
}
public boolean contains(Object object) {
return mSlides.contains(object);
}
public boolean containsAll(Collection<?> collection) {
return mSlides.containsAll(collection);
}
public boolean isEmpty() {
return mSlides.isEmpty();
}
public Iterator<SlideModel> iterator() {
return mSlides.iterator();
}
public boolean remove(Object object) {
if ((object != null) && mSlides.remove(object)) {
SlideModel slide = (SlideModel) object;
decreaseMessageSize(slide.getSlideSize());
slide.unregisterAllModelChangedObservers();
notifyModelChanged(true);
return true;
}
return false;
}
public boolean removeAll(Collection<?> collection) {
throw new UnsupportedOperationException("Operation not supported.");
}
public boolean retainAll(Collection<?> collection) {
throw new UnsupportedOperationException("Operation not supported.");
}
public int size() {
return mSlides.size();
}
public Object[] toArray() {
return mSlides.toArray();
}
public <T> T[] toArray(T[] array) {
return mSlides.toArray(array);
}
public void add(int location, SlideModel object) {
if (object != null) {
int increaseSize = object.getSlideSize();
checkMessageSize(increaseSize);
mSlides.add(location, object);
increaseMessageSize(increaseSize);
object.registerModelChangedObserver(this);
for (IModelChangedObserver observer : mModelChangedObservers) {
object.registerModelChangedObserver(observer);
}
notifyModelChanged(true);
}
}
public boolean addAll(int location,
Collection<? extends SlideModel> collection) {
throw new UnsupportedOperationException("Operation not supported.");
}
public SlideModel get(int location) {
return (location >= 0 && location < mSlides.size()) ? mSlides.get(location) : null;
}
public int indexOf(Object object) {
return mSlides.indexOf(object);
}
public int lastIndexOf(Object object) {
return mSlides.lastIndexOf(object);
}
public ListIterator<SlideModel> listIterator() {
return mSlides.listIterator();
}
public ListIterator<SlideModel> listIterator(int location) {
return mSlides.listIterator(location);
}
public SlideModel remove(int location) {
SlideModel slide = mSlides.remove(location);
if (slide != null) {
decreaseMessageSize(slide.getSlideSize());
slide.unregisterAllModelChangedObservers();
notifyModelChanged(true);
}
return slide;
}
public SlideModel set(int location, SlideModel object) {
SlideModel slide = mSlides.get(location);
if (null != object) {
int removeSize = 0;
int addSize = object.getSlideSize();
if (null != slide) {
removeSize = slide.getSlideSize();
}
if (addSize > removeSize) {
checkMessageSize(addSize - removeSize);
increaseMessageSize(addSize - removeSize);
} else {
decreaseMessageSize(removeSize - addSize);
}
}
slide = mSlides.set(location, object);
if (slide != null) {
slide.unregisterAllModelChangedObservers();
}
if (object != null) {
object.registerModelChangedObserver(this);
for (IModelChangedObserver observer : mModelChangedObservers) {
object.registerModelChangedObserver(observer);
}
}
notifyModelChanged(true);
return slide;
}
public List<SlideModel> subList(int start, int end) {
return mSlides.subList(start, end);
}
@Override
protected void registerModelChangedObserverInDescendants(
IModelChangedObserver observer) {
mLayout.registerModelChangedObserver(observer);
for (SlideModel slide : mSlides) {
slide.registerModelChangedObserver(observer);
}
}
@Override
protected void unregisterModelChangedObserverInDescendants(
IModelChangedObserver observer) {
mLayout.unregisterModelChangedObserver(observer);
for (SlideModel slide : mSlides) {
slide.unregisterModelChangedObserver(observer);
}
}
@Override
protected void unregisterAllModelChangedObserversInDescendants() {
mLayout.unregisterAllModelChangedObservers();
for (SlideModel slide : mSlides) {
slide.unregisterAllModelChangedObservers();
}
}
public void onModelChanged(Model model, boolean dataChanged) {
if (dataChanged) {
mDocumentCache = null;
mPduBodyCache = null;
}
}
public void sync(PduBody pb) {
for (SlideModel slide : mSlides) {
for (MediaModel media : slide) {
PduPart part = pb.getPartByContentLocation(media.getSrc());
if (part != null) {
media.setUri(part.getDataUri());
}
}
}
}
public void checkMessageSize(int increaseSize) throws ContentRestrictionException {
ContentRestriction cr = ContentRestrictionFactory.getContentRestriction();
cr.checkMessageSize(getTotalMsgSizeWithAllHead(), increaseSize, mContext.getContentResolver());
}
/**
* Determines whether this is a "simple" slideshow.
* Criteria:
* - Exactly one slide
* - Exactly one multimedia attachment, but no audio
* - It can optionally have a caption
*/
public boolean isSimple() {
// There must be one (and only one) slide.
if (size() != 1)
return false;
SlideModel slide = get(0);
// The slide must have either an image or video, but not both.
if (!(slide.hasImage() ^ slide.hasVideo()))
return false;
// No audio allowed.
if (slide.hasAudio())
return false;
return true;
}
/**
* add by luning at 2011.11.23
* @return
*/
public boolean isSimpleSlide() {
if (size() > 1)
return false;
SlideModel slide = get(0);
int size = slide.size();
if (size < 2)
return true;
else if (size == 2 && slide.hasText())
return true;
else
return false;
}
/**
* Make sure the text in slide 0 is no longer holding onto a reference to the text
* in the message text box.
*/
public void prepareForSend() {
if (size() == 1) {
TextModel text = get(0).getText();
if (text != null) {
text.cloneText();
}
}
}
public int getTotalMessageSize()//for bug newms00110111
{
int totalSize = 0;
for (SlideModel slide : mSlides) {
totalSize+=slide.getSlideSize();
}
// ======fixed CR<NEWMS00122616> by luning at 11-08-12 begin======
// totalSize +=getCurrentMessageSize();
// ======fixed CR<NEWMS00122616> by luning at 11-08-12 end======
totalSize += mSubjectSize;
return totalSize;
}
public int getTotalSlideCount() {
return mSlides.size();
}
public int getTotalMsgSizeWithSlideHead() {
return (getCurrentMessageSize()+getTotalSlideCount()*MmsConfig.getMaxSingleSlideSize());
}
public int getTotalMsgSizeWithAllHead() {
return (MmsConfig.getMessageWithPduHeadSize(getTotalMsgSizeWithSlideHead()));
}
public int getTotalMsgSizeWithAllHead(int size) {
return (MmsConfig.getMessageWithPduHeadSize(size+getTotalSlideCount()*MmsConfig.getMaxSingleSlideSize()));
}
// ===== fixed CR<NEWMS00129480> by luning at 11-10-13 begin =====
public int getMediaNum(){
int num = 0;
for (SlideModel slide : mSlides) {
for (MediaModel media : slide) {
num ++;
}
}
return num;
}
// ===== fixed CR<NEWMS00129480> by luning at 11-10-13 end =====
/**
* Resize all the resizeable media objects to fit in the remaining size of the slideshow.
* This should be called off of the UI thread.
*
* @throws MmsException, ExceedMessageSizeException
*/
public void finalResize(Uri messageUri) throws MmsException, ExceedMessageSizeException {
// Log.v(TAG, "Original message size: " + getCurrentMessageSize() + " getMaxMessageSize: "
// + MmsConfig.getMaxMessageSize());
// Figure out if we have any media items that need to be resized and total up the
// sizes of the items that can't be resized.
int totalSize = 0;
int resizableCnt = 0;
int fixedSizeTotal = 0;
boolean isSupportResize=false;
fixedSizeTotal = totalSize = mSubjectSize;
for (SlideModel slide : mSlides) {
for (MediaModel media : slide) {
totalSize += media.getMediaSize();//check resize or not for bug newms00110175
if (media.getMediaResizable()) {
++resizableCnt;
} else {
fixedSizeTotal += media.getMediaSize();
}
}
}
if (!isSupportResize || totalSize < MmsConfig.getMaxMessageSize()) {//check resize or not
return ;
}
if (resizableCnt > 0) {
int remainingSize = MmsConfig.getMaxMessageSize() - fixedSizeTotal - SLIDESHOW_SLOP;
if (remainingSize <= 0) {
throw new ExceedMessageSizeException("No room for pictures");
}
long messageId = ContentUris.parseId(messageUri);
int bytesPerMediaItem = remainingSize / resizableCnt;
// Resize the resizable media items to fit within their byte limit.
for (SlideModel slide : mSlides) {
for (MediaModel media : slide) {
if (media.getMediaResizable()) {
media.resizeMedia(bytesPerMediaItem, messageId);
}
}
}
// One last time through to calc the real message size.
totalSize = mSubjectSize;
for (SlideModel slide : mSlides) {
for (MediaModel media : slide) {
totalSize += media.getMediaSize();
}
}
// Log.v(TAG, "New message size: " + totalSize + " getMaxMessageSize: "
// + MmsConfig.getMaxMessageSize());
if (totalSize > MmsConfig.getMaxMessageSize()) {
throw new ExceedMessageSizeException("After compressing pictures, message too big");
}
setCurrentMessageSize(totalSize);
onModelChanged(this, true); // clear the cached pdu body
PduBody pb = toPduBody();
// This will write out all the new parts to:
// /data/data/com.android.providers.telephony/app_parts
// and at the same time delete the old parts.
PduPersister.getPduPersister(mContext).updateParts(messageUri, pb);
}
}
public void setSubjectSize(int subject_size) {
if(subject_size<0) return;
if(subject_size>mSubjectSize) {
//checkMessageSize(subject_size - mSubjectSize);
increaseMessageSize(subject_size - mSubjectSize);
} else if(subject_size<mSubjectSize) {
decreaseMessageSize(mSubjectSize-subject_size);
}
mSubjectSize = subject_size;
}
}