OSDN Git Service

Null check when evaluating valid resolution size
[android-x86/packages-apps-Camera2.git] / src / com / android / camera / settings / ResolutionSetting.java
index 6ef2406..50ee90c 100644 (file)
 package com.android.camera.settings;
 
 import android.content.ContentResolver;
+import android.graphics.ImageFormat;
+
 import com.android.camera.debug.Log;
+import com.android.camera.device.CameraId;
 import com.android.camera.exif.Rational;
 import com.android.camera.one.OneCamera;
+import com.android.camera.one.OneCamera.Facing;
 import com.android.camera.one.OneCameraAccessException;
 import com.android.camera.one.OneCameraCharacteristics;
 import com.android.camera.one.OneCameraManager;
 import com.android.camera.util.GservicesHelper;
 import com.android.camera.util.Size;
 
-import android.graphics.ImageFormat;
+import com.google.common.base.Preconditions;
 
 import java.util.List;
 
@@ -42,7 +46,8 @@ public class ResolutionSetting {
     private final String mResolutionBlackListBack;
     private final String mResolutionBlackListFront;
 
-    public ResolutionSetting(SettingsManager settingsManager, OneCameraManager oneCameraManager,
+    public ResolutionSetting(SettingsManager settingsManager,
+            OneCameraManager oneCameraManager,
             ContentResolver contentResolver) {
         mSettingsManager = settingsManager;
         mOneCameraManager = oneCameraManager;
@@ -55,13 +60,15 @@ public class ResolutionSetting {
      * Changes the picture size settings for the cameras with specified facing.
      * Pick the largest picture size with the specified aspect ratio.
      *
-     * @param cameraFacing The specified direction that the camera is facing.
+     * @param cameraId The specific camera device.
      * @param aspectRatio The chosen aspect ratio.
      */
-    public void setPictureAspectRatio(OneCamera.Facing cameraFacing, Rational aspectRatio)
+    public void setPictureAspectRatio(CameraId cameraId, Rational aspectRatio)
             throws OneCameraAccessException {
         OneCameraCharacteristics cameraCharacteristics =
-                mOneCameraManager.getCameraCharacteristics(cameraFacing);
+                mOneCameraManager.getOneCameraCharacteristics(cameraId);
+
+        Facing cameraFacing = cameraCharacteristics.getCameraDirection();
 
         // Pick the largest picture size with the selected aspect ratio and save
         // the choice for front camera.
@@ -70,10 +77,19 @@ public class ResolutionSetting {
         final String blacklist = cameraFacing == OneCamera.Facing.FRONT ? mResolutionBlackListFront
                 : mResolutionBlackListBack;
 
-        final List<Size> supportedPictureSizes =
-                ResolutionUtil.filterBlackListedSizes(
-                        cameraCharacteristics.getSupportedPictureSizes(ImageFormat.JPEG),
-                        blacklist);
+        // All resolutions supported by the camera.
+        List<Size> supportedPictureSizes = cameraCharacteristics
+                .getSupportedPictureSizes(ImageFormat.JPEG);
+
+        // Filter sizes which we are showing to the user in settings.
+        // This might also add some new resolution we support on some devices
+        // non-natively.
+        supportedPictureSizes = ResolutionUtil.getDisplayableSizesFromSupported(
+                supportedPictureSizes, cameraFacing == OneCamera.Facing.BACK);
+
+        // Filter the remaining sizes through our backlist.
+        supportedPictureSizes = ResolutionUtil.filterBlackListedSizes(supportedPictureSizes,
+                blacklist);
 
         final Size chosenPictureSize =
                 ResolutionUtil.getLargestPictureSize(aspectRatio, supportedPictureSizes);
@@ -85,11 +101,11 @@ public class ResolutionSetting {
 
     /**
      * Reads the picture size setting for the cameras with specified facing.
-     *
-     * @param cameraFacing The specified direction that the camera is facing.
-     * @return The preferred picture size.
+     * This specifically avoids reading camera characteristics unless the size
+     * is blacklisted or is not cached to prevent a crash.
      */
-    public Size getPictureSize(OneCamera.Facing cameraFacing) throws OneCameraAccessException {
+    public Size getPictureSize(CameraId cameraId, Facing cameraFacing)
+            throws OneCameraAccessException {
         final String pictureSizeSettingKey = cameraFacing == OneCamera.Facing.FRONT ?
                 Keys.KEY_PICTURE_SIZE_FRONT : Keys.KEY_PICTURE_SIZE_BACK;
 
@@ -111,15 +127,27 @@ public class ResolutionSetting {
         // If a picture size is set, check whether it's blacklisted.
         if (isPictureSizeSettingSet) {
             pictureSize = SettingsUtil.sizeFromSettingString(
-                    mSettingsManager.getString(SettingsManager.SCOPE_GLOBAL, pictureSizeSettingKey));
-            isPictureSizeBlacklisted = ResolutionUtil.isBlackListed(pictureSize, blacklist);
+                    mSettingsManager.getString(SettingsManager.SCOPE_GLOBAL,
+                            pictureSizeSettingKey));
+            isPictureSizeBlacklisted = pictureSize == null ||
+                    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 != null &&
+                pictureSize.width() > 0 && pictureSize.height() > 0;
+
+        if (!isPictureSizeSettingSet || isPictureSizeBlacklisted || !isPictureSizeFromSettingsValid) {
             final Rational aspectRatio = ResolutionUtil.ASPECT_RATIO_4x3;
 
-            final OneCameraCharacteristics cameraCharacteristics =
-                    mOneCameraManager.getCameraCharacteristics(cameraFacing);
+            OneCameraCharacteristics cameraCharacteristics =
+                    mOneCameraManager.getOneCameraCharacteristics(cameraId);
+
             final List<Size> supportedPictureSizes =
                     ResolutionUtil.filterBlackListedSizes(
                             cameraCharacteristics.getSupportedPictureSizes(ImageFormat.JPEG),
@@ -132,20 +160,25 @@ 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 cameraFacing The specified direction that the camera is facing.
+     * @param cameraId The specific camera device.
      * @return The preferred picture aspect ratio.
      * @throws OneCameraAccessException
      */
-    public Rational getPictureAspectRatio(OneCamera.Facing cameraFacing)
+    public Rational getPictureAspectRatio(CameraId cameraId, Facing facing)
             throws OneCameraAccessException {
-        Size pictureSize = getPictureSize(cameraFacing);
+        Size pictureSize = getPictureSize(cameraId, facing);
         return new Rational(pictureSize.getWidth(), pictureSize.getHeight());
     }
-}
\ No newline at end of file
+}