2 * Copyright (C) 2013 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.camera.settings;
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;
25 import com.android.camera.ListPreference;
26 import com.android.camera.util.SettingsHelper;
27 import com.android.camera2.R;
29 import java.util.List;
32 * SettingsManager class provides an api for getting and setting both
33 * global and local SharedPreferences.
35 public class SettingsManager {
36 private static final String TAG = "SettingsManager";
38 private final Context mContext;
39 private final SharedPreferences mDefaultSettings;
40 private final SettingsCache mSettingsCache;
41 private SharedPreferences mGlobalSettings;
42 private SharedPreferences mCameraSettings;
43 private OnSharedPreferenceChangeListener mListener;
44 private SettingsCapabilities mCapabilities;
46 private int mCameraId = -1;
48 public SettingsManager(Context context,
49 OnSharedPreferenceChangeListener globalListener,
53 SettingsCache.ExtraSettings extraSettings = new SettingsHelper();
54 mSettingsCache = new SettingsCache(mContext, extraSettings);
56 mDefaultSettings = PreferenceManager.getDefaultSharedPreferences(context);
57 initGlobal(globalListener);
59 int cameraId = Integer.parseInt(get(SETTING_CAMERA_ID));
60 if (cameraId < 0 || cameraId >= nCameras) {
61 setDefault(SETTING_CAMERA_ID);
66 * Initialize global SharedPreferences.
68 private void initGlobal(OnSharedPreferenceChangeListener listener) {
69 String globalKey = mContext.getPackageName() + "_preferences_camera";
70 mGlobalSettings = mContext.getSharedPreferences(
71 globalKey, Context.MODE_PRIVATE);
72 mGlobalSettings.registerOnSharedPreferenceChangeListener(listener);
76 * Initialize SharedPreferences for other cameras.
78 public void changeCamera(int cameraId, SettingsCapabilities capabilities) {
79 mCapabilities = capabilities;
80 mSettingsCache.setCapabilities(mCapabilities);
82 if (cameraId == mCameraId) {
83 if (mCameraSettings != null) {
84 mCameraSettings.registerOnSharedPreferenceChangeListener(mListener);
89 // We've changed camera ids, that means we need to flush the
90 // settings cache of settings dependent on SettingsCapabilities.
91 mSettingsCache.flush();
93 // Cache the camera id so we don't need to reload preferences
94 // if we're using the same camera.
97 String cameraKey = mContext.getPackageName() + "_preferences_" + cameraId;
98 mCameraSettings = mContext.getSharedPreferences(
99 cameraKey, Context.MODE_PRIVATE);
100 mCameraSettings.registerOnSharedPreferenceChangeListener(mListener);
104 * Interface with Camera Parameters and Modules.
106 public interface SettingsListener {
107 public void onSettingsChanged();
111 * Add a SettingsListener to the SettingsManager, which will execute
112 * onSettingsChanged when camera specific SharedPreferences has been updated.
114 public void addListener(final SettingsListener listener) {
116 new OnSharedPreferenceChangeListener() {
118 public void onSharedPreferenceChanged(
119 SharedPreferences sharedPreferences, String key) {
120 listener.onSettingsChanged();
126 * Remove a SettingsListener.
128 * This should be done in onPause if a listener has been set.
130 public void removeListener() {
131 if (mCameraSettings != null && mListener != null) {
132 mCameraSettings.unregisterOnSharedPreferenceChangeListener(mListener);
138 * SettingsCapabilities defines constraints around settings that need to be
139 * queried from external sources, like the camera parameters.
141 * This interface is camera api agnostic.
143 public interface SettingsCapabilities {
145 * Returns a list of the picture sizes currently
146 * supported by the camera device.
148 public List<Size> getSupportedPictureSizes();
151 * Returns a dynamically calculated list of
152 * exposure values, based on the min and max
153 * exposure compensation supported by the camera device.
155 public String[] getSupportedExposureValues();
158 * Returns a list of camera ids based on the number
159 * of cameras available on the device.
161 public String[] getSupportedCameraIds();
165 * Exposes SettingsCapabilities functionality.
167 public List<Size> getSupportedPictureSizes() {
168 if (mCapabilities != null) {
169 return mCapabilities.getSupportedPictureSizes();
176 * Get the camera id for which the SettingsManager has loaded camera
177 * specific preferences.
179 public int getRegisteredCameraId() {
183 // Manage individual settings.
184 public static final String VALUE_NONE = "none";
185 public static final String VALUE_ON = "on";
186 public static final String VALUE_OFF = "off";
188 public static final String TYPE_STRING = "string";
189 public static final String TYPE_BOOLEAN = "boolean";
190 public static final String TYPE_INTEGER = "integer";
192 public static final String SOURCE_DEFAULT = "default";
193 public static final String SOURCE_GLOBAL = "global";
194 public static final String SOURCE_CAMERA = "camera";
196 public static final boolean FLUSH_ON = true;
197 public static final boolean FLUSH_OFF = false;
199 // For quick lookup from id to Setting.
200 public static final int SETTING_RECORD_LOCATION = 0;
201 public static final int SETTING_VIDEO_QUALITY = 1;
202 public static final int SETTING_VIDEO_TIME_LAPSE_FRAME_INTERVAL = 2;
203 public static final int SETTING_PICTURE_SIZE = 3;
204 public static final int SETTING_JPEG_QUALITY = 4;
205 public static final int SETTING_FOCUS_MODE = 5;
206 public static final int SETTING_FLASH_MODE = 6;
207 public static final int SETTING_VIDEOCAMERA_FLASH_MODE = 7;
208 public static final int SETTING_WHITE_BALANCE = 8;
209 public static final int SETTING_SCENE_MODE = 9;
210 public static final int SETTING_EXPOSURE = 10;
211 public static final int SETTING_TIMER = 11;
212 public static final int SETTING_TIMER_SOUND_EFFECTS = 12;
213 public static final int SETTING_VIDEO_EFFECT = 13;
214 public static final int SETTING_CAMERA_ID = 14;
215 public static final int SETTING_CAMERA_HDR = 15;
216 public static final int SETTING_CAMERA_HDR_PLUS = 16;
217 public static final int SETTING_CAMERA_FIRST_USE_HINT_SHOWN = 17;
218 public static final int SETTING_VIDEO_FIRST_USE_HINT_SHOWN = 18;
219 public static final int SETTING_STARTUP_MODULE_INDEX = 19;
221 // Shared preference keys.
222 public static final String KEY_RECORD_LOCATION = "pref_camera_recordlocation_key";
223 public static final String KEY_VIDEO_QUALITY = "pref_video_quality_key";
224 public static final String KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL =
225 "pref_video_time_lapse_frame_interval_key";
226 public static final String KEY_PICTURE_SIZE = "pref_camera_picturesize_key";
227 public static final String KEY_JPEG_QUALITY = "pref_camera_jpegquality_key";
228 public static final String KEY_FOCUS_MODE = "pref_camera_focusmode_key";
229 public static final String KEY_FLASH_MODE = "pref_camera_flashmode_key";
230 public static final String KEY_VIDEOCAMERA_FLASH_MODE = "pref_camera_video_flashmode_key";
231 public static final String KEY_WHITE_BALANCE = "pref_camera_whitebalance_key";
232 public static final String KEY_SCENE_MODE = "pref_camera_scenemode_key";
233 public static final String KEY_EXPOSURE = "pref_camera_exposure_key";
234 public static final String KEY_TIMER = "pref_camera_timer_key";
235 public static final String KEY_TIMER_SOUND_EFFECTS = "pref_camera_timer_sound_key";
236 public static final String KEY_VIDEO_EFFECT = "pref_video_effect_key";
237 public static final String KEY_CAMERA_ID = "pref_camera_id_key";
238 public static final String KEY_CAMERA_HDR = "pref_camera_hdr_key";
239 public static final String KEY_CAMERA_HDR_PLUS = "pref_camera_hdr_plus_key";
240 public static final String KEY_CAMERA_FIRST_USE_HINT_SHOWN =
241 "pref_camera_first_use_hint_shown_key";
242 public static final String KEY_VIDEO_FIRST_USE_HINT_SHOWN =
243 "pref_video_first_use_hint_shown_key";
244 public static final String KEY_STARTUP_MODULE_INDEX = "camera.startup_module";
246 public static final int WHITE_BALANCE_DEFAULT_INDEX = 2;
250 * Defines a simple class for holding a the spec of a setting.
251 * This spec is used by the generic api methods to query and
254 public static class Setting {
255 private final String mSource;
256 private final String mType;
257 private final String mDefault;
258 private final String mKey;
259 private final String[] mValues;
260 private final boolean mFlushOnCameraChange;
263 * A constructor used to store a setting's profile.
265 Setting(String source, String type, String defaultValue, String key,
266 String[] values, boolean flushOnCameraChange) {
269 mDefault = defaultValue;
272 mFlushOnCameraChange = flushOnCameraChange;
276 * Returns the id of a SharedPreferences instance from which
277 * this Setting may be found.
278 * Possible values are {@link #SOURCE_DEFAULT}, {@link #SOURCE_GLOBAL},
279 * {@link #SOURCE_CAMERA}.
281 public String getSource() {
286 * Returns the type of the setting stored in SharedPreferences.
287 * Possible values are {@link #TYPE_STRING}, {@link #TYPE_INTEGER},
288 * {@link #TYPE_BOOLEAN}.
290 public String getType() {
295 * Returns the default value of this setting.
297 public String getDefault() {
302 * Returns the SharedPreferences key for this setting.
304 public String getKey() {
309 * Returns an array of possible String values for this setting.
310 * If this setting is not of type {@link #TYPE_STRING}, or
311 * it's not possible to generate the string values, this should
314 public String[] getStringValues() {
319 * Returns whether the setting should be flushed from the cache
320 * when the camera device has changed.
322 public boolean isFlushedOnCameraChanged() {
323 return mFlushOnCameraChange;
328 * Get the SharedPreferences needed to query/update the setting.
330 public SharedPreferences getSettingSource(Setting setting) {
331 String source = setting.getSource();
332 if (source.equals(SOURCE_DEFAULT)) {
333 return mDefaultSettings;
335 if (source.equals(SOURCE_GLOBAL)) {
336 return mGlobalSettings;
338 if (source.equals(SOURCE_CAMERA)) {
339 return mCameraSettings;
345 * Based on Setting id, finds the index of a Setting's
346 * String value in an array of possible String values.
348 * If the Setting is not of type String, this returns -1.
350 public int getStringValueIndex(int id) {
351 Setting setting = mSettingsCache.get(id);
352 if (setting == null || setting.getType() != TYPE_STRING) {
356 String value = get(id);
358 String[] possibleValues = setting.getStringValues();
359 if (possibleValues != null) {
360 for (int i = 0; i < possibleValues.length; i++) {
361 if (value.equals(possibleValues[i])) {
371 * Based on Setting id, sets a Setting's String value using the
372 * index into an array of possible String values.
374 * Fails to set a value if the index is out of bounds or the Setting
375 * is not of type String.
377 * @return Whether the value was set.
379 public boolean setStringValueIndex(int id, int index) {
380 Setting setting = mSettingsCache.get(id);
381 if (setting == null || setting.getType() != TYPE_STRING) {
385 String[] possibleValues = setting.getStringValues();
386 if (possibleValues != null) {
387 if (index >= 0 && index < possibleValues.length) {
388 set(id, possibleValues[index]);
396 * Get a Setting's String value based on Setting id.
398 // TODO: rename to something more descriptive.
399 public String get(int id) {
400 Setting setting = mSettingsCache.get(id);
401 SharedPreferences preferences = getSettingSource(setting);
402 if (preferences != null) {
403 return preferences.getString(setting.getKey(), setting.getDefault());
410 * Get a Setting's boolean value based on Setting id.
412 public boolean getBoolean(int id) {
413 Setting setting = mSettingsCache.get(id);
414 SharedPreferences preferences = getSettingSource(setting);
415 boolean defaultValue = setting.getDefault().equals(VALUE_ON);
416 if (preferences != null) {
417 return preferences.getBoolean(setting.getKey(), defaultValue);
424 * Get a Setting's int value based on Setting id.
426 public int getInt(int id) {
427 Setting setting = mSettingsCache.get(id);
428 SharedPreferences preferences = getSettingSource(setting);
429 int defaultValue = Integer.parseInt(setting.getDefault());
430 if (preferences != null) {
431 return preferences.getInt(setting.getKey(), defaultValue);
438 * Set a Setting with a String value based on Setting id.
440 // TODO: rename to something more descriptive.
441 public void set(int id, String value) {
442 Setting setting = mSettingsCache.get(id);
443 SharedPreferences preferences = getSettingSource(setting);
444 if (preferences != null) {
445 preferences.edit().putString(setting.getKey(), value).apply();
450 * Set a Setting with a boolean value based on Setting id.
452 public void setBoolean(int id, boolean value) {
453 Setting setting = mSettingsCache.get(id);
454 SharedPreferences preferences = getSettingSource(setting);
455 if (preferences != null) {
456 preferences.edit().putBoolean(setting.getKey(), value).apply();
461 * Set a Setting with an int value based on Setting id.
463 public void setInt(int id, int value) {
464 Setting setting = mSettingsCache.get(id);
465 SharedPreferences preferences = getSettingSource(setting);
466 if (preferences != null) {
467 preferences.edit().putInt(setting.getKey(), value).apply();
472 * Check if a Setting has ever been set based on Setting id.
474 public boolean isSet(int id) {
475 Setting setting = mSettingsCache.get(id);
476 SharedPreferences preferences = getSettingSource(setting);
477 if (preferences != null) {
478 return (preferences.getString(setting.getKey(), null) != null);
485 * Set a Setting to its default value based on Setting id.
487 public void setDefault(int id) {
488 Setting setting = mSettingsCache.get(id);
489 SharedPreferences preferences = getSettingSource(setting);
490 if (preferences != null) {
491 preferences.edit().putString(setting.getKey(), setting.getDefault());
495 public static Setting getLocationSetting(Context context) {
496 String defaultValue = context.getString(R.string.setting_none_value);
497 String[] values = context.getResources().getStringArray(
498 R.array.pref_camera_recordlocation_entryvalues);
499 return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_RECORD_LOCATION,
503 public static Setting getPictureSizeSetting(Context context) {
504 String defaultValue = null;
505 String[] values = context.getResources().getStringArray(
506 R.array.pref_camera_picturesize_entryvalues);
507 return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_PICTURE_SIZE,
511 public static Setting getDefaultCameraIdSetting(Context context,
512 SettingsCapabilities capabilities) {
513 String defaultValue = context.getString(R.string.pref_camera_id_default);
514 String[] values = null;
515 if (capabilities != null) {
516 values = capabilities.getSupportedCameraIds();
518 return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_CAMERA_ID,
522 public static Setting getWhiteBalanceSetting(Context context) {
523 String defaultValue = context.getString(R.string.pref_camera_whitebalance_default);
524 String[] values = context.getResources().getStringArray(
525 R.array.pref_camera_whitebalance_entryvalues);
526 return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue, KEY_WHITE_BALANCE,
530 public static Setting getHdrSetting(Context context) {
531 String defaultValue = context.getString(R.string.pref_camera_hdr_default);
532 String[] values = context.getResources().getStringArray(
533 R.array.pref_camera_hdr_entryvalues);
534 return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_CAMERA_HDR,
538 public static Setting getHdrPlusSetting(Context context) {
539 String defaultValue = context.getString(R.string.pref_camera_hdr_plus_default);
540 String[] values = context.getResources().getStringArray(
541 R.array.pref_camera_hdr_plus_entryvalues);
542 return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_CAMERA_HDR_PLUS,
546 public static Setting getSceneModeSetting(Context context) {
547 String defaultValue = context.getString(R.string.pref_camera_scenemode_default);
548 String[] values = context.getResources().getStringArray(
549 R.array.pref_camera_scenemode_entryvalues);
550 return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue, KEY_SCENE_MODE,
554 public static Setting getFlashSetting(Context context) {
555 String defaultValue = context.getString(R.string.pref_camera_flashmode_default);
556 String[] values = context.getResources().getStringArray(
557 R.array.pref_camera_flashmode_entryvalues);
558 return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue, KEY_FLASH_MODE,
562 public static Setting getExposureSetting(Context context,
563 SettingsCapabilities capabilities) {
564 String defaultValue = context.getString(R.string.pref_exposure_default);
565 String[] values = null;
566 if (capabilities != null) {
567 values = capabilities.getSupportedExposureValues();
569 return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue, KEY_EXPOSURE,
573 public static Setting getHintSetting(Context context) {
574 String defaultValue = context.getString(R.string.setting_on_value);
575 String[] values = null;
576 return new Setting(SOURCE_GLOBAL, TYPE_BOOLEAN, defaultValue,
577 KEY_CAMERA_FIRST_USE_HINT_SHOWN, values, FLUSH_OFF);
580 public static Setting getFocusModeSetting(Context context) {
581 String defaultValue = null;
582 String[] values = context.getResources().getStringArray(
583 R.array.pref_camera_focusmode_entryvalues);
584 return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue, KEY_FOCUS_MODE,
588 public static Setting getTimerSetting(Context context) {
589 String defaultValue = context.getString(R.string.pref_camera_timer_default);
590 String[] values = null; // TODO: get the values dynamically.
591 return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_TIMER,
595 public static Setting getTimerSoundSetting(Context context) {
596 String defaultValue = context.getString(R.string.pref_camera_timer_sound_default);
597 String[] values = context.getResources().getStringArray(
598 R.array.pref_camera_timer_sound_entryvalues);
599 return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_TIMER_SOUND_EFFECTS,
603 public static Setting getVideoQualitySetting(Context context) {
604 String defaultValue = context.getString(R.string.pref_video_quality_default);
605 String[] values = context.getResources().getStringArray(
606 R.array.pref_video_quality_entryvalues);
607 return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_VIDEO_QUALITY,
611 public static Setting getTimeLapseFrameIntervalSetting(Context context) {
612 String defaultValue = context.getString(
613 R.string.pref_video_time_lapse_frame_interval_default);
614 String[] values = context.getResources().getStringArray(
615 R.array.pref_video_time_lapse_frame_interval_entryvalues);
616 return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue,
617 KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL, values, FLUSH_OFF);
620 public static Setting getJpegQualitySetting(Context context) {
621 String defaultValue = context.getString(
622 R.string.pref_camera_jpeg_quality_normal);
623 String[] values = context.getResources().getStringArray(
624 R.array.pref_camera_jpeg_quality_entryvalues);
625 return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue, KEY_JPEG_QUALITY,
629 public static Setting getVideoFlashSetting(Context context) {
630 String defaultValue = context.getString(R.string.pref_camera_video_flashmode_default);
631 String[] values = context.getResources().getStringArray(
632 R.array.pref_camera_video_flashmode_entryvalues);
633 return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue,
634 KEY_VIDEOCAMERA_FLASH_MODE, values, FLUSH_OFF);
637 public static Setting getVideoEffectSetting(Context context) {
638 String defaultValue = context.getString(R.string.pref_video_effect_default);
639 String[] values = context.getResources().getStringArray(
640 R.array.pref_video_effect_entryvalues);
641 return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_VIDEO_EFFECT,
645 public static Setting getHintVideoSetting(Context context) {
646 String defaultValue = context.getString(R.string.setting_on_value);
647 String[] values = null;
648 return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue,
649 KEY_VIDEO_FIRST_USE_HINT_SHOWN, values, FLUSH_OFF);
652 public static Setting getStartupModuleSetting(Context context) {
653 String defaultValue = context.getString(R.string.pref_camera_startup_index_default);
654 String[] values = null;
655 return new Setting(SOURCE_DEFAULT, TYPE_INTEGER, defaultValue,
656 KEY_STARTUP_MODULE_INDEX, values, FLUSH_OFF);
662 * Returns whether the camera has been set to back facing
665 public boolean isCameraBackFacing() {
666 int cameraFacingIndex = getStringValueIndex(SETTING_CAMERA_ID);
667 String backFacingIndex = mContext.getString(R.string.pref_camera_id_index_back);
668 return (cameraFacingIndex == Integer.parseInt(backFacingIndex));
671 //TODO: refactor this into a separate utils module.
674 * Get a String value from first the ListPreference, and if not found
675 * from the SettingsManager.
677 * This is a wrapper that adds backwards compatibility to views that
678 * rely on PreferenceGroups.
680 public String getValueFromPreference(ListPreference pref) {
681 String value = pref.getValue();
683 Integer id = mSettingsCache.getId(pref.getKey());
693 * Set a String value first from the ListPreference, and if unable
694 * from the SettingsManager.
696 * This is a wrapper that adds backwards compatibility to views that
697 * rely on PreferenceGroups.
699 public void setValueFromPreference(ListPreference pref, String value) {
700 boolean set = pref.setValue(value);
702 Integer id = mSettingsCache.getId(pref.getKey());
710 * Set a String value first from the ListPreference based on a
711 * ListPreference index, and if unable use the ListPreference key
712 * to set the value using the SettingsManager.
714 * This is a wrapper that adds backwards compatibility to views that
715 * rely on PreferenceGroups.
717 public void setValueIndexFromPreference(ListPreference pref, int index) {
718 boolean set = pref.setValueIndex(index);
720 Integer id = mSettingsCache.getId(pref.getKey());
722 String value = pref.getValueAtIndex(index);