OSDN Git Service

Merge "Log capture session canceled events." into ub-camera-haleakala
authorPaul Rohde <codelogic@google.com>
Wed, 27 May 2015 23:36:28 +0000 (23:36 +0000)
committerAndroid (Google) Code Review <android-gerrit@google.com>
Wed, 27 May 2015 23:36:28 +0000 (23:36 +0000)
res/values-kk-rKZ/strings.xml
src/com/android/camera/CaptureModule.java
src/com/android/camera/MultiToggleImageButton.java
src/com/android/camera/exif/ExifInterface.java
src/com/android/camera/session/CaptureSessionImpl.java
src/com/android/camera/util/ExifUtil.java

index a160863..f59c607 100644 (file)
     <string name="video_recording_stopped" msgid="4658626532857624974">"Видео жазу тоқтады."</string>
     <string name="clear_effects" msgid="6192797848995967992">"Анықтық әсерлері"</string>
     <string name="effect_silly_faces" msgid="7952713419757286453">"ҚЫЗЫҚ БЕТ-ӘЛПЕТТЕР"</string>
-    <string name="effect_background" msgid="1358432220077975015">"Ð\96алпÑ\8b Ð¼Ð°Ò\93лұмаÑ\82"</string>
+    <string name="effect_background" msgid="1358432220077975015">"ФÐ\9eÐ\9d"</string>
     <string name="accessibility_shutter_button" msgid="6040483605347230438">"Сырғыту"</string>
     <string name="accessibility_cancel_button" msgid="5679989494636116448">"Өшіру"</string>
     <string name="accessibility_menu_button" msgid="7692103503958544723">"Mәзір түймесі"</string>
     <string name="time_lapse_seconds" msgid="7319683099532506270">"секундтар"</string>
     <string name="time_lapse_minutes" msgid="5325447383033224679">"минуттар"</string>
     <string name="time_lapse_hours" msgid="5294001144133261436">"сағаттар"</string>
-    <string name="time_lapse_interval_set" msgid="2418594453248958440">"Ð\9eÑ\80Ñ\8bндалдÑ\8b"</string>
+    <string name="time_lapse_interval_set" msgid="2418594453248958440">"Ð\94айÑ\8bн"</string>
     <string name="set_time_interval" msgid="2531393962847535331">"Уақыт аралығын орнату"</string>
     <string name="set_time_interval_help" msgid="64145154088021389">"Уақыт аралығы функциясы өшірулі. Уақыт аралығын реттеу үшін оны қосыңыз."</string>
     <string name="set_duration" msgid="1638453882581604341">"Ұзақтығын секундпен реттеу"</string>
     <string name="countdown_timer_duration_10s" msgid="9085308782250002795">"Кері санау таймерінің ұзақтығы 10 секундқа орнатылған"</string>
     <string name="more_options_desc" msgid="4628738800610478353">"Басқа опциялар"</string>
     <string name="cancel_button_description" msgid="3801167024006905033">"Өшіру"</string>
-    <string name="done_button_description" msgid="1334963435441544592">"Ð\9eÑ\80Ñ\8bндалдÑ\8b"</string>
+    <string name="done_button_description" msgid="1334963435441544592">"Ð\94айÑ\8bн"</string>
     <string name="retake_button_description" msgid="4234613030674787714">"Қайта түсіру"</string>
     <string name="review_button_description" msgid="7932122063748430080">"Қарап шығу"</string>
     <string name="share_button_description" msgid="5108508790540832053">"Бөлісу"</string>
index 204dc6a..79dfe09 100644 (file)
@@ -1374,9 +1374,21 @@ public class CaptureModule extends CameraModule implements
                   @Override
                   public void onFailure() {
                       Log.e(TAG, "Could not open camera.");
+                      // Sometimes the failure happens due to the controller
+                      // being in paused state but mCamera is already
+                      // initialized.  In these cases we just need to close the
+                      // camera device without showing the error dialog.
+                      // Application will properly reopen the camera on the next
+                      // resume operation (b/21025113).
+                      boolean isControllerPaused = mAppController.isPaused();
+                      if (mCamera != null) {
+                          mCamera.close();
+                      }
                       mCamera = null;
                       mCameraOpenCloseLock.release();
-                      mAppController.getFatalErrorHandler().onCameraOpenFailure();
+                      if (!isControllerPaused) {
+                          mAppController.getFatalErrorHandler().onCameraOpenFailure();
+                      }
                   }
 
                   @Override
index 8325933..34ffcef 100644 (file)
@@ -365,10 +365,10 @@ public class MultiToggleImageButton extends ImageButton {
     }
 
     private Bitmap combine(int oldState, int newState) {
-        // in some cases, a new set of image Ids are set via overrideImageIds()
-        // and oldState overruns the array.
+        // In some cases, a new set of image Ids are set via overrideImageIds()
+        // and oldState or newState overrun the array.
         // check here for that.
-        if (oldState >= mImageIds.length) {
+        if (oldState >= mImageIds.length || newState >= mImageIds.length) {
             return null;
         }
 
index 4b6eb8a..2a659c1 100644 (file)
@@ -70,6 +70,7 @@ public class ExifInterface {
     /**
      * Tag constants for Jeita EXIF 2.2
      */
+    public static final String EXIF_VERSION = "0220";
 
     // IFD 0
     public static final int TAG_IMAGE_WIDTH =
@@ -470,7 +471,7 @@ public class ExifInterface {
      */
     public static interface Flash {
         // LSB
-        public static final short DID_NOT_FIRED = 0;
+        public static final short DID_NOT_FIRE = 0;
         public static final short FIRED = 1;
         // 1st~2nd bits
         public static final short RETURN_NO_STROBE_RETURN_DETECTION_FUNCTION = 0 << 1;
@@ -1935,7 +1936,7 @@ public class ExifInterface {
      * {@link #TAG_DATE_TIME_ORIGINAL}.
      *
      * @param tagId one of the DateTimeStamp tags.
-     * @param timestamp a timestamp to format.
+     * @param timestamp a timestamp to format, in ms.
      * @param timezone a TimeZone object.
      * @return true if success, false if the tag could not be set.
      */
index 9576509..6166a33 100644 (file)
@@ -174,6 +174,11 @@ public class CaptureSessionImpl implements CaptureSession {
 
     @Override
     public void updateThumbnail(Bitmap bitmap) {
+        // No placeholder present means the task might already be finished or
+        // cancelled.
+        if (mPlaceHolder == null) {
+            return;
+        }
         if (mImageLifecycleListener != null) {
             mImageLifecycleListener.onMediumThumb();
         }
index ce847c2..18150a0 100644 (file)
@@ -26,6 +26,11 @@ import com.android.camera.one.v2.camera2proxy.CaptureResultProxy;
 import com.android.camera.processing.imagebackend.TaskImageContainer;
 import com.google.common.base.Optional;
 
+import java.text.DecimalFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
 /**
  * Exif utility functions.
  */
@@ -43,33 +48,17 @@ public class ExifUtil {
     }
 
     /**
-     * Adds the given location to the EXIF object.
-     *
-     * @param location The location to add.
-     */
-    public void addLocationToExif(Location location) {
-        mExif.addGpsTags(location.getLatitude(), location.getLongitude());
-        mExif.addGpsDateTimeStampTag(location.getTime());
-
-        double altitude = location.getAltitude();
-        if (altitude == 0) {
-            return;
-        }
-        short altitudeRef = altitude < 0 ? ExifInterface.GpsAltitudeRef.SEA_LEVEL_NEGATIVE
-                : ExifInterface.GpsAltitudeRef.SEA_LEVEL;
-        mExif.setTag(mExif.buildTag(ExifInterface.TAG_GPS_ALTITUDE_REF, altitudeRef));
-    }
-
-    /**
      * Populate the EXIF object with info pulled from a given capture result.
      *
      * @param image A {@link TaskImageContainer.TaskImage} from which to extract info from.
      * @param captureResult A {@link CaptureResultProxy} from which to extract info from.
-     * @param location optinally a location that should be added to the EXIF.
+     * @param location optionally a location that should be added to the EXIF.
      */
     public void populateExif(Optional<TaskImageContainer.TaskImage> image,
                              Optional<CaptureResultProxy> captureResult,
                              Optional<Location> location) {
+        addExifVersionToExif();
+        addTimestampToExif();
         addMakeAndModelToExif();
         if (image.isPresent()) {
             addImageDataToExif(image.get());
@@ -82,6 +71,47 @@ public class ExifUtil {
         }
     }
 
+    /**
+     * Adds the given location to the EXIF object.
+     *
+     * @param location The location to add.
+     */
+    public void addLocationToExif(Location location) {
+        final Long ALTITUDE_PRECISION = 1L; // GPS altitude isn't particularly accurate (determined empirically)
+
+        mExif.addGpsTags(location.getLatitude(), location.getLongitude());
+        mExif.addGpsDateTimeStampTag(location.getTime());
+
+        if (location.hasAltitude()) {
+            double altitude = location.getAltitude();
+            addExifTag(ExifInterface.TAG_GPS_ALTITUDE, rational(altitude, ALTITUDE_PRECISION));
+            short altitudeRef = altitude < 0 ? ExifInterface.GpsAltitudeRef.SEA_LEVEL_NEGATIVE
+                    : ExifInterface.GpsAltitudeRef.SEA_LEVEL;
+            addExifTag(ExifInterface.TAG_GPS_ALTITUDE_REF, altitudeRef);
+        }
+    }
+
+    private void addExifVersionToExif() {
+        addExifTag(ExifInterface.TAG_EXIF_VERSION, ExifInterface.EXIF_VERSION);
+    }
+
+    private void addTimestampToExif() {
+        final Long MS_TO_S = 1000L; // Milliseconds per second
+        final String subSecondFormat = "000";
+
+        Long timestampMs = System.currentTimeMillis();
+        TimeZone timezone = Calendar.getInstance().getTimeZone();
+        mExif.addDateTimeStampTag(ExifInterface.TAG_DATE_TIME, timestampMs, timezone);
+        mExif.addDateTimeStampTag(ExifInterface.TAG_DATE_TIME_DIGITIZED, timestampMs, timezone);
+        mExif.addDateTimeStampTag(ExifInterface.TAG_DATE_TIME_ORIGINAL, timestampMs, timezone);
+
+        Long subSeconds = timestampMs % MS_TO_S;
+        String subSecondsString = new DecimalFormat(subSecondFormat).format(subSeconds);
+        addExifTag(ExifInterface.TAG_SUB_SEC_TIME, subSecondsString);
+        addExifTag(ExifInterface.TAG_SUB_SEC_TIME_ORIGINAL, subSecondsString);
+        addExifTag(ExifInterface.TAG_SUB_SEC_TIME_DIGITIZED, subSecondsString);
+    }
+
     private void addMakeAndModelToExif() {
         addExifTag(ExifInterface.TAG_MAKE, Build.MANUFACTURER);
         addExifTag(ExifInterface.TAG_MODEL, Build.MODEL);
@@ -98,7 +128,7 @@ public class ExifUtil {
 
     private void addCaptureResultToExif(CaptureResultProxy result) {
         final Long NS_TO_S = 1000000000L; // Nanoseconds per second
-        final Long SHUTTER_SPEED_VALUE_PRECISION = 100L;
+        final Long SHUTTER_SPEED_VALUE_PRECISION = 1000L;
         final Long F_NUMBER_PRECISION = 100L;
         final Long APERTURE_VALUE_PRECISION = 100L;
         final Long FOCAL_LENGTH_PRECISION = 1000L; // micrometer precision
@@ -107,10 +137,10 @@ public class ExifUtil {
         Long exposureTimeNs = result.get(CaptureResult.SENSOR_EXPOSURE_TIME);
         addExifTag(ExifInterface.TAG_EXPOSURE_TIME, ratio(exposureTimeNs, NS_TO_S));
 
-        // Shutter speed value
+        // Shutter speed value (APEX unit, see Jeita EXIF 2.2 spec Annex C).
         if (exposureTimeNs != null) {
             Double exposureTime = (double) exposureTimeNs / NS_TO_S;
-            Double shutterSpeedValue = log2(exposureTime);
+            Double shutterSpeedValue = -log2(exposureTime);
             addExifTag(ExifInterface.TAG_SHUTTER_SPEED_VALUE, rational(shutterSpeedValue, SHUTTER_SPEED_VALUE_PRECISION));
         }
 
@@ -121,7 +151,7 @@ public class ExifUtil {
         Float fNumber = result.get(CaptureResult.LENS_APERTURE);
         addExifTag(ExifInterface.TAG_F_NUMBER, rational(fNumber, F_NUMBER_PRECISION));
 
-        // Aperture value
+        // Aperture value (APEX unit, see Jeita EXIF 2.2 spec Annex C).
         if (fNumber != null) {
             Double apertureValue = 2 * log2(fNumber);
             addExifTag(ExifInterface.TAG_APERTURE_VALUE, rational(apertureValue, APERTURE_VALUE_PRECISION));
@@ -130,6 +160,23 @@ public class ExifUtil {
         // Focal length
         Float focalLength = result.get(CaptureResult.LENS_FOCAL_LENGTH);
         addExifTag(ExifInterface.TAG_FOCAL_LENGTH, rational(focalLength, FOCAL_LENGTH_PRECISION));
+
+        // Flash mode
+        Integer flashMode = result.get(CaptureResult.FLASH_MODE);
+        if (flashMode == CaptureResult.FLASH_MODE_OFF) {
+            addExifTag(ExifInterface.TAG_FLASH, ExifInterface.Flash.DID_NOT_FIRE);
+        } else {
+            addExifTag(ExifInterface.TAG_FLASH, ExifInterface.Flash.FIRED);
+        }
+
+        // White balance
+        Integer whiteBalanceMode = result.get(CaptureResult.CONTROL_AWB_MODE);
+        if (whiteBalanceMode == CaptureResult.CONTROL_AWB_MODE_OFF) {
+            addExifTag(ExifInterface.TAG_WHITE_BALANCE, ExifInterface.WhiteBalance.MANUAL);
+        } else {
+            addExifTag(ExifInterface.TAG_WHITE_BALANCE, ExifInterface.WhiteBalance.AUTO);
+        }
+
     }
 
     private void addExifTag(int tagId, Object val) {