• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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           */
GpsData(double latitude, double longitude, double altitude, long timeStamp, String processingMethod)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. */
GpsData(GpsData src)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  
CameraSettings()107      protected CameraSettings() {
108      }
109  
110      /**
111       * Copy constructor.
112       *
113       * @param src The source settings.
114       * @return The copy of the source.
115       */
CameraSettings(CameraSettings src)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       */
copy()148      public abstract CameraSettings copy();
149  
150      /** General setting **/
151      @Deprecated
setSetting(String key, String value)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       */
setSizesLocked(boolean locked)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       */
setPreviewFpsRange(int min, int max)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       */
getPreviewFpsRangeMin()192      public int getPreviewFpsRangeMin() {
193          return mPreviewFpsRangeMin;
194      }
195  
196      /**
197       * @return The max of the preview FPS range.
198       */
getPreviewFpsRangeMax()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       */
setPreviewFrameRate(int frameRate)209      public void setPreviewFrameRate(int frameRate) {
210          if (frameRate > 0) {
211              mPreviewFrameRate = frameRate;
212              mPreviewFpsRangeMax = frameRate;
213              mPreviewFpsRangeMin = frameRate;
214          }
215      }
216  
getPreviewFrameRate()217      public int getPreviewFrameRate() {
218          return mPreviewFrameRate;
219      }
220  
221      /**
222       * @return The current preview size.
223       */
getCurrentPreviewSize()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       */
setPreviewSize(Size previewSize)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       */
setPreviewFormat(int format)248      public void setPreviewFormat(int format) {
249          mCurrentPreviewFormat = format;
250      }
251  
252      /**
253       * @return The preview format.
254       * @see {@link android.graphics.ImageFormat}.
255       */
getCurrentPreviewFormat()256      public int getCurrentPreviewFormat() {
257          return mCurrentPreviewFormat;
258      }
259  
260      /** Picture **/
261  
262      /**
263       * @return The current photo size.
264       */
getCurrentPhotoSize()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       */
setPhotoSize(Size photoSize)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       */
setPhotoFormat(int format)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       */
getCurrentPhotoFormat()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       */
setPhotoJpegCompressionQuality(int quality)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  
getPhotoJpegCompressionQuality()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       */
getCurrentZoomRatio()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       */
setZoomRatio(float ratio)336      public void setZoomRatio(float ratio) {
337          mCurrentZoomRatio = ratio;
338      }
339  
340      /** Exposure **/
341  
setExposureCompensationIndex(int index)342      public void setExposureCompensationIndex(int index) {
343          mExposureCompensationIndex = index;
344      }
345  
346      /**
347       * @return The exposure compensation, with 0 meaning unadjusted.
348       */
getExposureCompensationIndex()349      public int getExposureCompensationIndex() {
350          return mExposureCompensationIndex;
351      }
352  
setAutoExposureLock(boolean locked)353      public void setAutoExposureLock(boolean locked) {
354          mAutoExposureLocked = locked;
355      }
356  
isAutoExposureLocked()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       */
setMeteringAreas(List<Camera.Area> areas)369      public void setMeteringAreas(List<Camera.Area> areas) {
370          mMeteringAreas.clear();
371          if (areas != null) {
372              mMeteringAreas.addAll(areas);
373          }
374      }
375  
getMeteringAreas()376      public List<Camera.Area> getMeteringAreas() {
377          return new ArrayList<Camera.Area>(mMeteringAreas);
378      }
379  
380      /** Flash **/
381  
getCurrentFlashMode()382      public CameraCapabilities.FlashMode getCurrentFlashMode() {
383          return mCurrentFlashMode;
384      }
385  
setFlashMode(CameraCapabilities.FlashMode flashMode)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       */
setFocusMode(CameraCapabilities.FocusMode focusMode)396      public void setFocusMode(CameraCapabilities.FocusMode focusMode) {
397          mCurrentFocusMode = focusMode;
398      }
399  
400      /**
401       * @return The current focus mode.
402       */
getCurrentFocusMode()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       */
setFocusAreas(List<Camera.Area> areas)415      public void setFocusAreas(List<Camera.Area> areas) {
416          mFocusAreas.clear();
417          if (areas != null) {
418              mFocusAreas.addAll(areas);
419          }
420      }
421  
getFocusAreas()422      public List<Camera.Area> getFocusAreas() {
423          return new ArrayList<Camera.Area>(mFocusAreas);
424      }
425  
426      /** White balance **/
427  
setWhiteBalance(CameraCapabilities.WhiteBalance whiteBalance)428      public void setWhiteBalance(CameraCapabilities.WhiteBalance whiteBalance) {
429          mWhiteBalance = whiteBalance;
430      }
431  
getWhiteBalance()432      public CameraCapabilities.WhiteBalance getWhiteBalance() {
433          return mWhiteBalance;
434      }
435  
setAutoWhiteBalanceLock(boolean locked)436      public void setAutoWhiteBalanceLock(boolean locked) {
437          mAutoWhiteBalanceLocked = locked;
438      }
439  
isAutoWhiteBalanceLocked()440      public boolean isAutoWhiteBalanceLocked() {
441          return mAutoWhiteBalanceLocked;
442      }
443  
444      /** Scene mode **/
445  
446      /**
447       * @return The current scene mode.
448       */
getCurrentSceneMode()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       */
setSceneMode(CameraCapabilities.SceneMode sceneMode)459      public void setSceneMode(CameraCapabilities.SceneMode sceneMode) {
460          mCurrentSceneMode = sceneMode;
461      }
462  
463      /** Other Features **/
464  
setVideoStabilization(boolean enabled)465      public void setVideoStabilization(boolean enabled) {
466          mVideoStabilizationEnabled = enabled;
467      }
468  
isVideoStabilizationEnabled()469      public boolean isVideoStabilizationEnabled() {
470          return mVideoStabilizationEnabled;
471      }
472  
setRecordingHintEnabled(boolean hintEnabled)473      public void setRecordingHintEnabled(boolean hintEnabled) {
474          mRecordingHintEnabled = hintEnabled;
475      }
476  
isRecordingHintEnabled()477      public boolean isRecordingHintEnabled() {
478          return mRecordingHintEnabled;
479      }
480  
setGpsData(GpsData data)481      public void setGpsData(GpsData data) {
482          mGpsData = new GpsData(data);
483      }
484  
getGpsData()485      public GpsData getGpsData() {
486          return (mGpsData == null ? null : new GpsData(mGpsData));
487      }
488  
clearGpsData()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       */
setExifThumbnailSize(Size s)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       */
getExifThumbnailSize()509      public Size getExifThumbnailSize() {
510          return (mExifThumbnailSize == null) ? null : new Size(mExifThumbnailSize);
511      }
512  }
513