Home | History | Annotate | Download | only in hardware
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.hardware;
     18 
     19 import java.lang.ref.WeakReference;
     20 import java.util.ArrayList;
     21 import java.util.HashMap;
     22 import java.util.List;
     23 import java.util.StringTokenizer;
     24 import java.io.IOException;
     25 
     26 import android.util.Log;
     27 import android.view.Surface;
     28 import android.view.SurfaceHolder;
     29 import android.graphics.ImageFormat;
     30 import android.os.Handler;
     31 import android.os.Looper;
     32 import android.os.Message;
     33 
     34 /**
     35  * The Camera class is used to connect/disconnect with the camera service,
     36  * set capture settings, start/stop preview, snap a picture, and retrieve
     37  * frames for encoding for video.
     38  * <p>There is no default constructor for this class. Use {@link #open()} to
     39  * get a Camera object.</p>
     40  *
     41  * <p>In order to use the device camera, you must declare the
     42  * {@link android.Manifest.permission#CAMERA} permission in your Android
     43  * Manifest. Also be sure to include the
     44  * <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">&lt;uses-feature></a>
     45  * manifest element in order to declare camera features used by your application.
     46  * For example, if you use the camera and auto-focus feature, your Manifest
     47  * should include the following:</p>
     48  * <pre> &lt;uses-permission android:name="android.permission.CAMERA" />
     49  * &lt;uses-feature android:name="android.hardware.camera" />
     50  * &lt;uses-feature android:name="android.hardware.camera.autofocus" /></pre>
     51  *
     52  * <p class="caution"><strong>Caution:</strong> Different Android-powered devices
     53  * may have different hardware specifications, such as megapixel ratings and
     54  * auto-focus capabilities. In order for your application to be compatible with
     55  * more devices, you should not make assumptions about the device camera
     56  * specifications.</p>
     57  */
     58 public class Camera {
     59     private static final String TAG = "Camera";
     60 
     61     // These match the enums in frameworks/base/include/ui/Camera.h
     62     private static final int CAMERA_MSG_ERROR            = 0x001;
     63     private static final int CAMERA_MSG_SHUTTER          = 0x002;
     64     private static final int CAMERA_MSG_FOCUS            = 0x004;
     65     private static final int CAMERA_MSG_ZOOM             = 0x008;
     66     private static final int CAMERA_MSG_PREVIEW_FRAME    = 0x010;
     67     private static final int CAMERA_MSG_VIDEO_FRAME      = 0x020;
     68     private static final int CAMERA_MSG_POSTVIEW_FRAME   = 0x040;
     69     private static final int CAMERA_MSG_RAW_IMAGE        = 0x080;
     70     private static final int CAMERA_MSG_COMPRESSED_IMAGE = 0x100;
     71     private static final int CAMERA_MSG_ALL_MSGS         = 0x1FF;
     72 
     73     private int mNativeContext; // accessed by native methods
     74     private EventHandler mEventHandler;
     75     private ShutterCallback mShutterCallback;
     76     private PictureCallback mRawImageCallback;
     77     private PictureCallback mJpegCallback;
     78     private PreviewCallback mPreviewCallback;
     79     private PictureCallback mPostviewCallback;
     80     private AutoFocusCallback mAutoFocusCallback;
     81     private OnZoomChangeListener mZoomListener;
     82     private ErrorCallback mErrorCallback;
     83     private boolean mOneShot;
     84     private boolean mWithBuffer;
     85 
     86     /**
     87      * Returns a new Camera object.
     88      */
     89     public static Camera open() {
     90         return new Camera();
     91     }
     92 
     93     Camera() {
     94         mShutterCallback = null;
     95         mRawImageCallback = null;
     96         mJpegCallback = null;
     97         mPreviewCallback = null;
     98         mPostviewCallback = null;
     99         mZoomListener = null;
    100 
    101         Looper looper;
    102         if ((looper = Looper.myLooper()) != null) {
    103             mEventHandler = new EventHandler(this, looper);
    104         } else if ((looper = Looper.getMainLooper()) != null) {
    105             mEventHandler = new EventHandler(this, looper);
    106         } else {
    107             mEventHandler = null;
    108         }
    109 
    110         native_setup(new WeakReference<Camera>(this));
    111     }
    112 
    113     protected void finalize() {
    114         native_release();
    115     }
    116 
    117     private native final void native_setup(Object camera_this);
    118     private native final void native_release();
    119 
    120 
    121     /**
    122      * Disconnects and releases the Camera object resources.
    123      * <p>It is recommended that you call this as soon as you're done with the
    124      * Camera object.</p>
    125      */
    126     public final void release() {
    127         native_release();
    128     }
    129 
    130     /**
    131      * Reconnect to the camera after passing it to MediaRecorder. To save
    132      * setup/teardown time, a client of Camera can pass an initialized Camera
    133      * object to a MediaRecorder to use for video recording. Once the
    134      * MediaRecorder is done with the Camera, this method can be used to
    135      * re-establish a connection with the camera hardware. NOTE: The Camera
    136      * object must first be unlocked by the process that owns it before it
    137      * can be connected to another process.
    138      *
    139      * @throws IOException if the method fails.
    140      */
    141     public native final void reconnect() throws IOException;
    142 
    143     /**
    144      * Lock the camera to prevent other processes from accessing it. To save
    145      * setup/teardown time, a client of Camera can pass an initialized Camera
    146      * object to another process. This method is used to re-lock the Camera
    147      * object prevent other processes from accessing it. By default, the
    148      * Camera object is locked. Locking it again from the same process will
    149      * have no effect. Attempting to lock it from another process if it has
    150      * not been unlocked will fail.
    151      *
    152      * @throws RuntimeException if the method fails.
    153      */
    154     public native final void lock();
    155 
    156     /**
    157      * Unlock the camera to allow another process to access it. To save
    158      * setup/teardown time, a client of Camera can pass an initialized Camera
    159      * object to another process. This method is used to unlock the Camera
    160      * object before handing off the Camera object to the other process.
    161      *
    162      * @throws RuntimeException if the method fails.
    163      */
    164     public native final void unlock();
    165 
    166     /**
    167      * Sets the SurfaceHolder to be used for a picture preview. If the surface
    168      * changed since the last call, the screen will blank. Nothing happens
    169      * if the same surface is re-set.
    170      *
    171      * @param holder the SurfaceHolder upon which to place the picture preview
    172      * @throws IOException if the method fails.
    173      */
    174     public final void setPreviewDisplay(SurfaceHolder holder) throws IOException {
    175         if (holder != null) {
    176             setPreviewDisplay(holder.getSurface());
    177         } else {
    178             setPreviewDisplay((Surface)null);
    179         }
    180     }
    181 
    182     private native final void setPreviewDisplay(Surface surface);
    183 
    184     /**
    185      * Used to get a copy of each preview frame.
    186      */
    187     public interface PreviewCallback
    188     {
    189         /**
    190          * The callback that delivers the preview frames.
    191          *
    192          * @param data The contents of the preview frame in the format defined
    193          *  by {@link android.graphics.ImageFormat}, which can be queried
    194          *  with {@link android.hardware.Camera.Parameters#getPreviewFormat()}.
    195          *  If {@link android.hardware.Camera.Parameters#setPreviewFormat(int)}
    196          *             is never called, the default will be the YCbCr_420_SP
    197          *             (NV21) format.
    198          * @param camera The Camera service object.
    199          */
    200         void onPreviewFrame(byte[] data, Camera camera);
    201     };
    202 
    203     /**
    204      * Start drawing preview frames to the surface.
    205      */
    206     public native final void startPreview();
    207 
    208     /**
    209      * Stop drawing preview frames to the surface.
    210      */
    211     public native final void stopPreview();
    212 
    213     /**
    214      * Return current preview state.
    215      *
    216      * FIXME: Unhide before release
    217      * @hide
    218      */
    219     public native final boolean previewEnabled();
    220 
    221     /**
    222      * Can be called at any time to instruct the camera to use a callback for
    223      * each preview frame in addition to displaying it.
    224      *
    225      * @param cb A callback object that receives a copy of each preview frame.
    226      *           Pass null to stop receiving callbacks at any time.
    227      */
    228     public final void setPreviewCallback(PreviewCallback cb) {
    229         mPreviewCallback = cb;
    230         mOneShot = false;
    231         mWithBuffer = false;
    232         // Always use one-shot mode. We fake camera preview mode by
    233         // doing one-shot preview continuously.
    234         setHasPreviewCallback(cb != null, false);
    235     }
    236 
    237     /**
    238      * Installs a callback to retrieve a single preview frame, after which the
    239      * callback is cleared.
    240      *
    241      * @param cb A callback object that receives a copy of the preview frame.
    242      */
    243     public final void setOneShotPreviewCallback(PreviewCallback cb) {
    244         mPreviewCallback = cb;
    245         mOneShot = true;
    246         mWithBuffer = false;
    247         setHasPreviewCallback(cb != null, false);
    248     }
    249 
    250     private native final void setHasPreviewCallback(boolean installed, boolean manualBuffer);
    251 
    252     /**
    253      * Installs a callback which will get called as long as there are buffers in the
    254      * preview buffer queue, which minimizes dynamic allocation of preview buffers.
    255      *
    256      * Apps must call addCallbackBuffer to explicitly register the buffers to use, or no callbacks
    257      * will be received. addCallbackBuffer may be safely called before or after
    258      * a call to setPreviewCallbackWithBuffer with a non-null callback parameter.
    259      *
    260      * The buffer queue will be cleared upon any calls to setOneShotPreviewCallback,
    261      * setPreviewCallback, or to this method with a null callback parameter.
    262      *
    263      * @param cb A callback object that receives a copy of the preview frame.  A null value will clear the queue.
    264      */
    265     public final void setPreviewCallbackWithBuffer(PreviewCallback cb) {
    266         mPreviewCallback = cb;
    267         mOneShot = false;
    268         mWithBuffer = true;
    269         setHasPreviewCallback(cb != null, true);
    270     }
    271 
    272     /**
    273      * Adds a pre-allocated buffer to the preview callback buffer queue.
    274      * Applications can add one or more buffers to the queue. When a preview
    275      * frame arrives and there is still available buffer, buffer will be filled
    276      * and it is removed from the queue. Then preview callback is invoked with
    277      * the buffer. If a frame arrives and there is no buffer left, the frame is
    278      * discarded. Applications should add the buffers back when they finish the
    279      * processing.
    280      *
    281      * The image format of the callback buffer can be read from {@link
    282      * android.hardware.Camera.Parameters#getPreviewFormat()}. bitsPerPixel can
    283      * be read from {@link android.graphics.ImageFormat#getBitsPerPixel(int)}.
    284      * Preview width and height can be determined from getPreviewSize.
    285      *
    286      * Alternatively, a buffer from a previous callback may be passed in or used
    287      * to determine the size of new preview frame buffers.
    288      *
    289      * @param callbackBuffer The buffer to register. Size should be width * height * bitsPerPixel / 8.
    290      * @see #setPreviewCallbackWithBuffer(PreviewCallback)
    291      */
    292     public native final void addCallbackBuffer(byte[] callbackBuffer);
    293 
    294     private class EventHandler extends Handler
    295     {
    296         private Camera mCamera;
    297 
    298         public EventHandler(Camera c, Looper looper) {
    299             super(looper);
    300             mCamera = c;
    301         }
    302 
    303         @Override
    304         public void handleMessage(Message msg) {
    305             switch(msg.what) {
    306             case CAMERA_MSG_SHUTTER:
    307                 if (mShutterCallback != null) {
    308                     mShutterCallback.onShutter();
    309                 }
    310                 return;
    311 
    312             case CAMERA_MSG_RAW_IMAGE:
    313                 if (mRawImageCallback != null) {
    314                     mRawImageCallback.onPictureTaken((byte[])msg.obj, mCamera);
    315                 }
    316                 return;
    317 
    318             case CAMERA_MSG_COMPRESSED_IMAGE:
    319                 if (mJpegCallback != null) {
    320                     mJpegCallback.onPictureTaken((byte[])msg.obj, mCamera);
    321                 }
    322                 return;
    323 
    324             case CAMERA_MSG_PREVIEW_FRAME:
    325                 if (mPreviewCallback != null) {
    326                     PreviewCallback cb = mPreviewCallback;
    327                     if (mOneShot) {
    328                         // Clear the callback variable before the callback
    329                         // in case the app calls setPreviewCallback from
    330                         // the callback function
    331                         mPreviewCallback = null;
    332                     } else if (!mWithBuffer) {
    333                         // We're faking the camera preview mode to prevent
    334                         // the app from being flooded with preview frames.
    335                         // Set to oneshot mode again.
    336                         setHasPreviewCallback(true, false);
    337                     }
    338                     cb.onPreviewFrame((byte[])msg.obj, mCamera);
    339                 }
    340                 return;
    341 
    342             case CAMERA_MSG_POSTVIEW_FRAME:
    343                 if (mPostviewCallback != null) {
    344                     mPostviewCallback.onPictureTaken((byte[])msg.obj, mCamera);
    345                 }
    346                 return;
    347 
    348             case CAMERA_MSG_FOCUS:
    349                 if (mAutoFocusCallback != null) {
    350                     mAutoFocusCallback.onAutoFocus(msg.arg1 == 0 ? false : true, mCamera);
    351                 }
    352                 return;
    353 
    354             case CAMERA_MSG_ZOOM:
    355                 if (mZoomListener != null) {
    356                     mZoomListener.onZoomChange(msg.arg1, msg.arg2 != 0, mCamera);
    357                 }
    358                 return;
    359 
    360             case CAMERA_MSG_ERROR :
    361                 Log.e(TAG, "Error " + msg.arg1);
    362                 if (mErrorCallback != null) {
    363                     mErrorCallback.onError(msg.arg1, mCamera);
    364                 }
    365                 return;
    366 
    367             default:
    368                 Log.e(TAG, "Unknown message type " + msg.what);
    369                 return;
    370             }
    371         }
    372     }
    373 
    374     private static void postEventFromNative(Object camera_ref,
    375                                             int what, int arg1, int arg2, Object obj)
    376     {
    377         Camera c = (Camera)((WeakReference)camera_ref).get();
    378         if (c == null)
    379             return;
    380 
    381         if (c.mEventHandler != null) {
    382             Message m = c.mEventHandler.obtainMessage(what, arg1, arg2, obj);
    383             c.mEventHandler.sendMessage(m);
    384         }
    385     }
    386 
    387     /**
    388      * Handles the callback for the camera auto focus.
    389      * <p>Devices that do not support auto-focus will receive a "fake"
    390      * callback to this interface. If your application needs auto-focus and
    391      * should not be installed on devices <em>without</em> auto-focus, you must
    392      * declare that your app uses the
    393      * {@code android.hardware.camera.autofocus} feature, in the
    394      * <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">&lt;uses-feature></a>
    395      * manifest element.</p>
    396      */
    397     public interface AutoFocusCallback
    398     {
    399         /**
    400          * Callback for the camera auto focus. If the camera does not support
    401          * auto-focus and autoFocus is called, onAutoFocus will be called
    402          * immediately with success.
    403          *
    404          * @param success true if focus was successful, false if otherwise
    405          * @param camera  the Camera service object
    406          */
    407         void onAutoFocus(boolean success, Camera camera);
    408     };
    409 
    410     /**
    411      * Starts auto-focus function and registers a callback function to run when
    412      * camera is focused. Only valid after startPreview() has been called.
    413      * Applications should call {@link
    414      * android.hardware.Camera.Parameters#getFocusMode()} to determine if this
    415      * method should be called. If the camera does not support auto-focus, it is
    416      * a no-op and {@link AutoFocusCallback#onAutoFocus(boolean, Camera)}
    417      * callback will be called immediately.
    418      * <p>If your application should not be installed
    419      * on devices without auto-focus, you must declare that your application
    420      * uses auto-focus with the
    421      * <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">&lt;uses-feature></a>
    422      * manifest element.</p>
    423      * <p>If the current flash mode is not
    424      * {@link android.hardware.Camera.Parameters#FLASH_MODE_OFF}, flash may be
    425      * fired during auto-focus depending on the driver.<p>
    426      *
    427      * @param cb the callback to run
    428      */
    429     public final void autoFocus(AutoFocusCallback cb)
    430     {
    431         mAutoFocusCallback = cb;
    432         native_autoFocus();
    433     }
    434     private native final void native_autoFocus();
    435 
    436     /**
    437      * Cancels auto-focus function. If the auto-focus is still in progress,
    438      * this function will cancel it. Whether the auto-focus is in progress
    439      * or not, this function will return the focus position to the default.
    440      * If the camera does not support auto-focus, this is a no-op.
    441      */
    442     public final void cancelAutoFocus()
    443     {
    444         mAutoFocusCallback = null;
    445         native_cancelAutoFocus();
    446     }
    447     private native final void native_cancelAutoFocus();
    448 
    449     /**
    450      * An interface which contains a callback for the shutter closing after taking a picture.
    451      */
    452     public interface ShutterCallback
    453     {
    454         /**
    455          * Can be used to play a shutter sound as soon as the image has been captured, but before
    456          * the data is available.
    457          */
    458         void onShutter();
    459     }
    460 
    461     /**
    462      * Handles the callback for when a picture is taken.
    463      */
    464     public interface PictureCallback {
    465         /**
    466          * Callback for when a picture is taken.
    467          *
    468          * @param data   a byte array of the picture data
    469          * @param camera the Camera service object
    470          */
    471         void onPictureTaken(byte[] data, Camera camera);
    472     };
    473 
    474     /**
    475      * Triggers an asynchronous image capture. The camera service will initiate
    476      * a series of callbacks to the application as the image capture progresses.
    477      * The shutter callback occurs after the image is captured. This can be used
    478      * to trigger a sound to let the user know that image has been captured. The
    479      * raw callback occurs when the raw image data is available (NOTE: the data
    480      * may be null if the hardware does not have enough memory to make a copy).
    481      * The jpeg callback occurs when the compressed image is available. If the
    482      * application does not need a particular callback, a null can be passed
    483      * instead of a callback method.
    484      *
    485      * This method will stop the preview. Applications should not call {@link
    486      * #stopPreview()} before this. After jpeg callback is received,
    487      * applications can call {@link #startPreview()} to restart the preview.
    488      *
    489      * @param shutter   callback after the image is captured, may be null
    490      * @param raw       callback with raw image data, may be null
    491      * @param jpeg      callback with jpeg image data, may be null
    492      */
    493     public final void takePicture(ShutterCallback shutter, PictureCallback raw,
    494             PictureCallback jpeg) {
    495         takePicture(shutter, raw, null, jpeg);
    496     }
    497     private native final void native_takePicture();
    498 
    499     /**
    500      * Triggers an asynchronous image capture. The camera service will initiate
    501      * a series of callbacks to the application as the image capture progresses.
    502      * The shutter callback occurs after the image is captured. This can be used
    503      * to trigger a sound to let the user know that image has been captured. The
    504      * raw callback occurs when the raw image data is available (NOTE: the data
    505      * may be null if the hardware does not have enough memory to make a copy).
    506      * The postview callback occurs when a scaled, fully processed postview
    507      * image is available (NOTE: not all hardware supports this). The jpeg
    508      * callback occurs when the compressed image is available. If the
    509      * application does not need a particular callback, a null can be passed
    510      * instead of a callback method.
    511      *
    512      * This method will stop the preview. Applications should not call {@link
    513      * #stopPreview()} before this. After jpeg callback is received,
    514      * applications can call {@link #startPreview()} to restart the preview.
    515      *
    516      * @param shutter   callback after the image is captured, may be null
    517      * @param raw       callback with raw image data, may be null
    518      * @param postview  callback with postview image data, may be null
    519      * @param jpeg      callback with jpeg image data, may be null
    520      */
    521     public final void takePicture(ShutterCallback shutter, PictureCallback raw,
    522             PictureCallback postview, PictureCallback jpeg) {
    523         mShutterCallback = shutter;
    524         mRawImageCallback = raw;
    525         mPostviewCallback = postview;
    526         mJpegCallback = jpeg;
    527         native_takePicture();
    528     }
    529 
    530     /**
    531      * Zooms to the requested value smoothly. Driver will notify {@link
    532      * OnZoomChangeListener} of the zoom value and whether zoom is stopped at
    533      * the time. For example, suppose the current zoom is 0 and startSmoothZoom
    534      * is called with value 3. Method onZoomChange will be called three times
    535      * with zoom value 1, 2, and 3. The applications can call {@link
    536      * #stopSmoothZoom} to stop the zoom earlier. The applications should not
    537      * call startSmoothZoom again or change the zoom value before zoom stops. If
    538      * the passing zoom value equals to the current zoom value, no zoom callback
    539      * will be generated. This method is supported if {@link
    540      * android.hardware.Camera.Parameters#isSmoothZoomSupported} is true.
    541      *
    542      * @param value zoom value. The valid range is 0 to {@link
    543      *              android.hardware.Camera.Parameters#getMaxZoom}.
    544      * @throws IllegalArgumentException if the zoom value is invalid.
    545      * @throws RuntimeException if the method fails.
    546      */
    547     public native final void startSmoothZoom(int value);
    548 
    549     /**
    550      * Stops the smooth zoom. The applications should wait for the {@link
    551      * OnZoomChangeListener} to know when the zoom is actually stopped. This
    552      * method is supported if {@link
    553      * android.hardware.Camera.Parameters#isSmoothZoomSupported} is true.
    554      *
    555      * @throws RuntimeException if the method fails.
    556      */
    557     public native final void stopSmoothZoom();
    558 
    559     /**
    560      * Set the display orientation. This affects the preview frames and the
    561      * picture displayed after snapshot. This method is useful for portrait
    562      * mode applications.
    563      *
    564      * This does not affect the order of byte array passed in
    565      * {@link PreviewCallback#onPreviewFrame}. This method is not allowed to
    566      * be called during preview.
    567      *
    568      * @param degrees the angle that the picture will be rotated clockwise.
    569      *                Valid values are 0, 90, 180, and 270. The starting
    570      *                position is 0 (landscape).
    571      */
    572     public native final void setDisplayOrientation(int degrees);
    573 
    574     /**
    575      * Interface for a callback to be invoked when zoom value changes.
    576      */
    577     public interface OnZoomChangeListener
    578     {
    579         /**
    580          * Called when the zoom value has changed.
    581          *
    582          * @param zoomValue the current zoom value. In smooth zoom mode, camera
    583          *                  calls this for every new zoom value.
    584          * @param stopped whether smooth zoom is stopped. If the value is true,
    585          *                this is the last zoom update for the application.
    586          *
    587          * @param camera  the Camera service object
    588          * @see #startSmoothZoom(int)
    589          */
    590         void onZoomChange(int zoomValue, boolean stopped, Camera camera);
    591     };
    592 
    593     /**
    594      * Registers a listener to be notified when the zoom value is updated by the
    595      * camera driver during smooth zoom.
    596      *
    597      * @param listener the listener to notify
    598      * @see #startSmoothZoom(int)
    599      */
    600     public final void setZoomChangeListener(OnZoomChangeListener listener)
    601     {
    602         mZoomListener = listener;
    603     }
    604 
    605     // These match the enum in include/ui/Camera.h
    606     /** Unspecified camerar error.  @see #ErrorCallback */
    607     public static final int CAMERA_ERROR_UNKNOWN = 1;
    608     /** Media server died. In this case, the application must release the
    609      * Camera object and instantiate a new one. @see #ErrorCallback */
    610     public static final int CAMERA_ERROR_SERVER_DIED = 100;
    611 
    612     /**
    613      * Handles the camera error callback.
    614      */
    615     public interface ErrorCallback
    616     {
    617         /**
    618          * Callback for camera errors.
    619          * @param error   error code:
    620          * <ul>
    621          * <li>{@link #CAMERA_ERROR_UNKNOWN}
    622          * <li>{@link #CAMERA_ERROR_SERVER_DIED}
    623          * </ul>
    624          * @param camera  the Camera service object
    625          */
    626         void onError(int error, Camera camera);
    627     };
    628 
    629     /**
    630      * Registers a callback to be invoked when an error occurs.
    631      * @param cb the callback to run
    632      */
    633     public final void setErrorCallback(ErrorCallback cb)
    634     {
    635         mErrorCallback = cb;
    636     }
    637 
    638     private native final void native_setParameters(String params);
    639     private native final String native_getParameters();
    640 
    641     /**
    642      * Sets the Parameters for pictures from this Camera service.
    643      *
    644      * @param params the Parameters to use for this Camera service
    645      */
    646     public void setParameters(Parameters params) {
    647         native_setParameters(params.flatten());
    648     }
    649 
    650     /**
    651      * Returns the picture Parameters for this Camera service.
    652      */
    653     public Parameters getParameters() {
    654         Parameters p = new Parameters();
    655         String s = native_getParameters();
    656         p.unflatten(s);
    657         return p;
    658     }
    659 
    660     /**
    661      * Handles the picture size (dimensions).
    662      */
    663     public class Size {
    664         /**
    665          * Sets the dimensions for pictures.
    666          *
    667          * @param w the photo width (pixels)
    668          * @param h the photo height (pixels)
    669          */
    670         public Size(int w, int h) {
    671             width = w;
    672             height = h;
    673         }
    674         /**
    675          * Compares {@code obj} to this size.
    676          *
    677          * @param obj the object to compare this size with.
    678          * @return {@code true} if the width and height of {@code obj} is the
    679          *         same as those of this size. {@code false} otherwise.
    680          */
    681         @Override
    682         public boolean equals(Object obj) {
    683             if (!(obj instanceof Size)) {
    684                 return false;
    685             }
    686             Size s = (Size) obj;
    687             return width == s.width && height == s.height;
    688         }
    689         @Override
    690         public int hashCode() {
    691             return width * 32713 + height;
    692         }
    693         /** width of the picture */
    694         public int width;
    695         /** height of the picture */
    696         public int height;
    697     };
    698 
    699     /**
    700      * Handles the parameters for pictures created by a Camera service.
    701      *
    702      * <p>To make camera parameters take effect, applications have to call
    703      * Camera.setParameters. For example, after setWhiteBalance is called, white
    704      * balance is not changed until Camera.setParameters() is called.
    705      *
    706      * <p>Different devices may have different camera capabilities, such as
    707      * picture size or flash modes. The application should query the camera
    708      * capabilities before setting parameters. For example, the application
    709      * should call getSupportedColorEffects before calling setEffect. If the
    710      * camera does not support color effects, getSupportedColorEffects will
    711      * return null.
    712      */
    713     public class Parameters {
    714         // Parameter keys to communicate with the camera driver.
    715         private static final String KEY_PREVIEW_SIZE = "preview-size";
    716         private static final String KEY_PREVIEW_FORMAT = "preview-format";
    717         private static final String KEY_PREVIEW_FRAME_RATE = "preview-frame-rate";
    718         private static final String KEY_PICTURE_SIZE = "picture-size";
    719         private static final String KEY_PICTURE_FORMAT = "picture-format";
    720         private static final String KEY_JPEG_THUMBNAIL_SIZE = "jpeg-thumbnail-size";
    721         private static final String KEY_JPEG_THUMBNAIL_WIDTH = "jpeg-thumbnail-width";
    722         private static final String KEY_JPEG_THUMBNAIL_HEIGHT = "jpeg-thumbnail-height";
    723         private static final String KEY_JPEG_THUMBNAIL_QUALITY = "jpeg-thumbnail-quality";
    724         private static final String KEY_JPEG_QUALITY = "jpeg-quality";
    725         private static final String KEY_ROTATION = "rotation";
    726         private static final String KEY_GPS_LATITUDE = "gps-latitude";
    727         private static final String KEY_GPS_LONGITUDE = "gps-longitude";
    728         private static final String KEY_GPS_ALTITUDE = "gps-altitude";
    729         private static final String KEY_GPS_TIMESTAMP = "gps-timestamp";
    730         private static final String KEY_GPS_PROCESSING_METHOD = "gps-processing-method";
    731         private static final String KEY_WHITE_BALANCE = "whitebalance";
    732         private static final String KEY_EFFECT = "effect";
    733         private static final String KEY_ANTIBANDING = "antibanding";
    734         private static final String KEY_SCENE_MODE = "scene-mode";
    735         private static final String KEY_FLASH_MODE = "flash-mode";
    736         private static final String KEY_FOCUS_MODE = "focus-mode";
    737         private static final String KEY_FOCAL_LENGTH = "focal-length";
    738         private static final String KEY_HORIZONTAL_VIEW_ANGLE = "horizontal-view-angle";
    739         private static final String KEY_VERTICAL_VIEW_ANGLE = "vertical-view-angle";
    740         private static final String KEY_EXPOSURE_COMPENSATION = "exposure-compensation";
    741         private static final String KEY_MAX_EXPOSURE_COMPENSATION = "max-exposure-compensation";
    742         private static final String KEY_MIN_EXPOSURE_COMPENSATION = "min-exposure-compensation";
    743         private static final String KEY_EXPOSURE_COMPENSATION_STEP = "exposure-compensation-step";
    744         private static final String KEY_ZOOM = "zoom";
    745         private static final String KEY_MAX_ZOOM = "max-zoom";
    746         private static final String KEY_ZOOM_RATIOS = "zoom-ratios";
    747         private static final String KEY_ZOOM_SUPPORTED = "zoom-supported";
    748         private static final String KEY_SMOOTH_ZOOM_SUPPORTED = "smooth-zoom-supported";
    749         // Parameter key suffix for supported values.
    750         private static final String SUPPORTED_VALUES_SUFFIX = "-values";
    751 
    752         private static final String TRUE = "true";
    753 
    754         // Values for white balance settings.
    755         public static final String WHITE_BALANCE_AUTO = "auto";
    756         public static final String WHITE_BALANCE_INCANDESCENT = "incandescent";
    757         public static final String WHITE_BALANCE_FLUORESCENT = "fluorescent";
    758         public static final String WHITE_BALANCE_WARM_FLUORESCENT = "warm-fluorescent";
    759         public static final String WHITE_BALANCE_DAYLIGHT = "daylight";
    760         public static final String WHITE_BALANCE_CLOUDY_DAYLIGHT = "cloudy-daylight";
    761         public static final String WHITE_BALANCE_TWILIGHT = "twilight";
    762         public static final String WHITE_BALANCE_SHADE = "shade";
    763 
    764         // Values for color effect settings.
    765         public static final String EFFECT_NONE = "none";
    766         public static final String EFFECT_MONO = "mono";
    767         public static final String EFFECT_NEGATIVE = "negative";
    768         public static final String EFFECT_SOLARIZE = "solarize";
    769         public static final String EFFECT_SEPIA = "sepia";
    770         public static final String EFFECT_POSTERIZE = "posterize";
    771         public static final String EFFECT_WHITEBOARD = "whiteboard";
    772         public static final String EFFECT_BLACKBOARD = "blackboard";
    773         public static final String EFFECT_AQUA = "aqua";
    774 
    775         // Values for antibanding settings.
    776         public static final String ANTIBANDING_AUTO = "auto";
    777         public static final String ANTIBANDING_50HZ = "50hz";
    778         public static final String ANTIBANDING_60HZ = "60hz";
    779         public static final String ANTIBANDING_OFF = "off";
    780 
    781         // Values for flash mode settings.
    782         /**
    783          * Flash will not be fired.
    784          */
    785         public static final String FLASH_MODE_OFF = "off";
    786 
    787         /**
    788          * Flash will be fired automatically when required. The flash may be fired
    789          * during preview, auto-focus, or snapshot depending on the driver.
    790          */
    791         public static final String FLASH_MODE_AUTO = "auto";
    792 
    793         /**
    794          * Flash will always be fired during snapshot. The flash may also be
    795          * fired during preview or auto-focus depending on the driver.
    796          */
    797         public static final String FLASH_MODE_ON = "on";
    798 
    799         /**
    800          * Flash will be fired in red-eye reduction mode.
    801          */
    802         public static final String FLASH_MODE_RED_EYE = "red-eye";
    803 
    804         /**
    805          * Constant emission of light during preview, auto-focus and snapshot.
    806          * This can also be used for video recording.
    807          */
    808         public static final String FLASH_MODE_TORCH = "torch";
    809 
    810         // Values for scene mode settings.
    811         public static final String SCENE_MODE_AUTO = "auto";
    812         public static final String SCENE_MODE_ACTION = "action";
    813         public static final String SCENE_MODE_PORTRAIT = "portrait";
    814         public static final String SCENE_MODE_LANDSCAPE = "landscape";
    815         public static final String SCENE_MODE_NIGHT = "night";
    816         public static final String SCENE_MODE_NIGHT_PORTRAIT = "night-portrait";
    817         public static final String SCENE_MODE_THEATRE = "theatre";
    818         public static final String SCENE_MODE_BEACH = "beach";
    819         public static final String SCENE_MODE_SNOW = "snow";
    820         public static final String SCENE_MODE_SUNSET = "sunset";
    821         public static final String SCENE_MODE_STEADYPHOTO = "steadyphoto";
    822         public static final String SCENE_MODE_FIREWORKS = "fireworks";
    823         public static final String SCENE_MODE_SPORTS = "sports";
    824         public static final String SCENE_MODE_PARTY = "party";
    825         public static final String SCENE_MODE_CANDLELIGHT = "candlelight";
    826 
    827         /**
    828          * Applications are looking for a barcode. Camera driver will be
    829          * optimized for barcode reading.
    830          */
    831         public static final String SCENE_MODE_BARCODE = "barcode";
    832 
    833         // Values for focus mode settings.
    834         /**
    835          * Auto-focus mode.
    836          */
    837         public static final String FOCUS_MODE_AUTO = "auto";
    838 
    839         /**
    840          * Focus is set at infinity. Applications should not call
    841          * {@link #autoFocus(AutoFocusCallback)} in this mode.
    842          */
    843         public static final String FOCUS_MODE_INFINITY = "infinity";
    844         public static final String FOCUS_MODE_MACRO = "macro";
    845 
    846         /**
    847          * Focus is fixed. The camera is always in this mode if the focus is not
    848          * adjustable. If the camera has auto-focus, this mode can fix the
    849          * focus, which is usually at hyperfocal distance. Applications should
    850          * not call {@link #autoFocus(AutoFocusCallback)} in this mode.
    851          */
    852         public static final String FOCUS_MODE_FIXED = "fixed";
    853 
    854         /**
    855          * Extended depth of field (EDOF). Focusing is done digitally and
    856          * continuously. Applications should not call {@link
    857          * #autoFocus(AutoFocusCallback)} in this mode.
    858          */
    859         public static final String FOCUS_MODE_EDOF = "edof";
    860 
    861         // Formats for setPreviewFormat and setPictureFormat.
    862         private static final String PIXEL_FORMAT_YUV422SP = "yuv422sp";
    863         private static final String PIXEL_FORMAT_YUV420SP = "yuv420sp";
    864         private static final String PIXEL_FORMAT_YUV422I = "yuv422i-yuyv";
    865         private static final String PIXEL_FORMAT_RGB565 = "rgb565";
    866         private static final String PIXEL_FORMAT_JPEG = "jpeg";
    867 
    868         private HashMap<String, String> mMap;
    869 
    870         private Parameters() {
    871             mMap = new HashMap<String, String>();
    872         }
    873 
    874         /**
    875          * Writes the current Parameters to the log.
    876          * @hide
    877          * @deprecated
    878          */
    879         public void dump() {
    880             Log.e(TAG, "dump: size=" + mMap.size());
    881             for (String k : mMap.keySet()) {
    882                 Log.e(TAG, "dump: " + k + "=" + mMap.get(k));
    883             }
    884         }
    885 
    886         /**
    887          * Creates a single string with all the parameters set in
    888          * this Parameters object.
    889          * <p>The {@link #unflatten(String)} method does the reverse.</p>
    890          *
    891          * @return a String with all values from this Parameters object, in
    892          *         semi-colon delimited key-value pairs
    893          */
    894         public String flatten() {
    895             StringBuilder flattened = new StringBuilder();
    896             for (String k : mMap.keySet()) {
    897                 flattened.append(k);
    898                 flattened.append("=");
    899                 flattened.append(mMap.get(k));
    900                 flattened.append(";");
    901             }
    902             // chop off the extra semicolon at the end
    903             flattened.deleteCharAt(flattened.length()-1);
    904             return flattened.toString();
    905         }
    906 
    907         /**
    908          * Takes a flattened string of parameters and adds each one to
    909          * this Parameters object.
    910          * <p>The {@link #flatten()} method does the reverse.</p>
    911          *
    912          * @param flattened a String of parameters (key-value paired) that
    913          *                  are semi-colon delimited
    914          */
    915         public void unflatten(String flattened) {
    916             mMap.clear();
    917 
    918             StringTokenizer tokenizer = new StringTokenizer(flattened, ";");
    919             while (tokenizer.hasMoreElements()) {
    920                 String kv = tokenizer.nextToken();
    921                 int pos = kv.indexOf('=');
    922                 if (pos == -1) {
    923                     continue;
    924                 }
    925                 String k = kv.substring(0, pos);
    926                 String v = kv.substring(pos + 1);
    927                 mMap.put(k, v);
    928             }
    929         }
    930 
    931         public void remove(String key) {
    932             mMap.remove(key);
    933         }
    934 
    935         /**
    936          * Sets a String parameter.
    937          *
    938          * @param key   the key name for the parameter
    939          * @param value the String value of the parameter
    940          */
    941         public void set(String key, String value) {
    942             if (key.indexOf('=') != -1 || key.indexOf(';') != -1) {
    943                 Log.e(TAG, "Key \"" + key + "\" contains invalid character (= or ;)");
    944                 return;
    945             }
    946             if (value.indexOf('=') != -1 || value.indexOf(';') != -1) {
    947                 Log.e(TAG, "Value \"" + value + "\" contains invalid character (= or ;)");
    948                 return;
    949             }
    950 
    951             mMap.put(key, value);
    952         }
    953 
    954         /**
    955          * Sets an integer parameter.
    956          *
    957          * @param key   the key name for the parameter
    958          * @param value the int value of the parameter
    959          */
    960         public void set(String key, int value) {
    961             mMap.put(key, Integer.toString(value));
    962         }
    963 
    964         /**
    965          * Returns the value of a String parameter.
    966          *
    967          * @param key the key name for the parameter
    968          * @return the String value of the parameter
    969          */
    970         public String get(String key) {
    971             return mMap.get(key);
    972         }
    973 
    974         /**
    975          * Returns the value of an integer parameter.
    976          *
    977          * @param key the key name for the parameter
    978          * @return the int value of the parameter
    979          */
    980         public int getInt(String key) {
    981             return Integer.parseInt(mMap.get(key));
    982         }
    983 
    984         /**
    985          * Sets the dimensions for preview pictures.
    986          *
    987          * @param width  the width of the pictures, in pixels
    988          * @param height the height of the pictures, in pixels
    989          */
    990         public void setPreviewSize(int width, int height) {
    991             String v = Integer.toString(width) + "x" + Integer.toString(height);
    992             set(KEY_PREVIEW_SIZE, v);
    993         }
    994 
    995         /**
    996          * Returns the dimensions setting for preview pictures.
    997          *
    998          * @return a Size object with the height and width setting
    999          *          for the preview picture
   1000          */
   1001         public Size getPreviewSize() {
   1002             String pair = get(KEY_PREVIEW_SIZE);
   1003             return strToSize(pair);
   1004         }
   1005 
   1006         /**
   1007          * Gets the supported preview sizes.
   1008          *
   1009          * @return a list of Size object. This method will always return a list
   1010          *         with at least one element.
   1011          */
   1012         public List<Size> getSupportedPreviewSizes() {
   1013             String str = get(KEY_PREVIEW_SIZE + SUPPORTED_VALUES_SUFFIX);
   1014             return splitSize(str);
   1015         }
   1016 
   1017         /**
   1018          * Sets the dimensions for EXIF thumbnail in Jpeg picture. If
   1019          * applications set both width and height to 0, EXIF will not contain
   1020          * thumbnail.
   1021          *
   1022          * @param width  the width of the thumbnail, in pixels
   1023          * @param height the height of the thumbnail, in pixels
   1024          */
   1025         public void setJpegThumbnailSize(int width, int height) {
   1026             set(KEY_JPEG_THUMBNAIL_WIDTH, width);
   1027             set(KEY_JPEG_THUMBNAIL_HEIGHT, height);
   1028         }
   1029 
   1030         /**
   1031          * Returns the dimensions for EXIF thumbnail in Jpeg picture.
   1032          *
   1033          * @return a Size object with the height and width setting for the EXIF
   1034          *         thumbnails
   1035          */
   1036         public Size getJpegThumbnailSize() {
   1037             return new Size(getInt(KEY_JPEG_THUMBNAIL_WIDTH),
   1038                             getInt(KEY_JPEG_THUMBNAIL_HEIGHT));
   1039         }
   1040 
   1041         /**
   1042          * Gets the supported jpeg thumbnail sizes.
   1043          *
   1044          * @return a list of Size object. This method will always return a list
   1045          *         with at least two elements. Size 0,0 (no thumbnail) is always
   1046          *         supported.
   1047          */
   1048         public List<Size> getSupportedJpegThumbnailSizes() {
   1049             String str = get(KEY_JPEG_THUMBNAIL_SIZE + SUPPORTED_VALUES_SUFFIX);
   1050             return splitSize(str);
   1051         }
   1052 
   1053         /**
   1054          * Sets the quality of the EXIF thumbnail in Jpeg picture.
   1055          *
   1056          * @param quality the JPEG quality of the EXIF thumbnail. The range is 1
   1057          *                to 100, with 100 being the best.
   1058          */
   1059         public void setJpegThumbnailQuality(int quality) {
   1060             set(KEY_JPEG_THUMBNAIL_QUALITY, quality);
   1061         }
   1062 
   1063         /**
   1064          * Returns the quality setting for the EXIF thumbnail in Jpeg picture.
   1065          *
   1066          * @return the JPEG quality setting of the EXIF thumbnail.
   1067          */
   1068         public int getJpegThumbnailQuality() {
   1069             return getInt(KEY_JPEG_THUMBNAIL_QUALITY);
   1070         }
   1071 
   1072         /**
   1073          * Sets Jpeg quality of captured picture.
   1074          *
   1075          * @param quality the JPEG quality of captured picture. The range is 1
   1076          *                to 100, with 100 being the best.
   1077          */
   1078         public void setJpegQuality(int quality) {
   1079             set(KEY_JPEG_QUALITY, quality);
   1080         }
   1081 
   1082         /**
   1083          * Returns the quality setting for the JPEG picture.
   1084          *
   1085          * @return the JPEG picture quality setting.
   1086          */
   1087         public int getJpegQuality() {
   1088             return getInt(KEY_JPEG_QUALITY);
   1089         }
   1090 
   1091         /**
   1092          * Sets the rate at which preview frames are received. This is the
   1093          * target frame rate. The actual frame rate depends on the driver.
   1094          *
   1095          * @param fps the frame rate (frames per second)
   1096          */
   1097         public void setPreviewFrameRate(int fps) {
   1098             set(KEY_PREVIEW_FRAME_RATE, fps);
   1099         }
   1100 
   1101         /**
   1102          * Returns the setting for the rate at which preview frames are
   1103          * received. This is the target frame rate. The actual frame rate
   1104          * depends on the driver.
   1105          *
   1106          * @return the frame rate setting (frames per second)
   1107          */
   1108         public int getPreviewFrameRate() {
   1109             return getInt(KEY_PREVIEW_FRAME_RATE);
   1110         }
   1111 
   1112         /**
   1113          * Gets the supported preview frame rates.
   1114          *
   1115          * @return a list of supported preview frame rates. null if preview
   1116          *         frame rate setting is not supported.
   1117          */
   1118         public List<Integer> getSupportedPreviewFrameRates() {
   1119             String str = get(KEY_PREVIEW_FRAME_RATE + SUPPORTED_VALUES_SUFFIX);
   1120             return splitInt(str);
   1121         }
   1122 
   1123         /**
   1124          * Sets the image format for preview pictures.
   1125          * <p>If this is never called, the default format will be
   1126          * {@link android.graphics.ImageFormat#NV21}, which
   1127          * uses the NV21 encoding format.</p>
   1128          *
   1129          * @param pixel_format the desired preview picture format, defined
   1130          *   by one of the {@link android.graphics.ImageFormat} constants.
   1131          *   (E.g., <var>ImageFormat.NV21</var> (default),
   1132          *                      <var>ImageFormat.RGB_565</var>, or
   1133          *                      <var>ImageFormat.JPEG</var>)
   1134          * @see android.graphics.ImageFormat
   1135          */
   1136         public void setPreviewFormat(int pixel_format) {
   1137             String s = cameraFormatForPixelFormat(pixel_format);
   1138             if (s == null) {
   1139                 throw new IllegalArgumentException(
   1140                         "Invalid pixel_format=" + pixel_format);
   1141             }
   1142 
   1143             set(KEY_PREVIEW_FORMAT, s);
   1144         }
   1145 
   1146         /**
   1147          * Returns the image format for preview frames got from
   1148          * {@link PreviewCallback}.
   1149          *
   1150          * @return the preview format.
   1151          * @see android.graphics.ImageFormat
   1152          */
   1153         public int getPreviewFormat() {
   1154             return pixelFormatForCameraFormat(get(KEY_PREVIEW_FORMAT));
   1155         }
   1156 
   1157         /**
   1158          * Gets the supported preview formats.
   1159          *
   1160          * @return a list of supported preview formats. This method will always
   1161          *         return a list with at least one element.
   1162          * @see android.graphics.ImageFormat
   1163          */
   1164         public List<Integer> getSupportedPreviewFormats() {
   1165             String str = get(KEY_PREVIEW_FORMAT + SUPPORTED_VALUES_SUFFIX);
   1166             ArrayList<Integer> formats = new ArrayList<Integer>();
   1167             for (String s : split(str)) {
   1168                 int f = pixelFormatForCameraFormat(s);
   1169                 if (f == ImageFormat.UNKNOWN) continue;
   1170                 formats.add(f);
   1171             }
   1172             return formats;
   1173         }
   1174 
   1175         /**
   1176          * Sets the dimensions for pictures.
   1177          *
   1178          * @param width  the width for pictures, in pixels
   1179          * @param height the height for pictures, in pixels
   1180          */
   1181         public void setPictureSize(int width, int height) {
   1182             String v = Integer.toString(width) + "x" + Integer.toString(height);
   1183             set(KEY_PICTURE_SIZE, v);
   1184         }
   1185 
   1186         /**
   1187          * Returns the dimension setting for pictures.
   1188          *
   1189          * @return a Size object with the height and width setting
   1190          *          for pictures
   1191          */
   1192         public Size getPictureSize() {
   1193             String pair = get(KEY_PICTURE_SIZE);
   1194             return strToSize(pair);
   1195         }
   1196 
   1197         /**
   1198          * Gets the supported picture sizes.
   1199          *
   1200          * @return a list of supported picture sizes. This method will always
   1201          *         return a list with at least one element.
   1202          */
   1203         public List<Size> getSupportedPictureSizes() {
   1204             String str = get(KEY_PICTURE_SIZE + SUPPORTED_VALUES_SUFFIX);
   1205             return splitSize(str);
   1206         }
   1207 
   1208         /**
   1209          * Sets the image format for pictures.
   1210          *
   1211          * @param pixel_format the desired picture format
   1212          *                     (<var>ImageFormat.NV21</var>,
   1213          *                      <var>ImageFormat.RGB_565</var>, or
   1214          *                      <var>ImageFormat.JPEG</var>)
   1215          * @see android.graphics.ImageFormat
   1216          */
   1217         public void setPictureFormat(int pixel_format) {
   1218             String s = cameraFormatForPixelFormat(pixel_format);
   1219             if (s == null) {
   1220                 throw new IllegalArgumentException(
   1221                         "Invalid pixel_format=" + pixel_format);
   1222             }
   1223 
   1224             set(KEY_PICTURE_FORMAT, s);
   1225         }
   1226 
   1227         /**
   1228          * Returns the image format for pictures.
   1229          *
   1230          * @return the picture format
   1231          * @see android.graphics.ImageFormat
   1232          */
   1233         public int getPictureFormat() {
   1234             return pixelFormatForCameraFormat(get(KEY_PICTURE_FORMAT));
   1235         }
   1236 
   1237         /**
   1238          * Gets the supported picture formats.
   1239          *
   1240          * @return supported picture formats. This method will always return a
   1241          *         list with at least one element.
   1242          * @see android.graphics.ImageFormat
   1243          */
   1244         public List<Integer> getSupportedPictureFormats() {
   1245             String str = get(KEY_PICTURE_FORMAT + SUPPORTED_VALUES_SUFFIX);
   1246             ArrayList<Integer> formats = new ArrayList<Integer>();
   1247             for (String s : split(str)) {
   1248                 int f = pixelFormatForCameraFormat(s);
   1249                 if (f == ImageFormat.UNKNOWN) continue;
   1250                 formats.add(f);
   1251             }
   1252             return formats;
   1253         }
   1254 
   1255         private String cameraFormatForPixelFormat(int pixel_format) {
   1256             switch(pixel_format) {
   1257             case ImageFormat.NV16:      return PIXEL_FORMAT_YUV422SP;
   1258             case ImageFormat.NV21:      return PIXEL_FORMAT_YUV420SP;
   1259             case ImageFormat.YUY2:      return PIXEL_FORMAT_YUV422I;
   1260             case ImageFormat.RGB_565:   return PIXEL_FORMAT_RGB565;
   1261             case ImageFormat.JPEG:      return PIXEL_FORMAT_JPEG;
   1262             default:                    return null;
   1263             }
   1264         }
   1265 
   1266         private int pixelFormatForCameraFormat(String format) {
   1267             if (format == null)
   1268                 return ImageFormat.UNKNOWN;
   1269 
   1270             if (format.equals(PIXEL_FORMAT_YUV422SP))
   1271                 return ImageFormat.NV16;
   1272 
   1273             if (format.equals(PIXEL_FORMAT_YUV420SP))
   1274                 return ImageFormat.NV21;
   1275 
   1276             if (format.equals(PIXEL_FORMAT_YUV422I))
   1277                 return ImageFormat.YUY2;
   1278 
   1279             if (format.equals(PIXEL_FORMAT_RGB565))
   1280                 return ImageFormat.RGB_565;
   1281 
   1282             if (format.equals(PIXEL_FORMAT_JPEG))
   1283                 return ImageFormat.JPEG;
   1284 
   1285             return ImageFormat.UNKNOWN;
   1286         }
   1287 
   1288         /**
   1289          * Sets the orientation of the device in degrees. For example, suppose
   1290          * the natural position of the device is landscape. If the user takes a
   1291          * picture in landscape mode in 2048x1536 resolution, the rotation
   1292          * should be set to 0. If the user rotates the phone 90 degrees
   1293          * clockwise, the rotation should be set to 90. Applications can use
   1294          * {@link android.view.OrientationEventListener} to set this parameter.
   1295          *
   1296          * The camera driver may set orientation in the EXIF header without
   1297          * rotating the picture. Or the driver may rotate the picture and
   1298          * the EXIF thumbnail. If the Jpeg picture is rotated, the orientation
   1299          * in the EXIF header will be missing or 1 (row #0 is top and column #0
   1300          * is left side).
   1301          *
   1302          * @param rotation The orientation of the device in degrees. Rotation
   1303          *                 can only be 0, 90, 180 or 270.
   1304          * @throws IllegalArgumentException if rotation value is invalid.
   1305          * @see android.view.OrientationEventListener
   1306          */
   1307         public void setRotation(int rotation) {
   1308             if (rotation == 0 || rotation == 90 || rotation == 180
   1309                     || rotation == 270) {
   1310                 set(KEY_ROTATION, Integer.toString(rotation));
   1311             } else {
   1312                 throw new IllegalArgumentException(
   1313                         "Invalid rotation=" + rotation);
   1314             }
   1315         }
   1316 
   1317         /**
   1318          * Sets GPS latitude coordinate. This will be stored in JPEG EXIF
   1319          * header.
   1320          *
   1321          * @param latitude GPS latitude coordinate.
   1322          */
   1323         public void setGpsLatitude(double latitude) {
   1324             set(KEY_GPS_LATITUDE, Double.toString(latitude));
   1325         }
   1326 
   1327         /**
   1328          * Sets GPS longitude coordinate. This will be stored in JPEG EXIF
   1329          * header.
   1330          *
   1331          * @param longitude GPS longitude coordinate.
   1332          */
   1333         public void setGpsLongitude(double longitude) {
   1334             set(KEY_GPS_LONGITUDE, Double.toString(longitude));
   1335         }
   1336 
   1337         /**
   1338          * Sets GPS altitude. This will be stored in JPEG EXIF header.
   1339          *
   1340          * @param altitude GPS altitude in meters.
   1341          */
   1342         public void setGpsAltitude(double altitude) {
   1343             set(KEY_GPS_ALTITUDE, Double.toString(altitude));
   1344         }
   1345 
   1346         /**
   1347          * Sets GPS timestamp. This will be stored in JPEG EXIF header.
   1348          *
   1349          * @param timestamp GPS timestamp (UTC in seconds since January 1,
   1350          *                  1970).
   1351          */
   1352         public void setGpsTimestamp(long timestamp) {
   1353             set(KEY_GPS_TIMESTAMP, Long.toString(timestamp));
   1354         }
   1355 
   1356         /**
   1357          * Sets GPS processing method. It will store up to 32 characters
   1358          * in JPEG EXIF header.
   1359          *
   1360          * @param processing_method The processing method to get this location.
   1361          */
   1362         public void setGpsProcessingMethod(String processing_method) {
   1363             set(KEY_GPS_PROCESSING_METHOD, processing_method);
   1364         }
   1365 
   1366         /**
   1367          * Removes GPS latitude, longitude, altitude, and timestamp from the
   1368          * parameters.
   1369          */
   1370         public void removeGpsData() {
   1371             remove(KEY_GPS_LATITUDE);
   1372             remove(KEY_GPS_LONGITUDE);
   1373             remove(KEY_GPS_ALTITUDE);
   1374             remove(KEY_GPS_TIMESTAMP);
   1375             remove(KEY_GPS_PROCESSING_METHOD);
   1376         }
   1377 
   1378         /**
   1379          * Gets the current white balance setting.
   1380          *
   1381          * @return current white balance. null if white balance setting is not
   1382          *         supported.
   1383          * @see #WHITE_BALANCE_AUTO
   1384          * @see #WHITE_BALANCE_INCANDESCENT
   1385          * @see #WHITE_BALANCE_FLUORESCENT
   1386          * @see #WHITE_BALANCE_WARM_FLUORESCENT
   1387          * @see #WHITE_BALANCE_DAYLIGHT
   1388          * @see #WHITE_BALANCE_CLOUDY_DAYLIGHT
   1389          * @see #WHITE_BALANCE_TWILIGHT
   1390          * @see #WHITE_BALANCE_SHADE
   1391          *
   1392          */
   1393         public String getWhiteBalance() {
   1394             return get(KEY_WHITE_BALANCE);
   1395         }
   1396 
   1397         /**
   1398          * Sets the white balance.
   1399          *
   1400          * @param value new white balance.
   1401          * @see #getWhiteBalance()
   1402          */
   1403         public void setWhiteBalance(String value) {
   1404             set(KEY_WHITE_BALANCE, value);
   1405         }
   1406 
   1407         /**
   1408          * Gets the supported white balance.
   1409          *
   1410          * @return a list of supported white balance. null if white balance
   1411          *         setting is not supported.
   1412          * @see #getWhiteBalance()
   1413          */
   1414         public List<String> getSupportedWhiteBalance() {
   1415             String str = get(KEY_WHITE_BALANCE + SUPPORTED_VALUES_SUFFIX);
   1416             return split(str);
   1417         }
   1418 
   1419         /**
   1420          * Gets the current color effect setting.
   1421          *
   1422          * @return current color effect. null if color effect
   1423          *         setting is not supported.
   1424          * @see #EFFECT_NONE
   1425          * @see #EFFECT_MONO
   1426          * @see #EFFECT_NEGATIVE
   1427          * @see #EFFECT_SOLARIZE
   1428          * @see #EFFECT_SEPIA
   1429          * @see #EFFECT_POSTERIZE
   1430          * @see #EFFECT_WHITEBOARD
   1431          * @see #EFFECT_BLACKBOARD
   1432          * @see #EFFECT_AQUA
   1433          */
   1434         public String getColorEffect() {
   1435             return get(KEY_EFFECT);
   1436         }
   1437 
   1438         /**
   1439          * Sets the current color effect setting.
   1440          *
   1441          * @param value new color effect.
   1442          * @see #getColorEffect()
   1443          */
   1444         public void setColorEffect(String value) {
   1445             set(KEY_EFFECT, value);
   1446         }
   1447 
   1448         /**
   1449          * Gets the supported color effects.
   1450          *
   1451          * @return a list of supported color effects. null if color effect
   1452          *         setting is not supported.
   1453          * @see #getColorEffect()
   1454          */
   1455         public List<String> getSupportedColorEffects() {
   1456             String str = get(KEY_EFFECT + SUPPORTED_VALUES_SUFFIX);
   1457             return split(str);
   1458         }
   1459 
   1460 
   1461         /**
   1462          * Gets the current antibanding setting.
   1463          *
   1464          * @return current antibanding. null if antibanding setting is not
   1465          *         supported.
   1466          * @see #ANTIBANDING_AUTO
   1467          * @see #ANTIBANDING_50HZ
   1468          * @see #ANTIBANDING_60HZ
   1469          * @see #ANTIBANDING_OFF
   1470          */
   1471         public String getAntibanding() {
   1472             return get(KEY_ANTIBANDING);
   1473         }
   1474 
   1475         /**
   1476          * Sets the antibanding.
   1477          *
   1478          * @param antibanding new antibanding value.
   1479          * @see #getAntibanding()
   1480          */
   1481         public void setAntibanding(String antibanding) {
   1482             set(KEY_ANTIBANDING, antibanding);
   1483         }
   1484 
   1485         /**
   1486          * Gets the supported antibanding values.
   1487          *
   1488          * @return a list of supported antibanding values. null if antibanding
   1489          *         setting is not supported.
   1490          * @see #getAntibanding()
   1491          */
   1492         public List<String> getSupportedAntibanding() {
   1493             String str = get(KEY_ANTIBANDING + SUPPORTED_VALUES_SUFFIX);
   1494             return split(str);
   1495         }
   1496 
   1497         /**
   1498          * Gets the current scene mode setting.
   1499          *
   1500          * @return one of SCENE_MODE_XXX string constant. null if scene mode
   1501          *         setting is not supported.
   1502          * @see #SCENE_MODE_AUTO
   1503          * @see #SCENE_MODE_ACTION
   1504          * @see #SCENE_MODE_PORTRAIT
   1505          * @see #SCENE_MODE_LANDSCAPE
   1506          * @see #SCENE_MODE_NIGHT
   1507          * @see #SCENE_MODE_NIGHT_PORTRAIT
   1508          * @see #SCENE_MODE_THEATRE
   1509          * @see #SCENE_MODE_BEACH
   1510          * @see #SCENE_MODE_SNOW
   1511          * @see #SCENE_MODE_SUNSET
   1512          * @see #SCENE_MODE_STEADYPHOTO
   1513          * @see #SCENE_MODE_FIREWORKS
   1514          * @see #SCENE_MODE_SPORTS
   1515          * @see #SCENE_MODE_PARTY
   1516          * @see #SCENE_MODE_CANDLELIGHT
   1517          */
   1518         public String getSceneMode() {
   1519             return get(KEY_SCENE_MODE);
   1520         }
   1521 
   1522         /**
   1523          * Sets the scene mode. Changing scene mode may override other
   1524          * parameters (such as flash mode, focus mode, white balance). For
   1525          * example, suppose originally flash mode is on and supported flash
   1526          * modes are on/off. In night scene mode, both flash mode and supported
   1527          * flash mode may be changed to off. After setting scene mode,
   1528          * applications should call getParameters to know if some parameters are
   1529          * changed.
   1530          *
   1531          * @param value scene mode.
   1532          * @see #getSceneMode()
   1533          */
   1534         public void setSceneMode(String value) {
   1535             set(KEY_SCENE_MODE, value);
   1536         }
   1537 
   1538         /**
   1539          * Gets the supported scene modes.
   1540          *
   1541          * @return a list of supported scene modes. null if scene mode setting
   1542          *         is not supported.
   1543          * @see #getSceneMode()
   1544          */
   1545         public List<String> getSupportedSceneModes() {
   1546             String str = get(KEY_SCENE_MODE + SUPPORTED_VALUES_SUFFIX);
   1547             return split(str);
   1548         }
   1549 
   1550         /**
   1551          * Gets the current flash mode setting.
   1552          *
   1553          * @return current flash mode. null if flash mode setting is not
   1554          *         supported.
   1555          * @see #FLASH_MODE_OFF
   1556          * @see #FLASH_MODE_AUTO
   1557          * @see #FLASH_MODE_ON
   1558          * @see #FLASH_MODE_RED_EYE
   1559          * @see #FLASH_MODE_TORCH
   1560          */
   1561         public String getFlashMode() {
   1562             return get(KEY_FLASH_MODE);
   1563         }
   1564 
   1565         /**
   1566          * Sets the flash mode.
   1567          *
   1568          * @param value flash mode.
   1569          * @see #getFlashMode()
   1570          */
   1571         public void setFlashMode(String value) {
   1572             set(KEY_FLASH_MODE, value);
   1573         }
   1574 
   1575         /**
   1576          * Gets the supported flash modes.
   1577          *
   1578          * @return a list of supported flash modes. null if flash mode setting
   1579          *         is not supported.
   1580          * @see #getFlashMode()
   1581          */
   1582         public List<String> getSupportedFlashModes() {
   1583             String str = get(KEY_FLASH_MODE + SUPPORTED_VALUES_SUFFIX);
   1584             return split(str);
   1585         }
   1586 
   1587         /**
   1588          * Gets the current focus mode setting.
   1589          *
   1590          * @return current focus mode. If the camera does not support
   1591          *         auto-focus, this should return {@link #FOCUS_MODE_FIXED}. If
   1592          *         the focus mode is not FOCUS_MODE_FIXED or {@link
   1593          *         #FOCUS_MODE_INFINITY}, applications should call {@link
   1594          *         #autoFocus(AutoFocusCallback)} to start the focus.
   1595          * @see #FOCUS_MODE_AUTO
   1596          * @see #FOCUS_MODE_INFINITY
   1597          * @see #FOCUS_MODE_MACRO
   1598          * @see #FOCUS_MODE_FIXED
   1599          */
   1600         public String getFocusMode() {
   1601             return get(KEY_FOCUS_MODE);
   1602         }
   1603 
   1604         /**
   1605          * Sets the focus mode.
   1606          *
   1607          * @param value focus mode.
   1608          * @see #getFocusMode()
   1609          */
   1610         public void setFocusMode(String value) {
   1611             set(KEY_FOCUS_MODE, value);
   1612         }
   1613 
   1614         /**
   1615          * Gets the supported focus modes.
   1616          *
   1617          * @return a list of supported focus modes. This method will always
   1618          *         return a list with at least one element.
   1619          * @see #getFocusMode()
   1620          */
   1621         public List<String> getSupportedFocusModes() {
   1622             String str = get(KEY_FOCUS_MODE + SUPPORTED_VALUES_SUFFIX);
   1623             return split(str);
   1624         }
   1625 
   1626         /**
   1627          * Gets the focal length (in millimeter) of the camera.
   1628          *
   1629          * @return the focal length. This method will always return a valid
   1630          *         value.
   1631          */
   1632         public float getFocalLength() {
   1633             return Float.parseFloat(get(KEY_FOCAL_LENGTH));
   1634         }
   1635 
   1636         /**
   1637          * Gets the horizontal angle of view in degrees.
   1638          *
   1639          * @return horizontal angle of view. This method will always return a
   1640          *         valid value.
   1641          */
   1642         public float getHorizontalViewAngle() {
   1643             return Float.parseFloat(get(KEY_HORIZONTAL_VIEW_ANGLE));
   1644         }
   1645 
   1646         /**
   1647          * Gets the vertical angle of view in degrees.
   1648          *
   1649          * @return vertical angle of view. This method will always return a
   1650          *         valid value.
   1651          */
   1652         public float getVerticalViewAngle() {
   1653             return Float.parseFloat(get(KEY_VERTICAL_VIEW_ANGLE));
   1654         }
   1655 
   1656         /**
   1657          * Gets the current exposure compensation index.
   1658          *
   1659          * @return current exposure compensation index. The range is {@link
   1660          *         #getMinExposureCompensation} to {@link
   1661          *         #getMaxExposureCompensation}. 0 means exposure is not
   1662          *         adjusted.
   1663          */
   1664         public int getExposureCompensation() {
   1665             return getInt(KEY_EXPOSURE_COMPENSATION, 0);
   1666         }
   1667 
   1668         /**
   1669          * Sets the exposure compensation index.
   1670          *
   1671          * @param value exposure compensation index. The valid value range is
   1672          *        from {@link #getMinExposureCompensation} (inclusive) to {@link
   1673          *        #getMaxExposureCompensation} (inclusive). 0 means exposure is
   1674          *        not adjusted. Application should call
   1675          *        getMinExposureCompensation and getMaxExposureCompensation to
   1676          *        know if exposure compensation is supported.
   1677          */
   1678         public void setExposureCompensation(int value) {
   1679             set(KEY_EXPOSURE_COMPENSATION, value);
   1680         }
   1681 
   1682         /**
   1683          * Gets the maximum exposure compensation index.
   1684          *
   1685          * @return maximum exposure compensation index (>=0). If both this
   1686          *         method and {@link #getMinExposureCompensation} return 0,
   1687          *         exposure compensation is not supported.
   1688          */
   1689         public int getMaxExposureCompensation() {
   1690             return getInt(KEY_MAX_EXPOSURE_COMPENSATION, 0);
   1691         }
   1692 
   1693         /**
   1694          * Gets the minimum exposure compensation index.
   1695          *
   1696          * @return minimum exposure compensation index (<=0). If both this
   1697          *         method and {@link #getMaxExposureCompensation} return 0,
   1698          *         exposure compensation is not supported.
   1699          */
   1700         public int getMinExposureCompensation() {
   1701             return getInt(KEY_MIN_EXPOSURE_COMPENSATION, 0);
   1702         }
   1703 
   1704         /**
   1705          * Gets the exposure compensation step.
   1706          *
   1707          * @return exposure compensation step. Applications can get EV by
   1708          *         multiplying the exposure compensation index and step. Ex: if
   1709          *         exposure compensation index is -6 and step is 0.333333333, EV
   1710          *         is -2.
   1711          */
   1712         public float getExposureCompensationStep() {
   1713             return getFloat(KEY_EXPOSURE_COMPENSATION_STEP, 0);
   1714         }
   1715 
   1716         /**
   1717          * Gets current zoom value. This also works when smooth zoom is in
   1718          * progress. Applications should check {@link #isZoomSupported} before
   1719          * using this method.
   1720          *
   1721          * @return the current zoom value. The range is 0 to {@link
   1722          *         #getMaxZoom}. 0 means the camera is not zoomed.
   1723          */
   1724         public int getZoom() {
   1725             return getInt(KEY_ZOOM, 0);
   1726         }
   1727 
   1728         /**
   1729          * Sets current zoom value. If the camera is zoomed (value > 0), the
   1730          * actual picture size may be smaller than picture size setting.
   1731          * Applications can check the actual picture size after picture is
   1732          * returned from {@link PictureCallback}. The preview size remains the
   1733          * same in zoom. Applications should check {@link #isZoomSupported}
   1734          * before using this method.
   1735          *
   1736          * @param value zoom value. The valid range is 0 to {@link #getMaxZoom}.
   1737          */
   1738         public void setZoom(int value) {
   1739             set(KEY_ZOOM, value);
   1740         }
   1741 
   1742         /**
   1743          * Returns true if zoom is supported. Applications should call this
   1744          * before using other zoom methods.
   1745          *
   1746          * @return true if zoom is supported.
   1747          */
   1748         public boolean isZoomSupported() {
   1749             String str = get(KEY_ZOOM_SUPPORTED);
   1750             return TRUE.equals(str);
   1751         }
   1752 
   1753         /**
   1754          * Gets the maximum zoom value allowed for snapshot. This is the maximum
   1755          * value that applications can set to {@link #setZoom(int)}.
   1756          * Applications should call {@link #isZoomSupported} before using this
   1757          * method. This value may change in different preview size. Applications
   1758          * should call this again after setting preview size.
   1759          *
   1760          * @return the maximum zoom value supported by the camera.
   1761          */
   1762         public int getMaxZoom() {
   1763             return getInt(KEY_MAX_ZOOM, 0);
   1764         }
   1765 
   1766         /**
   1767          * Gets the zoom ratios of all zoom values. Applications should check
   1768          * {@link #isZoomSupported} before using this method.
   1769          *
   1770          * @return the zoom ratios in 1/100 increments. Ex: a zoom of 3.2x is
   1771          *         returned as 320. The number of elements is {@link
   1772          *         #getMaxZoom} + 1. The list is sorted from small to large. The
   1773          *         first element is always 100. The last element is the zoom
   1774          *         ratio of the maximum zoom value.
   1775          */
   1776         public List<Integer> getZoomRatios() {
   1777             return splitInt(get(KEY_ZOOM_RATIOS));
   1778         }
   1779 
   1780         /**
   1781          * Returns true if smooth zoom is supported. Applications should call
   1782          * this before using other smooth zoom methods.
   1783          *
   1784          * @return true if smooth zoom is supported.
   1785          */
   1786         public boolean isSmoothZoomSupported() {
   1787             String str = get(KEY_SMOOTH_ZOOM_SUPPORTED);
   1788             return TRUE.equals(str);
   1789         }
   1790 
   1791         // Splits a comma delimited string to an ArrayList of String.
   1792         // Return null if the passing string is null or the size is 0.
   1793         private ArrayList<String> split(String str) {
   1794             if (str == null) return null;
   1795 
   1796             // Use StringTokenizer because it is faster than split.
   1797             StringTokenizer tokenizer = new StringTokenizer(str, ",");
   1798             ArrayList<String> substrings = new ArrayList<String>();
   1799             while (tokenizer.hasMoreElements()) {
   1800                 substrings.add(tokenizer.nextToken());
   1801             }
   1802             return substrings;
   1803         }
   1804 
   1805         // Splits a comma delimited string to an ArrayList of Integer.
   1806         // Return null if the passing string is null or the size is 0.
   1807         private ArrayList<Integer> splitInt(String str) {
   1808             if (str == null) return null;
   1809 
   1810             StringTokenizer tokenizer = new StringTokenizer(str, ",");
   1811             ArrayList<Integer> substrings = new ArrayList<Integer>();
   1812             while (tokenizer.hasMoreElements()) {
   1813                 String token = tokenizer.nextToken();
   1814                 substrings.add(Integer.parseInt(token));
   1815             }
   1816             if (substrings.size() == 0) return null;
   1817             return substrings;
   1818         }
   1819 
   1820         // Returns the value of a float parameter.
   1821         private float getFloat(String key, float defaultValue) {
   1822             try {
   1823                 return Float.parseFloat(mMap.get(key));
   1824             } catch (NumberFormatException ex) {
   1825                 return defaultValue;
   1826             }
   1827         }
   1828 
   1829         // Returns the value of a integer parameter.
   1830         private int getInt(String key, int defaultValue) {
   1831             try {
   1832                 return Integer.parseInt(mMap.get(key));
   1833             } catch (NumberFormatException ex) {
   1834                 return defaultValue;
   1835             }
   1836         }
   1837 
   1838         // Splits a comma delimited string to an ArrayList of Size.
   1839         // Return null if the passing string is null or the size is 0.
   1840         private ArrayList<Size> splitSize(String str) {
   1841             if (str == null) return null;
   1842 
   1843             StringTokenizer tokenizer = new StringTokenizer(str, ",");
   1844             ArrayList<Size> sizeList = new ArrayList<Size>();
   1845             while (tokenizer.hasMoreElements()) {
   1846                 Size size = strToSize(tokenizer.nextToken());
   1847                 if (size != null) sizeList.add(size);
   1848             }
   1849             if (sizeList.size() == 0) return null;
   1850             return sizeList;
   1851         }
   1852 
   1853         // Parses a string (ex: "480x320") to Size object.
   1854         // Return null if the passing string is null.
   1855         private Size strToSize(String str) {
   1856             if (str == null) return null;
   1857 
   1858             int pos = str.indexOf('x');
   1859             if (pos != -1) {
   1860                 String width = str.substring(0, pos);
   1861                 String height = str.substring(pos + 1);
   1862                 return new Size(Integer.parseInt(width),
   1863                                 Integer.parseInt(height));
   1864             }
   1865             Log.e(TAG, "Invalid size parameter string=" + str);
   1866             return null;
   1867         }
   1868     };
   1869 }
   1870