Home | History | Annotate | Download | only in focus
      1 /*
      2  * Copyright (C) 2014 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.ui.focus;
     18 
     19 import android.graphics.RectF;
     20 
     21 import com.android.camera.async.MainThread;
     22 import com.android.camera.debug.Log;
     23 import com.android.camera.debug.Log.Tag;
     24 import com.android.camera.one.OneCamera.FocusDistanceListener;
     25 import com.android.camera.ui.motion.LinearScale;
     26 
     27 /**
     28  * The focus controller interacts with the focus ring UI element.
     29  */
     30 public class FocusController implements FocusDistanceListener {
     31     private static final Tag TAG = new Tag("FocusController");
     32 
     33     private final FocusRing mFocusRing;
     34     private final FocusSound mFocusSound;
     35     private final MainThread mMainThread;
     36 
     37     public FocusController(FocusRing focusRing, FocusSound focusSound, MainThread mainThread) {
     38         mFocusRing = focusRing;
     39         mFocusSound = focusSound;
     40         mMainThread = mainThread;
     41     }
     42 
     43     /**
     44      * Show a passive focus animation at the center of the active area.
     45      * This will likely be different than the view bounds due to varying image
     46      * ratios and dimensions.
     47      */
     48     public void showPassiveFocusAtCenter() {
     49         mMainThread.execute(new Runnable() {
     50             @Override
     51             public void run() {
     52                 Log.v(TAG, "Running showPassiveFocusAtCenter()");
     53                 mFocusRing.startPassiveFocus();
     54                 mFocusRing.centerFocusLocation();
     55             }
     56         });
     57     }
     58 
     59     /**
     60      * Show a passive focus animation at the given viewX and viewY position.
     61      * This is usually indicates the camera subsystem kicked off an auto-focus
     62      * at the given screen position.
     63      *
     64      * @param viewX the view's x coordinate
     65      * @param viewY the view's y coordinate
     66      */
     67     public void showPassiveFocusAt(final int viewX, final int viewY) {
     68         mMainThread.execute(new Runnable() {
     69             @Override
     70             public void run() {
     71                 Log.v(TAG, "Running showPassiveFocusAt(" + viewX + ", " + viewY + ")");
     72                 mFocusRing.startPassiveFocus();
     73                 mFocusRing.setFocusLocation(viewX, viewY);
     74             }
     75         });
     76     }
     77 
     78     /**
     79      * Show an active focus animation at the given viewX and viewY position.
     80      * This is normally initiated by the user touching the screen at a given
     81      * point.
     82      *
     83      * @param viewX the view's x coordinate
     84      * @param viewY the view's y coordinate
     85      */
     86     public void showActiveFocusAt(final int viewX, final int viewY) {
     87         mMainThread.execute(new Runnable() {
     88             @Override
     89             public void run() {
     90                 Log.v(TAG, "showActiveFocusAt(" + viewX + ", " + viewY + ")");
     91                 mFocusRing.startActiveFocus();
     92                 mFocusRing.setFocusLocation(viewX, viewY);
     93 
     94                 // TODO: Enable focus sound when better audio controls exist.
     95                 // mFocusSound.play();
     96             }
     97         });
     98     }
     99 
    100     /**
    101      * Stop any currently executing focus animation.
    102      */
    103     public void clearFocusIndicator() {
    104         mMainThread.execute(new Runnable() {
    105             @Override
    106             public void run() {
    107                 Log.v(TAG, "clearFocusIndicator()");
    108                 mFocusRing.stopFocusAnimations();
    109             }
    110         });
    111     }
    112 
    113     /**
    114      * Computing the correct location for the focus ring requires knowing
    115      * the screen position and size of the preview area so the drawing
    116      * operations can be clipped correctly.
    117      */
    118     public void configurePreviewDimensions(final RectF previewArea) {
    119         mMainThread.execute(new Runnable() {
    120             @Override
    121             public void run() {
    122                Log.v(TAG, "configurePreviewDimensions(" + previewArea + ")");
    123                mFocusRing.configurePreviewDimensions(previewArea);
    124             }
    125         });
    126     }
    127 
    128     /**
    129      * Set the radius of the focus ring as a radius between 0 and 1.
    130      * This will map to the min and max values computed for the UI.
    131      */
    132     public void setFocusRatio(final float ratio) {
    133         mMainThread.execute(new Runnable() {
    134             @Override
    135             public void run() {
    136                 if (mFocusRing.isPassiveFocusRunning() ||
    137                       mFocusRing.isActiveFocusRunning()) {
    138                     mFocusRing.setRadiusRatio(ratio);
    139                 }
    140             }
    141         });
    142     }
    143 
    144     @Override
    145     public void onFocusDistance(float lensDistance, LinearScale lensRange) {
    146         if (lensRange.isInDomain(lensDistance)) {
    147             setFocusRatio(lensRange.scale(lensDistance));
    148         }
    149     }
    150 }
    151