import com.android.camera.util.GservicesHelper;
import com.android.camera.util.Size;
+import com.google.common.base.Preconditions;
+
import java.util.List;
/**
* 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;
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(
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.
Size pictureSize = getPictureSize(cameraId, facing);
return new Rational(pictureSize.getWidth(), pictureSize.getHeight());
}
-}
\ No newline at end of file
+}
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;
}
/**
- * 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.
continue;
}
int pixelNum = size.getWidth() * size.getHeight();
- if (pixelNum > maxPixelNum) {
- maxPixelNum = pixelNum;
+ if (pixelNum > maxPixelNumWithAspect) {
+ maxPixelNumWithAspect = pixelNum;
maxSize = size;
}
}
+
return maxSize;
}