CameraSettings.java revision 6988d4e2ef8d14d8bf3ee81c8eb3175bbf1b88ec
177c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang/*
277c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang * Copyright (C) 2009 The Android Open Source Project
377c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang *
477c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang * Licensed under the Apache License, Version 2.0 (the "License");
577c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang * you may not use this file except in compliance with the License.
677c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang * You may obtain a copy of the License at
777c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang *
877c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang *      http://www.apache.org/licenses/LICENSE-2.0
977c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang *
1077c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang * Unless required by applicable law or agreed to in writing, software
1177c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang * distributed under the License is distributed on an "AS IS" BASIS,
1277c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1377c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang * See the License for the specific language governing permissions and
1477c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang * limitations under the License.
1577c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang */
1677c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang
17b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectpackage com.android.camera;
18b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1978f160ee416ba27ba55954950473e17ba9d20052Owen Linimport android.app.Activity;
2078f160ee416ba27ba55954950473e17ba9d20052Owen Linimport android.content.Context;
21b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.SharedPreferences;
222f3774c974a5a044a3b32ca68182a3f2180d0124Cheng-Ru Linimport android.graphics.drawable.Drawable;
2387341536812081826656040ac81f8f386c6c1407Wu-cheng Liimport android.hardware.Camera.Parameters;
244305c70dc849156be5d79d52772ea71cd890ca40Wu-cheng Liimport android.hardware.Camera.Size;
2533be45a1abaf6a8d611fb87b18945c84ab76c229Owen Linimport android.media.CamcorderProfile;
2678f160ee416ba27ba55954950473e17ba9d20052Owen Linimport android.preference.PreferenceManager;
277e4655b1b3fcbc543430bea680872f564af098f5Wei-Ta Chenimport android.util.Log;
28d4247bc43702d5ccda5dde40e948fffd6c4445eeRay Chen
29d4247bc43702d5ccda5dde40e948fffd6c4445eeRay Chenimport java.util.ArrayList;
304305c70dc849156be5d79d52772ea71cd890ca40Wu-cheng Liimport java.util.List;
3187341536812081826656040ac81f8f386c6c1407Wu-cheng Li
32271b3095b9f763421c0547109da9de774795072dChih-Chung Chang/**
33271b3095b9f763421c0547109da9de774795072dChih-Chung Chang *  Provides utilities and keys for Camera settings.
34271b3095b9f763421c0547109da9de774795072dChih-Chung Chang */
3578f160ee416ba27ba55954950473e17ba9d20052Owen Linpublic class CameraSettings {
3678f160ee416ba27ba55954950473e17ba9d20052Owen Lin    private static final int NOT_FOUND = -1;
3778f160ee416ba27ba55954950473e17ba9d20052Owen Lin
3878f160ee416ba27ba55954950473e17ba9d20052Owen Lin    public static final String KEY_VERSION = "pref_version_key";
3933be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin    public static final String KEY_RECORD_LOCATION = RecordLocationPreference.KEY;
40469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin    public static final String KEY_VIDEO_QUALITY = "pref_video_quality_key";
419dacf7b214339440c16f3d66e12d6afef1248f68Wu-cheng Li    public static final String KEY_PICTURE_SIZE = "pref_camera_picturesize_key";
42e0770004600f76cc4b440104e98e14712b4fd1c6Wu-cheng Li    public static final String KEY_JPEG_QUALITY = "pref_camera_jpegquality_key";
430f56ef5704b7f1a0874528367147487c051876d9Wu-cheng Li    public static final String KEY_FOCUS_MODE = "pref_camera_focusmode_key";
445945773c664ada754ce5eb9239bd4c8bd95ee4b4Wu-cheng Li    public static final String KEY_FLASH_MODE = "pref_camera_flashmode_key";
45da3e9964a4a82a942d7f450e7c89904f5c5aa03fWu-cheng Li    public static final String KEY_VIDEOCAMERA_FLASH_MODE = "pref_camera_video_flashmode_key";
4678f160ee416ba27ba55954950473e17ba9d20052Owen Lin    public static final String KEY_COLOR_EFFECT = "pref_camera_coloreffect_key";
4733be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin    public static final String KEY_WHITE_BALANCE = "pref_camera_whitebalance_key";
488d0ba007ec6ef9bb34dc0c9f40c4c29dad2691e0Owen Lin    public static final String KEY_SCENE_MODE = "pref_camera_scenemode_key";
4933be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin    public static final String KEY_QUICK_CAPTURE = "pref_camera_quickcapture_key";
5033be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin    public static final String KEY_EXPOSURE = "pref_camera_exposure_key";
518791695ba110ad0b088d2e8b3b0127c0042e1865Owen Lin
528791695ba110ad0b088d2e8b3b0127c0042e1865Owen Lin    public static final String QUICK_CAPTURE_ON = "on";
538791695ba110ad0b088d2e8b3b0127c0042e1865Owen Lin    public static final String QUICK_CAPTURE_OFF = "off";
546d12b828743cbd81767227229d6351ce412d5698Owen Lin
55469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin    private static final String VIDEO_QUALITY_HIGH = "high";
56469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin    private static final String VIDEO_QUALITY_MMS = "mms";
57469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin    private static final String VIDEO_QUALITY_YOUTUBE = "youtube";
586f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang
59469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin    public static final int CURRENT_VERSION = 4;
60b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
61469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin    // max video duration in seconds for mms and youtube.
62469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin    private static final int MMS_VIDEO_DURATION = CamcorderProfile.getMmsRecordingDurationInSeconds();
63469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin    private static final int YOUTUBE_VIDEO_DURATION = 10 * 60; // 10 mins
64469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin    private static final int DEFAULT_VIDEO_DURATION = 30 * 60; // 10 mins
65469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin
66469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin    public static final String DEFAULT_VIDEO_QUALITY_VALUE = "high";
67b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
6878f160ee416ba27ba55954950473e17ba9d20052Owen Lin    // MMS video length
6978f160ee416ba27ba55954950473e17ba9d20052Owen Lin    public static final int DEFAULT_VIDEO_DURATION_VALUE = -1;
704305c70dc849156be5d79d52772ea71cd890ca40Wu-cheng Li
7171d56e21859a797ec4633f209b3605276345d44eOwen Lin    @SuppressWarnings("unused")
7278f160ee416ba27ba55954950473e17ba9d20052Owen Lin    private static final String TAG = "CameraSettings";
7378f160ee416ba27ba55954950473e17ba9d20052Owen Lin
7478f160ee416ba27ba55954950473e17ba9d20052Owen Lin    private final Context mContext;
7578f160ee416ba27ba55954950473e17ba9d20052Owen Lin    private final Parameters mParameters;
7678f160ee416ba27ba55954950473e17ba9d20052Owen Lin
7778f160ee416ba27ba55954950473e17ba9d20052Owen Lin    public CameraSettings(Activity activity, Parameters parameters) {
7878f160ee416ba27ba55954950473e17ba9d20052Owen Lin        mContext = activity;
7978f160ee416ba27ba55954950473e17ba9d20052Owen Lin        mParameters = parameters;
8078f160ee416ba27ba55954950473e17ba9d20052Owen Lin    }
8178f160ee416ba27ba55954950473e17ba9d20052Owen Lin
8273e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    public PreferenceGroup getPreferenceGroup(int preferenceRes) {
8373e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        PreferenceInflater inflater = new PreferenceInflater(mContext);
8473e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        PreferenceGroup group =
8573e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin                (PreferenceGroup) inflater.inflate(preferenceRes);
8673e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        initPreference(group);
8773e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        return group;
8878f160ee416ba27ba55954950473e17ba9d20052Owen Lin    }
8978f160ee416ba27ba55954950473e17ba9d20052Owen Lin
9032bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin    public static void initialCameraPictureSize(
9132bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin            Context context, Parameters parameters) {
9232bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        // When launching the camera app first time, we will set the picture
9332bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        // size to the first one in the list defined in "arrays.xml" and is also
9432bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        // supported by the driver.
9532bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        List<Size> supported = parameters.getSupportedPictureSizes();
9632bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        if (supported == null) return;
9732bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        for (String candidate : context.getResources().getStringArray(
9832bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin                R.array.pref_camera_picturesize_entryvalues)) {
9932bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin            if (setCameraPictureSize(candidate, supported, parameters)) {
10032bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin                SharedPreferences.Editor editor = PreferenceManager
10132bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin                        .getDefaultSharedPreferences(context).edit();
10232bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin                editor.putString(KEY_PICTURE_SIZE, candidate);
10332bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin                editor.commit();
10432bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin                return;
10532bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin            }
10632bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        }
1074ddee78a1507b3c067745023bd2330b866b8aaf9Owen Lin        Log.e(TAG, "No supported picture size found");
10832bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin    }
10932bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin
1107e4655b1b3fcbc543430bea680872f564af098f5Wei-Ta Chen    public static void removePreferenceFromScreen(
11173e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            PreferenceGroup group, String key) {
11273e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        removePreference(group, key);
1137e4655b1b3fcbc543430bea680872f564af098f5Wei-Ta Chen    }
1147e4655b1b3fcbc543430bea680872f564af098f5Wei-Ta Chen
11532bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin    public static boolean setCameraPictureSize(
11632bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin            String candidate, List<Size> supported, Parameters parameters) {
11732bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        int index = candidate.indexOf('x');
11832bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        if (index == NOT_FOUND) return false;
11932bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        int width = Integer.parseInt(candidate.substring(0, index));
12032bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        int height = Integer.parseInt(candidate.substring(index + 1));
12132bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        for (Size size: supported) {
12232bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin            if (size.width == width && size.height == height) {
12332bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin                parameters.setPictureSize(width, height);
12432bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin                return true;
12532bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin            }
12632bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        }
12732bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        return false;
12832bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin    }
12932bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin
13073e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    private void initPreference(PreferenceGroup group) {
131469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin        ListPreference videoQuality = group.findPreference(KEY_VIDEO_QUALITY);
13273e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        ListPreference pictureSize = group.findPreference(KEY_PICTURE_SIZE);
13373e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        ListPreference whiteBalance =  group.findPreference(KEY_WHITE_BALANCE);
13473e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        ListPreference colorEffect = group.findPreference(KEY_COLOR_EFFECT);
13573e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        ListPreference sceneMode = group.findPreference(KEY_SCENE_MODE);
13673e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        ListPreference flashMode = group.findPreference(KEY_FLASH_MODE);
13773e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        ListPreference focusMode = group.findPreference(KEY_FOCUS_MODE);
13833be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        ListPreference exposure = group.findPreference(KEY_EXPOSURE);
1396988d4e2ef8d14d8bf3ee81c8eb3175bbf1b88ecOwen Lin        ListPreference videoFlashMode =
1406988d4e2ef8d14d8bf3ee81c8eb3175bbf1b88ecOwen Lin                group.findPreference(KEY_VIDEOCAMERA_FLASH_MODE);
14178f160ee416ba27ba55954950473e17ba9d20052Owen Lin
14278f160ee416ba27ba55954950473e17ba9d20052Owen Lin        // Since the screen could be loaded from different resources, we need
14378f160ee416ba27ba55954950473e17ba9d20052Owen Lin        // to check if the preference is available here
144469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin        if (videoQuality != null) {
14578f160ee416ba27ba55954950473e17ba9d20052Owen Lin            // Modify video duration settings.
14678f160ee416ba27ba55954950473e17ba9d20052Owen Lin            // The first entry is for MMS video duration, and we need to fill
14778f160ee416ba27ba55954950473e17ba9d20052Owen Lin            // in the device-dependent value (in seconds).
148469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin            CharSequence[] entries = videoQuality.getEntries();
149469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin            CharSequence[] values = videoQuality.getEntryValues();
150469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin            for (int i = 0; i < entries.length; ++i) {
151469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin                if (VIDEO_QUALITY_MMS.equals(values[i])) {
152469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin                    entries[i] = entries[i].toString().replace(
153469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin                            "30", Integer.toString(MMS_VIDEO_DURATION));
154469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin                    break;
155469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin                }
156469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin            }
1574305c70dc849156be5d79d52772ea71cd890ca40Wu-cheng Li        }
1584305c70dc849156be5d79d52772ea71cd890ca40Wu-cheng Li
15978f160ee416ba27ba55954950473e17ba9d20052Owen Lin        // Filter out unsupported settings / options
16078f160ee416ba27ba55954950473e17ba9d20052Owen Lin        if (pictureSize != null) {
16173e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            filterUnsupportedOptions(group, pictureSize, sizeListToStringList(
16278f160ee416ba27ba55954950473e17ba9d20052Owen Lin                    mParameters.getSupportedPictureSizes()));
1633f3c857e3f34650c15d764810335024654b0fcc3Owen Lin        }
16478f160ee416ba27ba55954950473e17ba9d20052Owen Lin        if (whiteBalance != null) {
16573e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            filterUnsupportedOptions(group,
16678f160ee416ba27ba55954950473e17ba9d20052Owen Lin                    whiteBalance, mParameters.getSupportedWhiteBalance());
1670f56ef5704b7f1a0874528367147487c051876d9Wu-cheng Li        }
16878f160ee416ba27ba55954950473e17ba9d20052Owen Lin        if (colorEffect != null) {
16973e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            filterUnsupportedOptions(group,
17078f160ee416ba27ba55954950473e17ba9d20052Owen Lin                    colorEffect, mParameters.getSupportedColorEffects());
17178f160ee416ba27ba55954950473e17ba9d20052Owen Lin        }
17278f160ee416ba27ba55954950473e17ba9d20052Owen Lin        if (sceneMode != null) {
17373e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            filterUnsupportedOptions(group,
17478f160ee416ba27ba55954950473e17ba9d20052Owen Lin                    sceneMode, mParameters.getSupportedSceneModes());
1750f56ef5704b7f1a0874528367147487c051876d9Wu-cheng Li        }
176b6ad206f53981faee04800b787569dbb60492844Owen Lin        if (flashMode != null) {
17773e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            filterUnsupportedOptions(group,
178b6ad206f53981faee04800b787569dbb60492844Owen Lin                    flashMode, mParameters.getSupportedFlashModes());
179b6ad206f53981faee04800b787569dbb60492844Owen Lin        }
180df3731bacfe26910a5dd0813c6aa80a6e55b85adCheng-Ru Lin        if (focusMode != null) {
18173e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            filterUnsupportedOptions(group,
182df3731bacfe26910a5dd0813c6aa80a6e55b85adCheng-Ru Lin                    focusMode, mParameters.getSupportedFocusModes());
1836988d4e2ef8d14d8bf3ee81c8eb3175bbf1b88ecOwen Lin        }
1846988d4e2ef8d14d8bf3ee81c8eb3175bbf1b88ecOwen Lin        if (videoFlashMode != null) {
1856988d4e2ef8d14d8bf3ee81c8eb3175bbf1b88ecOwen Lin            filterUnsupportedOptions(group,
1866988d4e2ef8d14d8bf3ee81c8eb3175bbf1b88ecOwen Lin                    videoFlashMode, mParameters.getSupportedFlashModes());
187df3731bacfe26910a5dd0813c6aa80a6e55b85adCheng-Ru Lin        }
18833be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin
18933be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        if (exposure != null) {
19033be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin            buildExposureCompensation(group, exposure);
19133be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        }
19233be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin    }
19333be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin
19433be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin    private void buildExposureCompensation(
19533be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin            PreferenceGroup group, ListPreference exposure) {
19633be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        int max = mParameters.getMaxExposureCompensation();
19733be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        int min = mParameters.getMinExposureCompensation();
19833be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        if (max == 0 && min == 0) {
19933be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin            removePreference(group, exposure.getKey());
20033be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin            return;
20133be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        }
20233be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        float step = mParameters.getExposureCompensationStep();
20333be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin
20433be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        // show only integer values for exposure compensation
20533be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        int maxValue = (int) Math.floor(max * step);
20633be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        int minValue = (int) Math.ceil(min * step);
20733be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        CharSequence entries[] = new CharSequence[maxValue - minValue + 1];
20833be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        CharSequence entryValues[] = new CharSequence[maxValue - minValue + 1];
20933be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        for (int i = minValue; i <= maxValue; ++i) {
21033be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin            entryValues[maxValue - i] = Integer.toString(Math.round(i / step));
21133be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin            StringBuilder builder = new StringBuilder();
21233be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin            if (i > 0) builder.append('+');
21333be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin            entries[maxValue - i] = builder.append(i).toString();
21433be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        }
21533be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        exposure.setEntries(entries);
21633be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        exposure.setEntryValues(entryValues);
217b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
218b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
21973e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    private static boolean removePreference(PreferenceGroup group, String key) {
22073e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        for (int i = 0, n = group.size(); i < n; i++) {
22173e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            CameraPreference child = group.get(i);
2225945773c664ada754ce5eb9239bd4c8bd95ee4b4Wu-cheng Li            if (child instanceof PreferenceGroup) {
22373e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin                if (removePreference((PreferenceGroup) child, key)) {
2245945773c664ada754ce5eb9239bd4c8bd95ee4b4Wu-cheng Li                    return true;
2255945773c664ada754ce5eb9239bd4c8bd95ee4b4Wu-cheng Li                }
2265945773c664ada754ce5eb9239bd4c8bd95ee4b4Wu-cheng Li            }
22773e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            if (child instanceof ListPreference &&
22873e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin                    ((ListPreference) child).getKey().equals(key)) {
22973e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin                group.removePreference(i);
23073e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin                return true;
23173e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            }
2325945773c664ada754ce5eb9239bd4c8bd95ee4b4Wu-cheng Li        }
2335945773c664ada754ce5eb9239bd4c8bd95ee4b4Wu-cheng Li        return false;
2345945773c664ada754ce5eb9239bd4c8bd95ee4b4Wu-cheng Li    }
2355945773c664ada754ce5eb9239bd4c8bd95ee4b4Wu-cheng Li
23673e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    private void filterUnsupportedOptions(PreferenceGroup group,
23778f160ee416ba27ba55954950473e17ba9d20052Owen Lin            ListPreference pref, List<String> supported) {
23878f160ee416ba27ba55954950473e17ba9d20052Owen Lin
239df3731bacfe26910a5dd0813c6aa80a6e55b85adCheng-Ru Lin        CharSequence[] allEntries = pref.getEntries();
240df3731bacfe26910a5dd0813c6aa80a6e55b85adCheng-Ru Lin
241df3731bacfe26910a5dd0813c6aa80a6e55b85adCheng-Ru Lin        // Remove the preference if the parameter is not supported or there is
242df3731bacfe26910a5dd0813c6aa80a6e55b85adCheng-Ru Lin        // only one options for the settings.
24322a695f8ca31dc2899e7206d68316c7e6d960657Owen Lin        if (supported == null || supported.size() <= 1) {
24473e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            removePreference(group, pref.getKey());
2459dacf7b214339440c16f3d66e12d6afef1248f68Wu-cheng Li            return;
2469dacf7b214339440c16f3d66e12d6afef1248f68Wu-cheng Li        }
2479dacf7b214339440c16f3d66e12d6afef1248f68Wu-cheng Li
2485945773c664ada754ce5eb9239bd4c8bd95ee4b4Wu-cheng Li        CharSequence[] allEntryValues = pref.getEntryValues();
2492f3774c974a5a044a3b32ca68182a3f2180d0124Cheng-Ru Lin        Drawable[] allIcons = (pref instanceof IconListPreference)
2502f3774c974a5a044a3b32ca68182a3f2180d0124Cheng-Ru Lin                ? ((IconListPreference) pref).getIcons()
2512f3774c974a5a044a3b32ca68182a3f2180d0124Cheng-Ru Lin                : null;
2522ac0387bbd6792187aeaacf10e40688f4260e316Wu-cheng Li        ArrayList<CharSequence> entries = new ArrayList<CharSequence>();
2532ac0387bbd6792187aeaacf10e40688f4260e316Wu-cheng Li        ArrayList<CharSequence> entryValues = new ArrayList<CharSequence>();
2542f3774c974a5a044a3b32ca68182a3f2180d0124Cheng-Ru Lin        ArrayList<Drawable> icons =
2552f3774c974a5a044a3b32ca68182a3f2180d0124Cheng-Ru Lin                allIcons == null ? null : new ArrayList<Drawable>();
2562ac0387bbd6792187aeaacf10e40688f4260e316Wu-cheng Li        for (int i = 0, len = allEntryValues.length; i < len; i++) {
25778f160ee416ba27ba55954950473e17ba9d20052Owen Lin            if (supported.indexOf(allEntryValues[i].toString()) != NOT_FOUND) {
2582ac0387bbd6792187aeaacf10e40688f4260e316Wu-cheng Li                entries.add(allEntries[i]);
2592ac0387bbd6792187aeaacf10e40688f4260e316Wu-cheng Li                entryValues.add(allEntryValues[i]);
2602f3774c974a5a044a3b32ca68182a3f2180d0124Cheng-Ru Lin                if (allIcons != null) icons.add(allIcons[i]);
26187341536812081826656040ac81f8f386c6c1407Wu-cheng Li            }
26287341536812081826656040ac81f8f386c6c1407Wu-cheng Li        }
26387341536812081826656040ac81f8f386c6c1407Wu-cheng Li
2642ac0387bbd6792187aeaacf10e40688f4260e316Wu-cheng Li        // Set entries and entry values to list preference.
2652f3774c974a5a044a3b32ca68182a3f2180d0124Cheng-Ru Lin        int size = entries.size();
2662f3774c974a5a044a3b32ca68182a3f2180d0124Cheng-Ru Lin        pref.setEntries(entries.toArray(new CharSequence[size]));
2672f3774c974a5a044a3b32ca68182a3f2180d0124Cheng-Ru Lin        pref.setEntryValues(entryValues.toArray(new CharSequence[size]));
2682f3774c974a5a044a3b32ca68182a3f2180d0124Cheng-Ru Lin        if (allIcons != null) {
2692f3774c974a5a044a3b32ca68182a3f2180d0124Cheng-Ru Lin            ((IconListPreference) pref)
2702f3774c974a5a044a3b32ca68182a3f2180d0124Cheng-Ru Lin                    .setIcons(icons.toArray(new Drawable[size]));
2712f3774c974a5a044a3b32ca68182a3f2180d0124Cheng-Ru Lin        }
27287341536812081826656040ac81f8f386c6c1407Wu-cheng Li
2732ac0387bbd6792187aeaacf10e40688f4260e316Wu-cheng Li        // Set the value to the first entry if it is invalid.
2742ac0387bbd6792187aeaacf10e40688f4260e316Wu-cheng Li        String value = pref.getValue();
27578f160ee416ba27ba55954950473e17ba9d20052Owen Lin        if (pref.findIndexOfValue(value) == NOT_FOUND) {
2762ac0387bbd6792187aeaacf10e40688f4260e316Wu-cheng Li            pref.setValueIndex(0);
27787341536812081826656040ac81f8f386c6c1407Wu-cheng Li        }
27887341536812081826656040ac81f8f386c6c1407Wu-cheng Li    }
27987341536812081826656040ac81f8f386c6c1407Wu-cheng Li
28078f160ee416ba27ba55954950473e17ba9d20052Owen Lin    private static List<String> sizeListToStringList(List<Size> sizes) {
28178f160ee416ba27ba55954950473e17ba9d20052Owen Lin        ArrayList<String> list = new ArrayList<String>();
28278f160ee416ba27ba55954950473e17ba9d20052Owen Lin        for (Size size : sizes) {
28378f160ee416ba27ba55954950473e17ba9d20052Owen Lin            list.add(String.format("%dx%d", size.width, size.height));
284c8cd9098d9ca174f5a0374789145faf1f15d503dRay Chen        }
28578f160ee416ba27ba55954950473e17ba9d20052Owen Lin        return list;
286b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
2876f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang
2886f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang    public static void upgradePreferences(SharedPreferences pref) {
2896f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang        int version;
2906f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang        try {
2916f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang            version = pref.getInt(KEY_VERSION, 0);
2926f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang        } catch (Exception ex) {
2936f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang            version = 0;
2946f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang        }
295a8bbcd7ce25aada705561852ea9f356dc38c0f43Cheng-Ru Lin        if (version == CURRENT_VERSION) return;
2966f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang
297a8bbcd7ce25aada705561852ea9f356dc38c0f43Cheng-Ru Lin        SharedPreferences.Editor editor = pref.edit();
2986f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang        if (version == 0) {
299469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin            // We won't use the preference which change in version 1.
300469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin            // So, just upgrade to version 1 directly
301faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang            version = 1;
302faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang        }
303faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang        if (version == 1) {
304faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang            // Change jpeg quality {65,75,85} to {normal,fine,superfine}
305faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang            String quality = pref.getString(KEY_JPEG_QUALITY, "85");
306faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang            if (quality.equals("65")) {
307faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang                quality = "normal";
308faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang            } else if (quality.equals("75")) {
309faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang                quality = "fine";
310faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang            } else {
311faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang                quality = "superfine";
312faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang            }
313faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang            editor.putString(KEY_JPEG_QUALITY, quality);
314faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang            version = 2;
3156f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang        }
3163e44f8076a16792bb295589ca4b467ba27ea2a6fOwen Lin        if (version == 2) {
3173e44f8076a16792bb295589ca4b467ba27ea2a6fOwen Lin            editor.putString(KEY_RECORD_LOCATION,
3183e44f8076a16792bb295589ca4b467ba27ea2a6fOwen Lin                    pref.getBoolean(KEY_RECORD_LOCATION, false)
3193e44f8076a16792bb295589ca4b467ba27ea2a6fOwen Lin                    ? RecordLocationPreference.VALUE_ON
3203e44f8076a16792bb295589ca4b467ba27ea2a6fOwen Lin                    : RecordLocationPreference.VALUE_NONE);
3213e44f8076a16792bb295589ca4b467ba27ea2a6fOwen Lin            version = 3;
3223e44f8076a16792bb295589ca4b467ba27ea2a6fOwen Lin        }
323469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin        if (version == 3) {
324469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin            // Just use video quality to replace it and
325469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin            // ignore the current settings.
326469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin            editor.remove("pref_camera_videoquality_key");
327469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin            editor.remove("pref_camera_video_duration_key");
328469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin        }
329a8bbcd7ce25aada705561852ea9f356dc38c0f43Cheng-Ru Lin        editor.putInt(KEY_VERSION, CURRENT_VERSION);
330a8bbcd7ce25aada705561852ea9f356dc38c0f43Cheng-Ru Lin        editor.commit();
3316f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang    }
332469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin
333469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin    public static boolean getVideoQuality(String quality) {
334469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin        return VIDEO_QUALITY_YOUTUBE.equals(
335469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin                quality) || VIDEO_QUALITY_HIGH.equals(quality);
336469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin    }
337469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin
338469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin    public static int getVidoeDurationInMillis(String quality) {
339469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin        if (VIDEO_QUALITY_MMS.equals(quality)) {
340469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin            return MMS_VIDEO_DURATION * 1000;
341469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin        } else if (VIDEO_QUALITY_YOUTUBE.equals(quality)) {
342469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin            return YOUTUBE_VIDEO_DURATION * 1000;
343469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin        }
344469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin        return DEFAULT_VIDEO_DURATION * 1000;
345469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin    }
346b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project}
347