From 8d8b329da25456adb5ee45e0450680654114e125 Mon Sep 17 00:00:00 2001 From: I-Jong Lin Date: Wed, 10 Jun 2015 17:10:30 -0700 Subject: [PATCH] Fix for invalidated resolutions via upgrade 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 --- .../android/camera/settings/ResolutionSetting.java | 30 +++++++++++++++----- .../android/camera/settings/ResolutionUtil.java | 32 ++++++++++++++++++---- 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/com/android/camera/settings/ResolutionSetting.java b/src/com/android/camera/settings/ResolutionSetting.java index 74524affd..5b8f1d940 100644 --- a/src/com/android/camera/settings/ResolutionSetting.java +++ b/src/com/android/camera/settings/ResolutionSetting.java @@ -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 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 +} diff --git a/src/com/android/camera/settings/ResolutionUtil.java b/src/com/android/camera/settings/ResolutionUtil.java index 93a9ead1e..73586d07f 100644 --- a/src/com/android/camera/settings/ResolutionUtil.java +++ b/src/com/android/camera/settings/ResolutionUtil.java @@ -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 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; } -- 2.11.0