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
195d08d2998fb809b4443d31d60ec38b12cda97be4Pin Tingimport android.annotation.TargetApi;
2078f160ee416ba27ba55954950473e17ba9d20052Owen Linimport android.app.Activity;
2178f160ee416ba27ba55954950473e17ba9d20052Owen Linimport android.content.Context;
22b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.SharedPreferences;
231ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Changimport android.content.SharedPreferences.Editor;
24c6c123c85fdc2bf9a9f93fd25f3b951c016a67c0Angus Kongimport android.content.res.Resources;
25ec6a318cdba09ff85bdcacd861442b617399b6daMichael Kolbimport android.content.res.TypedArray;
267add00693c1ec910bc8700fe046ee18cbe4e1148Wu-cheng Liimport android.hardware.Camera.CameraInfo;
2787341536812081826656040ac81f8f386c6c1407Wu-cheng Liimport android.hardware.Camera.Parameters;
284305c70dc849156be5d79d52772ea71cd890ca40Wu-cheng Liimport android.hardware.Camera.Size;
2933be45a1abaf6a8d611fb87b18945c84ab76c229Owen Linimport android.media.CamcorderProfile;
304d226d16bb06861527e5ec162e39d9673e23df83akahuangimport android.util.FloatMath;
317e4655b1b3fcbc543430bea680872f564af098f5Wei-Ta Chenimport android.util.Log;
32d4247bc43702d5ccda5dde40e948fffd6c4445eeRay Chen
335eddabb2790173fd451dbfb49824c05e4fba0501Chih-Chung Changimport com.android.gallery3d.common.ApiHelper;
345eddabb2790173fd451dbfb49824c05e4fba0501Chih-Chung Chang
35d4247bc43702d5ccda5dde40e948fffd6c4445eeRay Chenimport java.util.ArrayList;
364305c70dc849156be5d79d52772ea71cd890ca40Wu-cheng Liimport java.util.List;
37b10ed0f6bde8f02b3b8a0d66e337bdd32bee23a5Michael Kolbimport java.util.Locale;
3887341536812081826656040ac81f8f386c6c1407Wu-cheng Li
39271b3095b9f763421c0547109da9de774795072dChih-Chung Chang/**
40271b3095b9f763421c0547109da9de774795072dChih-Chung Chang *  Provides utilities and keys for Camera settings.
41271b3095b9f763421c0547109da9de774795072dChih-Chung Chang */
4278f160ee416ba27ba55954950473e17ba9d20052Owen Linpublic class CameraSettings {
4378f160ee416ba27ba55954950473e17ba9d20052Owen Lin    private static final int NOT_FOUND = -1;
4478f160ee416ba27ba55954950473e17ba9d20052Owen Lin
4578f160ee416ba27ba55954950473e17ba9d20052Owen Lin    public static final String KEY_VERSION = "pref_version_key";
461ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang    public static final String KEY_LOCAL_VERSION = "pref_local_version_key";
47a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong    public static final String KEY_RECORD_LOCATION = "pref_camera_recordlocation_key";
48469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin    public static final String KEY_VIDEO_QUALITY = "pref_video_quality_key";
49f6a9ed7f6b08d0694795adc6ea6fce999e8cab87Nipun Kwatra    public static final String KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL = "pref_video_time_lapse_frame_interval_key";
509dacf7b214339440c16f3d66e12d6afef1248f68Wu-cheng Li    public static final String KEY_PICTURE_SIZE = "pref_camera_picturesize_key";
51e0770004600f76cc4b440104e98e14712b4fd1c6Wu-cheng Li    public static final String KEY_JPEG_QUALITY = "pref_camera_jpegquality_key";
520f56ef5704b7f1a0874528367147487c051876d9Wu-cheng Li    public static final String KEY_FOCUS_MODE = "pref_camera_focusmode_key";
535945773c664ada754ce5eb9239bd4c8bd95ee4b4Wu-cheng Li    public static final String KEY_FLASH_MODE = "pref_camera_flashmode_key";
54da3e9964a4a82a942d7f450e7c89904f5c5aa03fWu-cheng Li    public static final String KEY_VIDEOCAMERA_FLASH_MODE = "pref_camera_video_flashmode_key";
5533be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin    public static final String KEY_WHITE_BALANCE = "pref_camera_whitebalance_key";
568d0ba007ec6ef9bb34dc0c9f40c4c29dad2691e0Owen Lin    public static final String KEY_SCENE_MODE = "pref_camera_scenemode_key";
5733be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin    public static final String KEY_EXPOSURE = "pref_camera_exposure_key";
5854d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    public static final String KEY_TIMER = "pref_camera_timer_key";
598e3b1df4fcc770965d0796ac2046ef9e265d4bdbDoris Liu    public static final String KEY_TIMER_SOUND_EFFECTS = "pref_camera_timer_sound_key";
6071e76dcebdbb3e5768fc948bed9c529a5787294eWu-cheng Li    public static final String KEY_VIDEO_EFFECT = "pref_video_effect_key";
617add00693c1ec910bc8700fe046ee18cbe4e1148Wu-cheng Li    public static final String KEY_CAMERA_ID = "pref_camera_id_key";
62ad30bda0d0103bd8a93eb834c234341b1ab1e77fWu-cheng Li    public static final String KEY_CAMERA_HDR = "pref_camera_hdr_key";
63d6e5029b2df45210834334f7c2e99dfc85e962f0Chih-yu Huang    public static final String KEY_CAMERA_FIRST_USE_HINT_SHOWN = "pref_camera_first_use_hint_shown_key";
64d6e5029b2df45210834334f7c2e99dfc85e962f0Chih-yu Huang    public static final String KEY_VIDEO_FIRST_USE_HINT_SHOWN = "pref_video_first_use_hint_shown_key";
658791695ba110ad0b088d2e8b3b0127c0042e1865Owen Lin
66f5876dbd29607a0e9762f88e9db6fa35ffb20067Owen Lin    public static final String EXPOSURE_DEFAULT_VALUE = "0";
67f5876dbd29607a0e9762f88e9db6fa35ffb20067Owen Lin
6805999715cc38365aa4751a2a355eb1af284573abAngus Kong    public static final int CURRENT_VERSION = 5;
69cfcb0b746106900c9233f9bf51843f82d50f9d20Angus Kong    public static final int CURRENT_LOCAL_VERSION = 2;
70b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
7178f160ee416ba27ba55954950473e17ba9d20052Owen Lin    private static final String TAG = "CameraSettings";
7278f160ee416ba27ba55954950473e17ba9d20052Owen Lin
7378f160ee416ba27ba55954950473e17ba9d20052Owen Lin    private final Context mContext;
7478f160ee416ba27ba55954950473e17ba9d20052Owen Lin    private final Parameters mParameters;
757add00693c1ec910bc8700fe046ee18cbe4e1148Wu-cheng Li    private final CameraInfo[] mCameraInfo;
76c300a0266d634bb7a1e2df816e97bad2836991acWu-cheng Li    private final int mCameraId;
7778f160ee416ba27ba55954950473e17ba9d20052Owen Lin
787add00693c1ec910bc8700fe046ee18cbe4e1148Wu-cheng Li    public CameraSettings(Activity activity, Parameters parameters,
79c300a0266d634bb7a1e2df816e97bad2836991acWu-cheng Li                          int cameraId, CameraInfo[] cameraInfo) {
8078f160ee416ba27ba55954950473e17ba9d20052Owen Lin        mContext = activity;
8178f160ee416ba27ba55954950473e17ba9d20052Owen Lin        mParameters = parameters;
82c300a0266d634bb7a1e2df816e97bad2836991acWu-cheng Li        mCameraId = cameraId;
837add00693c1ec910bc8700fe046ee18cbe4e1148Wu-cheng Li        mCameraInfo = cameraInfo;
8478f160ee416ba27ba55954950473e17ba9d20052Owen Lin    }
8578f160ee416ba27ba55954950473e17ba9d20052Owen Lin
8673e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    public PreferenceGroup getPreferenceGroup(int preferenceRes) {
8773e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        PreferenceInflater inflater = new PreferenceInflater(mContext);
8873e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        PreferenceGroup group =
8973e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin                (PreferenceGroup) inflater.inflate(preferenceRes);
90ed61bcd7cd05b41e5525570f9e271813695612b9Michael Kolb        if (mParameters != null) initPreference(group);
9173e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        return group;
9278f160ee416ba27ba55954950473e17ba9d20052Owen Lin    }
9378f160ee416ba27ba55954950473e17ba9d20052Owen Lin
945d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting    @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
95926405a84a882ab78f2f5aa1e88c4961640724f7Eino-Ville Talvala    public static String getDefaultVideoQuality(int cameraId,
96926405a84a882ab78f2f5aa1e88c4961640724f7Eino-Ville Talvala            String defaultQuality) {
975d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting        if (ApiHelper.HAS_FINE_RESOLUTION_QUALITY_LEVELS) {
985d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting            if (CamcorderProfile.hasProfile(
995d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting                    cameraId, Integer.valueOf(defaultQuality))) {
1005d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting                return defaultQuality;
1015d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting            }
10205999715cc38365aa4751a2a355eb1af284573abAngus Kong        }
10305999715cc38365aa4751a2a355eb1af284573abAngus Kong        return Integer.toString(CamcorderProfile.QUALITY_HIGH);
10405999715cc38365aa4751a2a355eb1af284573abAngus Kong    }
10505999715cc38365aa4751a2a355eb1af284573abAngus Kong
10632bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin    public static void initialCameraPictureSize(
10732bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin            Context context, Parameters parameters) {
10832bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        // When launching the camera app first time, we will set the picture
10932bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        // size to the first one in the list defined in "arrays.xml" and is also
11032bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        // supported by the driver.
11132bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        List<Size> supported = parameters.getSupportedPictureSizes();
11232bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        if (supported == null) return;
11332bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        for (String candidate : context.getResources().getStringArray(
11432bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin                R.array.pref_camera_picturesize_entryvalues)) {
11532bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin            if (setCameraPictureSize(candidate, supported, parameters)) {
1161ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang                SharedPreferences.Editor editor = ComboPreferences
1171ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang                        .get(context).edit();
11832bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin                editor.putString(KEY_PICTURE_SIZE, candidate);
1194714a1cf1d211aad2d8cf1802f85f649e744beb0Wu-cheng Li                editor.apply();
12032bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin                return;
12132bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin            }
12232bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        }
1234ddee78a1507b3c067745023bd2330b866b8aaf9Owen Lin        Log.e(TAG, "No supported picture size found");
12432bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin    }
12532bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin
1267e4655b1b3fcbc543430bea680872f564af098f5Wei-Ta Chen    public static void removePreferenceFromScreen(
12773e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            PreferenceGroup group, String key) {
12873e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        removePreference(group, key);
1297e4655b1b3fcbc543430bea680872f564af098f5Wei-Ta Chen    }
1307e4655b1b3fcbc543430bea680872f564af098f5Wei-Ta Chen
13132bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin    public static boolean setCameraPictureSize(
13232bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin            String candidate, List<Size> supported, Parameters parameters) {
13332bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        int index = candidate.indexOf('x');
13432bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        if (index == NOT_FOUND) return false;
13532bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        int width = Integer.parseInt(candidate.substring(0, index));
13632bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        int height = Integer.parseInt(candidate.substring(index + 1));
13705999715cc38365aa4751a2a355eb1af284573abAngus Kong        for (Size size : supported) {
13832bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin            if (size.width == width && size.height == height) {
13932bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin                parameters.setPictureSize(width, height);
14032bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin                return true;
14132bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin            }
14232bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        }
14332bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin        return false;
14432bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin    }
14532bfffa5822490ea0e105e9fe00b9df8db1b7b02Owen Lin
146c6c123c85fdc2bf9a9f93fd25f3b951c016a67c0Angus Kong    public static int getMaxVideoDuration(Context context) {
147c6c123c85fdc2bf9a9f93fd25f3b951c016a67c0Angus Kong        int duration = 0;  // in milliseconds, 0 means unlimited.
148c6c123c85fdc2bf9a9f93fd25f3b951c016a67c0Angus Kong        try {
149c6c123c85fdc2bf9a9f93fd25f3b951c016a67c0Angus Kong            duration = context.getResources().getInteger(R.integer.max_video_recording_length);
150c6c123c85fdc2bf9a9f93fd25f3b951c016a67c0Angus Kong        } catch (Resources.NotFoundException ex) {
151c6c123c85fdc2bf9a9f93fd25f3b951c016a67c0Angus Kong        }
152c6c123c85fdc2bf9a9f93fd25f3b951c016a67c0Angus Kong        return duration;
153c6c123c85fdc2bf9a9f93fd25f3b951c016a67c0Angus Kong    }
154c6c123c85fdc2bf9a9f93fd25f3b951c016a67c0Angus Kong
15573e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    private void initPreference(PreferenceGroup group) {
156469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin        ListPreference videoQuality = group.findPreference(KEY_VIDEO_QUALITY);
157b3681fed693233f202e250ff22fed70d1bbb1932Wu-cheng Li        ListPreference timeLapseInterval = group.findPreference(KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL);
15873e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        ListPreference pictureSize = group.findPreference(KEY_PICTURE_SIZE);
15973e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        ListPreference whiteBalance =  group.findPreference(KEY_WHITE_BALANCE);
16073e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        ListPreference sceneMode = group.findPreference(KEY_SCENE_MODE);
16173e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        ListPreference flashMode = group.findPreference(KEY_FLASH_MODE);
16273e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        ListPreference focusMode = group.findPreference(KEY_FOCUS_MODE);
163ec6a318cdba09ff85bdcacd861442b617399b6daMichael Kolb        IconListPreference exposure =
164ec6a318cdba09ff85bdcacd861442b617399b6daMichael Kolb                (IconListPreference) group.findPreference(KEY_EXPOSURE);
16554d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        CountDownTimerPreference timer =
16654d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu                (CountDownTimerPreference) group.findPreference(KEY_TIMER);
1678e3b1df4fcc770965d0796ac2046ef9e265d4bdbDoris Liu        ListPreference countDownSoundEffects = group.findPreference(KEY_TIMER_SOUND_EFFECTS);
168c300a0266d634bb7a1e2df816e97bad2836991acWu-cheng Li        IconListPreference cameraIdPref =
16905999715cc38365aa4751a2a355eb1af284573abAngus Kong                (IconListPreference) group.findPreference(KEY_CAMERA_ID);
1706988d4e2ef8d14d8bf3ee81c8eb3175bbf1b88ecOwen Lin        ListPreference videoFlashMode =
1716988d4e2ef8d14d8bf3ee81c8eb3175bbf1b88ecOwen Lin                group.findPreference(KEY_VIDEOCAMERA_FLASH_MODE);
17271e76dcebdbb3e5768fc948bed9c529a5787294eWu-cheng Li        ListPreference videoEffect = group.findPreference(KEY_VIDEO_EFFECT);
173ad30bda0d0103bd8a93eb834c234341b1ab1e77fWu-cheng Li        ListPreference cameraHdr = group.findPreference(KEY_CAMERA_HDR);
17478f160ee416ba27ba55954950473e17ba9d20052Owen Lin
17578f160ee416ba27ba55954950473e17ba9d20052Owen Lin        // Since the screen could be loaded from different resources, we need
17678f160ee416ba27ba55954950473e17ba9d20052Owen Lin        // to check if the preference is available here
177469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin        if (videoQuality != null) {
17805999715cc38365aa4751a2a355eb1af284573abAngus Kong            filterUnsupportedOptions(group, videoQuality, getSupportedVideoQuality());
1794305c70dc849156be5d79d52772ea71cd890ca40Wu-cheng Li        }
1804305c70dc849156be5d79d52772ea71cd890ca40Wu-cheng Li
18178f160ee416ba27ba55954950473e17ba9d20052Owen Lin        if (pictureSize != null) {
18273e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            filterUnsupportedOptions(group, pictureSize, sizeListToStringList(
18378f160ee416ba27ba55954950473e17ba9d20052Owen Lin                    mParameters.getSupportedPictureSizes()));
18463d92f7a1ff8210e271767f57dc49c9d0b1f4d31Ahbong Chang            filterSimilarPictureSize(group, pictureSize);
1853f3c857e3f34650c15d764810335024654b0fcc3Owen Lin        }
18678f160ee416ba27ba55954950473e17ba9d20052Owen Lin        if (whiteBalance != null) {
18773e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            filterUnsupportedOptions(group,
18878f160ee416ba27ba55954950473e17ba9d20052Owen Lin                    whiteBalance, mParameters.getSupportedWhiteBalance());
1890f56ef5704b7f1a0874528367147487c051876d9Wu-cheng Li        }
19078f160ee416ba27ba55954950473e17ba9d20052Owen Lin        if (sceneMode != null) {
19173e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            filterUnsupportedOptions(group,
19278f160ee416ba27ba55954950473e17ba9d20052Owen Lin                    sceneMode, mParameters.getSupportedSceneModes());
1930f56ef5704b7f1a0874528367147487c051876d9Wu-cheng Li        }
194b6ad206f53981faee04800b787569dbb60492844Owen Lin        if (flashMode != null) {
19573e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            filterUnsupportedOptions(group,
196b6ad206f53981faee04800b787569dbb60492844Owen Lin                    flashMode, mParameters.getSupportedFlashModes());
197b6ad206f53981faee04800b787569dbb60492844Owen Lin        }
198df3731bacfe26910a5dd0813c6aa80a6e55b85adCheng-Ru Lin        if (focusMode != null) {
199df90c922da29c6c4fa2de721e3cff19461c51715Ahbong Chang            if (!Util.isFocusAreaSupported(mParameters)) {
200f5d28a1e17e011daf601d464ce4aa0b8d0ce2f22Wu-cheng Li                filterUnsupportedOptions(group,
201f5d28a1e17e011daf601d464ce4aa0b8d0ce2f22Wu-cheng Li                        focusMode, mParameters.getSupportedFocusModes());
202f5d28a1e17e011daf601d464ce4aa0b8d0ce2f22Wu-cheng Li            } else {
203f5d28a1e17e011daf601d464ce4aa0b8d0ce2f22Wu-cheng Li                // Remove the focus mode if we can use tap-to-focus.
204f5d28a1e17e011daf601d464ce4aa0b8d0ce2f22Wu-cheng Li                removePreference(group, focusMode.getKey());
205f5d28a1e17e011daf601d464ce4aa0b8d0ce2f22Wu-cheng Li            }
2066988d4e2ef8d14d8bf3ee81c8eb3175bbf1b88ecOwen Lin        }
2076988d4e2ef8d14d8bf3ee81c8eb3175bbf1b88ecOwen Lin        if (videoFlashMode != null) {
2086988d4e2ef8d14d8bf3ee81c8eb3175bbf1b88ecOwen Lin            filterUnsupportedOptions(group,
2096988d4e2ef8d14d8bf3ee81c8eb3175bbf1b88ecOwen Lin                    videoFlashMode, mParameters.getSupportedFlashModes());
210df3731bacfe26910a5dd0813c6aa80a6e55b85adCheng-Ru Lin        }
2117add00693c1ec910bc8700fe046ee18cbe4e1148Wu-cheng Li        if (exposure != null) buildExposureCompensation(group, exposure);
212c300a0266d634bb7a1e2df816e97bad2836991acWu-cheng Li        if (cameraIdPref != null) buildCameraId(group, cameraIdPref);
213b3681fed693233f202e250ff22fed70d1bbb1932Wu-cheng Li
2145eddabb2790173fd451dbfb49824c05e4fba0501Chih-Chung Chang        if (timeLapseInterval != null) {
2155eddabb2790173fd451dbfb49824c05e4fba0501Chih-Chung Chang            if (ApiHelper.HAS_TIME_LAPSE_RECORDING) {
2165eddabb2790173fd451dbfb49824c05e4fba0501Chih-Chung Chang                resetIfInvalid(timeLapseInterval);
2175eddabb2790173fd451dbfb49824c05e4fba0501Chih-Chung Chang            } else {
2185eddabb2790173fd451dbfb49824c05e4fba0501Chih-Chung Chang                removePreference(group, timeLapseInterval.getKey());
2195eddabb2790173fd451dbfb49824c05e4fba0501Chih-Chung Chang            }
2205eddabb2790173fd451dbfb49824c05e4fba0501Chih-Chung Chang        }
2219efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        if (videoEffect != null) {
2228145371c52a62fbebbc20685bf0901ce50495e21Pin Ting            if (ApiHelper.HAS_EFFECTS_RECORDING) {
2238145371c52a62fbebbc20685bf0901ce50495e21Pin Ting                initVideoEffect(group, videoEffect);
2248145371c52a62fbebbc20685bf0901ce50495e21Pin Ting                resetIfInvalid(videoEffect);
2258145371c52a62fbebbc20685bf0901ce50495e21Pin Ting            } else {
2268145371c52a62fbebbc20685bf0901ce50495e21Pin Ting                filterUnsupportedOptions(group, videoEffect, null);
2278145371c52a62fbebbc20685bf0901ce50495e21Pin Ting            }
2289efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        }
229ad30bda0d0103bd8a93eb834c234341b1ab1e77fWu-cheng Li        if (cameraHdr != null && (!ApiHelper.HAS_CAMERA_HDR
230ad30bda0d0103bd8a93eb834c234341b1ab1e77fWu-cheng Li                    || !Util.isCameraHdrSupported(mParameters))) {
231ad30bda0d0103bd8a93eb834c234341b1ab1e77fWu-cheng Li            removePreference(group, cameraHdr.getKey());
232ad30bda0d0103bd8a93eb834c234341b1ab1e77fWu-cheng Li        }
23333be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin    }
23433be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin
23533be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin    private void buildExposureCompensation(
236ec6a318cdba09ff85bdcacd861442b617399b6daMichael Kolb            PreferenceGroup group, IconListPreference exposure) {
23733be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        int max = mParameters.getMaxExposureCompensation();
23833be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        int min = mParameters.getMinExposureCompensation();
23933be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        if (max == 0 && min == 0) {
24033be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin            removePreference(group, exposure.getKey());
24133be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin            return;
24233be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        }
24333be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        float step = mParameters.getExposureCompensationStep();
24433be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin
24533be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        // show only integer values for exposure compensation
2464d226d16bb06861527e5ec162e39d9673e23df83akahuang        int maxValue = (int) FloatMath.floor(max * step);
2474d226d16bb06861527e5ec162e39d9673e23df83akahuang        int minValue = (int) FloatMath.ceil(min * step);
24833be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        CharSequence entries[] = new CharSequence[maxValue - minValue + 1];
24933be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        CharSequence entryValues[] = new CharSequence[maxValue - minValue + 1];
250ec6a318cdba09ff85bdcacd861442b617399b6daMichael Kolb        int[] icons = new int[maxValue - minValue + 1];
251ec6a318cdba09ff85bdcacd861442b617399b6daMichael Kolb        TypedArray iconIds = mContext.getResources().obtainTypedArray(
252ec6a318cdba09ff85bdcacd861442b617399b6daMichael Kolb                R.array.pref_camera_exposure_icons);
25333be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        for (int i = minValue; i <= maxValue; ++i) {
25433be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin            entryValues[maxValue - i] = Integer.toString(Math.round(i / step));
25533be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin            StringBuilder builder = new StringBuilder();
25633be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin            if (i > 0) builder.append('+');
25733be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin            entries[maxValue - i] = builder.append(i).toString();
258ec6a318cdba09ff85bdcacd861442b617399b6daMichael Kolb            icons[maxValue - i] = iconIds.getResourceId(3 + i, 0);
25933be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        }
260ec6a318cdba09ff85bdcacd861442b617399b6daMichael Kolb        exposure.setUseSingleIcon(true);
26133be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        exposure.setEntries(entries);
26233be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        exposure.setEntryValues(entryValues);
263ec6a318cdba09ff85bdcacd861442b617399b6daMichael Kolb        exposure.setLargeIconIds(icons);
264b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
265b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
2667add00693c1ec910bc8700fe046ee18cbe4e1148Wu-cheng Li    private void buildCameraId(
26759ddc8c1add2fcffe523e3877baad1b6cc5ba2fbChung-yih Wang            PreferenceGroup group, IconListPreference preference) {
2687add00693c1ec910bc8700fe046ee18cbe4e1148Wu-cheng Li        int numOfCameras = mCameraInfo.length;
2697add00693c1ec910bc8700fe046ee18cbe4e1148Wu-cheng Li        if (numOfCameras < 2) {
27059ddc8c1add2fcffe523e3877baad1b6cc5ba2fbChung-yih Wang            removePreference(group, preference.getKey());
2717add00693c1ec910bc8700fe046ee18cbe4e1148Wu-cheng Li            return;
2727add00693c1ec910bc8700fe046ee18cbe4e1148Wu-cheng Li        }
2737add00693c1ec910bc8700fe046ee18cbe4e1148Wu-cheng Li
27470ad8651d018b6d3ddea2e0bb7c8b12384059bf0Angus Kong        CharSequence[] entryValues = new CharSequence[numOfCameras];
27570ad8651d018b6d3ddea2e0bb7c8b12384059bf0Angus Kong        for (int i = 0; i < numOfCameras; ++i) {
27670ad8651d018b6d3ddea2e0bb7c8b12384059bf0Angus Kong            entryValues[i] = "" + i;
2777add00693c1ec910bc8700fe046ee18cbe4e1148Wu-cheng Li        }
27859ddc8c1add2fcffe523e3877baad1b6cc5ba2fbChung-yih Wang        preference.setEntryValues(entryValues);
27959ddc8c1add2fcffe523e3877baad1b6cc5ba2fbChung-yih Wang    }
28059ddc8c1add2fcffe523e3877baad1b6cc5ba2fbChung-yih Wang
28173e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    private static boolean removePreference(PreferenceGroup group, String key) {
28273e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        for (int i = 0, n = group.size(); i < n; i++) {
28373e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            CameraPreference child = group.get(i);
2845945773c664ada754ce5eb9239bd4c8bd95ee4b4Wu-cheng Li            if (child instanceof PreferenceGroup) {
28573e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin                if (removePreference((PreferenceGroup) child, key)) {
2865945773c664ada754ce5eb9239bd4c8bd95ee4b4Wu-cheng Li                    return true;
2875945773c664ada754ce5eb9239bd4c8bd95ee4b4Wu-cheng Li                }
2885945773c664ada754ce5eb9239bd4c8bd95ee4b4Wu-cheng Li            }
28973e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            if (child instanceof ListPreference &&
29073e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin                    ((ListPreference) child).getKey().equals(key)) {
29173e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin                group.removePreference(i);
29273e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin                return true;
29373e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            }
2945945773c664ada754ce5eb9239bd4c8bd95ee4b4Wu-cheng Li        }
2955945773c664ada754ce5eb9239bd4c8bd95ee4b4Wu-cheng Li        return false;
2965945773c664ada754ce5eb9239bd4c8bd95ee4b4Wu-cheng Li    }
2975945773c664ada754ce5eb9239bd4c8bd95ee4b4Wu-cheng Li
29873e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    private void filterUnsupportedOptions(PreferenceGroup group,
29978f160ee416ba27ba55954950473e17ba9d20052Owen Lin            ListPreference pref, List<String> supported) {
30078f160ee416ba27ba55954950473e17ba9d20052Owen Lin
301df3731bacfe26910a5dd0813c6aa80a6e55b85adCheng-Ru Lin        // Remove the preference if the parameter is not supported or there is
302df3731bacfe26910a5dd0813c6aa80a6e55b85adCheng-Ru Lin        // only one options for the settings.
30322a695f8ca31dc2899e7206d68316c7e6d960657Owen Lin        if (supported == null || supported.size() <= 1) {
30473e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            removePreference(group, pref.getKey());
3059dacf7b214339440c16f3d66e12d6afef1248f68Wu-cheng Li            return;
3069dacf7b214339440c16f3d66e12d6afef1248f68Wu-cheng Li        }
3079dacf7b214339440c16f3d66e12d6afef1248f68Wu-cheng Li
3081e7d70c59c3547db7589c1cae977e98d9b4e95b9Owen Lin        pref.filterUnsupported(supported);
30922216b6cc942fc3a97b99d6bce4b1a86f19c08d4Wu-cheng Li        if (pref.getEntries().length <= 1) {
31022216b6cc942fc3a97b99d6bce4b1a86f19c08d4Wu-cheng Li            removePreference(group, pref.getKey());
31122216b6cc942fc3a97b99d6bce4b1a86f19c08d4Wu-cheng Li            return;
31222216b6cc942fc3a97b99d6bce4b1a86f19c08d4Wu-cheng Li        }
31387341536812081826656040ac81f8f386c6c1407Wu-cheng Li
314b3681fed693233f202e250ff22fed70d1bbb1932Wu-cheng Li        resetIfInvalid(pref);
315b3681fed693233f202e250ff22fed70d1bbb1932Wu-cheng Li    }
316b3681fed693233f202e250ff22fed70d1bbb1932Wu-cheng Li
31763d92f7a1ff8210e271767f57dc49c9d0b1f4d31Ahbong Chang    private void filterSimilarPictureSize(PreferenceGroup group,
31863d92f7a1ff8210e271767f57dc49c9d0b1f4d31Ahbong Chang            ListPreference pref) {
31963d92f7a1ff8210e271767f57dc49c9d0b1f4d31Ahbong Chang        pref.filterDuplicated();
32063d92f7a1ff8210e271767f57dc49c9d0b1f4d31Ahbong Chang        if (pref.getEntries().length <= 1) {
32163d92f7a1ff8210e271767f57dc49c9d0b1f4d31Ahbong Chang            removePreference(group, pref.getKey());
32263d92f7a1ff8210e271767f57dc49c9d0b1f4d31Ahbong Chang            return;
32363d92f7a1ff8210e271767f57dc49c9d0b1f4d31Ahbong Chang        }
32463d92f7a1ff8210e271767f57dc49c9d0b1f4d31Ahbong Chang        resetIfInvalid(pref);
32563d92f7a1ff8210e271767f57dc49c9d0b1f4d31Ahbong Chang    }
32663d92f7a1ff8210e271767f57dc49c9d0b1f4d31Ahbong Chang
327b3681fed693233f202e250ff22fed70d1bbb1932Wu-cheng Li    private void resetIfInvalid(ListPreference pref) {
3282ac0387bbd6792187aeaacf10e40688f4260e316Wu-cheng Li        // Set the value to the first entry if it is invalid.
3292ac0387bbd6792187aeaacf10e40688f4260e316Wu-cheng Li        String value = pref.getValue();
33078f160ee416ba27ba55954950473e17ba9d20052Owen Lin        if (pref.findIndexOfValue(value) == NOT_FOUND) {
3312ac0387bbd6792187aeaacf10e40688f4260e316Wu-cheng Li            pref.setValueIndex(0);
33287341536812081826656040ac81f8f386c6c1407Wu-cheng Li        }
33387341536812081826656040ac81f8f386c6c1407Wu-cheng Li    }
33487341536812081826656040ac81f8f386c6c1407Wu-cheng Li
33578f160ee416ba27ba55954950473e17ba9d20052Owen Lin    private static List<String> sizeListToStringList(List<Size> sizes) {
33678f160ee416ba27ba55954950473e17ba9d20052Owen Lin        ArrayList<String> list = new ArrayList<String>();
33778f160ee416ba27ba55954950473e17ba9d20052Owen Lin        for (Size size : sizes) {
338b10ed0f6bde8f02b3b8a0d66e337bdd32bee23a5Michael Kolb            list.add(String.format(Locale.ENGLISH, "%dx%d", size.width, size.height));
339c8cd9098d9ca174f5a0374789145faf1f15d503dRay Chen        }
34078f160ee416ba27ba55954950473e17ba9d20052Owen Lin        return list;
341b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
3426f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang
3431ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang    public static void upgradeLocalPreferences(SharedPreferences pref) {
3441ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang        int version;
3451ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang        try {
3461ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang            version = pref.getInt(KEY_LOCAL_VERSION, 0);
3471ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang        } catch (Exception ex) {
3481ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang            version = 0;
3491ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang        }
3501ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang        if (version == CURRENT_LOCAL_VERSION) return;
351cfcb0b746106900c9233f9bf51843f82d50f9d20Angus Kong
3521ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang        SharedPreferences.Editor editor = pref.edit();
353cfcb0b746106900c9233f9bf51843f82d50f9d20Angus Kong        if (version == 1) {
354cfcb0b746106900c9233f9bf51843f82d50f9d20Angus Kong            // We use numbers to represent the quality now. The quality definition is identical to
355cfcb0b746106900c9233f9bf51843f82d50f9d20Angus Kong            // that of CamcorderProfile.java.
356cfcb0b746106900c9233f9bf51843f82d50f9d20Angus Kong            editor.remove("pref_video_quality_key");
357cfcb0b746106900c9233f9bf51843f82d50f9d20Angus Kong        }
3581ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang        editor.putInt(KEY_LOCAL_VERSION, CURRENT_LOCAL_VERSION);
3594714a1cf1d211aad2d8cf1802f85f649e744beb0Wu-cheng Li        editor.apply();
3601ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang    }
3611ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang
3621ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang    public static void upgradeGlobalPreferences(SharedPreferences pref) {
36340ffd9c0f81e20a482ca6832a8585ac5232370bfChih-Chung Chang        upgradeOldVersion(pref);
36440ffd9c0f81e20a482ca6832a8585ac5232370bfChih-Chung Chang        upgradeCameraId(pref);
36540ffd9c0f81e20a482ca6832a8585ac5232370bfChih-Chung Chang    }
36640ffd9c0f81e20a482ca6832a8585ac5232370bfChih-Chung Chang
36740ffd9c0f81e20a482ca6832a8585ac5232370bfChih-Chung Chang    private static void upgradeOldVersion(SharedPreferences pref) {
3686f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang        int version;
3696f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang        try {
3706f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang            version = pref.getInt(KEY_VERSION, 0);
3716f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang        } catch (Exception ex) {
3726f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang            version = 0;
3736f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang        }
374a8bbcd7ce25aada705561852ea9f356dc38c0f43Cheng-Ru Lin        if (version == CURRENT_VERSION) return;
3756f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang
376a8bbcd7ce25aada705561852ea9f356dc38c0f43Cheng-Ru Lin        SharedPreferences.Editor editor = pref.edit();
3776f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang        if (version == 0) {
378469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin            // We won't use the preference which change in version 1.
379469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin            // So, just upgrade to version 1 directly
380faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang            version = 1;
381faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang        }
382faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang        if (version == 1) {
383faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang            // Change jpeg quality {65,75,85} to {normal,fine,superfine}
384faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang            String quality = pref.getString(KEY_JPEG_QUALITY, "85");
385faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang            if (quality.equals("65")) {
386faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang                quality = "normal";
387faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang            } else if (quality.equals("75")) {
388faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang                quality = "fine";
389faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang            } else {
390faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang                quality = "superfine";
391faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang            }
392faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang            editor.putString(KEY_JPEG_QUALITY, quality);
393faf398ff0fa2b51348b4545505112d70ba7b47a1Chih-Chung Chang            version = 2;
3946f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang        }
3953e44f8076a16792bb295589ca4b467ba27ea2a6fOwen Lin        if (version == 2) {
3963e44f8076a16792bb295589ca4b467ba27ea2a6fOwen Lin            editor.putString(KEY_RECORD_LOCATION,
3973e44f8076a16792bb295589ca4b467ba27ea2a6fOwen Lin                    pref.getBoolean(KEY_RECORD_LOCATION, false)
3983e44f8076a16792bb295589ca4b467ba27ea2a6fOwen Lin                    ? RecordLocationPreference.VALUE_ON
3993e44f8076a16792bb295589ca4b467ba27ea2a6fOwen Lin                    : RecordLocationPreference.VALUE_NONE);
4003e44f8076a16792bb295589ca4b467ba27ea2a6fOwen Lin            version = 3;
4013e44f8076a16792bb295589ca4b467ba27ea2a6fOwen Lin        }
402469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin        if (version == 3) {
403469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin            // Just use video quality to replace it and
404469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin            // ignore the current settings.
405469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin            editor.remove("pref_camera_videoquality_key");
406469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin            editor.remove("pref_camera_video_duration_key");
407469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin        }
40805999715cc38365aa4751a2a355eb1af284573abAngus Kong
409a8bbcd7ce25aada705561852ea9f356dc38c0f43Cheng-Ru Lin        editor.putInt(KEY_VERSION, CURRENT_VERSION);
4104714a1cf1d211aad2d8cf1802f85f649e744beb0Wu-cheng Li        editor.apply();
4116f2c530d91749ff2b235125c3d134c981970f13dChih-Chung Chang    }
412469a9ef839e38630e1e652d182f7e0ee5882e277Owen Lin
41340ffd9c0f81e20a482ca6832a8585ac5232370bfChih-Chung Chang    private static void upgradeCameraId(SharedPreferences pref) {
41440ffd9c0f81e20a482ca6832a8585ac5232370bfChih-Chung Chang        // The id stored in the preference may be out of range if we are running
41540ffd9c0f81e20a482ca6832a8585ac5232370bfChih-Chung Chang        // inside the emulator and a webcam is removed.
41640ffd9c0f81e20a482ca6832a8585ac5232370bfChih-Chung Chang        // Note: This method accesses the global preferences directly, not the
41740ffd9c0f81e20a482ca6832a8585ac5232370bfChih-Chung Chang        // combo preferences.
41840ffd9c0f81e20a482ca6832a8585ac5232370bfChih-Chung Chang        int cameraId = readPreferredCameraId(pref);
41940ffd9c0f81e20a482ca6832a8585ac5232370bfChih-Chung Chang        if (cameraId == 0) return;  // fast path
42040ffd9c0f81e20a482ca6832a8585ac5232370bfChih-Chung Chang
42140ffd9c0f81e20a482ca6832a8585ac5232370bfChih-Chung Chang        int n = CameraHolder.instance().getNumberOfCameras();
42240ffd9c0f81e20a482ca6832a8585ac5232370bfChih-Chung Chang        if (cameraId < 0 || cameraId >= n) {
42340ffd9c0f81e20a482ca6832a8585ac5232370bfChih-Chung Chang            writePreferredCameraId(pref, 0);
42440ffd9c0f81e20a482ca6832a8585ac5232370bfChih-Chung Chang        }
42540ffd9c0f81e20a482ca6832a8585ac5232370bfChih-Chung Chang    }
42640ffd9c0f81e20a482ca6832a8585ac5232370bfChih-Chung Chang
4271ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang    public static int readPreferredCameraId(SharedPreferences pref) {
4282b4b2a4b2ec489f93b2a98d5c90d972c50a38c7dWu-cheng Li        return Integer.parseInt(pref.getString(KEY_CAMERA_ID, "0"));
429ac9d0a1ce538eb4bd50cba3b257737a05b9ac4e5Chih-Chung Chang    }
430ac9d0a1ce538eb4bd50cba3b257737a05b9ac4e5Chih-Chung Chang
4311ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang    public static void writePreferredCameraId(SharedPreferences pref,
4321ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang            int cameraId) {
4331ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang        Editor editor = pref.edit();
4347add00693c1ec910bc8700fe046ee18cbe4e1148Wu-cheng Li        editor.putString(KEY_CAMERA_ID, Integer.toString(cameraId));
4354714a1cf1d211aad2d8cf1802f85f649e744beb0Wu-cheng Li        editor.apply();
436ac9d0a1ce538eb4bd50cba3b257737a05b9ac4e5Chih-Chung Chang    }
437003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li
438b0c6bcf47a8ca1c096d98ebebd33a821dd483585Chih-yu Huang    public static int readExposure(ComboPreferences preferences) {
439b0c6bcf47a8ca1c096d98ebebd33a821dd483585Chih-yu Huang        String exposure = preferences.getString(
440b0c6bcf47a8ca1c096d98ebebd33a821dd483585Chih-yu Huang                CameraSettings.KEY_EXPOSURE,
441b0c6bcf47a8ca1c096d98ebebd33a821dd483585Chih-yu Huang                EXPOSURE_DEFAULT_VALUE);
442b0c6bcf47a8ca1c096d98ebebd33a821dd483585Chih-yu Huang        try {
443b0c6bcf47a8ca1c096d98ebebd33a821dd483585Chih-yu Huang            return Integer.parseInt(exposure);
444b0c6bcf47a8ca1c096d98ebebd33a821dd483585Chih-yu Huang        } catch (Exception ex) {
445b0c6bcf47a8ca1c096d98ebebd33a821dd483585Chih-yu Huang            Log.e(TAG, "Invalid exposure: " + exposure);
446b0c6bcf47a8ca1c096d98ebebd33a821dd483585Chih-yu Huang        }
447b0c6bcf47a8ca1c096d98ebebd33a821dd483585Chih-yu Huang        return 0;
448b0c6bcf47a8ca1c096d98ebebd33a821dd483585Chih-yu Huang    }
449003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li
4509efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala    public static int readEffectType(SharedPreferences pref) {
4519efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        String effectSelection = pref.getString(KEY_VIDEO_EFFECT, "none");
4529efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        if (effectSelection.equals("none")) {
4539efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala            return EffectsRecorder.EFFECT_NONE;
4549efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        } else if (effectSelection.startsWith("goofy_face")) {
4559efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala            return EffectsRecorder.EFFECT_GOOFY_FACE;
4569efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        } else if (effectSelection.startsWith("backdropper")) {
4579efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala            return EffectsRecorder.EFFECT_BACKDROPPER;
4589efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        }
4599efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        Log.e(TAG, "Invalid effect selection: " + effectSelection);
4609efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        return EffectsRecorder.EFFECT_NONE;
4619efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala    }
4629efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala
4639efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala    public static Object readEffectParameter(SharedPreferences pref) {
4649efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        String effectSelection = pref.getString(KEY_VIDEO_EFFECT, "none");
4659efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        if (effectSelection.equals("none")) {
4669efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala            return null;
4679efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        }
4689efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        int separatorIndex = effectSelection.indexOf('/');
4699efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        String effectParameter =
4709efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala                effectSelection.substring(separatorIndex + 1);
4719efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        if (effectSelection.startsWith("goofy_face")) {
4729efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala            if (effectParameter.equals("squeeze")) {
4739efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala                return EffectsRecorder.EFFECT_GF_SQUEEZE;
4749efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala            } else if (effectParameter.equals("big_eyes")) {
4759efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala                return EffectsRecorder.EFFECT_GF_BIG_EYES;
4769efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala            } else if (effectParameter.equals("big_mouth")) {
4779efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala                return EffectsRecorder.EFFECT_GF_BIG_MOUTH;
4789efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala            } else if (effectParameter.equals("small_mouth")) {
4799efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala                return EffectsRecorder.EFFECT_GF_SMALL_MOUTH;
4809efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala            } else if (effectParameter.equals("big_nose")) {
4819efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala                return EffectsRecorder.EFFECT_GF_BIG_NOSE;
4829efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala            } else if (effectParameter.equals("small_eyes")) {
4839efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala                return EffectsRecorder.EFFECT_GF_SMALL_EYES;
4849efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala            }
4859efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        } else if (effectSelection.startsWith("backdropper")) {
4869efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala            // Parameter is a string that either encodes the URI to use,
4879efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala            // or specifies 'gallery'.
4889efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala            return effectParameter;
4899efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        }
4909efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala
4919efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        Log.e(TAG, "Invalid effect selection: " + effectSelection);
4929efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        return null;
4939efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala    }
4949efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala
495003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li    public static void restorePreferences(Context context,
496003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li            ComboPreferences preferences, Parameters parameters) {
497003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li        int currentCameraId = readPreferredCameraId(preferences);
498003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li
499003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li        // Clear the preferences of both cameras.
500003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li        int backCameraId = CameraHolder.instance().getBackCameraId();
501003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li        if (backCameraId != -1) {
502003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li            preferences.setLocalId(context, backCameraId);
503003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li            Editor editor = preferences.edit();
504003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li            editor.clear();
505003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li            editor.apply();
506003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li        }
507003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li        int frontCameraId = CameraHolder.instance().getFrontCameraId();
508003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li        if (frontCameraId != -1) {
509003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li            preferences.setLocalId(context, frontCameraId);
510003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li            Editor editor = preferences.edit();
511003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li            editor.clear();
512003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li            editor.apply();
513003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li        }
514003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li
5154a70e66b58207703f8a705548efcd5353106e452Wu-cheng Li        // Switch back to the preferences of the current camera. Otherwise,
5164a70e66b58207703f8a705548efcd5353106e452Wu-cheng Li        // we may write the preference to wrong camera later.
5174a70e66b58207703f8a705548efcd5353106e452Wu-cheng Li        preferences.setLocalId(context, currentCameraId);
5184a70e66b58207703f8a705548efcd5353106e452Wu-cheng Li
519003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li        upgradeGlobalPreferences(preferences.getGlobal());
520003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li        upgradeLocalPreferences(preferences.getLocal());
521003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li
522003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li        // Write back the current camera id because parameters are related to
523003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li        // the camera. Otherwise, we may switch to the front camera but the
524003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li        // initial picture size is that of the back camera.
525003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li        initialCameraPictureSize(context, parameters);
526003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li        writePreferredCameraId(preferences, currentCameraId);
527003dd5a52457c024a0f99a2bb222bfc6ad70bbe5Wu-cheng Li    }
52810208b3b4e2e9ca5af27be49356288531e3cd45bWu-cheng Li
52905999715cc38365aa4751a2a355eb1af284573abAngus Kong    private ArrayList<String> getSupportedVideoQuality() {
53005999715cc38365aa4751a2a355eb1af284573abAngus Kong        ArrayList<String> supported = new ArrayList<String>();
53105999715cc38365aa4751a2a355eb1af284573abAngus Kong        // Check for supported quality
5325d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting        if (ApiHelper.HAS_FINE_RESOLUTION_QUALITY_LEVELS) {
5335d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting            getFineResolutionQuality(supported);
5345d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting        } else {
5355d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting            supported.add(Integer.toString(CamcorderProfile.QUALITY_HIGH));
5365d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting            CamcorderProfile high = CamcorderProfile.get(
5375d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting                    mCameraId, CamcorderProfile.QUALITY_HIGH);
5385d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting            CamcorderProfile low = CamcorderProfile.get(
5395d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting                    mCameraId, CamcorderProfile.QUALITY_LOW);
5405d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting            if (high.videoFrameHeight * high.videoFrameWidth >
5415d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting                    low.videoFrameHeight * low.videoFrameWidth) {
5425d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting                supported.add(Integer.toString(CamcorderProfile.QUALITY_LOW));
5435d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting            }
5445d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting        }
5455d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting
5465d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting        return supported;
5475d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting    }
5485d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting
5495d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting    @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
5505d08d2998fb809b4443d31d60ec38b12cda97be4Pin Ting    private void getFineResolutionQuality(ArrayList<String> supported) {
55105999715cc38365aa4751a2a355eb1af284573abAngus Kong        if (CamcorderProfile.hasProfile(mCameraId, CamcorderProfile.QUALITY_1080P)) {
55205999715cc38365aa4751a2a355eb1af284573abAngus Kong            supported.add(Integer.toString(CamcorderProfile.QUALITY_1080P));
55305999715cc38365aa4751a2a355eb1af284573abAngus Kong        }
55405999715cc38365aa4751a2a355eb1af284573abAngus Kong        if (CamcorderProfile.hasProfile(mCameraId, CamcorderProfile.QUALITY_720P)) {
55505999715cc38365aa4751a2a355eb1af284573abAngus Kong            supported.add(Integer.toString(CamcorderProfile.QUALITY_720P));
55610208b3b4e2e9ca5af27be49356288531e3cd45bWu-cheng Li        }
55705999715cc38365aa4751a2a355eb1af284573abAngus Kong        if (CamcorderProfile.hasProfile(mCameraId, CamcorderProfile.QUALITY_480P)) {
55805999715cc38365aa4751a2a355eb1af284573abAngus Kong            supported.add(Integer.toString(CamcorderProfile.QUALITY_480P));
55905999715cc38365aa4751a2a355eb1af284573abAngus Kong        }
56010208b3b4e2e9ca5af27be49356288531e3cd45bWu-cheng Li    }
5619efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala
5629efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala    private void initVideoEffect(PreferenceGroup group, ListPreference videoEffect) {
5639efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        CharSequence[] values = videoEffect.getEntryValues();
5649efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala
56505999715cc38365aa4751a2a355eb1af284573abAngus Kong        boolean goofyFaceSupported =
56605999715cc38365aa4751a2a355eb1af284573abAngus Kong                EffectsRecorder.isEffectSupported(EffectsRecorder.EFFECT_GOOFY_FACE);
5679efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        boolean backdropperSupported =
5689efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala                EffectsRecorder.isEffectSupported(EffectsRecorder.EFFECT_BACKDROPPER) &&
569f2229614847f060be34593757ca402ae62c7cc7dAhbong Chang                Util.isAutoExposureLockSupported(mParameters) &&
570f2229614847f060be34593757ca402ae62c7cc7dAhbong Chang                Util.isAutoWhiteBalanceLockSupported(mParameters);
5719efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala
5729efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        ArrayList<String> supported = new ArrayList<String>();
5739efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        for (CharSequence value : values) {
5749efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala            String effectSelection = value.toString();
5759efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala            if (!goofyFaceSupported && effectSelection.startsWith("goofy_face")) continue;
5769efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala            if (!backdropperSupported && effectSelection.startsWith("backdropper")) continue;
5779efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala            supported.add(effectSelection);
5789efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        }
5799efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala
5809efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala        filterUnsupportedOptions(group, videoEffect, supported);
5819efb0b19fa929c528253f0a9b6f5b27791e1ee52Eino-Ville Talvala    }
582b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project}
583