1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.camera.captureintent; 18 19 import com.android.camera.app.CameraAppUI; 20 import com.android.camera.async.MainThread; 21 import com.android.camera.hardware.HardwareSpec; 22 import com.android.camera.ui.CountDownView; 23 import com.android.camera.ui.PreviewOverlay; 24 import com.android.camera.ui.PreviewStatusListener; 25 import com.android.camera.ui.ProgressOverlay; 26 import com.android.camera.ui.focus.FocusRing; 27 import com.android.camera.util.AndroidServices; 28 import com.android.camera.util.Size; 29 import com.android.camera2.R; 30 31 import android.graphics.Bitmap; 32 import android.graphics.Matrix; 33 import android.graphics.RectF; 34 import android.view.LayoutInflater; 35 import android.view.View; 36 import android.view.ViewGroup; 37 import android.widget.FrameLayout; 38 import android.widget.ImageView; 39 40 /** 41 * Contains the UI for the ImageCaptureIntentModule. 42 */ 43 public class CaptureIntentModuleUI { 44 public interface Listener { onZoomRatioChanged(float zoomRatio)45 public void onZoomRatioChanged(float zoomRatio); 46 } 47 private final Listener mListener; 48 49 private final CameraAppUI mAppUI; 50 private final View mRootView; 51 private final PreviewOverlay mPreviewOverlay; 52 private final ProgressOverlay mProgressOverlay; 53 private final FocusRing mFocusRing; 54 private final CountDownView mCountdownView; 55 56 /** The image view to display the captured picture. */ 57 private final ImageView mIntentReviewImageView; 58 59 /** The layout rect of the preview. */ 60 private RectF mPreviewRect; 61 62 private final PreviewStatusListener.PreviewAreaChangedListener mPreviewAreaChangedListener = 63 new PreviewStatusListener.PreviewAreaChangedListener() { 64 @Override 65 public void onPreviewAreaChanged(RectF previewArea) { 66 mPreviewRect = previewArea; 67 mCountdownView.onPreviewAreaChanged(previewArea); 68 mProgressOverlay.setBounds(previewArea); 69 FrameLayout.LayoutParams params = 70 (FrameLayout.LayoutParams) mIntentReviewImageView.getLayoutParams(); 71 72 /** 73 * WAR for b/19676505: On Nexus 6 / 16:9 / portrait, for 74 * some reasons the previewArea width is 1345.499999999.... 75 * Use Math.ceil here to make the width 1346. 76 */ 77 params.width = (int) Math.ceil((double) previewArea.width()); 78 79 params.height = Math.round(previewArea.height()); 80 params.setMargins( 81 Math.round(previewArea.left), Math.round(previewArea.top), 0, 0); 82 mIntentReviewImageView.setLayoutParams(params); 83 } 84 }; 85 CaptureIntentModuleUI( CameraAppUI appUI, View parent, Listener listener)86 public CaptureIntentModuleUI( 87 CameraAppUI appUI, View parent, Listener listener) { 88 89 mAppUI = appUI; 90 mListener = listener; 91 mRootView = parent; 92 93 mIntentReviewImageView = (ImageView) mRootView.findViewById(R.id.intent_review_imageview); 94 95 final LayoutInflater layoutInflater = AndroidServices.instance().provideLayoutInflater(); 96 97 ViewGroup moduleRoot = (ViewGroup) mRootView.findViewById(R.id.module_layout); 98 layoutInflater.inflate(R.layout.capture_module, moduleRoot, true); 99 100 mPreviewOverlay = (PreviewOverlay) mRootView.findViewById(R.id.preview_overlay); 101 mProgressOverlay = (ProgressOverlay) mRootView.findViewById(R.id.progress_overlay); 102 mFocusRing = (FocusRing) mRootView.findViewById(R.id.focus_ring); 103 mCountdownView = (CountDownView) mRootView.findViewById(R.id.count_down_view); 104 105 mPreviewRect = new RectF(0, 0, 0, 0); 106 } 107 108 /** 109 * Obtains the current preview layout rect. 110 */ getPreviewRect()111 public RectF getPreviewRect() { 112 return mPreviewRect; 113 } 114 115 /** 116 * Obtains the current preview layout size. 117 */ getPreviewSurfaceSize()118 public Size getPreviewSurfaceSize() { 119 return new Size(mAppUI.getSurfaceWidth(), mAppUI.getSurfaceHeight()); 120 } 121 122 /** 123 * Configures the bottom bar UI. 124 * 125 * @param hardwareSpec The hardware spec. 126 * @param bottomBarSpec The bottom bar spec. 127 */ applyModuleSpecs( HardwareSpec hardwareSpec, CameraAppUI.BottomBarUISpec bottomBarSpec)128 public void applyModuleSpecs( 129 HardwareSpec hardwareSpec, 130 CameraAppUI.BottomBarUISpec bottomBarSpec) { 131 MainThread.checkMainThread(); 132 mAppUI.applyModuleSpecs(hardwareSpec, bottomBarSpec); 133 } 134 135 /** 136 * Called when the module got resumed. 137 */ onModuleResumed()138 public void onModuleResumed() { 139 MainThread.checkMainThread(); 140 // Listen to preview layout change event. Adjust review image view 141 // layout to match preview layout. 142 // 143 // Doing this here rather than in ctor is because TextureViewHelper 144 // doesn't exist until the module got initialized. 145 mAppUI.addPreviewAreaChangedListener(mPreviewAreaChangedListener); 146 } 147 148 /** 149 * Called when the module got paused. 150 */ onModulePaused()151 public void onModulePaused() { 152 MainThread.checkMainThread(); 153 mAppUI.removePreviewAreaChangedListener(mPreviewAreaChangedListener); 154 } 155 156 /** 157 * Update preview transform matrix. 158 * 159 * @param matrix The preview transform matrix. 160 */ updatePreviewTransform(Matrix matrix)161 public void updatePreviewTransform(Matrix matrix) { 162 MainThread.checkMainThread(); 163 mAppUI.updatePreviewTransform(matrix); 164 } 165 166 /** 167 * Update preview aspect ratio. 168 * 169 * This is useful only when TextureViewHelper auto transform is enabled. 170 * 171 * @param aspectRatio The preview aspect ratio. 172 */ updatePreviewAspectRatio(float aspectRatio)173 public void updatePreviewAspectRatio(float aspectRatio) { 174 MainThread.checkMainThread(); 175 mAppUI.updatePreviewAspectRatio(aspectRatio); 176 } 177 178 /** 179 * Called when the preview is started. 180 */ onPreviewStarted()181 public void onPreviewStarted() { 182 MainThread.checkMainThread(); 183 mAppUI.onPreviewStarted(); 184 } 185 186 /** 187 * Enables zoom UI, setting maximum zoom. 188 * Called from Module when camera is available. 189 * 190 * @param maxZoom maximum zoom value. 191 */ initializeZoom(float maxZoom)192 public void initializeZoom(float maxZoom) { 193 MainThread.checkMainThread(); 194 mPreviewOverlay.setupZoom(maxZoom, 0, mZoomChancedListener); 195 } 196 getFocusRing()197 public FocusRing getFocusRing() { 198 return mFocusRing; 199 } 200 setShutterButtonEnabled(boolean enabled)201 public void setShutterButtonEnabled(boolean enabled) { 202 MainThread.checkMainThread(); 203 mAppUI.setShutterButtonEnabled(enabled); 204 } 205 startFlashAnimation(boolean shortFlash)206 public void startFlashAnimation(boolean shortFlash) { 207 MainThread.checkMainThread(); 208 mAppUI.startFlashAnimation(shortFlash); 209 } 210 211 /** 212 * Starts the countdown timer. 213 * 214 * @param sec seconds to countdown 215 */ startCountdown(int sec)216 public void startCountdown(int sec) { 217 MainThread.checkMainThread(); 218 mAppUI.transitionToCancel(); 219 mCountdownView.startCountDown(sec); 220 } 221 222 /** 223 * Cancels the on-going countdown, if any. 224 */ cancelCountDown()225 public void cancelCountDown() { 226 mCountdownView.cancelCountDown(); 227 } 228 229 /** 230 * Sets a listener that gets notified when the countdown is finished. 231 */ setCountdownFinishedListener(CountDownView.OnCountDownStatusListener listener)232 public void setCountdownFinishedListener(CountDownView.OnCountDownStatusListener listener) { 233 mCountdownView.setCountDownStatusListener(listener); 234 } 235 236 /** 237 * Transition to the UI where users can review the taken photo. 238 * 239 * @param reviewPictureBitmap The picture bitmap to be shown. 240 */ showPictureReviewUI(Bitmap reviewPictureBitmap)241 public void showPictureReviewUI(Bitmap reviewPictureBitmap) { 242 MainThread.checkMainThread(); 243 244 mIntentReviewImageView.setImageBitmap(reviewPictureBitmap); 245 mIntentReviewImageView.setVisibility(View.VISIBLE); 246 247 mAppUI.transitionToIntentReviewLayout(); 248 mAppUI.hideModeOptions(); 249 mAppUI.disableModeOptions(); 250 mAppUI.setShutterButtonEnabled(false); 251 } 252 253 /** 254 * Transition to the UI where users can take a photo. 255 */ showPictureCaptureUI()256 public void showPictureCaptureUI() { 257 MainThread.checkMainThread(); 258 259 mIntentReviewImageView.setVisibility(View.INVISIBLE); 260 mIntentReviewImageView.setImageBitmap(null); 261 262 mAppUI.transitionToIntentCaptureLayout(); 263 mAppUI.syncModeOptionIndicators(); 264 mAppUI.enableModeOptions(); 265 mAppUI.showModeOptions(); 266 mAppUI.setShutterButtonEnabled(true); 267 mAppUI.setShouldSuppressCaptureIndicator(true); 268 } 269 freezeScreenUntilPreviewReady()270 public void freezeScreenUntilPreviewReady() { 271 MainThread.checkMainThread(); 272 mAppUI.freezeScreenUntilPreviewReady(); 273 } 274 275 /** Set up listener to receive zoom changes from View and send to module. */ 276 private final PreviewOverlay.OnZoomChangedListener mZoomChancedListener = 277 new PreviewOverlay.OnZoomChangedListener() { 278 @Override 279 public void onZoomValueChanged(float ratio) { 280 mListener.onZoomRatioChanged(ratio); 281 } 282 283 @Override 284 public void onZoomStart() { 285 } 286 287 @Override 288 public void onZoomEnd() { 289 } 290 }; 291 } 292