OSDN Git Service

Fix for invalidated resolutions via upgrade
authorI-Jong Lin <ijonglin@google.com>
Thu, 11 Jun 2015 00:10:30 +0000 (17:10 -0700)
committerI-Jong Lin <ijonglin@google.com>
Thu, 11 Jun 2015 00:10:30 +0000 (17:10 -0700)
Bug: 21758681

There was a upgrade bug where an valid resolution of the
previous version of the Camera App could then be invalidated
the subsequent version of the Camera App.  If there were no
other valid resolutions of the same aspect ratio available
to the app, the current Camera App would choose (0,0) as its
default size and then write this value into the saved settings.

This fix allows the current Camera App to consider other resolutions
not of aspect ratio as a fallback resolution setting.  Also, if
an invalid resolution valid has been saved to the settings, it
also ignores it and then resaves a valid resolution value to the
settings.

Change-Id: I08f19d1ee6491619e92697897b73e4fd33a19a00

src/com/android/camera/settings/ResolutionSetting.java
src/com/android/camera/settings/ResolutionUtil.java

index 74524af..5b8f1d9 100644 (file)
@@ -30,6 +30,8 @@ import com.android.camera.one.OneCameraManager;
 import com.android.camera.util.GservicesHelper;
 import com.android.camera.util.Size;
 
+import com.google.common.base.Preconditions;
+
 import java.util.List;
 
 /**
@@ -103,7 +105,7 @@ public class ResolutionSetting {
      * is blacklisted or is not cached to prevent a crash.
      */
     public Size getPictureSize(CameraId cameraId, Facing cameraFacing)
-          throws OneCameraAccessException {
+            throws OneCameraAccessException {
         final String pictureSizeSettingKey = cameraFacing == OneCamera.Facing.FRONT ?
                 Keys.KEY_PICTURE_SIZE_FRONT : Keys.KEY_PICTURE_SIZE_BACK;
 
@@ -126,16 +128,25 @@ public class ResolutionSetting {
         if (isPictureSizeSettingSet) {
             pictureSize = SettingsUtil.sizeFromSettingString(
                     mSettingsManager.getString(SettingsManager.SCOPE_GLOBAL,
-                          pictureSizeSettingKey));
+                            pictureSizeSettingKey));
             isPictureSizeBlacklisted = pictureSize == null ||
-                  ResolutionUtil.isBlackListed(pictureSize, blacklist);
+                    ResolutionUtil.isBlackListed(pictureSize, blacklist);
         }
 
-        if (!isPictureSizeSettingSet || isPictureSizeBlacklisted){
+        // Due to b/21758681, it is possible that an invalid picture size has
+        // been saved to the settings. Therefore, picture size is set AND is not
+        // blacklisted, but completely invalid. In these cases, need to take the
+        // fallback, instead of the saved value. This logic should now save a
+        // valid picture size to the settings and self-correct the state of the
+        // settings.
+        final boolean isPictureSizeFromSettingsValid =
+                pictureSize.width() > 0 && pictureSize.height() > 0;
+
+        if (!isPictureSizeSettingSet || isPictureSizeBlacklisted || !isPictureSizeFromSettingsValid) {
             final Rational aspectRatio = ResolutionUtil.ASPECT_RATIO_4x3;
 
             OneCameraCharacteristics cameraCharacteristics =
-                  mOneCameraManager.getOneCameraCharacteristics(cameraId);
+                    mOneCameraManager.getOneCameraCharacteristics(cameraId);
 
             final List<Size> supportedPictureSizes =
                     ResolutionUtil.filterBlackListedSizes(
@@ -149,12 +160,17 @@ public class ResolutionSetting {
                     SettingsUtil.sizeToSettingString(fallbackPictureSize));
             pictureSize = fallbackPictureSize;
             Log.e(TAG, "Picture size setting is not set. Choose " + fallbackPictureSize);
+            // Crash here if invariants are violated
+            Preconditions.checkNotNull(fallbackPictureSize);
+            Preconditions.checkState(fallbackPictureSize.width() > 0
+                    && fallbackPictureSize.height() > 0);
         }
         return pictureSize;
     }
 
     /**
-     * Obtains the preferred picture aspect ratio in terms of the picture size setting.
+     * Obtains the preferred picture aspect ratio in terms of the picture size
+     * setting.
      *
      * @param cameraId The specific camera device.
      * @return The preferred picture aspect ratio.
@@ -165,4 +181,4 @@ public class ResolutionSetting {
         Size pictureSize = getPictureSize(cameraId, facing);
         return new Rational(pictureSize.getWidth(), pictureSize.getHeight());
     }
-}
\ No newline at end of file
+}
index 93a9ead..73586d0 100644 (file)
@@ -24,6 +24,7 @@ import com.android.camera.exif.Rational;
 import com.android.camera.util.AndroidServices;
 import com.android.camera.util.ApiHelper;
 import com.android.camera.util.Size;
+
 import com.google.common.collect.Lists;
 
 import java.math.BigInteger;
@@ -359,15 +360,35 @@ public class ResolutionUtil {
     }
 
     /**
-     * Selects the maximal resolution for the given aspect ratio from all available resolutions.
+     * Selects the maximal resolution for the given desired aspect ratio from all available
+     * resolutions.  If no resolution exists for the desired aspect ratio, return a resolution
+     * with the maximum number of pixels.
      *
      * @param desiredAspectRatio The desired aspect ratio.
      * @param sizes All available resolutions.
-     * @return The maximal resolution for 4x3 aspect ratio
+     * @return The maximal resolution for desired aspect ratio ; if no sizes are found, then
+     *      return size of (0,0)
      */
     public static Size getLargestPictureSize(Rational desiredAspectRatio, List<Size> sizes) {
-        int maxPixelNum = 0;
+        int maxPixelNumNoAspect = 0;
         Size maxSize = new Size(0, 0);
+
+        // Fix for b/21758681
+        // Do first pass with the candidate with closest size, regardless of aspect ratio,
+        // to loosen the requirement of valid preview sizes.  As long as one size exists
+        // in the list, we should pass back a valid size.
+        for (Size size : sizes) {
+            int pixelNum = size.getWidth() * size.getHeight();
+            if (pixelNum > maxPixelNumNoAspect) {
+                maxPixelNumNoAspect = pixelNum;
+                maxSize = size;
+            }
+        }
+
+        // With second pass, override first pass with the candidate with closest
+        // size AND similar aspect ratio.  If there are no valid candidates are found
+        // in the second pass, take the candidate from the first pass.
+        int maxPixelNumWithAspect = 0;
         for (Size size : sizes) {
             Rational aspectRatio = getAspectRatio(size);
             // Skip if the aspect ratio is not desired.
@@ -375,11 +396,12 @@ public class ResolutionUtil {
                 continue;
             }
             int pixelNum = size.getWidth() * size.getHeight();
-            if (pixelNum > maxPixelNum) {
-                maxPixelNum = pixelNum;
+            if (pixelNum > maxPixelNumWithAspect) {
+                maxPixelNumWithAspect = pixelNum;
                 maxSize = size;
             }
         }
+
         return maxSize;
     }