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 com.android.mms.model.AudioModel; 22 import com.android.mms.model.ImageModel; 23 import com.android.mms.model.LayoutModel; 24 import com.android.mms.model.MediaModel; 25 import com.android.mms.model.Model; 26 import com.android.mms.model.RegionMediaModel; 27 import com.android.mms.model.RegionModel; 28 import com.android.mms.model.SlideModel; 29 import com.android.mms.model.SlideshowModel; 30 import com.android.mms.model.TextModel; 31 import com.android.mms.model.VideoModel; 32 import com.android.mms.model.MediaModel.MediaAction; 33 import com.android.mms.ui.AdaptableSlideViewInterface.OnSizeChangedListener; 34 35 import android.content.Context; 36 import android.drm.mobile1.DrmException; 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 SlideshowPresenter(Context context, ViewInterface view, Model model)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 81 if (LOCAL_LOGV) { 82 Log.v(TAG, "ratio_w = " + mWidthTransformRatio 83 + ", ratio_h = " + mHeightTransformRatio); 84 } 85 } 86 }; 87 getWidthTransformRatio(int width, int layoutWidth)88 private float getWidthTransformRatio(int width, int layoutWidth) { 89 if (width > 0) { 90 return (float) layoutWidth / (float) width; 91 } 92 return 1.0f; 93 } 94 getHeightTransformRatio(int height, int layoutHeight)95 private float getHeightTransformRatio(int height, int layoutHeight) { 96 if (height > 0) { 97 return (float) layoutHeight / (float) height; 98 } 99 return 1.0f; 100 } 101 transformWidth(int width)102 private int transformWidth(int width) { 103 return (int) (width / mWidthTransformRatio); 104 } 105 transformHeight(int height)106 private int transformHeight(int height) { 107 return (int) (height / mHeightTransformRatio); 108 } 109 110 @Override present()111 public void present() { 112 presentSlide((SlideViewInterface) mView, ((SlideshowModel) mModel).get(mLocation)); 113 } 114 115 /** 116 * @param view 117 * @param model 118 */ presentSlide(SlideViewInterface view, SlideModel model)119 protected void presentSlide(SlideViewInterface view, SlideModel model) { 120 view.reset(); 121 122 try { 123 for (MediaModel media : model) { 124 if (media instanceof RegionMediaModel) { 125 presentRegionMedia(view, (RegionMediaModel) media, true); 126 } else if (media.isAudio()) { 127 presentAudio(view, (AudioModel) media, true); 128 } 129 } 130 } catch (DrmException e) { 131 Log.e(TAG, e.getMessage(), e); 132 Toast.makeText(mContext, 133 mContext.getString(R.string.insufficient_drm_rights), 134 Toast.LENGTH_SHORT).show(); 135 } 136 } 137 138 /** 139 * @param view 140 * @throws DrmException 141 */ presentRegionMedia(SlideViewInterface view, RegionMediaModel rMedia, boolean dataChanged)142 protected void presentRegionMedia(SlideViewInterface view, 143 RegionMediaModel rMedia, boolean dataChanged) 144 throws DrmException { 145 RegionModel r = (rMedia).getRegion(); 146 if (rMedia.isText()) { 147 presentText(view, (TextModel) rMedia, r, dataChanged); 148 } else if (rMedia.isImage()) { 149 presentImage(view, (ImageModel) rMedia, r, dataChanged); 150 } else if (rMedia.isVideo()) { 151 presentVideo(view, (VideoModel) rMedia, r, dataChanged); 152 } 153 } 154 presentAudio(SlideViewInterface view, AudioModel audio, boolean dataChanged)155 protected void presentAudio(SlideViewInterface view, AudioModel audio, 156 boolean dataChanged) throws DrmException { 157 // Set audio only when data changed. 158 if (dataChanged) { 159 view.setAudio(audio.getUriWithDrmCheck(), audio.getSrc(), audio.getExtras()); 160 } 161 162 MediaAction action = audio.getCurrentAction(); 163 if (action == MediaAction.START) { 164 view.startAudio(); 165 } else if (action == MediaAction.PAUSE) { 166 view.pauseAudio(); 167 } else if (action == MediaAction.STOP) { 168 view.stopAudio(); 169 } else if (action == MediaAction.SEEK) { 170 view.seekAudio(audio.getSeekTo()); 171 } 172 } 173 presentText(SlideViewInterface view, TextModel text, RegionModel r, boolean dataChanged)174 protected void presentText(SlideViewInterface view, TextModel text, 175 RegionModel r, boolean dataChanged) { 176 if (dataChanged) { 177 view.setText(text.getSrc(), text.getText()); 178 } 179 180 if (view instanceof AdaptableSlideViewInterface) { 181 ((AdaptableSlideViewInterface) view).setTextRegion( 182 transformWidth(r.getLeft()), 183 transformHeight(r.getTop()), 184 transformWidth(r.getWidth()), 185 transformHeight(r.getHeight())); 186 } 187 view.setTextVisibility(text.isVisible()); 188 } 189 190 /** 191 * @param view 192 * @param image 193 * @param r 194 * @throws DrmException 195 */ presentImage(SlideViewInterface view, ImageModel image, RegionModel r, boolean dataChanged)196 protected void presentImage(SlideViewInterface view, ImageModel image, 197 RegionModel r, boolean dataChanged) throws DrmException { 198 if (dataChanged) { 199 view.setImage(image.getSrc(), image.getBitmapWithDrmCheck()); 200 } 201 202 if (view instanceof AdaptableSlideViewInterface) { 203 ((AdaptableSlideViewInterface) view).setImageRegion( 204 transformWidth(r.getLeft()), 205 transformHeight(r.getTop()), 206 transformWidth(r.getWidth()), 207 transformHeight(r.getHeight())); 208 } 209 view.setImageRegionFit(r.getFit()); 210 view.setImageVisibility(image.isVisible()); 211 } 212 213 /** 214 * @param view 215 * @param video 216 * @param r 217 * @throws DrmException 218 */ presentVideo(SlideViewInterface view, VideoModel video, RegionModel r, boolean dataChanged)219 protected void presentVideo(SlideViewInterface view, VideoModel video, 220 RegionModel r, boolean dataChanged) throws DrmException { 221 if (dataChanged) { 222 view.setVideo(video.getSrc(), video.getUriWithDrmCheck()); 223 } 224 225 if (view instanceof AdaptableSlideViewInterface) { 226 ((AdaptableSlideViewInterface) view).setVideoRegion( 227 transformWidth(r.getLeft()), 228 transformHeight(r.getTop()), 229 transformWidth(r.getWidth()), 230 transformHeight(r.getHeight())); 231 } 232 view.setVideoVisibility(video.isVisible()); 233 234 MediaAction action = video.getCurrentAction(); 235 if (action == MediaAction.START) { 236 view.startVideo(); 237 } else if (action == MediaAction.PAUSE) { 238 view.pauseVideo(); 239 } else if (action == MediaAction.STOP) { 240 view.stopVideo(); 241 } else if (action == MediaAction.SEEK) { 242 view.seekVideo(video.getSeekTo()); 243 } 244 } 245 setLocation(int location)246 public void setLocation(int location) { 247 mLocation = location; 248 } 249 getLocation()250 public int getLocation() { 251 return mLocation; 252 } 253 goBackward()254 public void goBackward() { 255 if (mLocation > 0) { 256 mLocation--; 257 } 258 } 259 goForward()260 public void goForward() { 261 if (mLocation < (mSlideNumber - 1)) { 262 mLocation++; 263 } 264 } 265 onModelChanged(final Model model, final boolean dataChanged)266 public void onModelChanged(final Model model, final boolean dataChanged) { 267 final SlideViewInterface view = (SlideViewInterface) mView; 268 269 // FIXME: Should be optimized. 270 if (model instanceof SlideshowModel) { 271 // TODO: 272 } else if (model instanceof SlideModel) { 273 if (((SlideModel) model).isVisible()) { 274 mHandler.post(new Runnable() { 275 public void run() { 276 presentSlide(view, (SlideModel) model); 277 } 278 }); 279 } else { 280 mHandler.post(new Runnable() { 281 public void run() { 282 goForward(); 283 } 284 }); 285 } 286 } else if (model instanceof MediaModel) { 287 if (model instanceof RegionMediaModel) { 288 mHandler.post(new Runnable() { 289 public void run() { 290 try { 291 presentRegionMedia(view, (RegionMediaModel) model, dataChanged); 292 } catch (DrmException e) { 293 Log.e(TAG, e.getMessage(), e); 294 Toast.makeText(mContext, 295 mContext.getString(R.string.insufficient_drm_rights), 296 Toast.LENGTH_SHORT).show(); 297 } 298 } 299 }); 300 } else if (((MediaModel) model).isAudio()) { 301 mHandler.post(new Runnable() { 302 public void run() { 303 try { 304 presentAudio(view, (AudioModel) model, dataChanged); 305 } catch (DrmException e) { 306 Log.e(TAG, e.getMessage(), e); 307 Toast.makeText(mContext, 308 mContext.getString(R.string.insufficient_drm_rights), 309 Toast.LENGTH_SHORT).show(); 310 } 311 } 312 }); 313 } 314 } else if (model instanceof RegionModel) { 315 // TODO: 316 } 317 } 318 } 319