Util.java revision 9e1fcfe35695fd1e71d6c86f28075ca356e5bad5
16d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim/*
26d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Copyright (C) 2009 The Android Open Source Project
36d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *
46d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Licensed under the Apache License, Version 2.0 (the "License");
56d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * you may not use this file except in compliance with the License.
66d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * You may obtain a copy of the License at
76d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *
86d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *      http://www.apache.org/licenses/LICENSE-2.0
96d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim *
106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Unless required by applicable law or agreed to in writing, software
116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * distributed under the License is distributed on an "AS IS" BASIS,
126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * See the License for the specific language governing permissions and
146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * limitations under the License.
156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */
166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimpackage com.android.camera;
186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.app.Activity;
206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.app.AlertDialog;
216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.content.Context;
226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.content.DialogInterface;
236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.graphics.Bitmap;
246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.graphics.BitmapFactory;
256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.graphics.Matrix;
266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.Camera;
276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.Camera.Parameters;
286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.hardware.Camera.Size;
296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.telephony.TelephonyManager;
306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.util.Log;
316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.view.Display;
326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.view.Surface;
336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.view.View;
346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.view.animation.Animation;
356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport android.view.animation.TranslateAnimation;
366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.io.Closeable;
386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.lang.reflect.Method;
396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.util.List;
406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimimport java.util.StringTokenizer;
416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim/**
436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim * Collection of utility functions used in this package.
446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim */
456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kimpublic class Util {
466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final String TAG = "Util";
476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final int DIRECTION_LEFT = 0;
486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final int DIRECTION_RIGHT = 1;
496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final int DIRECTION_UP = 2;
506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final int DIRECTION_DOWN = 3;
516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public static final String REVIEW_ACTION = "com.android.camera.action.REVIEW";
536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    // Private intent extras. Test only.
556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static final String EXTRAS_CAMERA_FACING =
566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            "android.intent.extras.CAMERA_FACING";
576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private Util() {
596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    // Rotates the bitmap by the specified degree.
626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    // If a new bitmap is created, the original bitmap is recycled.
636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public static Bitmap rotate(Bitmap b, int degrees) {
646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return rotateAndMirror(b, degrees, false);
656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    // Rotates and/or mirrors the bitmap. If a new bitmap is created, the
686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    // original bitmap is recycled.
696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public static Bitmap rotateAndMirror(Bitmap b, int degrees, boolean mirror) {
706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if ((degrees != 0 || mirror) && b != null) {
716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Matrix m = new Matrix();
726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            m.setRotate(degrees,
736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    (float) b.getWidth() / 2, (float) b.getHeight() / 2);
746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (mirror) {
756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                m.postScale(-1, 1);
766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                degrees = (degrees + 360) % 360;
776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                if (degrees == 0 || degrees == 180) {
786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    m.postTranslate((float) b.getWidth(), 0);
796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                } else if (degrees == 90 || degrees == 270) {
806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    m.postTranslate((float) b.getHeight(), 0);
816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                } else {
826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    throw new IllegalArgumentException("Invalid degrees=" + degrees);
836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            try {
876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                Bitmap b2 = Bitmap.createBitmap(
886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                        b, 0, 0, b.getWidth(), b.getHeight(), m, true);
896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                if (b != b2) {
906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    b.recycle();
916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    b = b2;
926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            } catch (OutOfMemoryError ex) {
946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                // We have no memory to rotate. Return the original bitmap.
956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return b;
986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    /*
1016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Compute the sample size as a function of minSideLength
1026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * and maxNumOfPixels.
1036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * minSideLength is used to specify that minimal width or height of a
1046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * bitmap.
1056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * maxNumOfPixels is used to specify the maximal size in pixels that is
1066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * tolerable in terms of memory usage.
1076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
1086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * The function returns a sample size based on the constraints.
1096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Both size and minSideLength can be passed in as -1
1106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * which indicates no care of the corresponding constraint.
1116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * The functions prefers returning a sample size that
1126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * generates a smaller bitmap, unless minSideLength = -1.
1136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     *
1146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Also, the function rounds up the sample size to a power of 2 or multiple
1156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * of 8 because BitmapFactory only honors sample size this way.
1166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * For example, BitmapFactory downsamples an image by 2 even though the
1176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * request is 3. So we round up the sample size to avoid OOM.
1186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
1196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public static int computeSampleSize(BitmapFactory.Options options,
1206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            int minSideLength, int maxNumOfPixels) {
1216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        int initialSize = computeInitialSampleSize(options, minSideLength,
1226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                maxNumOfPixels);
1236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        int roundedSize;
1256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (initialSize <= 8) {
1266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            roundedSize = 1;
1276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            while (roundedSize < initialSize) {
1286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                roundedSize <<= 1;
1296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
1306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } else {
1316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            roundedSize = (initialSize + 7) / 8 * 8;
1326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return roundedSize;
1356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
1366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static int computeInitialSampleSize(BitmapFactory.Options options,
1386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            int minSideLength, int maxNumOfPixels) {
1396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        double w = options.outWidth;
1406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        double h = options.outHeight;
1416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        int lowerBound = (maxNumOfPixels < 0) ? 1 :
1436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
1446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        int upperBound = (minSideLength < 0) ? 128 :
1456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                (int) Math.min(Math.floor(w / minSideLength),
1466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                Math.floor(h / minSideLength));
1476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (upperBound < lowerBound) {
1496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // return the larger one when there is no overlapping zone.
1506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            return lowerBound;
1516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (maxNumOfPixels < 0 && minSideLength < 0) {
1546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            return 1;
1556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } else if (minSideLength < 0) {
1566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            return lowerBound;
1576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } else {
1586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            return upperBound;
1596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
1616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public static Bitmap makeBitmap(byte[] jpegData, int maxNumOfPixels) {
1636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        try {
1646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            BitmapFactory.Options options = new BitmapFactory.Options();
1656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            options.inJustDecodeBounds = true;
1666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length,
1676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    options);
1686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (options.mCancel || options.outWidth == -1
1696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    || options.outHeight == -1) {
1706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                return null;
1716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
1726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            options.inSampleSize = computeSampleSize(
1736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    options, -1, maxNumOfPixels);
1746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            options.inJustDecodeBounds = false;
1756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            options.inDither = false;
1776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            options.inPreferredConfig = Bitmap.Config.ARGB_8888;
1786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            return BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length,
1796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    options);
1806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } catch (OutOfMemoryError ex) {
1816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Log.e(TAG, "Got oom exception ", ex);
1826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            return null;
1836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
1856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public static void closeSilently(Closeable c) {
1876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (c == null) return;
1886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        try {
1896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            c.close();
1906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } catch (Throwable t) {
1916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // do nothing
1926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
1946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
1956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public static void Assert(boolean cond) {
1966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (!cond) {
1976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            throw new AssertionError();
1986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
1996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public static void showFatalErrorAndFinish(
2026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            final Activity activity, String title, String message) {
2036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        DialogInterface.OnClickListener buttonListener =
2046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                new DialogInterface.OnClickListener() {
2056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            public void onClick(DialogInterface dialog, int which) {
2066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                activity.finish();
2076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
2086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        };
2096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        new AlertDialog.Builder(activity)
2106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                .setCancelable(false)
2116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                .setIconAttribute(android.R.attr.alertDialogIcon)
2126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                .setTitle(title)
2136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                .setMessage(message)
2146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                .setNeutralButton(R.string.details_ok, buttonListener)
2156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                .show();
2166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public static <T> T checkNotNull(T object) {
2196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (object == null) throw new NullPointerException();
2206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return object;
2216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public static boolean equals(Object a, Object b) {
2246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return (a == b) || (a == null ? false : a.equals(b));
2256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public static int nextPowerOf2(int n) {
2286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        n -= 1;
2296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        n |= n >>> 16;
2306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        n |= n >>> 8;
2316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        n |= n >>> 4;
2326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        n |= n >>> 2;
2336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        n |= n >>> 1;
2346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return n + 1;
2356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public static float distance(float x, float y, float sx, float sy) {
2386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        float dx = x - sx;
2396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        float dy = y - sy;
2406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return (float) Math.sqrt(dx * dx + dy * dy);
2416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public static int clamp(int x, int min, int max) {
2446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (x > max) return max;
2456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (x < min) return min;
2466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return x;
2476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public static int getDisplayRotation(Activity activity) {
2506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        int rotation = activity.getWindowManager().getDefaultDisplay()
2516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                .getRotation();
2526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        switch (rotation) {
2536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            case Surface.ROTATION_0: return 0;
2546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            case Surface.ROTATION_90: return 90;
2556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            case Surface.ROTATION_180: return 180;
2566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            case Surface.ROTATION_270: return 270;
2576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
2586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return 0;
2596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public static void setCameraDisplayOrientation(int degrees,
2626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            int cameraId, Camera camera) {
2636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // See android.hardware.Camera.setCameraDisplayOrientation for
2646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // documentation.
2656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Camera.CameraInfo info = new Camera.CameraInfo();
2666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Camera.getCameraInfo(cameraId, info);
2676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        int result;
2686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
2696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            result = (info.orientation + degrees) % 360;
2706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            result = (360 - result) % 360;  // compensate the mirror
2716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } else {  // back-facing
2726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            result = (info.orientation - degrees + 360) % 360;
2736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
2746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        camera.setDisplayOrientation(result);
2756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
2766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public static Size getOptimalPreviewSize(Activity currentActivity,
2786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            List<Size> sizes, double targetRatio) {
2796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Use a very small tolerance because we want an exact match.
2806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        final double ASPECT_TOLERANCE = 0.001;
2816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (sizes == null) return null;
2826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Size optimalSize = null;
2846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        double minDiff = Double.MAX_VALUE;
2856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Because of bugs of overlay and layout, we sometimes will try to
2876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // layout the viewfinder in the portrait orientation and thus get the
2886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // wrong size of mSurfaceView. When we change the preview size, the
2896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // new overlay will be created before the old one closed, which causes
2906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // an exception. For now, just get the screen size
2916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Display display = currentActivity.getWindowManager().getDefaultDisplay();
2936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        int targetHeight = Math.min(display.getHeight(), display.getWidth());
2946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
2956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (targetHeight <= 0) {
2966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // We don't know the size of SurfaceView, use screen height
2976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            targetHeight = display.getHeight();
2986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
2996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Try to find an size match aspect ratio and size
3016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        for (Size size : sizes) {
3026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            double ratio = (double) size.width / size.height;
3036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
3046d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (Math.abs(size.height - targetHeight) < minDiff) {
3056d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                optimalSize = size;
3066d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                minDiff = Math.abs(size.height - targetHeight);
3076d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
3086d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
3096d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3106d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Cannot find the one match the aspect ratio. This should not happen.
3116d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        // Ignore the requirement.
3126d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (optimalSize == null) {
3136d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Log.w(TAG, "No preview size match the aspect ratio");
3146d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            minDiff = Double.MAX_VALUE;
3156d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            for (Size size : sizes) {
3166d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                if (Math.abs(size.height - targetHeight) < minDiff) {
3176d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    optimalSize = size;
3186d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    minDiff = Math.abs(size.height - targetHeight);
3196d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                }
3206d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
3216d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
3226d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return optimalSize;
3236d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
3246d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3256d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public static void dumpParameters(Parameters parameters) {
3266d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        String flattened = parameters.flatten();
3276d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        StringTokenizer tokenizer = new StringTokenizer(flattened, ";");
3286d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        Log.d(TAG, "Dump all camera parameters:");
3296d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        while (tokenizer.hasMoreElements()) {
3306d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Log.d(TAG, tokenizer.nextToken());
3316d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
3326d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
3336d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3346d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim   /**
3356d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     * Returns whether the device is voice-capable (meaning, it can do MMS).
3366d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim     */
3376d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public static boolean isMmsCapable(Context context) {
3386d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        TelephonyManager telephonyManager = (TelephonyManager)
3396d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                context.getSystemService(Context.TELEPHONY_SERVICE);
3406d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (telephonyManager == null) {
3416d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            return false;
3426d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
3436d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3446d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        try {
3456d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Class partypes[] = new Class[0];
3466d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Method sIsVoiceCapable = TelephonyManager.class.getMethod(
3476d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                    "isVoiceCapable", partypes);
3486d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3496d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Object arglist[] = new Object[0];
3506d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            Object retobj = sIsVoiceCapable.invoke(telephonyManager, arglist);
3516d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            return (Boolean) retobj;
3526d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } catch (java.lang.reflect.InvocationTargetException ite) {
3536d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Failure, must be another device.
3546d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Assume that it is voice capable.
3556d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } catch (IllegalAccessException iae) {
3566d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Failure, must be an other device.
3576d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Assume that it is voice capable.
3586d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } catch (NoSuchMethodException nsme) {
3596d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
3606d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return true;
3616d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
3626d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3636d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    // This is for test only. Allow the camera to launch the specific camera.
3646d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public static int getCameraFacingIntentExtras(Activity currentActivity) {
3656d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        int cameraId = -1;
3666d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3676d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        int intentCameraId =
3686d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                currentActivity.getIntent().getIntExtra(Util.EXTRAS_CAMERA_FACING, -1);
3696d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3706d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        if (isFrontCameraIntent(intentCameraId)) {
3716d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Check if the front camera exist
3726d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            int frontCameraId = CameraHolder.instance().getFrontCameraId();
3736d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (frontCameraId != -1) {
3746d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                cameraId = frontCameraId;
3756d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
3766d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        } else if (isBackCameraIntent(intentCameraId)) {
3776d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            // Check if the back camera exist
3786d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            int backCameraId = CameraHolder.instance().getBackCameraId();
3796d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            if (backCameraId != -1) {
3806d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                cameraId = backCameraId;
3816d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim            }
3826d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        }
3836d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return cameraId;
3846d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
3856d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3866d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static boolean isFrontCameraIntent(int intentCameraId) {
3876d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return (intentCameraId == android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT);
3886d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
3896d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3906d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static boolean isBackCameraIntent(int intentCameraId) {
3916d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return (intentCameraId == android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK);
3926d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
3936d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3946d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    private static int mLocation[] = new int[2];
3956d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim
3966d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    // This method is not thread-safe.
3976d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    public static boolean pointInView(float x, float y, View v) {
3986d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        v.getLocationInWindow(mLocation);
3996d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim        return x >= mLocation[0] && x < (mLocation[0] + v.getWidth())
4006d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim                && y >= mLocation[1] && y < (mLocation[1] + v.getHeight());
4016d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim    }
4026d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim}
4036d8fd0a23fdc01b9414202c3de9bba41222583e6Hyungtae Tim Kim