Home | History | Annotate | Download | only in captureintent
      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 {
     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 
     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      */
    111     public RectF getPreviewRect() {
    112         return mPreviewRect;
    113     }
    114 
    115     /**
    116      * Obtains the current preview layout size.
    117      */
    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      */
    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      */
    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      */
    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      */
    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      */
    173     public void updatePreviewAspectRatio(float aspectRatio) {
    174         MainThread.checkMainThread();
    175         mAppUI.updatePreviewAspectRatio(aspectRatio);
    176     }
    177 
    178     /**
    179      * Called when the preview is started.
    180      */
    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      */
    192     public void initializeZoom(float maxZoom) {
    193         MainThread.checkMainThread();
    194         mPreviewOverlay.setupZoom(maxZoom, 0, mZoomChancedListener);
    195     }
    196 
    197     public FocusRing getFocusRing() {
    198         return mFocusRing;
    199     }
    200 
    201     public void setShutterButtonEnabled(boolean enabled) {
    202         MainThread.checkMainThread();
    203         mAppUI.setShutterButtonEnabled(enabled);
    204     }
    205 
    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      */
    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      */
    225     public void cancelCountDown() {
    226         mCountdownView.cancelCountDown();
    227     }
    228 
    229     /**
    230      * Sets a listener that gets notified when the countdown is finished.
    231      */
    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      */
    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      */
    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 
    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