VideoUI.java revision 59390061e26d3d481c6e0c9b22fb3ee8ec8387b0
1/* 2 * Copyright (C) 2012 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 17package com.android.camera; 18 19import android.graphics.Bitmap; 20import android.graphics.Color; 21import android.graphics.Matrix; 22import android.graphics.SurfaceTexture; 23import android.graphics.drawable.ColorDrawable; 24import android.hardware.Camera.Parameters; 25import android.os.Handler; 26import android.os.Message; 27import android.util.Log; 28import android.view.Gravity; 29import android.view.SurfaceHolder; 30import android.view.SurfaceView; 31import android.view.TextureView; 32import android.view.TextureView.SurfaceTextureListener; 33import android.view.View; 34import android.view.View.OnClickListener; 35import android.view.View.OnLayoutChangeListener; 36import android.view.ViewGroup; 37import android.widget.FrameLayout.LayoutParams; 38import android.widget.ImageView; 39import android.widget.LinearLayout; 40import android.widget.PopupWindow; 41import android.widget.TextView; 42 43import com.android.camera.CameraPreference.OnPreferenceChangedListener; 44import com.android.camera.ui.AbstractSettingPopup; 45import com.android.camera.ui.CameraControls; 46import com.android.camera.ui.CameraRootView; 47import com.android.camera.ui.ModuleSwitcher; 48import com.android.camera.ui.PieRenderer; 49import com.android.camera.ui.RenderOverlay; 50import com.android.camera.ui.RotateLayout; 51import com.android.camera.ui.ZoomRenderer; 52import com.android.camera.util.CameraUtil; 53import com.android.camera2.R; 54 55import java.util.List; 56 57public class VideoUI implements PieRenderer.PieListener, 58 PreviewGestures.SingleTapListener, 59 CameraRootView.MyDisplayListener, 60 SurfaceTextureListener, SurfaceHolder.Callback { 61 private static final String TAG = "CAM_VideoUI"; 62 private static final int UPDATE_TRANSFORM_MATRIX = 1; 63 // module fields 64 private CameraActivity mActivity; 65 private View mRootView; 66 private TextureView mTextureView; 67 // An review image having same size as preview. It is displayed when 68 // recording is stopped in capture intent. 69 private ImageView mReviewImage; 70 private View mReviewCancelButton; 71 private View mReviewDoneButton; 72 private View mReviewPlayButton; 73 private ShutterButton mShutterButton; 74 private ModuleSwitcher mSwitcher; 75 private TextView mRecordingTimeView; 76 private LinearLayout mLabelsLinearLayout; 77 private View mTimeLapseLabel; 78 private RenderOverlay mRenderOverlay; 79 private PieRenderer mPieRenderer; 80 private VideoMenu mVideoMenu; 81 private CameraControls mCameraControls; 82 private SettingsPopup mPopup; 83 private ZoomRenderer mZoomRenderer; 84 private PreviewGestures mGestures; 85 private View mMenuButton; 86 private OnScreenIndicators mOnScreenIndicators; 87 private RotateLayout mRecordingTimeRect; 88 private boolean mRecordingStarted = false; 89 private SurfaceTexture mSurfaceTexture; 90 private VideoController mController; 91 private int mZoomMax; 92 private List<Integer> mZoomRatios; 93 private View mPreviewThumb; 94 private View mFlashOverlay; 95 96 private SurfaceView mSurfaceView = null; 97 private int mPreviewWidth = 0; 98 private int mPreviewHeight = 0; 99 private float mSurfaceTextureUncroppedWidth; 100 private float mSurfaceTextureUncroppedHeight; 101 private float mAspectRatio = 4f / 3f; 102 private Matrix mMatrix = null; 103 private final AnimationManager mAnimationManager; 104 private final Handler mHandler = new Handler() { 105 @Override 106 public void handleMessage(Message msg) { 107 switch (msg.what) { 108 case UPDATE_TRANSFORM_MATRIX: 109 setTransformMatrix(mPreviewWidth, mPreviewHeight); 110 break; 111 default: 112 break; 113 } 114 } 115 }; 116 private OnLayoutChangeListener mLayoutListener = new OnLayoutChangeListener() { 117 @Override 118 public void onLayoutChange(View v, int left, int top, int right, 119 int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { 120 int width = right - left; 121 int height = bottom - top; 122 // Full-screen screennail 123 int w = width; 124 int h = height; 125 if (CameraUtil.getDisplayRotation(mActivity) % 180 != 0) { 126 w = height; 127 h = width; 128 } 129 if (mPreviewWidth != width || mPreviewHeight != height) { 130 mPreviewWidth = width; 131 mPreviewHeight = height; 132 onScreenSizeChanged(width, height, w, h); 133 } 134 } 135 }; 136 137 private class SettingsPopup extends PopupWindow { 138 public SettingsPopup(View popup) { 139 super(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 140 setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); 141 setOutsideTouchable(true); 142 setFocusable(true); 143 popup.setVisibility(View.VISIBLE); 144 setContentView(popup); 145 showAtLocation(mRootView, Gravity.CENTER, 0, 0); 146 } 147 148 public void dismiss(boolean topLevelOnly) { 149 super.dismiss(); 150 popupDismissed(); 151 showUI(); 152 mVideoMenu.popupDismissed(topLevelOnly); 153 } 154 155 @Override 156 public void dismiss() { 157 // Called by Framework when touch outside the popup or hit back key 158 dismiss(true); 159 } 160 } 161 162 public VideoUI(CameraActivity activity, VideoController controller, View parent) { 163 mActivity = activity; 164 mController = controller; 165 mRootView = parent; 166 mActivity.getLayoutInflater().inflate(R.layout.video_module, (ViewGroup) mRootView, true); 167 mTextureView = (TextureView) mRootView.findViewById(R.id.preview_content); 168 mTextureView.setSurfaceTextureListener(this); 169 mTextureView.addOnLayoutChangeListener(mLayoutListener); 170 mFlashOverlay = mRootView.findViewById(R.id.flash_overlay); 171 mShutterButton = (ShutterButton) mRootView.findViewById(R.id.shutter_button); 172 mSwitcher = (ModuleSwitcher) mRootView.findViewById(R.id.camera_switcher); 173 mSwitcher.setCurrentIndex(ModuleSwitcher.VIDEO_MODULE_INDEX); 174 mSwitcher.setSwitchListener(mActivity); 175 initializeMiscControls(); 176 initializeControlByIntent(); 177 initializeOverlay(); 178 mAnimationManager = new AnimationManager(); 179 } 180 181 182 public void initializeSurfaceView() { 183 mSurfaceView = new SurfaceView(mActivity); 184 ((ViewGroup) mRootView).addView(mSurfaceView, 0); 185 mSurfaceView.getHolder().addCallback(this); 186 } 187 188 private void initializeControlByIntent() { 189 mMenuButton = mRootView.findViewById(R.id.menu); 190 mMenuButton.setOnClickListener(new OnClickListener() { 191 @Override 192 public void onClick(View v) { 193 if (mPieRenderer != null) { 194 mPieRenderer.showInCenter(); 195 } 196 } 197 }); 198 199 mCameraControls = (CameraControls) mRootView.findViewById(R.id.camera_controls); 200 mOnScreenIndicators = new OnScreenIndicators(mActivity, 201 mRootView.findViewById(R.id.on_screen_indicators)); 202 mOnScreenIndicators.resetToDefault(); 203 if (mController.isVideoCaptureIntent()) { 204 hideSwitcher(); 205 mActivity.getLayoutInflater().inflate(R.layout.review_module_control, 206 (ViewGroup) mCameraControls); 207 // Cannot use RotateImageView for "done" and "cancel" button because 208 // the tablet layout uses RotateLayout, which cannot be cast to 209 // RotateImageView. 210 mReviewDoneButton = mRootView.findViewById(R.id.btn_done); 211 mReviewCancelButton = mRootView.findViewById(R.id.btn_cancel); 212 mReviewPlayButton = mRootView.findViewById(R.id.btn_play); 213 mReviewCancelButton.setVisibility(View.VISIBLE); 214 mReviewDoneButton.setOnClickListener(new OnClickListener() { 215 @Override 216 public void onClick(View v) { 217 mController.onReviewDoneClicked(v); 218 } 219 }); 220 mReviewCancelButton.setOnClickListener(new OnClickListener() { 221 @Override 222 public void onClick(View v) { 223 mController.onReviewCancelClicked(v); 224 } 225 }); 226 mReviewPlayButton.setOnClickListener(new OnClickListener() { 227 @Override 228 public void onClick(View v) { 229 mController.onReviewPlayClicked(v); 230 } 231 }); 232 } 233 } 234 235 public void setPreviewSize(int width, int height) { 236 if (width == 0 || height == 0) { 237 Log.w(TAG, "Preview size should not be 0."); 238 return; 239 } 240 if (width > height) { 241 mAspectRatio = (float) width / height; 242 } else { 243 mAspectRatio = (float) height / width; 244 } 245 mHandler.sendEmptyMessage(UPDATE_TRANSFORM_MATRIX); 246 } 247 248 public int getPreviewWidth() { 249 return mPreviewWidth; 250 } 251 252 public int getPreviewHeight() { 253 return mPreviewHeight; 254 } 255 256 public void onScreenSizeChanged(int width, int height, int previewWidth, int previewHeight) { 257 setTransformMatrix(width, height); 258 } 259 260 private void setTransformMatrix(int width, int height) { 261 mMatrix = mTextureView.getTransform(mMatrix); 262 int orientation = CameraUtil.getDisplayRotation(mActivity); 263 float scaleX = 1f, scaleY = 1f; 264 float scaledTextureWidth, scaledTextureHeight; 265 if (width > height) { 266 scaledTextureWidth = Math.max(width, 267 (int) (height * mAspectRatio)); 268 scaledTextureHeight = Math.max(height, 269 (int)(width / mAspectRatio)); 270 } else { 271 scaledTextureWidth = Math.max(width, 272 (int) (height / mAspectRatio)); 273 scaledTextureHeight = Math.max(height, 274 (int) (width * mAspectRatio)); 275 } 276 277 if (mSurfaceTextureUncroppedWidth != scaledTextureWidth || 278 mSurfaceTextureUncroppedHeight != scaledTextureHeight) { 279 mSurfaceTextureUncroppedWidth = scaledTextureWidth; 280 mSurfaceTextureUncroppedHeight = scaledTextureHeight; 281 } 282 scaleX = scaledTextureWidth / width; 283 scaleY = scaledTextureHeight / height; 284 mMatrix.setScale(scaleX, scaleY, (float) width / 2, (float) height / 2); 285 mTextureView.setTransform(mMatrix); 286 287 if (mSurfaceView != null && mSurfaceView.getVisibility() == View.VISIBLE) { 288 LayoutParams lp = (LayoutParams) mSurfaceView.getLayoutParams(); 289 lp.width = (int) mSurfaceTextureUncroppedWidth; 290 lp.height = (int) mSurfaceTextureUncroppedHeight; 291 lp.gravity = Gravity.CENTER; 292 mSurfaceView.requestLayout(); 293 } 294 } 295 296 /** 297 * Starts a flash animation 298 */ 299 public void animateFlash() { 300 mAnimationManager.startFlashAnimation(mFlashOverlay); 301 } 302 303 /** 304 * Starts a capture animation 305 */ 306 public void animateCapture() { 307 Bitmap bitmap = null; 308 if (mTextureView != null) { 309 bitmap = mTextureView.getBitmap((int) mSurfaceTextureUncroppedWidth / 2, 310 (int) mSurfaceTextureUncroppedHeight / 2); 311 } 312 animateCapture(bitmap); 313 } 314 315 /** 316 * Starts a capture animation 317 * @param bitmap the captured image that we shrink and slide in the animation 318 */ 319 public void animateCapture(Bitmap bitmap) { 320 if (bitmap == null) { 321 Log.e(TAG, "No valid bitmap for capture animation."); 322 return; 323 } 324 ((ImageView) mPreviewThumb).setImageBitmap(bitmap); 325 mAnimationManager.startCaptureAnimation(mPreviewThumb); 326 } 327 328 /** 329 * Cancels on-going animations 330 */ 331 public void cancelAnimations() { 332 mAnimationManager.cancelAnimations(); 333 } 334 335 public void hideUI() { 336 mCameraControls.setVisibility(View.INVISIBLE); 337 mSwitcher.closePopup(); 338 } 339 340 public void showUI() { 341 mCameraControls.setVisibility(View.VISIBLE); 342 } 343 344 public void hideSwitcher() { 345 mSwitcher.closePopup(); 346 mSwitcher.setVisibility(View.INVISIBLE); 347 } 348 349 public void showSwitcher() { 350 mSwitcher.setVisibility(View.VISIBLE); 351 } 352 353 public boolean collapseCameraControls() { 354 boolean ret = false; 355 if (mPopup != null) { 356 dismissPopup(false); 357 ret = true; 358 } 359 return ret; 360 } 361 362 public boolean removeTopLevelPopup() { 363 if (mPopup != null) { 364 dismissPopup(true); 365 return true; 366 } 367 return false; 368 } 369 370 public void enableCameraControls(boolean enable) { 371 if (mGestures != null) { 372 mGestures.setZoomOnly(!enable); 373 } 374 if (mPieRenderer != null && mPieRenderer.showsItems()) { 375 mPieRenderer.hide(); 376 } 377 } 378 379 public void initDisplayChangeListener() { 380 ((CameraRootView) mRootView).setDisplayChangeListener(this); 381 } 382 383 public void removeDisplayChangeListener() { 384 ((CameraRootView) mRootView).removeDisplayChangeListener(); 385 } 386 387 public void overrideSettings(final String... keyvalues) { 388 mVideoMenu.overrideSettings(keyvalues); 389 } 390 391 public void setOrientationIndicator(int orientation, boolean animation) { 392 // We change the orientation of the linearlayout only for phone UI 393 // because when in portrait the width is not enough. 394 if (mLabelsLinearLayout != null) { 395 if (((orientation / 90) & 1) == 0) { 396 mLabelsLinearLayout.setOrientation(LinearLayout.VERTICAL); 397 } else { 398 mLabelsLinearLayout.setOrientation(LinearLayout.HORIZONTAL); 399 } 400 } 401 mRecordingTimeRect.setOrientation(0, animation); 402 } 403 404 public SurfaceHolder getSurfaceHolder() { 405 return mSurfaceView.getHolder(); 406 } 407 408 public void hideSurfaceView() { 409 mSurfaceView.setVisibility(View.GONE); 410 mTextureView.setVisibility(View.VISIBLE); 411 setTransformMatrix(mPreviewWidth, mPreviewHeight); 412 } 413 414 public void showSurfaceView() { 415 mSurfaceView.setVisibility(View.VISIBLE); 416 mTextureView.setVisibility(View.GONE); 417 setTransformMatrix(mPreviewWidth, mPreviewHeight); 418 } 419 420 private void initializeOverlay() { 421 mRenderOverlay = (RenderOverlay) mRootView.findViewById(R.id.render_overlay); 422 if (mPieRenderer == null) { 423 mPieRenderer = new PieRenderer(mActivity); 424 mVideoMenu = new VideoMenu(mActivity, this, mPieRenderer); 425 mPieRenderer.setPieListener(this); 426 } 427 mRenderOverlay.addRenderer(mPieRenderer); 428 if (mZoomRenderer == null) { 429 mZoomRenderer = new ZoomRenderer(mActivity); 430 } 431 mRenderOverlay.addRenderer(mZoomRenderer); 432 if (mGestures == null) { 433 mGestures = new PreviewGestures(mActivity, this, mZoomRenderer, mPieRenderer); 434 mRenderOverlay.setGestures(mGestures); 435 } 436 mGestures.setRenderOverlay(mRenderOverlay); 437 438 mPreviewThumb = mRootView.findViewById(R.id.preview_thumb); 439 mPreviewThumb.setOnClickListener(new OnClickListener() { 440 @Override 441 public void onClick(View v) { 442 // Do not allow navigation to filmstrip during video recording 443 if (!mRecordingStarted) { 444 mActivity.gotoGallery(); 445 } 446 } 447 }); 448 } 449 450 public void setPrefChangedListener(OnPreferenceChangedListener listener) { 451 mVideoMenu.setListener(listener); 452 } 453 454 private void initializeMiscControls() { 455 mReviewImage = (ImageView) mRootView.findViewById(R.id.review_image); 456 mShutterButton.setImageResource(R.drawable.btn_new_shutter_video); 457 mShutterButton.setOnShutterButtonListener(mController); 458 mShutterButton.setVisibility(View.VISIBLE); 459 mShutterButton.requestFocus(); 460 mShutterButton.enableTouch(true); 461 mRecordingTimeView = (TextView) mRootView.findViewById(R.id.recording_time); 462 mRecordingTimeRect = (RotateLayout) mRootView.findViewById(R.id.recording_time_rect); 463 mTimeLapseLabel = mRootView.findViewById(R.id.time_lapse_label); 464 // The R.id.labels can only be found in phone layout. 465 // That is, mLabelsLinearLayout should be null in tablet layout. 466 mLabelsLinearLayout = (LinearLayout) mRootView.findViewById(R.id.labels); 467 } 468 469 public void updateOnScreenIndicators(Parameters param, ComboPreferences prefs) { 470 mOnScreenIndicators.updateFlashOnScreenIndicator(param.getFlashMode()); 471 boolean location = RecordLocationPreference.get( 472 prefs, mActivity.getContentResolver()); 473 mOnScreenIndicators.updateLocationIndicator(location); 474 475 } 476 477 public void setAspectRatio(double ratio) { 478 // mPreviewFrameLayout.setAspectRatio(ratio); 479 } 480 481 public void showTimeLapseUI(boolean enable) { 482 if (mTimeLapseLabel != null) { 483 mTimeLapseLabel.setVisibility(enable ? View.VISIBLE : View.GONE); 484 } 485 } 486 487 private void openMenu() { 488 if (mPieRenderer != null) { 489 mPieRenderer.showInCenter(); 490 } 491 } 492 493 public void dismissPopup(boolean topLevelOnly) { 494 // In review mode, we do not want to bring up the camera UI 495 if (mController.isInReviewMode()) return; 496 if (mPopup != null) { 497 mPopup.dismiss(topLevelOnly); 498 } 499 } 500 501 private void popupDismissed() { 502 mPopup = null; 503 } 504 505 public void showPopup(AbstractSettingPopup popup) { 506 hideUI(); 507 508 if (mPopup != null) { 509 mPopup.dismiss(false); 510 } 511 mPopup = new SettingsPopup(popup); 512 } 513 514 public void onShowSwitcherPopup() { 515 hidePieRenderer(); 516 } 517 518 public boolean hidePieRenderer() { 519 if (mPieRenderer != null && mPieRenderer.showsItems()) { 520 mPieRenderer.hide(); 521 return true; 522 } 523 return false; 524 } 525 526 // disable preview gestures after shutter is pressed 527 public void setShutterPressed(boolean pressed) { 528 if (mGestures == null) return; 529 mGestures.setEnabled(!pressed); 530 } 531 532 public void enableShutter(boolean enable) { 533 if (mShutterButton != null) { 534 mShutterButton.setEnabled(enable); 535 } 536 } 537 538 // PieListener 539 @Override 540 public void onPieOpened(int centerX, int centerY) { 541 setSwipingEnabled(false); 542 } 543 544 @Override 545 public void onPieClosed() { 546 setSwipingEnabled(true); 547 } 548 549 public void setSwipingEnabled(boolean enable) { 550 mActivity.setSwipingEnabled(enable); 551 } 552 553 public void showPreviewBorder(boolean enable) { 554 // TODO: mPreviewFrameLayout.showBorder(enable); 555 } 556 557 // SingleTapListener 558 // Preview area is touched. Take a picture. 559 @Override 560 public void onSingleTapUp(View view, int x, int y) { 561 mController.onSingleTapUp(view, x, y); 562 } 563 564 public void showRecordingUI(boolean recording) { 565 mRecordingStarted = recording; 566 mMenuButton.setVisibility(recording ? View.GONE : View.VISIBLE); 567 mOnScreenIndicators.setVisibility(recording ? View.GONE : View.VISIBLE); 568 if (recording) { 569 mShutterButton.setImageResource(R.drawable.btn_shutter_video_recording); 570 hideSwitcher(); 571 mRecordingTimeView.setText(""); 572 mRecordingTimeView.setVisibility(View.VISIBLE); 573 } else { 574 mShutterButton.setImageResource(R.drawable.btn_new_shutter_video); 575 if (!mController.isVideoCaptureIntent()) { 576 showSwitcher(); 577 } 578 mRecordingTimeView.setVisibility(View.GONE); 579 } 580 } 581 582 public void showReviewImage(Bitmap bitmap) { 583 mReviewImage.setImageBitmap(bitmap); 584 mReviewImage.setVisibility(View.VISIBLE); 585 } 586 587 public void showReviewControls() { 588 CameraUtil.fadeOut(mShutterButton); 589 CameraUtil.fadeIn(mReviewDoneButton); 590 CameraUtil.fadeIn(mReviewPlayButton); 591 mReviewImage.setVisibility(View.VISIBLE); 592 mMenuButton.setVisibility(View.GONE); 593 mOnScreenIndicators.setVisibility(View.GONE); 594 } 595 596 public void hideReviewUI() { 597 mReviewImage.setVisibility(View.GONE); 598 mShutterButton.setEnabled(true); 599 mMenuButton.setVisibility(View.VISIBLE); 600 mOnScreenIndicators.setVisibility(View.VISIBLE); 601 CameraUtil.fadeOut(mReviewDoneButton); 602 CameraUtil.fadeOut(mReviewPlayButton); 603 CameraUtil.fadeIn(mShutterButton); 604 } 605 606 private void setShowMenu(boolean show) { 607 if (mOnScreenIndicators != null) { 608 mOnScreenIndicators.setVisibility(show ? View.VISIBLE : View.GONE); 609 } 610 if (mMenuButton != null) { 611 mMenuButton.setVisibility(show ? View.VISIBLE : View.GONE); 612 } 613 } 614 615 public void onPreviewFocusChanged(boolean previewFocused) { 616 if (previewFocused) { 617 showUI(); 618 } else { 619 hideUI(); 620 } 621 if (mGestures != null) { 622 mGestures.setEnabled(previewFocused); 623 } 624 if (mRenderOverlay != null) { 625 // this can not happen in capture mode 626 mRenderOverlay.setVisibility(previewFocused ? View.VISIBLE : View.GONE); 627 } 628 setShowMenu(previewFocused); 629 } 630 631 public void initializePopup(PreferenceGroup pref) { 632 mVideoMenu.initialize(pref); 633 } 634 635 public void initializeZoom(Parameters param) { 636 if (param == null || !param.isZoomSupported()) { 637 mGestures.setZoomEnabled(false); 638 return; 639 } 640 mGestures.setZoomEnabled(true); 641 mZoomMax = param.getMaxZoom(); 642 mZoomRatios = param.getZoomRatios(); 643 // Currently we use immediate zoom for fast zooming to get better UX and 644 // there is no plan to take advantage of the smooth zoom. 645 mZoomRenderer.setZoomMax(mZoomMax); 646 mZoomRenderer.setZoom(param.getZoom()); 647 mZoomRenderer.setZoomValue(mZoomRatios.get(param.getZoom())); 648 mZoomRenderer.setOnZoomChangeListener(new ZoomChangeListener()); 649 } 650 651 public void clickShutter() { 652 mShutterButton.performClick(); 653 } 654 655 public void pressShutter(boolean pressed) { 656 mShutterButton.setPressed(pressed); 657 } 658 659 public View getShutterButton() { 660 return mShutterButton; 661 } 662 663 public void setRecordingTime(String text) { 664 mRecordingTimeView.setText(text); 665 } 666 667 public void setRecordingTimeTextColor(int color) { 668 mRecordingTimeView.setTextColor(color); 669 } 670 671 public boolean isVisible() { 672 return mCameraControls.getVisibility() == View.VISIBLE; 673 } 674 675 @Override 676 public void onDisplayChanged() { 677 mCameraControls.checkLayoutFlip(); 678 mController.updateCameraOrientation(); 679 } 680 681 private class ZoomChangeListener implements ZoomRenderer.OnZoomChangedListener { 682 @Override 683 public void onZoomValueChanged(int index) { 684 int newZoom = mController.onZoomChanged(index); 685 if (mZoomRenderer != null) { 686 mZoomRenderer.setZoomValue(mZoomRatios.get(newZoom)); 687 } 688 } 689 690 @Override 691 public void onZoomStart() { 692 } 693 694 @Override 695 public void onZoomEnd() { 696 } 697 } 698 699 public SurfaceTexture getSurfaceTexture() { 700 return mSurfaceTexture; 701 } 702 703 // SurfaceTexture callbacks 704 @Override 705 public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 706 mSurfaceTexture = surface; 707 mController.onPreviewUIReady(); 708 } 709 710 @Override 711 public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 712 mSurfaceTexture = null; 713 mController.onPreviewUIDestroyed(); 714 Log.d(TAG, "surfaceTexture is destroyed"); 715 return true; 716 } 717 718 @Override 719 public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 720 } 721 722 @Override 723 public void onSurfaceTextureUpdated(SurfaceTexture surface) { 724 } 725 726 // SurfaceHolder callbacks 727 @Override 728 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 729 Log.v(TAG, "Surface changed. width=" + width + ". height=" + height); 730 } 731 732 @Override 733 public void surfaceCreated(SurfaceHolder holder) { 734 Log.v(TAG, "Surface created"); 735 } 736 737 @Override 738 public void surfaceDestroyed(SurfaceHolder holder) { 739 Log.v(TAG, "Surface destroyed"); 740 mController.stopPreview(); 741 } 742} 743