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