Fix the camera preview demo.

The preview size will be checked now in Camera HAL. So, we change the code to
get the supported preview sizes and find one of the size that match the
surface's width and height.
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.java b/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.java
index e3cf976..171c885 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.java
@@ -19,24 +19,27 @@
 import android.app.Activity;
 import android.content.Context;
 import android.hardware.Camera;
+import android.hardware.Camera.Size;
 import android.os.Bundle;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 import android.view.Window;
+
 import java.io.IOException;
+import java.util.List;
 
 // ----------------------------------------------------------------------
 
-public class CameraPreview extends Activity {    
+public class CameraPreview extends Activity {
     private Preview mPreview;
-    
+
     @Override
 	protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        
+
         // Hide the window title.
         requestWindowFeature(Window.FEATURE_NO_TITLE);
-    
+
         // Create our Preview view and set it as the content of our activity.
         mPreview = new Preview(this);
         setContentView(mPreview);
@@ -49,10 +52,10 @@
 class Preview extends SurfaceView implements SurfaceHolder.Callback {
     SurfaceHolder mHolder;
     Camera mCamera;
-    
+
     Preview(Context context) {
         super(context);
-        
+
         // Install a SurfaceHolder.Callback so we get notified when the
         // underlying surface is created and destroyed.
         mHolder = getHolder();
@@ -82,11 +85,49 @@
         mCamera = null;
     }
 
+
+    private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
+        final double ASPECT_TOLERANCE = 0.05;
+        double targetRatio = (double) w / h;
+        if (sizes == null) return null;
+
+        Size optimalSize = null;
+        double minDiff = Double.MAX_VALUE;
+
+        int targetHeight = h;
+
+        // Try to find an size match aspect ratio and size
+        for (Size size : sizes) {
+            double ratio = (double) size.width / size.height;
+            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
+            if (Math.abs(size.height - targetHeight) < minDiff) {
+                optimalSize = size;
+                minDiff = Math.abs(size.height - targetHeight);
+            }
+        }
+
+        // Cannot find the one match the aspect ratio, ignore the requirement
+        if (optimalSize == null) {
+            minDiff = Double.MAX_VALUE;
+            for (Size size : sizes) {
+                if (Math.abs(size.height - targetHeight) < minDiff) {
+                    optimalSize = size;
+                    minDiff = Math.abs(size.height - targetHeight);
+                }
+            }
+        }
+        return optimalSize;
+    }
+
     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
         // Now that the size is known, set up the camera parameters and begin
         // the preview.
         Camera.Parameters parameters = mCamera.getParameters();
-        parameters.setPreviewSize(w, h);
+
+        List<Size> sizes = parameters.getSupportedPreviewSizes();
+        Size optimalSize = getOptimalPreviewSize(sizes, w, h);
+        parameters.setPreviewSize(optimalSize.width, optimalSize.height);
+
         mCamera.setParameters(parameters);
         mCamera.startPreview();
     }