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