OSDN Git Service

Ensure that SharedPreference listeners respond to known keys.
[android-x86/packages-apps-Camera2.git] / src / com / android / camera / settings / SettingsManager.java
1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.camera.settings;
18
19 import android.content.Context;
20 import android.content.SharedPreferences;
21 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
22 import android.hardware.Camera.Size;
23 import android.preference.PreferenceManager;
24 import android.util.Log;
25
26 import com.android.camera.ListPreference;
27 import com.android.camera.util.SettingsHelper;
28 import com.android.camera2.R;
29
30 import java.util.List;
31 import java.util.ArrayList;
32
33 /**
34  * SettingsManager class provides an api for getting and setting both
35  * global and local SharedPreferences.
36  */
37 public class SettingsManager {
38     private static final String TAG = "SettingsManager";
39
40     private final Context mContext;
41     private final SharedPreferences mDefaultSettings;
42     private final SettingsCache mSettingsCache;
43     private SharedPreferences mGlobalSettings;
44     private SharedPreferences mCameraSettings;
45     private SettingsCapabilities mCapabilities;
46
47     private int mCameraId = -1;
48
49     private final List<OnSharedPreferenceChangeListener>
50         mSharedPreferenceListeners =
51         new ArrayList<OnSharedPreferenceChangeListener>();
52
53     public SettingsManager(Context context, int nCameras) {
54         mContext = context;
55
56         SettingsCache.ExtraSettings extraSettings = new SettingsHelper();
57         mSettingsCache = new SettingsCache(mContext, extraSettings);
58
59         mDefaultSettings = PreferenceManager.getDefaultSharedPreferences(context);
60         initGlobal();
61
62         int cameraId = Integer.parseInt(get(SETTING_CAMERA_ID));
63         if (cameraId < 0 || cameraId >= nCameras) {
64             setDefault(SETTING_CAMERA_ID);
65         }
66     }
67
68     /**
69      * Initialize global SharedPreferences.
70      */
71     private void initGlobal() {
72         String globalKey = mContext.getPackageName() + "_preferences_camera";
73         mGlobalSettings = mContext.getSharedPreferences(globalKey, Context.MODE_PRIVATE);
74     }
75
76     /**
77      * Initialize SharedPreferences for other cameras.
78      */
79     public void changeCamera(int cameraId, SettingsCapabilities capabilities) {
80         mCapabilities = capabilities;
81         mSettingsCache.setCapabilities(mCapabilities);
82
83         if (cameraId == mCameraId) {
84             return;
85         }
86
87         // We've changed camera ids, that means we need to flush the
88         // settings cache of settings dependent on SettingsCapabilities.
89         mSettingsCache.flush();
90
91         // Cache the camera id so we don't need to reload preferences
92         // if we're using the same camera.
93         mCameraId = cameraId;
94
95         String cameraKey = mContext.getPackageName() + "_preferences_" + cameraId;
96         mCameraSettings = mContext.getSharedPreferences(
97             cameraKey, Context.MODE_PRIVATE);
98         for (OnSharedPreferenceChangeListener listener : mSharedPreferenceListeners) {
99             mCameraSettings.registerOnSharedPreferenceChangeListener(listener);
100         }
101     }
102
103     /**
104      * Interface with Camera Parameters and Modules.
105      */
106     public interface OnSettingChangedListener {
107         /**
108          * Called every time a SharedPreference has been changed.
109          */
110         public void onSettingChanged(SettingsManager settingsManager, int setting);
111     }
112
113     private OnSharedPreferenceChangeListener getSharedPreferenceListener(
114             final OnSettingChangedListener listener) {
115         return new OnSharedPreferenceChangeListener() {
116                 @Override
117                 public void onSharedPreferenceChanged(
118                         SharedPreferences sharedPreferences, String key) {
119                     Integer settingId = mSettingsCache.getId(key);
120                     if (settingId != null) {
121                         listener.onSettingChanged(SettingsManager.this, settingId);
122                     }
123                 }
124             };
125     }
126
127     /**
128      * Add an OnSettingChangedListener to the SettingsManager, which will execute
129      * onSettingsChanged when any SharedPreference has been updated.
130      */
131     public void addListener(final OnSettingChangedListener listener) {
132         if (listener == null) {
133             throw new IllegalArgumentException("OnSettingChangedListener cannot be null.");
134         }
135
136         OnSharedPreferenceChangeListener sharedPreferenceListener =
137             getSharedPreferenceListener(listener);
138
139         if (!mSharedPreferenceListeners.contains(sharedPreferenceListener)) {
140             mSharedPreferenceListeners.add(sharedPreferenceListener);
141
142             if (mGlobalSettings != null) {
143                 mGlobalSettings.registerOnSharedPreferenceChangeListener(sharedPreferenceListener);
144             }
145
146             if (mCameraSettings != null) {
147                 mCameraSettings.registerOnSharedPreferenceChangeListener(sharedPreferenceListener);
148             }
149
150             if (mDefaultSettings != null) {
151                 mDefaultSettings.registerOnSharedPreferenceChangeListener(sharedPreferenceListener);
152             }
153         }
154     }
155
156     /**
157      * Remove a specific SettingsListener.
158      * This should be done in onPause if a listener has been set.
159      */
160     public void removeListener(OnSettingChangedListener listener) {
161         if (listener == null) {
162             throw new IllegalArgumentException();
163         }
164
165         OnSharedPreferenceChangeListener sharedPreferenceListener =
166             getSharedPreferenceListener(listener);
167
168         if (mSharedPreferenceListeners.contains(sharedPreferenceListener)) {
169             mSharedPreferenceListeners.remove(sharedPreferenceListener);
170
171             if (mGlobalSettings != null) {
172                 mGlobalSettings.unregisterOnSharedPreferenceChangeListener(
173                     sharedPreferenceListener);
174             }
175
176             if (mCameraSettings != null) {
177                 mCameraSettings.unregisterOnSharedPreferenceChangeListener(
178                     sharedPreferenceListener);
179             }
180
181             if (mDefaultSettings != null) {
182                 mDefaultSettings.unregisterOnSharedPreferenceChangeListener(
183                     sharedPreferenceListener);
184             }
185         }
186     }
187
188     /**
189      * Remove all OnSharedPreferenceChangedListener's.
190      * This should be done in onDestroy.
191      */
192     public void removeAllListeners() {
193         for (OnSharedPreferenceChangeListener listener : mSharedPreferenceListeners) {
194             if (mGlobalSettings != null) {
195                 mGlobalSettings.unregisterOnSharedPreferenceChangeListener(listener);
196             }
197
198             if (mCameraSettings != null) {
199                 mCameraSettings.unregisterOnSharedPreferenceChangeListener(listener);
200             }
201
202             if (mDefaultSettings != null) {
203                 mDefaultSettings.unregisterOnSharedPreferenceChangeListener(listener);
204             }
205         }
206         mSharedPreferenceListeners.clear();
207     }
208
209     /**
210      * SettingsCapabilities defines constraints around settings that need to be
211      * queried from external sources, like the camera parameters.
212      *
213      * This interface is camera api agnostic.
214      */
215     public interface SettingsCapabilities {
216         /**
217          * Returns a list of the picture sizes currently
218          * supported by the camera device.
219          */
220         public List<Size> getSupportedPictureSizes();
221
222         /**
223          * Returns a dynamically calculated list of
224          * exposure values, based on the min and max
225          * exposure compensation supported by the camera device.
226          */
227         public String[] getSupportedExposureValues();
228
229         /**
230          * Returns a list of camera ids based on the number
231          * of cameras available on the device.
232          */
233         public String[] getSupportedCameraIds();
234     }
235
236     /**
237      * Exposes SettingsCapabilities functionality.
238      */
239     public List<Size> getSupportedPictureSizes() {
240         if (mCapabilities != null) {
241             return mCapabilities.getSupportedPictureSizes();
242         } else {
243             return null;
244         }
245     }
246
247     /**
248      * Get the camera id for which the SettingsManager has loaded camera
249      * specific preferences.
250      */
251     public int getRegisteredCameraId() {
252         return mCameraId;
253     }
254
255     // Manage individual settings.
256     public static final String VALUE_NONE = "none";
257     public static final String VALUE_ON = "on";
258     public static final String VALUE_OFF = "off";
259
260     public static final String TYPE_STRING = "string";
261     public static final String TYPE_BOOLEAN = "boolean";
262     public static final String TYPE_INTEGER = "integer";
263
264     public static final String SOURCE_DEFAULT = "default";
265     public static final String SOURCE_GLOBAL = "global";
266     public static final String SOURCE_CAMERA = "camera";
267
268     public static final boolean FLUSH_ON = true;
269     public static final boolean FLUSH_OFF = false;
270
271     // For quick lookup from id to Setting.
272     public static final int SETTING_RECORD_LOCATION = 0;
273     public static final int SETTING_VIDEO_QUALITY = 1;
274     public static final int SETTING_VIDEO_TIME_LAPSE_FRAME_INTERVAL = 2;
275     public static final int SETTING_PICTURE_SIZE = 3;
276     public static final int SETTING_JPEG_QUALITY = 4;
277     public static final int SETTING_FOCUS_MODE = 5;
278     public static final int SETTING_FLASH_MODE = 6;
279     public static final int SETTING_VIDEOCAMERA_FLASH_MODE = 7;
280     public static final int SETTING_WHITE_BALANCE = 8;
281     public static final int SETTING_SCENE_MODE = 9;
282     public static final int SETTING_EXPOSURE = 10;
283     public static final int SETTING_TIMER = 11;
284     public static final int SETTING_TIMER_SOUND_EFFECTS = 12;
285     public static final int SETTING_VIDEO_EFFECT = 13;
286     public static final int SETTING_CAMERA_ID = 14;
287     public static final int SETTING_CAMERA_HDR = 15;
288     public static final int SETTING_CAMERA_HDR_PLUS = 16;
289     public static final int SETTING_CAMERA_FIRST_USE_HINT_SHOWN = 17;
290     public static final int SETTING_VIDEO_FIRST_USE_HINT_SHOWN = 18;
291     public static final int SETTING_STARTUP_MODULE_INDEX = 19;
292     public static final int SETTING_CAMERA_REFOCUS = 20;
293     public static final int SETTING_SHIMMY_REMAINING_PLAY_TIMES_INDEX = 21;
294
295     // Shared preference keys.
296     public static final String KEY_RECORD_LOCATION = "pref_camera_recordlocation_key";
297     public static final String KEY_VIDEO_QUALITY = "pref_video_quality_key";
298     public static final String KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL =
299         "pref_video_time_lapse_frame_interval_key";
300     public static final String KEY_PICTURE_SIZE = "pref_camera_picturesize_key";
301     public static final String KEY_JPEG_QUALITY = "pref_camera_jpegquality_key";
302     public static final String KEY_FOCUS_MODE = "pref_camera_focusmode_key";
303     public static final String KEY_FLASH_MODE = "pref_camera_flashmode_key";
304     public static final String KEY_VIDEOCAMERA_FLASH_MODE = "pref_camera_video_flashmode_key";
305     public static final String KEY_WHITE_BALANCE = "pref_camera_whitebalance_key";
306     public static final String KEY_SCENE_MODE = "pref_camera_scenemode_key";
307     public static final String KEY_EXPOSURE = "pref_camera_exposure_key";
308     public static final String KEY_TIMER = "pref_camera_timer_key";
309     public static final String KEY_TIMER_SOUND_EFFECTS = "pref_camera_timer_sound_key";
310     public static final String KEY_VIDEO_EFFECT = "pref_video_effect_key";
311     public static final String KEY_CAMERA_ID = "pref_camera_id_key";
312     public static final String KEY_CAMERA_HDR = "pref_camera_hdr_key";
313     public static final String KEY_CAMERA_HDR_PLUS = "pref_camera_hdr_plus_key";
314     public static final String KEY_CAMERA_FIRST_USE_HINT_SHOWN =
315         "pref_camera_first_use_hint_shown_key";
316     public static final String KEY_VIDEO_FIRST_USE_HINT_SHOWN =
317         "pref_video_first_use_hint_shown_key";
318     public static final String KEY_STARTUP_MODULE_INDEX = "camera.startup_module";
319     public static final String KEY_CAMERA_REFOCUS = "pref_camera_refocus";
320     public static final String KEY_SHIMMY_REMAINING_PLAY_TIMES =
321             "pref_shimmy_remaining_play_times";
322
323     public static final int WHITE_BALANCE_DEFAULT_INDEX = 2;
324
325
326     /**
327      * Defines a simple class for holding a the spec of a setting.
328      * This spec is used by the generic api methods to query and
329      * update a setting.
330      */
331     public static class Setting {
332         private final String mSource;
333         private final String mType;
334         private final String mDefault;
335         private final String mKey;
336         private final String[] mValues;
337         private final boolean mFlushOnCameraChange;
338
339         /**
340          * A constructor used to store a setting's profile.
341          */
342         Setting(String source, String type, String defaultValue, String key,
343                 String[] values, boolean flushOnCameraChange) {
344             mSource = source;
345             mType = type;
346             mDefault = defaultValue;
347             mKey = key;
348             mValues = values;
349             mFlushOnCameraChange = flushOnCameraChange;
350         }
351
352         /**
353          * Returns the id of a SharedPreferences instance from which
354          * this Setting may be found.
355          * Possible values are {@link #SOURCE_DEFAULT}, {@link #SOURCE_GLOBAL},
356          * {@link #SOURCE_CAMERA}.
357          */
358         public String getSource() {
359             return mSource;
360         }
361
362         /**
363          * Returns the type of the setting stored in SharedPreferences.
364          * Possible values are {@link #TYPE_STRING}, {@link #TYPE_INTEGER},
365          * {@link #TYPE_BOOLEAN}.
366          */
367         public String getType() {
368             return mType;
369         }
370
371         /**
372          * Returns the default value of this setting.
373          */
374         public String getDefault() {
375             return mDefault;
376         }
377
378         /**
379          * Returns the SharedPreferences key for this setting.
380          */
381         public String getKey() {
382             return mKey;
383         }
384
385         /**
386          * Returns an array of possible String values for this setting.
387          * If this setting is not of type {@link #TYPE_STRING}, or
388          * it's not possible to generate the string values, this should
389          * return null;
390          */
391         public String[] getStringValues() {
392             return mValues;
393         }
394
395         /**
396          * Returns whether the setting should be flushed from the cache
397          * when the camera device has changed.
398          */
399         public boolean isFlushedOnCameraChanged() {
400             return mFlushOnCameraChange;
401         }
402     }
403
404     /**
405      * Get the SharedPreferences needed to query/update the setting.
406      */
407     public SharedPreferences getSettingSource(Setting setting) {
408         String source = setting.getSource();
409         if (source.equals(SOURCE_DEFAULT)) {
410             return mDefaultSettings;
411         }
412         if (source.equals(SOURCE_GLOBAL)) {
413             return mGlobalSettings;
414         }
415         if (source.equals(SOURCE_CAMERA)) {
416             return mCameraSettings;
417         }
418         return null;
419     }
420
421     /**
422      * Based on Setting id, finds the index of a Setting's
423      * String value in an array of possible String values.
424      *
425      * If the Setting is not of type String, this returns -1.
426      *
427      * <p>TODO: make this a supported api call for all types.</p>
428      */
429     public int getStringValueIndex(int id) {
430         Setting setting = mSettingsCache.get(id);
431         if (setting == null || !TYPE_STRING.equals(setting.getType())) {
432             return -1;
433         }
434
435         String value = get(id);
436         if (value != null) {
437             String[] possibleValues = setting.getStringValues();
438             if (possibleValues != null) {
439                 for (int i = 0; i < possibleValues.length; i++) {
440                     if (value.equals(possibleValues[i])) {
441                         return i;
442                     }
443                 }
444             }
445         }
446         return -1;
447     }
448
449     /**
450      * Based on Setting id, sets a Setting's String value using the
451      * index into an array of possible String values.
452      *
453      * Fails to set a value if the index is out of bounds or the Setting
454      * is not of type String.
455      *
456      * @return Whether the value was set.
457      */
458     public boolean setStringValueIndex(int id, int index) {
459         Setting setting = mSettingsCache.get(id);
460         if (setting == null || setting.getType() != TYPE_STRING) {
461             return false;
462         }
463
464         String[] possibleValues = setting.getStringValues();
465         if (possibleValues != null) {
466             if (index >= 0 && index < possibleValues.length) {
467                 set(id, possibleValues[index]);
468                 return true;
469             }
470         }
471         return false;
472     }
473
474     /**
475      * Get a Setting's String value based on Setting id.
476      */
477     // TODO: rename to something more descriptive.
478     public String get(int id) {
479         Setting setting = mSettingsCache.get(id);
480         SharedPreferences preferences = getSettingSource(setting);
481         if (preferences != null) {
482             return preferences.getString(setting.getKey(), setting.getDefault());
483         } else {
484             return null;
485         }
486     }
487
488     /**
489      * Get a Setting's boolean value based on Setting id.
490      */
491     public boolean getBoolean(int id) {
492         Setting setting = mSettingsCache.get(id);
493         SharedPreferences preferences = getSettingSource(setting);
494         boolean defaultValue = setting.getDefault().equals(VALUE_ON);
495         if (preferences != null) {
496             return preferences.getBoolean(setting.getKey(), defaultValue);
497         } else {
498             return defaultValue;
499         }
500     }
501
502     /**
503      * Get a Setting's int value based on Setting id.
504      */
505     public int getInt(int id) {
506         Setting setting = mSettingsCache.get(id);
507         SharedPreferences preferences = getSettingSource(setting);
508         int defaultValue = Integer.parseInt(setting.getDefault());
509         if (preferences != null) {
510             return preferences.getInt(setting.getKey(), defaultValue);
511         } else {
512             return defaultValue;
513         }
514     }
515
516     /**
517      * Set a Setting with a String value based on Setting id.
518      */
519     // TODO: rename to something more descriptive.
520     public void set(int id, String value) {
521         Setting setting = mSettingsCache.get(id);
522         SharedPreferences preferences = getSettingSource(setting);
523         if (preferences != null) {
524             preferences.edit().putString(setting.getKey(), value).apply();
525         }
526     }
527
528     /**
529      * Set a Setting with a boolean value based on Setting id.
530      */
531     public void setBoolean(int id, boolean value) {
532         Setting setting = mSettingsCache.get(id);
533         SharedPreferences preferences = getSettingSource(setting);
534         if (preferences != null) {
535             preferences.edit().putBoolean(setting.getKey(), value).apply();
536         }
537     }
538
539     /**
540      * Set a Setting with an int value based on Setting id.
541      */
542     public void setInt(int id, int value) {
543         Setting setting = mSettingsCache.get(id);
544         SharedPreferences preferences = getSettingSource(setting);
545         if (preferences != null) {
546             preferences.edit().putInt(setting.getKey(), value).apply();
547         }
548     }
549
550     /**
551      * Check if a Setting has ever been set based on Setting id.
552      */
553     public boolean isSet(int id) {
554         Setting setting = mSettingsCache.get(id);
555         SharedPreferences preferences = getSettingSource(setting);
556         if (preferences != null) {
557             return (preferences.getString(setting.getKey(), null) != null);
558         } else {
559             return false;
560         }
561     }
562
563     /**
564      * Set a Setting to its default value based on Setting id.
565      */
566     public void setDefault(int id) {
567         Setting setting = mSettingsCache.get(id);
568         SharedPreferences preferences = getSettingSource(setting);
569         if (preferences != null) {
570             preferences.edit().putString(setting.getKey(), setting.getDefault());
571         }
572     }
573
574     /**
575      * Check if a Setting is set to its default value.
576      */
577     public boolean isDefault(int id) {
578         Setting setting = mSettingsCache.get(id);
579         SharedPreferences preferences = getSettingSource(setting);
580         if (preferences != null) {
581             String type = setting.getType();
582             if (TYPE_STRING.equals(type)) {
583                 String value = get(id);
584                 return (value.equals(setting.getDefault()));
585             } else if (TYPE_BOOLEAN.equals(type)) {
586                 boolean value = getBoolean(id);
587                 boolean defaultValue = VALUE_ON.equals(setting.getDefault());
588                 return (value == defaultValue);
589             } else if (TYPE_INTEGER.equals(type)) {
590                 int value = getInt(id);
591                 int defaultValue = Integer.parseInt(setting.getDefault());
592                 return (value == defaultValue);
593             } else {
594                 throw new IllegalArgumentException("Type " + type + " is not known.");
595             }
596         } else {
597             return false;
598         }
599     }
600
601     public static Setting getLocationSetting(Context context) {
602         String defaultValue = context.getString(R.string.setting_none_value);
603         String[] values = context.getResources().getStringArray(
604             R.array.pref_camera_recordlocation_entryvalues);
605         return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_RECORD_LOCATION,
606             values, FLUSH_OFF);
607     }
608
609     public static Setting getPictureSizeSetting(Context context) {
610         String defaultValue = null;
611         String[] values = context.getResources().getStringArray(
612             R.array.pref_camera_picturesize_entryvalues);
613         return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_PICTURE_SIZE,
614             values, FLUSH_OFF);
615     }
616
617     public static Setting getDefaultCameraIdSetting(Context context,
618             SettingsCapabilities capabilities) {
619         String defaultValue = context.getString(R.string.pref_camera_id_default);
620         String[] values = null;
621         if (capabilities != null) {
622             values = capabilities.getSupportedCameraIds();
623         }
624         return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_CAMERA_ID,
625             values, FLUSH_ON);
626     }
627
628     public static Setting getWhiteBalanceSetting(Context context) {
629         String defaultValue = context.getString(R.string.pref_camera_whitebalance_default);
630         String[] values = context.getResources().getStringArray(
631             R.array.pref_camera_whitebalance_entryvalues);
632         return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue, KEY_WHITE_BALANCE,
633             values, FLUSH_OFF);
634     }
635
636     public static Setting getHdrSetting(Context context) {
637         String defaultValue = context.getString(R.string.pref_camera_hdr_default);
638         String[] values = context.getResources().getStringArray(
639             R.array.pref_camera_hdr_entryvalues);
640         return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_CAMERA_HDR,
641             values, FLUSH_OFF);
642     }
643
644     public static Setting getHdrPlusSetting(Context context) {
645         String defaultValue = context.getString(R.string.pref_camera_hdr_plus_default);
646         String[] values = context.getResources().getStringArray(
647             R.array.pref_camera_hdr_plus_entryvalues);
648         return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_CAMERA_HDR_PLUS,
649             values, FLUSH_OFF);
650     }
651
652     public static Setting getSceneModeSetting(Context context) {
653         String defaultValue = context.getString(R.string.pref_camera_scenemode_default);
654         String[] values = context.getResources().getStringArray(
655             R.array.pref_camera_scenemode_entryvalues);
656         return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue, KEY_SCENE_MODE,
657             values, FLUSH_OFF);
658     }
659
660     public static Setting getFlashSetting(Context context) {
661         String defaultValue = context.getString(R.string.pref_camera_flashmode_default);
662         String[] values = context.getResources().getStringArray(
663             R.array.pref_camera_flashmode_entryvalues);
664         return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue, KEY_FLASH_MODE,
665             values, FLUSH_OFF);
666     }
667
668     public static Setting getExposureSetting(Context context,
669             SettingsCapabilities capabilities) {
670         String defaultValue = context.getString(R.string.pref_exposure_default);
671         String[] values = null;
672         if (capabilities != null) {
673             values = capabilities.getSupportedExposureValues();
674         }
675         return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue, KEY_EXPOSURE,
676             values, FLUSH_ON);
677     }
678
679     public static Setting getHintSetting(Context context) {
680         String defaultValue = context.getString(R.string.setting_on_value);
681         String[] values = null;
682         return new Setting(SOURCE_GLOBAL, TYPE_BOOLEAN, defaultValue,
683             KEY_CAMERA_FIRST_USE_HINT_SHOWN, values, FLUSH_OFF);
684     }
685
686     public static Setting getFocusModeSetting(Context context) {
687         String defaultValue = null;
688         String[] values = context.getResources().getStringArray(
689             R.array.pref_camera_focusmode_entryvalues);
690         return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue, KEY_FOCUS_MODE,
691             values, FLUSH_OFF);
692     }
693
694     public static Setting getTimerSetting(Context context) {
695         String defaultValue = context.getString(R.string.pref_camera_timer_default);
696         String[] values = null; // TODO: get the values dynamically.
697         return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_TIMER,
698             values, FLUSH_OFF);
699     }
700
701     public static Setting getTimerSoundSetting(Context context) {
702         String defaultValue = context.getString(R.string.pref_camera_timer_sound_default);
703         String[] values = context.getResources().getStringArray(
704             R.array.pref_camera_timer_sound_entryvalues);
705         return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_TIMER_SOUND_EFFECTS,
706             values, FLUSH_OFF);
707     }
708
709     public static Setting getVideoQualitySetting(Context context) {
710         String defaultValue = context.getString(R.string.pref_video_quality_default);
711         String[] values = context.getResources().getStringArray(
712             R.array.pref_video_quality_entryvalues);
713         return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_VIDEO_QUALITY,
714             values, FLUSH_OFF);
715     }
716
717     public static Setting getTimeLapseFrameIntervalSetting(Context context) {
718         String defaultValue = context.getString(
719             R.string.pref_video_time_lapse_frame_interval_default);
720         String[] values = context.getResources().getStringArray(
721             R.array.pref_video_time_lapse_frame_interval_entryvalues);
722         return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue,
723             KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL, values, FLUSH_OFF);
724     }
725
726     public static Setting getJpegQualitySetting(Context context) {
727         String defaultValue = context.getString(
728             R.string.pref_camera_jpeg_quality_normal);
729         String[] values = context.getResources().getStringArray(
730             R.array.pref_camera_jpeg_quality_entryvalues);
731         return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue, KEY_JPEG_QUALITY,
732             values, FLUSH_OFF);
733     }
734
735     public static Setting getVideoFlashSetting(Context context) {
736         String defaultValue = context.getString(R.string.pref_camera_video_flashmode_default);
737         String[] values = context.getResources().getStringArray(
738             R.array.pref_camera_video_flashmode_entryvalues);
739         return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue,
740             KEY_VIDEOCAMERA_FLASH_MODE, values, FLUSH_OFF);
741     }
742
743     public static Setting getVideoEffectSetting(Context context) {
744         String defaultValue = context.getString(R.string.pref_video_effect_default);
745         String[] values = context.getResources().getStringArray(
746             R.array.pref_video_effect_entryvalues);
747         return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_VIDEO_EFFECT,
748             values, FLUSH_OFF);
749     }
750
751     public static Setting getHintVideoSetting(Context context) {
752         String defaultValue = context.getString(R.string.setting_on_value);
753         String[] values = null;
754         return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue,
755             KEY_VIDEO_FIRST_USE_HINT_SHOWN, values, FLUSH_OFF);
756     }
757
758     public static Setting getStartupModuleSetting(Context context) {
759         String defaultValue = context.getString(R.string.pref_camera_startup_index_default);
760         String[] values = null;
761         return new Setting(SOURCE_DEFAULT, TYPE_INTEGER, defaultValue,
762             KEY_STARTUP_MODULE_INDEX, values, FLUSH_OFF);
763     }
764
765     public static Setting getShimmyRemainingTimesSetting(Context context) {
766         String defaultValue = context.getString(R.string.pref_shimmy_play_times);
767         return new Setting(SOURCE_DEFAULT, TYPE_INTEGER, defaultValue,
768                 KEY_SHIMMY_REMAINING_PLAY_TIMES, null, FLUSH_OFF);
769     }
770
771     public static Setting getRefocusSetting(Context context) {
772         String defaultValue = context.getString(R.string.setting_off_value);
773         String[] values = context.getResources().getStringArray(
774             R.array.pref_camera_refocus_entryvalues);
775         return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue,
776             KEY_CAMERA_REFOCUS, values, FLUSH_OFF);
777     }
778
779     // Utilities.
780
781     /**
782      * Returns whether the camera has been set to back facing
783      * in settings.
784      */
785     public boolean isCameraBackFacing() {
786         int cameraFacingIndex = getStringValueIndex(SETTING_CAMERA_ID);
787         String backFacingIndex = mContext.getString(R.string.pref_camera_id_index_back);
788         return (cameraFacingIndex == Integer.parseInt(backFacingIndex));
789     }
790
791     /**
792      * Returns whether refocus mode is set on.
793      */
794     public boolean isRefocusOn() {
795         String refocusOn = get(SettingsManager.SETTING_CAMERA_REFOCUS);
796         return refocusOn.equals(SettingsManager.VALUE_ON);
797     }
798
799     /**
800      * Returns whether hdr plus mode is set on.
801      */
802     public boolean isHdrPlusOn() {
803         String hdrOn = get(SettingsManager.SETTING_CAMERA_HDR);
804         return hdrOn.equals(SettingsManager.VALUE_ON);
805     }
806
807     //TODO: refactor this into a separate utils module.
808
809     /**
810      * Get a String value from first the ListPreference, and if not found
811      * from the SettingsManager.
812      *
813      * This is a wrapper that adds backwards compatibility to views that
814      * rely on PreferenceGroups.
815      */
816     public String getValueFromPreference(ListPreference pref) {
817         String value = pref.getValue();
818         if (value == null) {
819             Integer id = mSettingsCache.getId(pref.getKey());
820             if (id == null) {
821                 return null;
822             }
823             value = get(id);
824         }
825         return value;
826     }
827
828     /**
829      * Set a String value first from the ListPreference, and if unable
830      * from the SettingsManager.
831      *
832      * This is a wrapper that adds backwards compatibility to views that
833      * rely on PreferenceGroups.
834      */
835     public void setValueFromPreference(ListPreference pref, String value) {
836         boolean set = pref.setValue(value);
837         if (!set) {
838             Integer id = mSettingsCache.getId(pref.getKey());
839             if (id != null) {
840                 set(id, value);
841             }
842         }
843     }
844
845     /**
846      * Set a String value first from the ListPreference based on a
847      * ListPreference index, and if unable use the ListPreference key
848      * to set the value using the SettingsManager.
849      *
850      * This is a wrapper that adds backwards compatibility to views that
851      * rely on PreferenceGroups.
852      */
853     public void setValueIndexFromPreference(ListPreference pref, int index) {
854         boolean set = pref.setValueIndex(index);
855         if (!set) {
856             Integer id = mSettingsCache.getId(pref.getKey());
857             if (id != null) {
858                 String value = pref.getValueAtIndex(index);
859                 set(id, value);
860             }
861         }
862     }
863 }