Home | History | Annotate | Download | only in ui
      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.ui;
     19 
     20 import com.android.mms.R;
     21 import android.drm.mobile1.DrmException;
     22 import com.android.mms.model.AudioModel;
     23 import com.android.mms.model.ImageModel;
     24 import com.android.mms.model.LayoutModel;
     25 import com.android.mms.model.MediaModel;
     26 import com.android.mms.model.Model;
     27 import com.android.mms.model.RegionMediaModel;
     28 import com.android.mms.model.RegionModel;
     29 import com.android.mms.model.SlideModel;
     30 import com.android.mms.model.SlideshowModel;
     31 import com.android.mms.model.TextModel;
     32 import com.android.mms.model.VideoModel;
     33 import com.android.mms.model.MediaModel.MediaAction;
     34 import com.android.mms.ui.AdaptableSlideViewInterface.OnSizeChangedListener;
     35 
     36 import android.content.Context;
     37 import android.os.Handler;
     38 import android.util.Config;
     39 import android.util.Log;
     40 import android.widget.Toast;
     41 
     42 /**
     43  * A basic presenter of slides.
     44  */
     45 public class SlideshowPresenter extends Presenter {
     46     private static final String TAG = "SlideshowPresenter";
     47     private static final boolean DEBUG = false;
     48     private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
     49 
     50     protected int mLocation;
     51     protected final int mSlideNumber;
     52 
     53     protected float mWidthTransformRatio;
     54     protected float mHeightTransformRatio;
     55 
     56     // Since only the original thread that created a view hierarchy can touch
     57     // its views, we have to use Handler to manage the views in the some
     58     // callbacks such as onModelChanged().
     59     protected final Handler mHandler = new Handler();
     60 
     61     public SlideshowPresenter(Context context, ViewInterface view, Model model) {
     62         super(context, view, model);
     63         mLocation = 0;
     64         mSlideNumber = ((SlideshowModel) mModel).size();
     65 
     66         if (view instanceof AdaptableSlideViewInterface) {
     67             ((AdaptableSlideViewInterface) view).setOnSizeChangedListener(
     68                     mViewSizeChangedListener);
     69         }
     70     }
     71 
     72     private final OnSizeChangedListener mViewSizeChangedListener =
     73         new OnSizeChangedListener() {
     74         public void onSizeChanged(int width, int height) {
     75             LayoutModel layout = ((SlideshowModel) mModel).getLayout();
     76             mWidthTransformRatio = getWidthTransformRatio(
     77                     width, layout.getLayoutWidth());
     78             mHeightTransformRatio = getHeightTransformRatio(
     79                     height, layout.getLayoutHeight());
     80             // The ratio indicates how to reduce the source to match the View,
     81             // so the larger one should be used.
     82             float ratio = mWidthTransformRatio > mHeightTransformRatio ?
     83                     mWidthTransformRatio : mHeightTransformRatio;
     84             mWidthTransformRatio = ratio;
     85             mHeightTransformRatio = ratio;
     86             if (LOCAL_LOGV) {
     87                 Log.v(TAG, "ratio_w = " + mWidthTransformRatio
     88                         + ", ratio_h = " + mHeightTransformRatio);
     89             }
     90         }
     91     };
     92 
     93     private float getWidthTransformRatio(int width, int layoutWidth) {
     94         if (width > 0) {
     95             return (float) layoutWidth / (float) width;
     96         }
     97         return 1.0f;
     98     }
     99 
    100     private float getHeightTransformRatio(int height, int layoutHeight) {
    101         if (height > 0) {
    102             return (float) layoutHeight / (float) height;
    103         }
    104         return 1.0f;
    105     }
    106 
    107     private int transformWidth(int width) {
    108         return (int) (width / mWidthTransformRatio);
    109     }
    110 
    111     private int transformHeight(int height) {
    112         return (int) (height / mHeightTransformRatio);
    113     }
    114 
    115     @Override
    116     public void present() {
    117         presentSlide((SlideViewInterface) mView, ((SlideshowModel) mModel).get(mLocation));
    118     }
    119 
    120     /**
    121      * @param view
    122      * @param model
    123      */
    124     protected void presentSlide(SlideViewInterface view, SlideModel model) {
    125         view.reset();
    126 
    127         try {
    128             for (MediaModel media : model) {
    129                 if (media instanceof RegionMediaModel) {
    130                     presentRegionMedia(view, (RegionMediaModel) media, true);
    131                 } else if (media.isAudio()) {
    132                     presentAudio(view, (AudioModel) media, true);
    133                 }
    134             }
    135         } catch (DrmException e) {
    136             Log.e(TAG, e.getMessage(), e);
    137             Toast.makeText(mContext,
    138                     mContext.getString(R.string.insufficient_drm_rights),
    139                     Toast.LENGTH_SHORT).show();
    140         }
    141     }
    142 
    143     /**
    144      * @param view
    145      * @throws DrmException
    146      */
    147     protected void presentRegionMedia(SlideViewInterface view,
    148             RegionMediaModel rMedia, boolean dataChanged)
    149             throws DrmException {
    150         RegionModel r = (rMedia).getRegion();
    151         if (rMedia.isText()) {
    152             presentText(view, (TextModel) rMedia, r, dataChanged);
    153         } else if (rMedia.isImage()) {
    154             presentImage(view, (ImageModel) rMedia, r, dataChanged);
    155         } else if (rMedia.isVideo()) {
    156             presentVideo(view, (VideoModel) rMedia, r, dataChanged);
    157         }
    158     }
    159 
    160     protected void presentAudio(SlideViewInterface view, AudioModel audio,
    161             boolean dataChanged) throws DrmException {
    162         // Set audio only when data changed.
    163         if (dataChanged) {
    164             view.setAudio(audio.getUriWithDrmCheck(), audio.getSrc(), audio.getExtras());
    165         }
    166 
    167         MediaAction action = audio.getCurrentAction();
    168         if (action == MediaAction.START) {
    169             view.startAudio();
    170         } else if (action == MediaAction.PAUSE) {
    171             view.pauseAudio();
    172         } else if (action == MediaAction.STOP) {
    173             view.stopAudio();
    174         } else if (action == MediaAction.SEEK) {
    175             view.seekAudio(audio.getSeekTo());
    176         }
    177     }
    178 
    179     protected void presentText(SlideViewInterface view, TextModel text,
    180             RegionModel r, boolean dataChanged) {
    181         if (dataChanged) {
    182             view.setText(text.getSrc(), text.getText());
    183         }
    184 
    185         if (view instanceof AdaptableSlideViewInterface) {
    186             ((AdaptableSlideViewInterface) view).setTextRegion(
    187                     transformWidth(r.getLeft()),
    188                     transformHeight(r.getTop()),
    189                     transformWidth(r.getWidth()),
    190                     transformHeight(r.getHeight()));
    191         }
    192         view.setTextVisibility(text.isVisible());
    193     }
    194 
    195     /**
    196      * @param view
    197      * @param image
    198      * @param r
    199      * @throws DrmException
    200      */
    201     protected void presentImage(SlideViewInterface view, ImageModel image,
    202             RegionModel r, boolean dataChanged) throws DrmException {
    203         if (dataChanged) {
    204             view.setImage(image.getSrc(), image.getBitmapWithDrmCheck());
    205         }
    206 
    207         if (view instanceof AdaptableSlideViewInterface) {
    208             ((AdaptableSlideViewInterface) view).setImageRegion(
    209                     transformWidth(r.getLeft()),
    210                     transformHeight(r.getTop()),
    211                     transformWidth(r.getWidth()),
    212                     transformHeight(r.getHeight()));
    213         }
    214         view.setImageRegionFit(r.getFit());
    215         view.setImageVisibility(image.isVisible());
    216     }
    217 
    218     /**
    219      * @param view
    220      * @param video
    221      * @param r
    222      * @throws DrmException
    223      */
    224     protected void presentVideo(SlideViewInterface view, VideoModel video,
    225             RegionModel r, boolean dataChanged) throws DrmException {
    226         if (dataChanged) {
    227             view.setVideo(video.getSrc(), video.getUriWithDrmCheck());
    228         }
    229 
    230         if (view instanceof AdaptableSlideViewInterface) {
    231             ((AdaptableSlideViewInterface) view).setVideoRegion(
    232                     transformWidth(r.getLeft()),
    233                     transformHeight(r.getTop()),
    234                     transformWidth(r.getWidth()),
    235                     transformHeight(r.getHeight()));
    236         }
    237         view.setVideoVisibility(video.isVisible());
    238 
    239         MediaAction action = video.getCurrentAction();
    240         if (action == MediaAction.START) {
    241             view.startVideo();
    242         } else if (action == MediaAction.PAUSE) {
    243             view.pauseVideo();
    244         } else if (action == MediaAction.STOP) {
    245             view.stopVideo();
    246         } else if (action == MediaAction.SEEK) {
    247             view.seekVideo(video.getSeekTo());
    248         }
    249     }
    250 
    251     public void setLocation(int location) {
    252         mLocation = location;
    253     }
    254 
    255     public int getLocation() {
    256         return mLocation;
    257     }
    258 
    259     public void goBackward() {
    260         if (mLocation > 0) {
    261             mLocation--;
    262         }
    263     }
    264 
    265     public void goForward() {
    266         if (mLocation < (mSlideNumber - 1)) {
    267             mLocation++;
    268         }
    269     }
    270 
    271     public void onModelChanged(final Model model, final boolean dataChanged) {
    272         final SlideViewInterface view = (SlideViewInterface) mView;
    273 
    274         // FIXME: Should be optimized.
    275         if (model instanceof SlideshowModel) {
    276             // TODO:
    277         } else if (model instanceof SlideModel) {
    278             if (((SlideModel) model).isVisible()) {
    279                 mHandler.post(new Runnable() {
    280                     public void run() {
    281                         presentSlide(view, (SlideModel) model);
    282                     }
    283                 });
    284             } else {
    285                 mHandler.post(new Runnable() {
    286                     public void run() {
    287                         goForward();
    288                     }
    289                 });
    290             }
    291         } else if (model instanceof MediaModel) {
    292             if (model instanceof RegionMediaModel) {
    293                 mHandler.post(new Runnable() {
    294                     public void run() {
    295                         try {
    296                             presentRegionMedia(view, (RegionMediaModel) model, dataChanged);
    297                         } catch (DrmException e) {
    298                             Log.e(TAG, e.getMessage(), e);
    299                             Toast.makeText(mContext,
    300                                     mContext.getString(R.string.insufficient_drm_rights),
    301                                     Toast.LENGTH_SHORT).show();
    302                         }
    303                     }
    304                 });
    305             } else if (((MediaModel) model).isAudio()) {
    306                 mHandler.post(new Runnable() {
    307                     public void run() {
    308                         try {
    309                             presentAudio(view, (AudioModel) model, dataChanged);
    310                         } catch (DrmException e) {
    311                             Log.e(TAG, e.getMessage(), e);
    312                             Toast.makeText(mContext,
    313                                     mContext.getString(R.string.insufficient_drm_rights),
    314                                     Toast.LENGTH_SHORT).show();
    315                         }
    316                     }
    317                 });
    318             }
    319         } else if (model instanceof RegionModel) {
    320             // TODO:
    321         }
    322     }
    323 }
    324