Home | History | Annotate | Download | only in portability
      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.ex.camera2.portability;
     18 
     19 import android.hardware.Camera;
     20 
     21 import com.android.ex.camera2.portability.debug.Log;
     22 
     23 import java.util.ArrayList;
     24 import java.util.List;
     25 import java.util.Map;
     26 import java.util.TreeMap;
     27 
     28 /**
     29  * A class which stores the camera settings.
     30  */
     31 public abstract class CameraSettings {
     32     private static final Log.Tag TAG = new Log.Tag("CamSet");
     33 
     34     // Attempts to provide a value outside this range will be ignored.
     35     private static final int MIN_JPEG_COMPRESSION_QUALITY = 1;
     36     private static final int MAX_JPEG_COMPRESSION_QUALITY = 100;
     37 
     38     protected final Map<String, String> mGeneralSetting = new TreeMap<>();
     39     protected final List<Camera.Area> mMeteringAreas = new ArrayList<>();
     40     protected final List<Camera.Area> mFocusAreas = new ArrayList<>();
     41     protected boolean mSizesLocked;
     42     protected int mPreviewFpsRangeMin;
     43     protected int mPreviewFpsRangeMax;
     44     protected int mPreviewFrameRate;
     45     protected Size mCurrentPreviewSize;
     46     private int mCurrentPreviewFormat;
     47     protected Size mCurrentPhotoSize;
     48     protected byte mJpegCompressQuality;
     49     protected int mCurrentPhotoFormat;
     50     protected float mCurrentZoomRatio;
     51     protected int mExposureCompensationIndex;
     52     protected CameraCapabilities.FlashMode mCurrentFlashMode;
     53     protected CameraCapabilities.FocusMode mCurrentFocusMode;
     54     protected CameraCapabilities.SceneMode mCurrentSceneMode;
     55     protected CameraCapabilities.WhiteBalance mWhiteBalance;
     56     protected boolean mVideoStabilizationEnabled;
     57     protected boolean mAutoExposureLocked;
     58     protected boolean mAutoWhiteBalanceLocked;
     59     protected boolean mRecordingHintEnabled;
     60     protected GpsData mGpsData;
     61     protected Size mExifThumbnailSize;
     62 
     63     /**
     64      * An immutable class storing GPS related information.
     65      * <p>It's a hack since we always use GPS time stamp but does not use other
     66      * fields sometimes. Setting processing method to null means the other
     67      * fields should not be used.</p>
     68      */
     69     public static class GpsData {
     70         public final double latitude;
     71         public final double longitude;
     72         public final double altitude;
     73         public final long timeStamp;
     74         public final String processingMethod;
     75 
     76         /**
     77          * Construct what may or may not actually represent a location,
     78          * depending on the value of {@code processingMethod}.
     79          *
     80          * <p>Setting {@code processingMethod} to {@code null} means that
     81          * {@code latitude}, {@code longitude}, and {@code altitude} will be
     82          * completely ignored.</p>
     83          */
     84         public GpsData(double latitude, double longitude, double altitude, long timeStamp,
     85                 String processingMethod) {
     86             if (processingMethod == null &&
     87                     (latitude != 0.0 || longitude != 0.0 || altitude != 0.0)) {
     88                 Log.w(TAG, "GpsData's nonzero data will be ignored due to null processingMethod");
     89             }
     90             this.latitude = latitude;
     91             this.longitude = longitude;
     92             this.altitude = altitude;
     93             this.timeStamp = timeStamp;
     94             this.processingMethod = processingMethod;
     95         }
     96 
     97         /** Copy constructor. */
     98         public GpsData(GpsData src) {
     99             this.latitude = src.latitude;
    100             this.longitude = src.longitude;
    101             this.altitude = src.altitude;
    102             this.timeStamp = src.timeStamp;
    103             this.processingMethod = src.processingMethod;
    104         }
    105     }
    106 
    107     protected CameraSettings() {
    108     }
    109 
    110     /**
    111      * Copy constructor.
    112      *
    113      * @param src The source settings.
    114      * @return The copy of the source.
    115      */
    116     protected CameraSettings(CameraSettings src) {
    117         mGeneralSetting.putAll(src.mGeneralSetting);
    118         mMeteringAreas.addAll(src.mMeteringAreas);
    119         mFocusAreas.addAll(src.mFocusAreas);
    120         mSizesLocked = src.mSizesLocked;
    121         mPreviewFpsRangeMin = src.mPreviewFpsRangeMin;
    122         mPreviewFpsRangeMax = src.mPreviewFpsRangeMax;
    123         mPreviewFrameRate = src.mPreviewFrameRate;
    124         mCurrentPreviewSize =
    125                 (src.mCurrentPreviewSize == null ? null : new Size(src.mCurrentPreviewSize));
    126         mCurrentPreviewFormat = src.mCurrentPreviewFormat;
    127         mCurrentPhotoSize =
    128                 (src.mCurrentPhotoSize == null ? null : new Size(src.mCurrentPhotoSize));
    129         mJpegCompressQuality = src.mJpegCompressQuality;
    130         mCurrentPhotoFormat = src.mCurrentPhotoFormat;
    131         mCurrentZoomRatio = src.mCurrentZoomRatio;
    132         mExposureCompensationIndex = src.mExposureCompensationIndex;
    133         mCurrentFlashMode = src.mCurrentFlashMode;
    134         mCurrentFocusMode = src.mCurrentFocusMode;
    135         mCurrentSceneMode = src.mCurrentSceneMode;
    136         mWhiteBalance = src.mWhiteBalance;
    137         mVideoStabilizationEnabled = src.mVideoStabilizationEnabled;
    138         mAutoExposureLocked = src.mAutoExposureLocked;
    139         mAutoWhiteBalanceLocked = src.mAutoWhiteBalanceLocked;
    140         mRecordingHintEnabled = src.mRecordingHintEnabled;
    141         mGpsData = src.mGpsData;
    142         mExifThumbnailSize = src.mExifThumbnailSize;
    143     }
    144 
    145     /**
    146      * @return A copy of this object, as an instance of the implementing class.
    147      */
    148     public abstract CameraSettings copy();
    149 
    150     /** General setting **/
    151     @Deprecated
    152     public void setSetting(String key, String value) {
    153         mGeneralSetting.put(key, value);
    154     }
    155 
    156     /**
    157      * Changes whether classes outside this class are allowed to set the preview
    158      * and photo capture sizes.
    159      *
    160      * @param locked Whether to prevent changes to these fields.
    161      *
    162      * @see #setPhotoSize
    163      * @see #setPreviewSize
    164      */
    165     /*package*/ void setSizesLocked(boolean locked) {
    166         mSizesLocked = locked;
    167     }
    168 
    169     /**  Preview **/
    170 
    171     /**
    172      * Sets the preview FPS range. This call will invalidate prior calls to
    173      * {@link #setPreviewFrameRate(int)}.
    174      *
    175      * @param min The min FPS.
    176      * @param max The max FPS.
    177      */
    178     public void setPreviewFpsRange(int min, int max) {
    179         if (min > max) {
    180             int temp = max;
    181             max = min;
    182             min = temp;
    183         }
    184         mPreviewFpsRangeMax = max;
    185         mPreviewFpsRangeMin = min;
    186         mPreviewFrameRate = -1;
    187     }
    188 
    189     /**
    190      * @return The min of the preview FPS range.
    191      */
    192     public int getPreviewFpsRangeMin() {
    193         return mPreviewFpsRangeMin;
    194     }
    195 
    196     /**
    197      * @return The max of the preview FPS range.
    198      */
    199     public int getPreviewFpsRangeMax() {
    200         return mPreviewFpsRangeMax;
    201     }
    202 
    203     /**
    204      * Sets the preview FPS. This call will invalidate prior calls to
    205      * {@link #setPreviewFpsRange(int, int)}.
    206      *
    207      * @param frameRate The target frame rate.
    208      */
    209     public void setPreviewFrameRate(int frameRate) {
    210         if (frameRate > 0) {
    211             mPreviewFrameRate = frameRate;
    212             mPreviewFpsRangeMax = frameRate;
    213             mPreviewFpsRangeMin = frameRate;
    214         }
    215     }
    216 
    217     public int getPreviewFrameRate() {
    218         return mPreviewFrameRate;
    219     }
    220 
    221     /**
    222      * @return The current preview size.
    223      */
    224     public Size getCurrentPreviewSize() {
    225         return new Size(mCurrentPreviewSize);
    226     }
    227 
    228     /**
    229      * @param previewSize The size to use for preview.
    230      * @return Whether the operation was allowed (i.e. the sizes are unlocked).
    231      */
    232     public boolean setPreviewSize(Size previewSize) {
    233         if (mSizesLocked) {
    234             Log.w(TAG, "Attempt to change preview size while locked");
    235             return false;
    236         }
    237 
    238         mCurrentPreviewSize = new Size(previewSize);
    239         return true;
    240     }
    241 
    242     /**
    243      * Sets the preview format.
    244      *
    245      * @param format
    246      * @see {@link android.graphics.ImageFormat}.
    247      */
    248     public void setPreviewFormat(int format) {
    249         mCurrentPreviewFormat = format;
    250     }
    251 
    252     /**
    253      * @return The preview format.
    254      * @see {@link android.graphics.ImageFormat}.
    255      */
    256     public int getCurrentPreviewFormat() {
    257         return mCurrentPreviewFormat;
    258     }
    259 
    260     /** Picture **/
    261 
    262     /**
    263      * @return The current photo size.
    264      */
    265     public Size getCurrentPhotoSize() {
    266         return new Size(mCurrentPhotoSize);
    267     }
    268 
    269     /**
    270      * @param photoSize The size to use for preview.
    271      * @return Whether the operation was allowed (i.e. the sizes are unlocked).
    272      */
    273     public boolean setPhotoSize(Size photoSize) {
    274         if (mSizesLocked) {
    275             Log.w(TAG, "Attempt to change photo size while locked");
    276             return false;
    277         }
    278 
    279         mCurrentPhotoSize = new Size(photoSize);
    280         return true;
    281     }
    282 
    283     /**
    284      * Sets the format for the photo.
    285      *
    286      * @param format The format for the photos taken.
    287      * @see {@link android.graphics.ImageFormat}.
    288      */
    289     public void setPhotoFormat(int format) {
    290         mCurrentPhotoFormat = format;
    291     }
    292 
    293     /**
    294      * @return The format for the photos taken.
    295      * @see {@link android.graphics.ImageFormat}.
    296      */
    297     public int getCurrentPhotoFormat() {
    298         return mCurrentPhotoFormat;
    299     }
    300 
    301     /**
    302      * Sets the JPEG compression quality.
    303      *
    304      * @param quality The quality for JPEG.
    305      */
    306     public void setPhotoJpegCompressionQuality(int quality) {
    307         if (quality < MIN_JPEG_COMPRESSION_QUALITY || quality > MAX_JPEG_COMPRESSION_QUALITY) {
    308             Log.w(TAG, "Ignoring JPEG quality that falls outside the expected range");
    309             return;
    310         }
    311         // This is safe because the positive numbers go up to 127.
    312         mJpegCompressQuality = (byte) quality;
    313     }
    314 
    315     public int getPhotoJpegCompressionQuality() {
    316         return mJpegCompressQuality;
    317     }
    318 
    319     /** Zoom **/
    320 
    321     /**
    322      * @return The current zoom ratio. The min is 1.0f.
    323      */
    324     public float getCurrentZoomRatio() {
    325         return mCurrentZoomRatio;
    326     }
    327 
    328     /**
    329      * Sets the zoom ratio.
    330      * @param ratio The new zoom ratio. Should be in the range between 1.0 to
    331      *              the value returned from {@link
    332      *              com.android.camera.cameradevice.CameraCapabilities#getMaxZoomRatio()}.
    333      * @throws java.lang.UnsupportedOperationException if the ratio is not
    334      *         supported.
    335      */
    336     public void setZoomRatio(float ratio) {
    337         mCurrentZoomRatio = ratio;
    338     }
    339 
    340     /** Exposure **/
    341 
    342     public void setExposureCompensationIndex(int index) {
    343         mExposureCompensationIndex = index;
    344     }
    345 
    346     /**
    347      * @return The exposure compensation, with 0 meaning unadjusted.
    348      */
    349     public int getExposureCompensationIndex() {
    350         return mExposureCompensationIndex;
    351     }
    352 
    353     public void setAutoExposureLock(boolean locked) {
    354         mAutoExposureLocked = locked;
    355     }
    356 
    357     public boolean isAutoExposureLocked() {
    358         return mAutoExposureLocked;
    359     }
    360 
    361     /**
    362      * @param areas The areas for autoexposure. The coordinate system has domain
    363      *              and range [-1000,1000], measured relative to the visible
    364      *              preview image, with orientation matching that of the sensor.
    365      *              This means the coordinates must be transformed to account
    366      *              for the devices rotation---but not the zoom level---before
    367      *              being passed into this method.
    368      */
    369     public void setMeteringAreas(List<Camera.Area> areas) {
    370         mMeteringAreas.clear();
    371         if (areas != null) {
    372             mMeteringAreas.addAll(areas);
    373         }
    374     }
    375 
    376     public List<Camera.Area> getMeteringAreas() {
    377         return new ArrayList<Camera.Area>(mMeteringAreas);
    378     }
    379 
    380     /** Flash **/
    381 
    382     public CameraCapabilities.FlashMode getCurrentFlashMode() {
    383         return mCurrentFlashMode;
    384     }
    385 
    386     public void setFlashMode(CameraCapabilities.FlashMode flashMode) {
    387         mCurrentFlashMode = flashMode;
    388     }
    389 
    390     /** Focus **/
    391 
    392     /**
    393      * Sets the focus mode.
    394      * @param focusMode The focus mode to use.
    395      */
    396     public void setFocusMode(CameraCapabilities.FocusMode focusMode) {
    397         mCurrentFocusMode = focusMode;
    398     }
    399 
    400     /**
    401      * @return The current focus mode.
    402      */
    403     public CameraCapabilities.FocusMode getCurrentFocusMode() {
    404         return mCurrentFocusMode;
    405     }
    406 
    407     /**
    408      * @param areas The areas to focus. The coordinate system has domain and
    409      *              range [-1000,1000], measured relative to the visible preview
    410      *              image, with orientation matching that of the sensor. This
    411      *              means the coordinates must be transformed to account for
    412      *              the devices rotation---but not the zoom level---before being
    413      *              passed into this method.
    414      */
    415     public void setFocusAreas(List<Camera.Area> areas) {
    416         mFocusAreas.clear();
    417         if (areas != null) {
    418             mFocusAreas.addAll(areas);
    419         }
    420     }
    421 
    422     public List<Camera.Area> getFocusAreas() {
    423         return new ArrayList<Camera.Area>(mFocusAreas);
    424     }
    425 
    426     /** White balance **/
    427 
    428     public void setWhiteBalance(CameraCapabilities.WhiteBalance whiteBalance) {
    429         mWhiteBalance = whiteBalance;
    430     }
    431 
    432     public CameraCapabilities.WhiteBalance getWhiteBalance() {
    433         return mWhiteBalance;
    434     }
    435 
    436     public void setAutoWhiteBalanceLock(boolean locked) {
    437         mAutoWhiteBalanceLocked = locked;
    438     }
    439 
    440     public boolean isAutoWhiteBalanceLocked() {
    441         return mAutoWhiteBalanceLocked;
    442     }
    443 
    444     /** Scene mode **/
    445 
    446     /**
    447      * @return The current scene mode.
    448      */
    449     public CameraCapabilities.SceneMode getCurrentSceneMode() {
    450         return mCurrentSceneMode;
    451     }
    452 
    453     /**
    454      * Sets the scene mode for capturing.
    455      *
    456      * @param sceneMode The scene mode to use.
    457      * @throws java.lang.UnsupportedOperationException if it's not supported.
    458      */
    459     public void setSceneMode(CameraCapabilities.SceneMode sceneMode) {
    460         mCurrentSceneMode = sceneMode;
    461     }
    462 
    463     /** Other Features **/
    464 
    465     public void setVideoStabilization(boolean enabled) {
    466         mVideoStabilizationEnabled = enabled;
    467     }
    468 
    469     public boolean isVideoStabilizationEnabled() {
    470         return mVideoStabilizationEnabled;
    471     }
    472 
    473     public void setRecordingHintEnabled(boolean hintEnabled) {
    474         mRecordingHintEnabled = hintEnabled;
    475     }
    476 
    477     public boolean isRecordingHintEnabled() {
    478         return mRecordingHintEnabled;
    479     }
    480 
    481     public void setGpsData(GpsData data) {
    482         mGpsData = new GpsData(data);
    483     }
    484 
    485     public GpsData getGpsData() {
    486         return (mGpsData == null ? null : new GpsData(mGpsData));
    487     }
    488 
    489     public void clearGpsData() {
    490         mGpsData = null;
    491     }
    492 
    493     /**
    494      * Sets the size of the thumbnail in EXIF header. To suppress thumbnail
    495      * generation, set a size of (0,0).
    496      *
    497      * @param s The size for the thumbnail. If {@code null}, agent will not
    498      *          set a thumbnail size.
    499      */
    500     public void setExifThumbnailSize(Size s) {
    501         mExifThumbnailSize = s;
    502     }
    503 
    504     /**
    505      * Gets the size of the thumbnail in EXIF header.
    506      *
    507      * @return desired thumbnail size, or null if no size was set
    508      */
    509     public Size getExifThumbnailSize() {
    510         return (mExifThumbnailSize == null) ? null : new Size(mExifThumbnailSize);
    511     }
    512 }
    513