CameraSettings.java revision 7af25641ec401d9f669497bd401020f2cb5933ef
1package com.android.camera;
2
3import android.app.Activity;
4import android.content.Context;
5import android.content.SharedPreferences;
6import android.hardware.Camera.Parameters;
7import android.hardware.Camera.Size;
8import android.os.SystemProperties;
9import android.preference.ListPreference;
10import android.preference.Preference;
11import android.preference.PreferenceGroup;
12import android.preference.PreferenceManager;
13import android.preference.PreferenceScreen;
14import android.util.Log;
15
16import java.util.ArrayList;
17import java.util.List;
18
19public class CameraSettings {
20    private static final int FIRST_REQUEST_CODE = 100;
21    private static final int NOT_FOUND = -1;
22
23    public static final String KEY_VERSION = "pref_version_key";
24    public static final String KEY_RECORD_LOCATION =
25            "pref_camera_recordlocation_key";
26    public static final String KEY_VIDEO_QUALITY =
27            "pref_camera_videoquality_key";
28    public static final String KEY_VIDEO_DURATION =
29            "pref_camera_video_duration_key";
30    public static final String KEY_PICTURE_SIZE = "pref_camera_picturesize_key";
31    public static final String KEY_JPEG_QUALITY = "pref_camera_jpegquality_key";
32    public static final String KEY_FOCUS_MODE = "pref_camera_focusmode_key";
33    public static final String KEY_FLASH_MODE = "pref_camera_flashmode_key";
34    public static final String KEY_COLOR_EFFECT = "pref_camera_coloreffect_key";
35    public static final String KEY_WHITE_BALANCE =
36            "pref_camera_whitebalance_key";
37    public static final String KEY_SCENE_MODE = "pref_camera_scenemode_key";
38
39    public static final int CURRENT_VERSION = 1;
40
41    // max mms video duration in seconds.
42    public static final int MMS_VIDEO_DURATION =
43            SystemProperties.getInt("ro.media.enc.lprof.duration", 60);
44
45    public static final boolean DEFAULT_VIDEO_QUALITY_VALUE = true;
46
47    // MMS video length
48    public static final int DEFAULT_VIDEO_DURATION_VALUE = -1;
49
50    @SuppressWarnings("unused")
51    private static final String TAG = "CameraSettings";
52
53    private final Context mContext;
54    private final Parameters mParameters;
55    private final PreferenceManager mManager;
56
57    public CameraSettings(Activity activity, Parameters parameters) {
58        mContext = activity;
59        mParameters = parameters;
60        mManager = new PreferenceManager(activity, FIRST_REQUEST_CODE);
61    }
62
63    public PreferenceScreen getPreferenceScreen(int preferenceRes) {
64        PreferenceScreen screen = mManager.createPreferenceScreen(mContext);
65        mManager.inflateFromResource(mContext, preferenceRes, screen);
66        initPreference(screen);
67        return screen;
68    }
69
70    public static void initialCameraPictureSize(
71            Context context, Parameters parameters) {
72        // When launching the camera app first time, we will set the picture
73        // size to the first one in the list defined in "arrays.xml" and is also
74        // supported by the driver.
75        List<Size> supported = parameters.getSupportedPictureSizes();
76        if (supported == null) return;
77        for (String candidate : context.getResources().getStringArray(
78                R.array.pref_camera_picturesize_entryvalues)) {
79            if (setCameraPictureSize(candidate, supported, parameters)) {
80                SharedPreferences.Editor editor = PreferenceManager
81                        .getDefaultSharedPreferences(context).edit();
82                editor.putString(KEY_PICTURE_SIZE, candidate);
83                editor.commit();
84                return;
85            }
86        }
87    }
88
89    public static void removePreferenceFromScreen(
90            PreferenceScreen screen, String key) {
91        Preference pref = screen.findPreference(key);
92        if (pref == null) {
93            Log.i(TAG, "No preference found based the key : " + key);
94            throw new IllegalArgumentException();
95        } else {
96            removePreference(screen, pref);
97        }
98    }
99
100    public static boolean setCameraPictureSize(
101            String candidate, List<Size> supported, Parameters parameters) {
102        int index = candidate.indexOf('x');
103        if (index == NOT_FOUND) return false;
104        int width = Integer.parseInt(candidate.substring(0, index));
105        int height = Integer.parseInt(candidate.substring(index + 1));
106        for (Size size: supported) {
107            if (size.width == width && size.height == height) {
108                parameters.setPictureSize(width, height);
109                return true;
110            }
111        }
112        return false;
113    }
114
115    private void initPreference(PreferenceScreen screen) {
116        ListPreference videoDuration =
117                (ListPreference) screen.findPreference(KEY_VIDEO_DURATION);
118        ListPreference pictureSize =
119                (ListPreference) screen.findPreference(KEY_PICTURE_SIZE);
120        ListPreference whiteBalance =
121                (ListPreference) screen.findPreference(KEY_WHITE_BALANCE);
122        ListPreference colorEffect =
123                (ListPreference) screen.findPreference(KEY_COLOR_EFFECT);
124        ListPreference sceneMode =
125                (ListPreference) screen.findPreference(KEY_SCENE_MODE);
126        ListPreference flashMode =
127                (ListPreference) screen.findPreference(KEY_FLASH_MODE);
128
129        // Since the screen could be loaded from different resources, we need
130        // to check if the preference is available here
131        if (videoDuration != null) {
132            // Modify video duration settings.
133            // The first entry is for MMS video duration, and we need to fill
134            // in the device-dependent value (in seconds).
135            CharSequence[] entries = videoDuration.getEntries();
136            entries[0] = String.format(
137                    entries[0].toString(), MMS_VIDEO_DURATION);
138        }
139
140        // Filter out unsupported settings / options
141        if (pictureSize != null) {
142            filterUnsupportedOptions(screen, pictureSize, sizeListToStringList(
143                    mParameters.getSupportedPictureSizes()));
144        }
145        if (whiteBalance != null) {
146            filterUnsupportedOptions(screen,
147                    whiteBalance, mParameters.getSupportedWhiteBalance());
148        }
149        if (colorEffect != null) {
150            filterUnsupportedOptions(screen,
151                    colorEffect, mParameters.getSupportedColorEffects());
152        }
153        if (sceneMode != null) {
154            filterUnsupportedOptions(screen,
155                    sceneMode, mParameters.getSupportedSceneModes());
156        }
157        if (flashMode != null) {
158            filterUnsupportedOptions(screen,
159                    flashMode, mParameters.getSupportedFlashModes());
160        }
161    }
162
163    private static boolean removePreference(PreferenceGroup group,
164            Preference remove) {
165        if (group.removePreference(remove)) return true;
166
167        for (int i = 0; i < group.getPreferenceCount(); i++) {
168            final Preference child = group.getPreference(i);
169            if (child instanceof PreferenceGroup) {
170                if (removePreference((PreferenceGroup) child, remove)) {
171                    return true;
172                }
173            }
174        }
175        return false;
176    }
177
178    private void filterUnsupportedOptions(PreferenceScreen screen,
179            ListPreference pref, List<String> supported) {
180
181        // Remove the preference if the parameter is not supported.
182        if (supported == null) {
183            removePreference(screen, pref);
184            return;
185        }
186
187        // Prepare setting entries and entry values.
188        CharSequence[] allEntries = pref.getEntries();
189        CharSequence[] allEntryValues = pref.getEntryValues();
190        ArrayList<CharSequence> entries = new ArrayList<CharSequence>();
191        ArrayList<CharSequence> entryValues = new ArrayList<CharSequence>();
192        for (int i = 0, len = allEntryValues.length; i < len; i++) {
193            if (supported.indexOf(allEntryValues[i].toString()) != NOT_FOUND) {
194                entries.add(allEntries[i]);
195                entryValues.add(allEntryValues[i]);
196            }
197        }
198
199        // Set entries and entry values to list preference.
200        pref.setEntries(entries.toArray(new CharSequence[entries.size()]));
201        pref.setEntryValues(entryValues.toArray(
202                new CharSequence[entryValues.size()]));
203
204        // Set the value to the first entry if it is invalid.
205        String value = pref.getValue();
206        if (pref.findIndexOfValue(value) == NOT_FOUND) {
207            pref.setValueIndex(0);
208        }
209    }
210
211    private static List<String> sizeListToStringList(List<Size> sizes) {
212        ArrayList<String> list = new ArrayList<String>();
213        for (Size size : sizes) {
214            list.add(String.format("%dx%d", size.width, size.height));
215        }
216        return list;
217    }
218
219    public static void upgradePreferences(SharedPreferences pref) {
220        int version;
221        try {
222            version = pref.getInt(KEY_VERSION, 0);
223        } catch (Exception ex) {
224            version = 0;
225        }
226        if (version == CURRENT_VERSION) return;
227
228        SharedPreferences.Editor editor = pref.edit();
229        if (version == 0) {
230            // For old version, change 1 to -1 for video duration preference.
231            if (pref.getString(KEY_VIDEO_DURATION, "1").equals("1")) {
232                editor.putString(KEY_VIDEO_DURATION, "-1");
233            }
234        }
235        editor.putInt(KEY_VERSION, CURRENT_VERSION);
236        editor.commit();
237    }
238}
239