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