`
baobaoupup
  • 浏览: 470894 次
文章分类
社区版块
存档分类
最新评论

SlideshowModel

 
阅读更多
/*
* 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 org.w3c.dom.Node;
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.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

import com.android.mms.data.VCardComposer;
import android.content.ContentResolver;
import android.database.Cursor;
import com.google.android.mms.pdu.CharacterSets;
import android.pim.vcard.VCardConfig;





public class SlideshowModel extends Model
implements List<SlideModel>, IModelChangedObserver {
private static final String TAG = "Mms/slideshow";

private final LayoutModel mLayout;
private final ArrayList<SlideModel> mSlides;
private SMILDocument mDocumentCache;
private PduBody mPduBodyCache;
private int mCurrentMessageSize;
private Context mContext;

// amount of space to leave in a slideshow for text and overhead.
public static final int SLIDESHOW_SLOP = 1024;

private SlideshowModel(Context context) {
mLayout = new LayoutModel();
mSlides = new ArrayList<SlideModel>();
mContext = context;
}

private SlideshowModel (
LayoutModel layouts, ArrayList<SlideModel> slides,
SMILDocument documentCache, PduBody pbCache,
Context context) {
mLayout = layouts;
mSlides = slides;
mContext = context;

mDocumentCache = documentCache;
mPduBodyCache = pbCache;
for (SlideModel slide : mSlides) {
increaseMessageSize(slide.getSlideSize());
slide.setParent(this);
}
}

public static SlideshowModel createNew(Context context) {
return new SlideshowModel(context);
}

public static SlideshowModel createFromMessageUri(
Context context, Uri uri) throws MmsException {
return createFromPduBody(context, getPduBody(context, uri));
}

public static SlideshowModel createFromPduBody(Context context, PduBody pb) 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);

// Create slide models.
SMILElement docBody = document.getBody();
NodeList slideNodes = docBody.getChildNodes();
int slidesNum = slideNodes.getLength();
ArrayList<SlideModel> slides = 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);

// 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 = null;
Node item = mediaNodes.item(j);
if (item instanceof SMILMediaElement) {
sme = (SMILMediaElement) item;
}
if (sme == null) {
continue;
}
try {
MediaModel media = MediaModelFactory.getMediaModel(
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);
}
}
//Begin Added xin.wu@archermind.com -20111118-
int slideModel_time=(int) (par.getDur() * 1000);
if(slideModel_time<1000){
slideModel_time=1000;
}
//End Added xin.wu@archermind.com -20111118-
SlideModel slide = new SlideModel(slideModel_time, mediaSet);
slide.setFill(par.getFill());
SmilHelper.addParElementEventListeners((EventTarget) par, slide);
slides.add(slide);
}

SlideshowModel slideshow = new SlideshowModel(layouts, slides, document, pb, context);
slideshow.registerModelChangedObserver(slideshow);
return slideshow;
}



//Begin modified by chenjiajian for optimize slideshow code 2012.3.5
public static SlideshowModel createFromPduBodySimple(Context context, PduBody pb) 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();
Log.e("CJJ--ssm","regionsNum = "+regionsNum);
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);

// Create slide models.
SMILElement docBody = document.getBody();
NodeList slideNodes = docBody.getChildNodes();
int slidesNum = slideNodes.getLength();
Log.e("CJJ--ssm","slidesNum = "+slidesNum);
ArrayList<SlideModel> slides = new ArrayList<SlideModel>(slidesNum);
//chenjiajian modify for load 2 or 1 slidesNum
// for (int i = 0; i < slidesNum; i++) {
int simpleCnt = 0;
if(slidesNum >2){
simpleCnt = 2;
}else{
simpleCnt = slidesNum;
}
for (int i = 0; i < simpleCnt; i++) {
// FIXME: This is NOT compatible with the SMILDocument which is
// generated by some other mobile phones.
SMILParElement par = (SMILParElement) slideNodes.item(i);
Log.e("CJJ--ssm", "par = " + par);

// Create media models for each slide.
NodeList mediaNodes = par.getChildNodes();
Log.e("CJJ--ssm", "mediaNodes = " + mediaNodes);
int mediaNum = mediaNodes.getLength();
// int mediaNum = 1;
Log.e("CJJ--ssm", "mediaNum = " + mediaNum);
ArrayList<MediaModel> mediaSet = new ArrayList<MediaModel>(mediaNum);

// add by chenjiajian for vCard

int partNum = pb.getPartsNum();
Log.e("CJJ--ssm", "partNum = " + partNum);
for (int p = 0; p < partNum; p++) {
try {
PduPart part = pb.getPart(p);
String type = new String(part.getContentType());
Log.e("CJJ--ssm", "370 type = " + type);
if (!ContentType.isImageType(type) && !ContentType.isVideoType(type)
&& !ContentType.isAudioType(type) && !type.startsWith("application/")
&& !type.equals(ContentType.TEXT_PLAIN)) {
Log.e("CJJ--ssm", "isVcard");
// String Location = new
// String(part.getContentLocation());
Uri uri = part.getDataUri();
Log.e("CJJ--ssm", "uri = " + uri);
if (null != uri) {

String mId = uri.getLastPathSegment();
VCardComposer mComposer = new VCardComposer(context,
VCardConfig.VCARD_TYPE_DEFAULT, false);
ContentResolver cr = context.getContentResolver();
Cursor mCursor = cr.query(uri, null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
// String vCardname = new
// String(part.getName());
// String vCardId = new
// String(part.getContentId());
String displayName = "Vcard";

if (part.getName() != null) {
displayName = new String(part.getName());
} else if (part.getContentId() != null) {
displayName = new String(part.getContentId());
}
Log.e("CJJ--ssm", "displayName = " + displayName);
// MediaModel media = new ContactModel(context,
// type,
// mCursor.getString(mCursor.getColumnIndex("display_name"))+".vcf",
// CharacterSets.ANY_CHARSET,
// mComposer.createOneEntryInternal(mId,null).getBytes());
MediaModel media = new ContactModel(context,
ContentType.TEXT_VCARD, displayName, part.getCharset(),
part.getData());
Log.e("CJJ--ssm", "mediaSet.add");
mediaSet.add(media);
mCursor.close();
}
}

}
} catch (Exception e) {
// TODO Auto-generated catch block
Log.e(TAG, e.toString());
// e.printStackTrace();
}
}

// chenjiajian

for (int j = 0; j < mediaNum; j++) {
SMILMediaElement sme = null;
Node item = mediaNodes.item(j);
if (item instanceof SMILMediaElement) {
Log.e("CJJ--ssm", "370 instanceof SMILMediaElement");
sme = (SMILMediaElement) item;
}
Log.e("CJJ--ssm", "sme = " + sme);
if (sme == null) {
continue;
}
try {
Log.e("CJJ--ssm", "layouts = " + layouts);
MediaModel media = MediaModelFactory.getMediaModel(context, sme, layouts, pb);

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);
}
}
// Begin Added xin.wu@archermind.com -20111118-
int slideModel_time = (int) (par.getDur() * 1000);
if (slideModel_time < 1000) {
slideModel_time = 1000;
}
// End Added xin.wu@archermind.com -20111118-
SlideModel slide = new SlideModel(slideModel_time, mediaSet);
slide.setFill(par.getFill());
SmilHelper.addParElementEventListeners((EventTarget) par, slide);
slides.add(slide);
}


SlideshowModel slideshow = new SlideshowModel(layouts, slides, document, pb, context);
slideshow.registerModelChangedObserver(slideshow);
return slideshow;
}
//End modified by chenjiajian for optimize slideshow code 2012.3.5
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;
for (SlideModel slide : mSlides) {
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());
Log.e("CJJ","ContentType = "+media.getContentType());

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());
Log.e("CJJ","location = "+location);
// 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());
Log.e("CJJ","contentId = "+contentId);
}
Log.e("CJJ","isDrmProtected = "+media.isDrmProtected()+" isText = "+media.isText()+" isImage = "+media.isImage()+" isContace = "+media.isContact());
if (media.isDrmProtected()) {
DrmWrapper wrapper = media.getDrmObject();
part.setDataUri(wrapper.getOriginalUri());
part.setData(wrapper.getOriginalData());
Log.e("CJJ","wrapper-uri = "+wrapper.getOriginalUri()+" wrapper-data = "+wrapper.getOriginalData());
} else if (media.isText()) {
part.setData(((TextModel) media).getText().getBytes());
} else if (media.isImage() || media.isVideo() || media.isAudio()) {
part.setDataUri(media.getUri());
}
//Add by jian.zhang for fix bug 391 2011.10.19 begin
else if (media.isContact()) {
ContactModel contact = (ContactModel) media;
part.setData((contact.getContact().getBytes()));
part.setCharset(contact.getCharset());
Log.e("CJJ","contact-Data = "+contact.getContact()+" contact-Charset = "+contact.getCharset());
// addSmil = false;
}
//Add by jian.zhang for fix bug 391 2011.10.19 end
else {
Log.w(TAG, "Unsupport media: " + media);
}

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);
}

// 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.setContentId("smil".getBytes());
smilPart.setContentLocation("smil.xml".getBytes());
smilPart.setContentType(ContentType.APP_SMIL.getBytes());
smilPart.setData(out.toByteArray());
pb.addPart(0, smilPart);

return pb;
}

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;//modify by zhangfei
}
}

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(mCurrentMessageSize, 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;

//Add by jian.zhang for fix bug 391 2011.10.19 begin
if (slide.hasContact()) {
return false;
}
//Add by jian.zhang for fix bug 391 2011.10.19 end

return true;
}

/**
* 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();
}
}
}

// Benig added by chenjiajian@newpostcom.com.cn.-20111018-
/**
*add Resize() method and call before getCurrentMessageSize(),
*because mms picture size was wrong.
*/
public void Resize() {//this method modify by zhangfei 2011-12-13 for
int totalSize = 0;
int count = mSlides.size();
if (count == 1) {
for (MediaModel media : mSlides.get(0)) {
totalSize += media.getMediaSize();
}
} else {
ArrayList<Uri> uris = new ArrayList<Uri>();
for (SlideModel slide : mSlides) {
for (MediaModel media : slide) {
if (uris.contains(media.getUri())) {
continue;
} else {
uris.add(media.getUri());
// Begin: modify by huangle@npte.local to fix cr 1345, 1315--2012.03.08
//totalSize += media.getMediaSize();
totalSize += (Math.ceil(((float)media.getMediaSize())/((float)4096)))*4096 ;
// End: modify by huangle@npte.local to fix cr 1345, 1315--2012.03.08
}
}
}
uris.clear();
uris = null;
}

if (totalSize > MmsConfig.getMaxMessageSize()) {
throw new ExceedMessageSizeException(
"After compressing pictures, message too big");
}
setCurrentMessageSize(totalSize);
}
// End added by chenjiajian@newpostcom.com.cn.-20111018-

/**
* 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 resizableCnt = 0;
int fixedSizeTotal = 0;
for (SlideModel slide : mSlides) {
for (MediaModel media : slide) {
if (media.getMediaResizable()) {
++resizableCnt;
} else {
fixedSizeTotal += media.getMediaSize();
}
}
}
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()) {
//Begin Modify by xin.wu@archermind.com -20111027-
// if(media.getContentType().equals("image/gif")&&(media.getMediaSize()<MmsConfig.getMaxMessageSize())){
if(media.getMediaSize()<MmsConfig.getMaxMessageSize()){
// if media is image/gif and size less than 300k, will not resize and compress
}
else{
//delete by zhangfei 2011-11-10 start
Log.d(TAG, "finalResize");
media.resizeMedia(bytesPerMediaItem, messageId);
//delete by zhangfei 2011-11-10 end
}
//End Modify by xin.wu@archermind.com -20111027-
}
}
}
// One last time through to calc the real message size.
int totalSize = 0;
//modify by zhangfei 2012-01-02 for calculate the attachment size start
// for (SlideModel slide : mSlides) {
// for (MediaModel media : slide) {
// totalSize += media.getMediaSize();
// }
// }
Resize();
totalSize = getCurrentMessageSize();
//modify by zhangfei 2012-01-02 for calculate the attachment size end
// 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);
}
}

}


分享到:
评论

相关推荐

    Android Mms之:深入MMS支持

    Composing and editingMMS在Android Mms应用里面的具体实现形式,或数据结构是SlideshowModel,它是一个每个节点为SlideModel的ArrayList,SlideModel是一个Model的List,也就是它可以接收任何Model的子类,Audio,...

    电子、通信、计算机大类学生课程实验的心得体会

    电子、通信、计算机大类学生课程实验的心得体会 电子、通信、计算机大类的学生课程实验是工科教育中非常重要的一环,它不仅能够加深学生对理论知识的理解,还能培养学生的实践能力和创新思维。

    【营销】任务一金融产品与金融产品营销认识.docx

    【营销】任务一金融产品与金融产品营销认识.docx

    单片机课程实验-秒表实现

    1.了解LED数码管的工作原理,为秒表时钟模块的实现打下基础。 LED数码管是一种常用的数字显示器件,通过控制每个LED的亮灭来显示数字。在秒表时钟模块中,我们需要利用LED数码管的这一特性,通过单片机控制数码管的显示,从而实现时钟的功能。因此,了解LED数码管的工作原理对于实现秒表时钟模块至关重要。 2.掌握51单片机与LED数码管的接口技术,是实现秒表时钟模块的关键。 51单片机是一种常用的微控制器,可以通过接口与外部设备进行通信。在秒表时钟模块中,我们需要通过单片机与LED数码管之间的接口,控制数码管的显示。因此,掌握51单片机与LED数码管的接口技术是实现秒表时钟模块的关键。在实际操作中,我们需要根据接口协议和数据传输方式,编写相应的程序来控制数码管的显示。 3.合理利用定时器/计数器,是实现秒表时钟模块的效率保障。 在秒表时钟模块中,我们需要实现计时功能,这需要使用到定时器/计数器。定时器/计数器可以用来产生计时脉冲,从而控制秒表的计时。通过合理利用定时器/计数器,可以提高秒表时钟模块的计时精度和效率。在实际操作中,我们需要根据具体的应用场景和需求,选择合适的定时器/计数器参

    基于LSTM的SDN流量预测与负载均衡python源码+详细注释+数据.zip

    个人98分期末大作业项目,代码完整下载可用。主要针对计算机相关专业的正在做课程设计和期末大作业的学生和需要项目实战练习的学习者。包含全部项目源码、该项目可以直接使用、项目都经过严格调试,下载即用确保可以运行!

    实验室管理微信小程序设计

    实验室管理微信小程序设计

    机械设计CNC自动打孔机(sw18可编辑+工程图)非常好的设计图纸100%好用.zip

    机械设计CNC自动打孔机(sw18可编辑+工程图)非常好的设计图纸100%好用.zip

    51单片机使用蜂鸣器来播放音乐蜂鸣器播放音乐-小星星亮晶晶

    51单片机使用蜂鸣器来播放音乐蜂鸣器播放音乐-小星星亮晶晶 通过PWM信号来控制蜂鸣器,改变PWM的频率,可以改变蜂鸣器的发声音调,从而可以播.适合新手使用

    机械设计德国6层电万能蒸烤箱(sw21可编辑+cad)非常好的设计图纸100%好用.zip

    机械设计德国6层电万能蒸烤箱(sw21可编辑+cad)非常好的设计图纸100%好用.zip

    node-v12.22.5-darwin-x64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    超声波传感器系列 UFA-150, UFA-200 安装指南

    超声波传感器系列 UFA-150, UFA-200 安装指南

    VOS4890 户外电源系统 用户手册

    VOS4890 户外电源系统 用户手册

    金融产品可行性报告.docx

    金融产品可行性报告.docx

    node-v12.18.2-linux-s390x.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    printer.cfg

    printer.cfg

    【计算机二级实操】液晶背光开关控制实验(汇编语言).zip

    【计算机二级实操】液晶背光开关控制实验(汇编语言).zip

    Java毕业设计-基于SpringBoot + Vue 的音乐网站系统 (源码+数据库+文档).zip

    基于Spring Boot和Vue的音乐网站系统是一种使用Spring Boot框架和Vue框架进行开发的在线音乐平台系统。下面是一个简单的介绍: 后端(Spring Boot)部分: 1. 数据库设计:设计合适的数据库模式来存储音乐信息,包括歌曲、专辑、歌手等相关信息。 2. 接口设计:根据需求设计合适的RESTful API接口,用于处理前端请求。您可以使用Spring MVC来开发这些接口,并使用Spring Data JPA来处理数据库访问。 3. 用户管理:实现用户注册、登录、权限管理等功能。使用Spring Security来处理用户认证和授权。 4. 音乐资源管理:上传/编辑/删除音乐、/删除/编辑/分类专辑和歌手等功能。您可以使用Spring Boot提供的文件上传和管理功能,以及数据库来存储和管理相关信息。 5. 推荐系统:实现根据用户的兴趣和行为进行个性化的音乐推荐。可以使用协同过滤、内容推荐或机器学习等技术来进行推荐算法的实现。 前端(Vue)部分: 1. 页面设计:使用Vue框架用户界面,包括首页、歌单推荐、搜索、歌手页面等。使用Vue Router

    中国各地级市工业三废数据(2006-2021年).xlsx

    中国各地级市工业三废数据(2006-2021年).xlsx

    基于扩散模型的半监督脑肿瘤分割内含数据集和环境说明.zip

    本项目致力于基于扩散模型的半监督脑肿瘤分割,旨在提高医学影像在脑肿瘤诊断中的应用。项目利用扩散模型对脑部MRI影像中的肿瘤区域进行精确分割。 在数据集方面,我们使用了公开的脑部MRI影像数据集,如BRATS、Medical Segmentation Decathlon等,并进行了预处理,包括格式转换、裁剪、翻转等操作。在环境搭建方面,我们使用Python编程语言,基于TensorFlow和PyTorch深度学习框架进行开发。为了提高计算效率,我们还使用了GPU加速计算。此外,我们还采用了Docker容器技术,确保实验结果的可重复性。 项目完成后,将实现对脑部MRI影像中肿瘤区域的精确分割,为脑肿瘤的诊断和治疗提供有力支持。同时,项目成果也可应用于其他医学影像分析领域,如肿瘤检测、病变分割等。

    python学习导航.txt

    python烟花代码

Global site tag (gtag.js) - Google Analytics