CameraAppUI.java revision 482de029dc20e0a577388a602985fb31c3200309
1/* 2 * Copyright (C) 2013 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.app; 18 19import android.content.Context; 20import android.graphics.Matrix; 21import android.graphics.SurfaceTexture; 22import android.util.Log; 23import android.view.GestureDetector; 24import android.view.LayoutInflater; 25import android.view.MotionEvent; 26import android.view.TextureView; 27import android.view.View; 28import android.view.ViewConfiguration; 29import android.view.ViewGroup; 30import android.widget.FrameLayout; 31 32import com.android.camera.AnimationManager; 33import com.android.camera.TextureViewHelper; 34import com.android.camera.ShutterButton; 35import com.android.camera.filmstrip.FilmstripContentPanel; 36import com.android.camera.ui.BottomBar; 37import com.android.camera.ui.CaptureAnimationOverlay; 38import com.android.camera.ui.MainActivityLayout; 39import com.android.camera.ui.ModeListView; 40import com.android.camera.ui.ModeTransitionView; 41import com.android.camera.ui.PreviewOverlay; 42import com.android.camera.ui.PreviewStatusListener; 43import com.android.camera.widget.FilmstripLayout; 44import com.android.camera2.R; 45 46/** 47 * CameraAppUI centralizes control of views shared across modules. Whereas module 48 * specific views will be handled in each Module UI. For example, we can now 49 * bring the flash animation and capture animation up from each module to app 50 * level, as these animations are largely the same for all modules. 51 * 52 * This class also serves to disambiguate touch events. It recognizes all the 53 * swipe gestures that happen on the preview by attaching a touch listener to 54 * a full-screen view on top of preview TextureView. Since CameraAppUI has knowledge 55 * of how swipe from each direction should be handled, it can then redirect these 56 * events to appropriate recipient views. 57 */ 58public class CameraAppUI implements ModeListView.ModeSwitchListener, 59 TextureView.SurfaceTextureListener { 60 61 /** 62 * The bottom controls on the filmstrip. 63 */ 64 public static interface BottomControls { 65 /** Values for the view state of the button. */ 66 public final int VIEW_NONE = 0; 67 public final int VIEW_PHOTO_SPHERE = 1; 68 public final int VIEW_RGBZ = 2; 69 70 /** 71 * Sets a new or replaces an existing listener for bottom control events. 72 */ 73 void setListener(Listener listener); 74 75 /** 76 * Set if the bottom controls are visible. 77 * @param visible {@code true} if visible. 78 */ 79 void setVisible(boolean visible); 80 81 /** 82 * @param visible Whether the button is visible. 83 */ 84 void setEditButtonVisibility(boolean visible); 85 86 /** 87 * @param enabled Whether the button is enabled. 88 */ 89 void setEditEnabled(boolean enabled); 90 91 /** 92 * Sets the visibility of the view-photosphere button. 93 * 94 * @param state one of {@link #VIEW_NONE}, {@link #VIEW_PHOTO_SPHERE}, 95 * {@link #VIEW_RGBZ}. 96 */ 97 void setViewButtonVisibility(int state); 98 99 /** 100 * @param enabled Whether the button is enabled. 101 */ 102 void setViewEnabled(boolean enabled); 103 104 /** 105 * @param visible Whether the button is visible. 106 */ 107 void setTinyPlanetButtonVisibility(boolean visible); 108 109 /** 110 * @param enabled Whether the button is enabled. 111 */ 112 void setTinyPlanetEnabled(boolean enabled); 113 114 /** 115 * @param visible Whether the button is visible. 116 */ 117 void setDeleteButtonVisibility(boolean visible); 118 119 /** 120 * @param enabled Whether the button is enabled. 121 */ 122 void setDeleteEnabled(boolean enabled); 123 124 /** 125 * @param visible Whether the button is visible. 126 */ 127 void setShareButtonVisibility(boolean visible); 128 129 /** 130 * @param enabled Whether the button is enabled. 131 */ 132 void setShareEnabled(boolean enabled); 133 134 /** 135 * @param visible Whether the button is visible. 136 */ 137 void setGalleryButtonVisibility(boolean visible); 138 139 /** 140 * Classes implementing this interface can listen for events on the bottom 141 * controls. 142 */ 143 public static interface Listener { 144 /** 145 * Called when the user pressed the "view" button to e.g. view a photo 146 * sphere or RGBZ image. 147 */ 148 public void onExternalViewer(); 149 150 /** 151 * Called when the "edit" button is pressed. 152 */ 153 public void onEdit(); 154 155 /** 156 * Called when the "tiny planet" button is pressed. 157 */ 158 public void onTinyPlanet(); 159 160 /** 161 * Called when the "delete" button is pressed. 162 */ 163 public void onDelete(); 164 165 /** 166 * Called when the "share" button is pressed. 167 */ 168 public void onShare(); 169 170 /** 171 * Called when the "gallery" button is pressed. 172 */ 173 public void onGallery(); 174 } 175 } 176 177 private final static String TAG = "CameraAppUI"; 178 179 private final AppController mController; 180 private final boolean mIsCaptureIntent; 181 private final boolean mIsSecureCamera; 182 private final AnimationManager mAnimationManager; 183 184 // Swipe states: 185 private final static int IDLE = 0; 186 private final static int SWIPE_UP = 1; 187 private final static int SWIPE_DOWN = 2; 188 private final static int SWIPE_LEFT = 3; 189 private final static int SWIPE_RIGHT = 4; 190 191 // Touch related measures: 192 private final int mSlop; 193 private final static int SWIPE_TIME_OUT_MS = 500; 194 195 private final static int SHIMMY_DELAY_MS = 1000; 196 197 // Mode cover states: 198 private final static int COVER_HIDDEN = 0; 199 private final static int COVER_SHOWN = 1; 200 private final static int COVER_WILL_HIDE_AT_NEXT_FRAME = 2; 201 private static final int COVER_WILL_HIDE_AT_NEXT_TEXTURE_UPDATE = 3; 202 203 // App level views: 204 private final FrameLayout mCameraRootView; 205 private final ModeTransitionView mModeTransitionView; 206 private final MainActivityLayout mAppRootView; 207 private final ModeListView mModeListView; 208 private final FilmstripLayout mFilmstripLayout; 209 private TextureView mTextureView; 210 private FrameLayout mModuleUI; 211 private BottomBar mBottomBar; 212 213 private TextureViewHelper mTextureViewHelper; 214 private final GestureDetector mGestureDetector; 215 private int mSwipeState = IDLE; 216 private PreviewOverlay mPreviewOverlay; 217 private CaptureAnimationOverlay mCaptureOverlay; 218 private PreviewStatusListener mPreviewStatusListener; 219 private int mModeCoverState = COVER_HIDDEN; 220 private final FilmstripBottomControls mFilmstripBottomControls; 221 private final FilmstripContentPanel mFilmstripPanel; 222 private Runnable mHideCoverRunnable; 223 private final View.OnLayoutChangeListener mPreviewLayoutChangeListener 224 = new View.OnLayoutChangeListener() { 225 @Override 226 public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, 227 int oldTop, int oldRight, int oldBottom) { 228 if (mPreviewStatusListener != null) { 229 mPreviewStatusListener.onPreviewLayoutChanged(v, left, top, right, bottom, oldLeft, 230 oldTop, oldRight, oldBottom); 231 } 232 } 233 }; 234 235 public void updatePreviewAspectRatio(float aspectRatio) { 236 mTextureViewHelper.updateAspectRatio(aspectRatio); 237 } 238 239 /** 240 * This is to support modules that calculate their own transform matrix because 241 * they need to use a transform matrix to rotate the preview. 242 * 243 * @param matrix transform matrix to be set on the TextureView 244 */ 245 public void updatePreviewTransform(Matrix matrix) { 246 mTextureViewHelper.updateTransform(matrix); 247 } 248 249 public interface AnimationFinishedListener { 250 public void onAnimationFinished(boolean success); 251 } 252 253 private class MyTouchListener implements View.OnTouchListener { 254 private boolean mScaleStarted = false; 255 @Override 256 public boolean onTouch(View v, MotionEvent event) { 257 if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { 258 mScaleStarted = false; 259 } else if (event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) { 260 mScaleStarted = true; 261 } 262 return (!mScaleStarted) && mGestureDetector.onTouchEvent(event); 263 } 264 } 265 266 /** 267 * This gesture listener finds out the direction of the scroll gestures and 268 * sends them to CameraAppUI to do further handling. 269 */ 270 private class MyGestureListener extends GestureDetector.SimpleOnGestureListener { 271 private MotionEvent mDown; 272 273 @Override 274 public boolean onScroll(MotionEvent e1, MotionEvent ev, float distanceX, float distanceY) { 275 if (ev.getEventTime() - ev.getDownTime() > SWIPE_TIME_OUT_MS 276 || mSwipeState != IDLE 277 || mIsCaptureIntent) { 278 return false; 279 } 280 281 int deltaX = (int) (ev.getX() - mDown.getX()); 282 int deltaY = (int) (ev.getY() - mDown.getY()); 283 if (ev.getActionMasked() == MotionEvent.ACTION_MOVE) { 284 if (Math.abs(deltaX) > mSlop || Math.abs(deltaY) > mSlop) { 285 // Calculate the direction of the swipe. 286 if (deltaX >= Math.abs(deltaY)) { 287 // Swipe right. 288 setSwipeState(SWIPE_RIGHT); 289 } else if (deltaX <= -Math.abs(deltaY)) { 290 // Swipe left. 291 setSwipeState(SWIPE_LEFT); 292 } else if (deltaY >= Math.abs(deltaX)) { 293 // Swipe down. 294 setSwipeState(SWIPE_DOWN); 295 } else if (deltaY <= -Math.abs(deltaX)) { 296 // Swipe up. 297 setSwipeState(SWIPE_UP); 298 } 299 } 300 } 301 return true; 302 } 303 304 private void setSwipeState(int swipeState) { 305 mSwipeState = swipeState; 306 // Notify new swipe detected. 307 onSwipeDetected(swipeState); 308 } 309 310 @Override 311 public boolean onDown(MotionEvent ev) { 312 mDown = MotionEvent.obtain(ev); 313 mSwipeState = IDLE; 314 return false; 315 } 316 } 317 318 public CameraAppUI(AppController controller, MainActivityLayout appRootView, 319 boolean isSecureCamera, boolean isCaptureIntent) { 320 mSlop = ViewConfiguration.get(controller.getAndroidContext()).getScaledTouchSlop(); 321 mController = controller; 322 mIsSecureCamera = isSecureCamera; 323 mIsCaptureIntent = isCaptureIntent; 324 325 mAppRootView = appRootView; 326 mFilmstripLayout = (FilmstripLayout) appRootView.findViewById(R.id.filmstrip_layout); 327 mCameraRootView = (FrameLayout) appRootView.findViewById(R.id.camera_app_root); 328 mModeTransitionView = (ModeTransitionView) 329 mAppRootView.findViewById(R.id.mode_transition_view); 330 mFilmstripBottomControls = new FilmstripBottomControls( 331 (ViewGroup) mAppRootView.findViewById(R.id.filmstrip_bottom_controls)); 332 mFilmstripPanel = (FilmstripContentPanel) mAppRootView.findViewById(R.id.filmstrip_layout); 333 mGestureDetector = new GestureDetector(controller.getAndroidContext(), 334 new MyGestureListener()); 335 mModeListView = (ModeListView) appRootView.findViewById(R.id.mode_list_layout); 336 if (mModeListView != null) { 337 mModeListView.setModeSwitchListener(this); 338 } else { 339 Log.e(TAG, "Cannot find mode list in the view hierarchy"); 340 } 341 mAnimationManager = new AnimationManager(); 342 } 343 344 /** 345 * Redirects touch events to appropriate recipient views based on swipe direction. 346 * More specifically, swipe up and swipe down will be handled by the view that handles 347 * mode transition; swipe left will be send to filmstrip; swipe right will be redirected 348 * to mode list in order to bring up mode list. 349 */ 350 private void onSwipeDetected(int swipeState) { 351 if (swipeState == SWIPE_UP || swipeState == SWIPE_DOWN) { 352 // Quick switch between photo/video. 353 if (mController.getCurrentModuleIndex() == ModeListView.MODE_PHOTO || 354 mController.getCurrentModuleIndex() == ModeListView.MODE_VIDEO) { 355 mAppRootView.redirectTouchEventsTo(mModeTransitionView); 356 357 final int moduleToTransitionTo = 358 mController.getCurrentModuleIndex() == ModeListView.MODE_PHOTO ? 359 ModeListView.MODE_VIDEO : ModeListView.MODE_PHOTO; 360 int shadeColorId = ModeListView.getModeThemeColor(moduleToTransitionTo); 361 int iconRes = ModeListView.getModeIconResourceId(moduleToTransitionTo); 362 363 AnimationFinishedListener listener = new AnimationFinishedListener() { 364 @Override 365 public void onAnimationFinished(boolean success) { 366 if (success) { 367 mHideCoverRunnable = new Runnable() { 368 @Override 369 public void run() { 370 mModeTransitionView.startPeepHoleAnimation(); 371 } 372 }; 373 mModeCoverState = COVER_SHOWN; 374 // Go to new module when the previous operation is successful. 375 mController.onModeSelected(moduleToTransitionTo); 376 } 377 } 378 }; 379 if (mSwipeState == SWIPE_UP) { 380 mModeTransitionView.prepareToPullUpShade(shadeColorId, iconRes, listener); 381 } else { 382 mModeTransitionView.prepareToPullDownShade(shadeColorId, iconRes, listener); 383 } 384 } 385 } else if (swipeState == SWIPE_LEFT) { 386 // Pass the touch sequence to filmstrip layout. 387 mAppRootView.redirectTouchEventsTo(mFilmstripLayout); 388 } else if (swipeState == SWIPE_RIGHT) { 389 // Pass the touch to mode switcher 390 mAppRootView.redirectTouchEventsTo(mModeListView); 391 } 392 } 393 394 /** 395 * Gets called when activity resumes in preview. 396 */ 397 public void resume() { 398 if (mTextureView == null || mTextureView.getSurfaceTexture() != null) { 399 if (!mIsCaptureIntent) { 400 mModeListView.startAccordionAnimationWithDelay(SHIMMY_DELAY_MS); 401 } 402 } else { 403 // Show mode theme cover until preview is ready 404 showModeCoverUntilPreviewReady(); 405 } 406 // Hide action bar first since we are in full screen mode first, and 407 // switch the system UI to lights-out mode. 408 mFilmstripPanel.hide(); 409 } 410 411 /** 412 * A cover view showing the mode theme color and mode icon will be visible on 413 * top of preview until preview is ready (i.e. camera preview is started and 414 * the first frame has been received). 415 */ 416 private void showModeCoverUntilPreviewReady() { 417 int modeId = mController.getCurrentModuleIndex(); 418 int colorId = ModeListView.getModeThemeColor(modeId); 419 int iconId = ModeListView.getModeIconResourceId(modeId); 420 mModeTransitionView.setupModeCover(colorId, iconId); 421 mHideCoverRunnable = new Runnable() { 422 @Override 423 public void run() { 424 mModeTransitionView.hideModeCover(new AnimationFinishedListener() { 425 @Override 426 public void onAnimationFinished(boolean success) { 427 if (success) { 428 // Show shimmy in SHIMMY_DELAY_MS 429 if (!mIsCaptureIntent) { 430 mModeListView.startAccordionAnimationWithDelay(SHIMMY_DELAY_MS); 431 } 432 } 433 } 434 }); 435 } 436 }; 437 mModeCoverState = COVER_SHOWN; 438 } 439 440 private void hideModeCover() { 441 if (mHideCoverRunnable != null) { 442 mAppRootView.post(mHideCoverRunnable); 443 mHideCoverRunnable = null; 444 } 445 mModeCoverState = COVER_HIDDEN; 446 } 447 448 /** 449 * Called when the back key is pressed. 450 * 451 * @return Whether the UI responded to the key event. 452 */ 453 public boolean onBackPressed() { 454 if (mFilmstripLayout.getVisibility() == View.VISIBLE) { 455 return mFilmstripLayout.onBackPressed(); 456 } else { 457 return mModeListView.onBackPressed(); 458 } 459 } 460 461 /** 462 * Sets a {@link com.android.camera.ui.PreviewStatusListener} that 463 * listens to SurfaceTexture changes. In addition, the listener will also provide 464 * a {@link android.view.GestureDetector.OnGestureListener}, which will listen to 465 * gestures that happen on camera preview. 466 * 467 * @param previewStatusListener the listener that gets notified when SurfaceTexture 468 * changes 469 */ 470 public void setPreviewStatusListener(PreviewStatusListener previewStatusListener) { 471 mPreviewStatusListener = previewStatusListener; 472 if (mPreviewStatusListener != null) { 473 GestureDetector.OnGestureListener gestureListener 474 = mPreviewStatusListener.getGestureListener(); 475 if (gestureListener != null) { 476 mPreviewOverlay.setGestureListener(gestureListener); 477 } 478 mTextureViewHelper.setAutoAdjustTransform( 479 mPreviewStatusListener.shouldAutoAdjustTransformMatrixOnLayout()); 480 if (mPreviewStatusListener.shouldAutoAdjustBottomBar()) { 481 mBottomBar = (BottomBar) mAppRootView.findViewById(R.id.bottom_bar); 482 mTextureViewHelper.addPreviewAreaSizeChangedListener(mBottomBar); 483 } 484 } 485 } 486 487 /** 488 * Adds a listener to receive callbacks when preview area size changes. 489 */ 490 public void addPreviewAreaSizeChangedListener( 491 PreviewStatusListener.PreviewAreaSizeChangedListener listener) { 492 mTextureViewHelper.addPreviewAreaSizeChangedListener(listener); 493 } 494 495 /** 496 * Removes a listener that receives callbacks when preview area size changes. 497 */ 498 public void removePreviewAreaSizeChangedListener( 499 PreviewStatusListener.PreviewAreaSizeChangedListener listener) { 500 mTextureViewHelper.removePreviewAreaSizeChangedListener(listener); 501 } 502 503 /** 504 * This inflates generic_module layout, which contains all the shared views across 505 * modules. Then each module inflates their own views in the given view group. For 506 * now, this is called every time switching from a not-yet-refactored module to a 507 * refactored module. In the future, this should only need to be done once per app 508 * start. 509 */ 510 public void prepareModuleUI() { 511 mCameraRootView.removeAllViews(); 512 LayoutInflater inflater = (LayoutInflater) mController.getAndroidContext() 513 .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 514 inflater.inflate(R.layout.generic_module, mCameraRootView, true); 515 516 mModuleUI = (FrameLayout) mCameraRootView.findViewById(R.id.module_layout); 517 mTextureView = (TextureView) mCameraRootView.findViewById(R.id.preview_content); 518 mTextureViewHelper = new TextureViewHelper(mTextureView); 519 mTextureViewHelper.setSurfaceTextureListener(this); 520 mTextureViewHelper.setOnLayoutChangeListener(mPreviewLayoutChangeListener); 521 522 mPreviewOverlay = (PreviewOverlay) mCameraRootView.findViewById(R.id.preview_overlay); 523 mPreviewOverlay.setOnTouchListener(new MyTouchListener()); 524 mCaptureOverlay = (CaptureAnimationOverlay) 525 mCameraRootView.findViewById(R.id.capture_overlay); 526 527 mBottomBar = (BottomBar) mAppRootView.findViewById(R.id.bottom_bar); 528 mBottomBar.setupToggle(mIsCaptureIntent); 529 } 530 531 // TODO: Remove this when refactor is done. 532 // This is here to ensure refactored modules can work with not-yet-refactored ones. 533 public void clearCameraUI() { 534 mCameraRootView.removeAllViews(); 535 mModuleUI = null; 536 mTextureView = null; 537 mPreviewOverlay = null; 538 mBottomBar = null; 539 setBottomBarShutterListener(null); 540 } 541 542 /** 543 * Called indirectly from each module in their initialization to get a view group 544 * to inflate the module specific views in. 545 * 546 * @return a view group for modules to attach views to 547 */ 548 public FrameLayout getModuleRootView() { 549 // TODO: Change it to mModuleUI when refactor is done 550 return mCameraRootView; 551 } 552 553 /** 554 * Remove all the module specific views. 555 */ 556 public void clearModuleUI() { 557 if (mModuleUI != null) { 558 mModuleUI.removeAllViews(); 559 } 560 mTextureViewHelper.addPreviewAreaSizeChangedListener(null); 561 562 mPreviewStatusListener = null; 563 mPreviewOverlay.reset(); 564 } 565 566 /** 567 * Gets called when preview is started. 568 */ 569 public void onPreviewStarted() { 570 if (mModeCoverState == COVER_SHOWN) { 571 if (mController.getCurrentModuleIndex() == ModeListView.MODE_GCAM) { 572 // For modules that use camera2 api, check surfaceTexture update 573 mModeCoverState = COVER_WILL_HIDE_AT_NEXT_TEXTURE_UPDATE; 574 } else { 575 mModeCoverState = COVER_WILL_HIDE_AT_NEXT_FRAME; 576 mController.setupOneShotPreviewListener(); 577 } 578 } 579 } 580 581 /** 582 * Gets notified when next preview frame comes in. 583 */ 584 public void onNewPreviewFrame() { 585 hideModeCover(); 586 mModeCoverState = COVER_HIDDEN; 587 } 588 589 /** 590 * Gets called when a mode is selected from {@link com.android.camera.ui.ModeListView} 591 * 592 * @param modeIndex mode index of the selected mode 593 */ 594 @Override 595 public void onModeSelected(int modeIndex) { 596 mHideCoverRunnable = new Runnable() { 597 @Override 598 public void run() { 599 mModeListView.startModeSelectionAnimation(); 600 } 601 }; 602 mModeCoverState = COVER_SHOWN; 603 604 int lastIndex = mController.getCurrentModuleIndex(); 605 mController.onModeSelected(modeIndex); 606 int currentIndex = mController.getCurrentModuleIndex(); 607 608 if (mTextureView == null) { 609 // TODO: Remove this when all the modules use TextureView 610 int temporaryDelay = 600; // ms 611 mModeListView.postDelayed(new Runnable() { 612 @Override 613 public void run() { 614 hideModeCover(); 615 } 616 }, temporaryDelay); 617 } else if (lastIndex == currentIndex) { 618 hideModeCover(); 619 } 620 } 621 622 /********************** Capture animation **********************/ 623 /* TODO: This session is subject to UX changes. In addition to the generic 624 flash animation and post capture animation, consider designating a parameter 625 for specifying the type of animation, as well as an animation finished listener 626 so that modules can have more knowledge of the status of the animation. */ 627 628 /** 629 * Starts the pre-capture animation. 630 */ 631 public void startPreCaptureAnimation() { 632 mCaptureOverlay.startFlashAnimation(); 633 } 634 635 /** 636 * Cancels the pre-capture animation. 637 */ 638 public void cancelPreCaptureAnimation() { 639 mAnimationManager.cancelAnimations(); 640 } 641 642 /** 643 * Cancels the post-capture animation. 644 */ 645 public void cancelPostCaptureAnimation() { 646 mAnimationManager.cancelAnimations(); 647 } 648 649 public FilmstripContentPanel getFilmstripContentPanel() { 650 return mFilmstripPanel; 651 } 652 653 /** 654 * @return The {@link com.android.camera.app.CameraAppUI.BottomControls} on the 655 * bottom of the filmstrip. 656 */ 657 public BottomControls getFilmstripBottomControls() { 658 return mFilmstripBottomControls; 659 } 660 661 /** 662 * @param listener The listener for bottom controls. 663 */ 664 public void setFilmstripBottomControlsListener(BottomControls.Listener listener) { 665 mFilmstripBottomControls.setListener(listener); 666 } 667 668 /***************************SurfaceTexture Listener*********************************/ 669 670 @Override 671 public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 672 Log.v(TAG, "SurfaceTexture is available"); 673 if (mPreviewStatusListener != null) { 674 mPreviewStatusListener.onSurfaceTextureAvailable(surface, width, height); 675 } 676 } 677 678 @Override 679 public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 680 if (mPreviewStatusListener != null) { 681 mPreviewStatusListener.onSurfaceTextureSizeChanged(surface, width, height); 682 } 683 } 684 685 @Override 686 public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 687 Log.v(TAG, "SurfaceTexture is destroyed"); 688 if (mPreviewStatusListener != null) { 689 return mPreviewStatusListener.onSurfaceTextureDestroyed(surface); 690 } 691 return false; 692 } 693 694 @Override 695 public void onSurfaceTextureUpdated(SurfaceTexture surface) { 696 if (mModeCoverState == COVER_WILL_HIDE_AT_NEXT_TEXTURE_UPDATE) { 697 hideModeCover(); 698 mModeCoverState = COVER_HIDDEN; 699 } 700 if (mPreviewStatusListener != null) { 701 mPreviewStatusListener.onSurfaceTextureUpdated(surface); 702 } 703 } 704 705 /** 706 * Sets the color of the bottom bar. 707 */ 708 public void setBottomBarColor(int colorId) { 709 mBottomBar.setBackgroundColor(colorId); 710 } 711 712 /** 713 * Set the visibility of the bottom bar. 714 */ 715 // TODO: needed for when panorama is managed by the generic module ui. 716 public void setBottomBarVisible(boolean visible) { 717 mBottomBar.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); 718 } 719 720 /** 721 * If the bottom bar is visible (hence has been drawn), 722 * this sets a {@link #ShutterButton.OnShutterButtonListener} 723 * on the global shutter button, 724 */ 725 public void setBottomBarShutterListener( 726 ShutterButton.OnShutterButtonListener listener) { 727 ShutterButton shutterButton 728 = (ShutterButton) mCameraRootView.findViewById(R.id.shutter_button); 729 if (shutterButton != null) { 730 shutterButton.setOnShutterButtonListener(listener); 731 } 732 } 733 734 /** 735 * Performs a transition to the global intent layout. 736 */ 737 public void transitionToIntentLayout() { 738 mBottomBar.transitionToIntentLayout(); 739 } 740 741 /** 742 * Performs a transition to the global intent review layout. 743 */ 744 public void transitionToIntentReviewLayout() { 745 mBottomBar.transitionToIntentReviewLayout(); 746 } 747} 748