import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.preference.PreferenceManager;
-import android.util.Log;
import android.util.SparseArray;
import com.android.camera.ListPreference;
import com.android.camera.app.AppController;
+import com.android.camera.app.LocationManager;
+import com.android.camera.debug.Log;
+import com.android.camera.util.CameraUtil;
import com.android.camera.util.SettingsHelper;
import com.android.camera2.R;
import java.util.List;
/**
- * SettingsManager class provides an api for getting and setting both
- * global and local SharedPreferences.
+ * SettingsManager class provides an api for getting and setting both global and
+ * local SharedPreferences.
*/
public class SettingsManager {
- private static final String TAG = "SettingsManager";
+ private static final Log.Tag TAG = new Log.Tag("SettingsManager");
private final Context mContext;
private final SharedPreferences mDefaultSettings;
private final SettingsCache mSettingsCache;
private SharedPreferences mGlobalSettings;
private SharedPreferences mCameraSettings;
- private final SparseArray<SharedPreferences> mModuleSettings
- = new SparseArray<SharedPreferences>();
+ private final SparseArray<SharedPreferences> mModuleSettings = new SparseArray<SharedPreferences>();
private SettingsCapabilities mCapabilities;
private int mCameraId = -1;
- private AppController mAppController;
+ private final AppController mAppController;
/**
- * A List of OnSettingChangedListener's, maintained
- * to compare to new listeners and prevent duplicate
- * registering.
+ * General settings upgrade model:
+ *
+ * On app upgrade, there are three main ways Settings can be stale/incorrect:
+ * (1) if the type of a setting has changed.
+ * (2) if a set value is no longer a member of the set of possible values.
+ * (3) if the SharedPreferences backing file has changed for a setting.
+ *
+ * Recovery strategies:
+ * (1) catch the ClassCastException or NumberFormatException and try to do a
+ * type conversion, or reset the setting to whatever default is valid.
+ * (2) sanitize sets, and reset to default if set value is no longer valid.
+ * (3) use the default value by virtue of the setting not yet being in the
+ * new file.
+ *
+ * Special cases:
+ *
+ * There are some settings which shouldn't be reset to default on upgrade if
+ * possible. We provide a callback which is executed only on strict upgrade.
+ * This callback does special case upgrades to a subset of the settings. This
+ * contrasts with the general upgrade strategies, which happen lazily, once a
+ * setting is used.
+ *
+ * Removing obsolete key/value pairs:
+ *
+ * This can be done in the strict upgrade callback. The strict upgrade callback
+ * should be idempotent, so it is important to leave removal code in the upgrade
+ * callback so the key/value pairs are removed even if a user skips a version.
*/
- private final List<OnSettingChangedListener>
- mListeners = new ArrayList<OnSettingChangedListener>();
+ public interface StrictUpgradeCallback {
+ /**
+ * Will be executed in the SettingsManager constructor if the strict
+ * upgrade version counter has changed.
+ */
+ public void upgrade(SettingsManager settingsManager, int version);
+ }
+
+ /**
+ * Increment this value whenever a new StrictUpgradeCallback needs to
+ * be executed. This defines upgrade behavior that should be executed
+ * strictly on app upgrades, when the upgrade behavior differs from the general,
+ * lazy upgrade strategies.
+ */
+ private static final int STRICT_UPGRADE_VERSION = 2;
/**
- * A List of OnSharedPreferenceChangeListener's, maintained
- * to hold pointers to actually registered listeners,
- * so they can be unregistered.
+ * A List of OnSettingChangedListener's, maintained to compare to new
+ * listeners and prevent duplicate registering.
*/
- private final List<OnSharedPreferenceChangeListener>
- mSharedPreferenceListeners = new ArrayList<OnSharedPreferenceChangeListener>();
+ private final List<OnSettingChangedListener> mListeners = new ArrayList<OnSettingChangedListener>();
- public SettingsManager(Context context, AppController app, int nCameras) {
+ /**
+ * A List of OnSharedPreferenceChangeListener's, maintained to hold pointers
+ * to actually registered listeners, so they can be unregistered.
+ */
+ private final List<OnSharedPreferenceChangeListener> mSharedPreferenceListeners = new ArrayList<OnSharedPreferenceChangeListener>();
+
+ public SettingsManager(Context context, AppController app, int nCameras,
+ StrictUpgradeCallback upgradeCallback) {
mContext = context;
mAppController = app;
mDefaultSettings = PreferenceManager.getDefaultSharedPreferences(context);
initGlobal();
+
+ if (upgradeCallback != null) {
+ // Check for a strict version upgrade.
+ int version = getInt(SETTING_STRICT_UPGRADE_VERSION);
+ if (STRICT_UPGRADE_VERSION != version) {
+ upgradeCallback.upgrade(this, STRICT_UPGRADE_VERSION);
+ }
+ setInt(SETTING_STRICT_UPGRADE_VERSION, STRICT_UPGRADE_VERSION);
+ }
}
/**
String cameraKey = mContext.getPackageName() + "_preferences_" + cameraId;
mCameraSettings = mContext.getSharedPreferences(
- cameraKey, Context.MODE_PRIVATE);
+ cameraKey, Context.MODE_PRIVATE);
for (OnSharedPreferenceChangeListener listener : mSharedPreferenceListeners) {
mCameraSettings.registerOnSharedPreferenceChangeListener(listener);
private OnSharedPreferenceChangeListener getSharedPreferenceListener(
final OnSettingChangedListener listener) {
return new OnSharedPreferenceChangeListener() {
- @Override
- public void onSharedPreferenceChanged(
- SharedPreferences sharedPreferences, String key) {
- Integer settingId = mSettingsCache.getId(key);
- if (settingId != null) {
- listener.onSettingChanged(SettingsManager.this, settingId);
- } else {
- Log.w(TAG, "Setting id from key=" + key + " is null");
- }
+ @Override
+ public void onSharedPreferenceChanged(
+ SharedPreferences sharedPreferences, String key) {
+ Integer settingId = mSettingsCache.getId(key);
+ if (settingId != null) {
+ listener.onSettingChanged(SettingsManager.this, settingId);
+ } else {
+ Log.w(TAG, "Setting id from key=" + key + " is null");
}
- };
+ }
+ };
}
/**
- * Add an OnSettingChangedListener to the SettingsManager, which will execute
- * onSettingsChanged when any SharedPreference has been updated.
+ * Add an OnSettingChangedListener to the SettingsManager, which will
+ * execute onSettingsChanged when any SharedPreference has been updated.
*/
public void addListener(final OnSettingChangedListener listener) {
if (listener == null) {
mListeners.add(listener);
OnSharedPreferenceChangeListener sharedPreferenceListener =
- getSharedPreferenceListener(listener);
+ getSharedPreferenceListener(listener);
mSharedPreferenceListeners.add(sharedPreferenceListener);
if (mGlobalSettings != null) {
}
/**
- * Remove a specific SettingsListener.
- * This should be done in onPause if a listener has been set.
+ * Remove a specific SettingsListener. This should be done in onPause if a
+ * listener has been set.
*/
public void removeListener(OnSettingChangedListener listener) {
if (listener == null) {
// Get the reference to the actual OnSharedPreferenceChangeListener
// that was registered.
OnSharedPreferenceChangeListener sharedPreferenceListener =
- mSharedPreferenceListeners.get(index);
+ mSharedPreferenceListeners.get(index);
mSharedPreferenceListeners.remove(index);
if (mGlobalSettings != null) {
mGlobalSettings.unregisterOnSharedPreferenceChangeListener(
- sharedPreferenceListener);
+ sharedPreferenceListener);
}
if (mCameraSettings != null) {
mCameraSettings.unregisterOnSharedPreferenceChangeListener(
- sharedPreferenceListener);
+ sharedPreferenceListener);
}
if (mDefaultSettings != null) {
mDefaultSettings.unregisterOnSharedPreferenceChangeListener(
- sharedPreferenceListener);
+ sharedPreferenceListener);
}
}
/**
- * Remove all OnSharedPreferenceChangedListener's.
- * This should be done in onDestroy.
+ * Remove all OnSharedPreferenceChangedListener's. This should be done in
+ * onDestroy.
*/
public void removeAllListeners() {
for (OnSharedPreferenceChangeListener listener : mSharedPreferenceListeners) {
/**
* SettingsCapabilities defines constraints around settings that need to be
- * queried from external sources, like the camera parameters.
- *
- * This interface is camera api agnostic.
+ * queried from external sources, like the camera parameters. This interface
+ * is camera api agnostic.
*/
public interface SettingsCapabilities {
/**
- * Returns a dynamically calculated list of
- * exposure values, based on the min and max
- * exposure compensation supported by the camera device.
+ * Returns a dynamically calculated list of exposure values, based on
+ * the min and max exposure compensation supported by the camera device.
*/
public String[] getSupportedExposureValues();
/**
- * Returns a list of camera ids based on the number
- * of cameras available on the device.
+ * Returns a list of camera ids based on the number of cameras available
+ * on the device.
*/
public String[] getSupportedCameraIds();
}
// For quick lookup from id to Setting.
public static final int SETTING_RECORD_LOCATION = 0;
- public static final int SETTING_VIDEO_QUALITY = 1;
- public static final int SETTING_VIDEO_TIME_LAPSE_FRAME_INTERVAL = 2;
- public static final int SETTING_PICTURE_SIZE = 3;
- public static final int SETTING_JPEG_QUALITY = 4;
- public static final int SETTING_FOCUS_MODE = 5;
- public static final int SETTING_FLASH_MODE = 6;
- public static final int SETTING_VIDEOCAMERA_FLASH_MODE = 7;
- public static final int SETTING_WHITE_BALANCE = 8;
- public static final int SETTING_SCENE_MODE = 9;
- public static final int SETTING_EXPOSURE = 10;
- public static final int SETTING_TIMER = 11;
- public static final int SETTING_TIMER_SOUND_EFFECTS = 12;
- public static final int SETTING_VIDEO_EFFECT = 13;
- public static final int SETTING_CAMERA_ID = 14;
- public static final int SETTING_CAMERA_HDR = 15;
- public static final int SETTING_CAMERA_HDR_PLUS = 16;
- public static final int SETTING_CAMERA_FIRST_USE_HINT_SHOWN = 17;
- public static final int SETTING_VIDEO_FIRST_USE_HINT_SHOWN = 18;
- public static final int SETTING_STARTUP_MODULE_INDEX = 19;
- public static final int SETTING_CAMERA_REFOCUS = 20;
- public static final int SETTING_SHIMMY_REMAINING_PLAY_TIMES_INDEX = 21;
- public static final int SETTING_KEY_CAMERA_MODULE_LAST_USED_INDEX = 22;
- public static final int SETTING_CAMERA_PANO_ORIENTATION = 23;
+ public static final int SETTING_VIDEO_QUALITY_BACK = 1;
+ public static final int SETTING_VIDEO_QUALITY_FRONT = 2;
+ public static final int SETTING_VIDEO_TIME_LAPSE_FRAME_INTERVAL = 3;
+ public static final int SETTING_PICTURE_SIZE_BACK = 4;
+ public static final int SETTING_PICTURE_SIZE_FRONT = 5;
+ public static final int SETTING_JPEG_QUALITY = 6;
+ public static final int SETTING_FOCUS_MODE = 7;
+ public static final int SETTING_FLASH_MODE = 8;
+ public static final int SETTING_VIDEOCAMERA_FLASH_MODE = 9;
+ public static final int SETTING_SCENE_MODE = 11;
+ public static final int SETTING_EXPOSURE = 12;
+ public static final int SETTING_VIDEO_EFFECT = 15;
+ public static final int SETTING_CAMERA_ID = 16;
+ public static final int SETTING_CAMERA_HDR = 17;
+ public static final int SETTING_CAMERA_HDR_PLUS = 18;
+ public static final int SETTING_CAMERA_FIRST_USE_HINT_SHOWN = 19;
+ public static final int SETTING_VIDEO_FIRST_USE_HINT_SHOWN = 20;
+ public static final int SETTING_STARTUP_MODULE_INDEX = 21;
+ public static final int SETTING_KEY_CAMERA_MODULE_LAST_USED_INDEX = 23;
+ public static final int SETTING_CAMERA_PANO_ORIENTATION = 24;
+ public static final int SETTING_CAMERA_GRID_LINES = 25;
+ public static final int SETTING_RELEASE_DIALOG_LAST_SHOWN_VERSION = 26;
+ public static final int SETTING_FLASH_SUPPORTED_BACK_CAMERA = 27;
+ public static final int SETTING_STRICT_UPGRADE_VERSION = 28;
+ // A boolean for requesting to return to HDR plus
+ // as soon as possible, if a user requests a setting/mode option
+ // that forces them to leave HDR plus.
+ public static final int SETTING_REQUEST_RETURN_HDR_PLUS = 30;
// Shared preference keys.
public static final String KEY_RECORD_LOCATION = "pref_camera_recordlocation_key";
- public static final String KEY_VIDEO_QUALITY = "pref_video_quality_key";
+ public static final String KEY_VIDEO_QUALITY_BACK = "pref_video_quality_back_key";
+ public static final String KEY_VIDEO_QUALITY_FRONT = "pref_video_quality_front_key";
public static final String KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL =
- "pref_video_time_lapse_frame_interval_key";
- public static final String KEY_PICTURE_SIZE = "pref_camera_picturesize_key";
+ "pref_video_time_lapse_frame_interval_key";
+ public static final String KEY_PICTURE_SIZE_BACK = "pref_camera_picturesize_back_key";
+ public static final String KEY_PICTURE_SIZE_FRONT = "pref_camera_picturesize_front_key";
public static final String KEY_JPEG_QUALITY = "pref_camera_jpegquality_key";
public static final String KEY_FOCUS_MODE = "pref_camera_focusmode_key";
public static final String KEY_FLASH_MODE = "pref_camera_flashmode_key";
public static final String KEY_VIDEOCAMERA_FLASH_MODE = "pref_camera_video_flashmode_key";
- public static final String KEY_WHITE_BALANCE = "pref_camera_whitebalance_key";
public static final String KEY_SCENE_MODE = "pref_camera_scenemode_key";
public static final String KEY_EXPOSURE = "pref_camera_exposure_key";
- public static final String KEY_TIMER = "pref_camera_timer_key";
- public static final String KEY_TIMER_SOUND_EFFECTS = "pref_camera_timer_sound_key";
public static final String KEY_VIDEO_EFFECT = "pref_video_effect_key";
public static final String KEY_CAMERA_ID = "pref_camera_id_key";
public static final String KEY_CAMERA_HDR = "pref_camera_hdr_key";
public static final String KEY_CAMERA_HDR_PLUS = "pref_camera_hdr_plus_key";
public static final String KEY_CAMERA_FIRST_USE_HINT_SHOWN =
- "pref_camera_first_use_hint_shown_key";
+ "pref_camera_first_use_hint_shown_key";
public static final String KEY_VIDEO_FIRST_USE_HINT_SHOWN =
- "pref_video_first_use_hint_shown_key";
+ "pref_video_first_use_hint_shown_key";
public static final String KEY_STARTUP_MODULE_INDEX = "camera.startup_module";
- public static final String KEY_CAMERA_REFOCUS = "pref_camera_refocus";
- public static final String KEY_SHIMMY_REMAINING_PLAY_TIMES =
- "pref_shimmy_remaining_play_times";
public static final String KEY_CAMERA_MODULE_LAST_USED =
"pref_camera_module_last_used_index";
public static final String KEY_CAMERA_PANO_ORIENTATION = "pref_camera_pano_orientation";
+ public static final String KEY_CAMERA_GRID_LINES = "pref_camera_grid_lines";
+ public static final String KEY_RELEASE_DIALOG_LAST_SHOWN_VERSION =
+ "pref_release_dialog_last_shown_version";
+ public static final String KEY_FLASH_SUPPORTED_BACK_CAMERA =
+ "pref_flash_supported_back_camera";
+ public static final String KEY_STRICT_UPGRADE_VERSION = "pref_strict_upgrade_version";
+ public static final String KEY_REQUEST_RETURN_HDR_PLUS = "pref_request_return_hdr_plus";
public static final int WHITE_BALANCE_DEFAULT_INDEX = 2;
-
/**
- * Defines a simple class for holding a the spec of a setting.
- * This spec is used by the generic api methods to query and
- * update a setting.
+ * Defines a simple class for holding a the spec of a setting. This spec is
+ * used by the generic api methods to query and update a setting.
*/
public static class Setting {
private final String mSource;
/**
* A constructor used to store a setting's profile.
*/
- Setting(String source, String type, String defaultValue, String key,
+ public Setting(String source, String type, String defaultValue, String key,
String[] values, boolean flushOnCameraChange) {
mSource = source;
mType = type;
}
/**
- * Returns the id of a SharedPreferences instance from which
- * this Setting may be found.
- * Possible values are {@link #SOURCE_DEFAULT}, {@link #SOURCE_GLOBAL},
- * {@link #SOURCE_CAMERA}.
+ * Returns the id of a SharedPreferences instance from which this
+ * Setting may be found. Possible values are {@link #SOURCE_DEFAULT},
+ * {@link #SOURCE_GLOBAL}, {@link #SOURCE_CAMERA}.
*/
public String getSource() {
return mSource;
}
/**
- * Returns the type of the setting stored in SharedPreferences.
- * Possible values are {@link #TYPE_STRING}, {@link #TYPE_INTEGER},
+ * Returns the type of the setting stored in SharedPreferences. Possible
+ * values are {@link #TYPE_STRING}, {@link #TYPE_INTEGER},
* {@link #TYPE_BOOLEAN}.
*/
public String getType() {
}
/**
- * Returns an array of possible String values for this setting.
- * If this setting is not of type {@link #TYPE_STRING}, or
- * it's not possible to generate the string values, this should
- * return null;
+ * Returns an array of possible String values for this setting. If this
+ * setting is not of type {@link #TYPE_STRING}, or it's not possible to
+ * generate the string values, this should return null;
*/
public String[] getStringValues() {
return mValues;
}
/**
- * Returns whether the setting should be flushed from the cache
- * when the camera device has changed.
+ * Returns whether the setting should be flushed from the cache when the
+ * camera device has changed.
*/
public boolean isFlushedOnCameraChanged() {
return mFlushOnCameraChange;
* Get the SharedPreferences needed to query/update the setting.
*/
public SharedPreferences getSettingSource(Setting setting) {
- String source = setting.getSource();
+ return getSettingSource(setting.getSource());
+ }
+
+ private SharedPreferences getSettingSource(String source) {
if (source.equals(SOURCE_DEFAULT)) {
return mDefaultSettings;
}
return mCameraSettings;
}
if (source.equals(SOURCE_MODULE)) {
- int modeIndex = mAppController.getCurrentModuleIndex();
+ int modeIndex = CameraUtil.getCameraModeParentModeId(
+ mAppController.getCurrentModuleIndex(), mAppController.getAndroidContext());
return getModulePreferences(modeIndex);
}
return null;
}
/**
- * Based on Setting id, finds the index of a Setting's
- * String value in an array of possible String values.
- *
- * If the Setting is not of type String, this returns -1.
- *
- * <p>TODO: make this a supported api call for all types.</p>
+ * Based on Setting id, finds the index of a Setting's String value in an
+ * array of possible String values. If the Setting is not of type String,
+ * this returns -1.
+ * <p>
+ * TODO: make this a supported api call for all types.
+ * </p>
*/
public int getStringValueIndex(int id) {
Setting setting = mSettingsCache.get(id);
if (setting == null || !TYPE_STRING.equals(setting.getType())) {
return -1;
}
+ return getStringValueIndex(setting.getStringValues(), get(id));
+ }
- String value = get(id);
+ private int getStringValueIndex(String[] possibleValues, String value) {
if (value != null) {
- String[] possibleValues = setting.getStringValues();
if (possibleValues != null) {
for (int i = 0; i < possibleValues.length; i++) {
if (value.equals(possibleValues[i])) {
}
/**
- * Based on Setting id, sets a Setting's String value using the
- * index into an array of possible String values.
- *
- * Fails to set a value if the index is out of bounds or the Setting
- * is not of type String.
+ * Based on Setting id, sets a Setting's String value using the index into
+ * an array of possible String values. Fails to set a value if the index is
+ * out of bounds or the Setting is not of type String.
*
* @return Whether the value was set.
*/
}
/**
+ * Returns whether this Setting was last set as a String.
+ */
+ private boolean isString(int id, String source) {
+ Setting setting = mSettingsCache.get(id);
+ SharedPreferences preferences = getSettingSource(source);
+ try {
+ preferences.getString(setting.getKey(), null);
+ return true;
+ } catch (ClassCastException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns whether this Setting was last set as a boolean.
+ */
+ private boolean isBoolean(int id, String source) {
+ Setting setting = mSettingsCache.get(id);
+ SharedPreferences preferences = getSettingSource(source);
+ try {
+ preferences.getBoolean(setting.getKey(), false);
+ return true;
+ } catch (ClassCastException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns whether this Setting was last set as an Integer.
+ */
+ private boolean isInteger(int id, String source) {
+ Setting setting = mSettingsCache.get(id);
+ SharedPreferences preferences = getSettingSource(source);
+ try {
+ preferences.getInt(setting.getKey(), 0);
+ return true;
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Recover a Setting by converting it to a String if the type
+ * is known and the type conversion is successful, otherwise
+ * reset to the default.
+ */
+ private String recoverToString(int id, String source) {
+ String value;
+ try {
+ if (isBoolean(id, source)) {
+ value = (getBoolean(id, source) ? VALUE_ON : VALUE_OFF);
+ } else if (isInteger(id, source)) {
+ value = Integer.toString(getInt(id, source));
+ } else {
+ throw new Exception();
+ }
+ } catch (Exception e) {
+ value = mSettingsCache.get(id).getDefault();
+ }
+ set(id, source, value);
+ return value;
+ }
+
+ /**
+ * Recover a Setting by converting it to a boolean if the type
+ * is known and the type conversion is successful, otherwise
+ * reset to the default.
+ */
+ private boolean recoverToBoolean(int id, String source) {
+ boolean value;
+ try {
+ if (isString(id, source)) {
+ value = VALUE_ON.equals(get(id, source));
+ } else if (isInteger(id, source)) {
+ value = getInt(id, source) != 0;
+ } else {
+ throw new Exception();
+ }
+ } catch (Exception e) {
+ value = VALUE_ON.equals(mSettingsCache.get(id).getDefault());
+ }
+ setBoolean(id, source, value);
+ return value;
+ }
+
+ /**
+ * Recover a Setting by converting it to an Integer if the type
+ * is known and the type conversion is successful, otherwise
+ * reset to the default.
+ */
+ private int recoverToInteger(int id, String source) {
+ int value;
+ try {
+ if (isString(id, source)) {
+ value = Integer.parseInt(get(id, source));
+ } else if (isBoolean(id, source)) {
+ value = getBoolean(id, source) ? 1 : 0;
+ } else {
+ throw new Exception();
+ }
+ } catch (Exception e) {
+ value = Integer.parseInt(mSettingsCache.get(id).getDefault());
+ }
+ setInt(id, value);
+ return value;
+ }
+
+ /**
+ * Check if a String value is in the set of possible values for a Setting.
+ * We only keep track of possible values for String types for now.
+ */
+ private String sanitize(Setting setting, String value) {
+ if (setting.getStringValues() != null &&
+ getStringValueIndex(setting.getStringValues(), value) < 0) {
+ // If the set of possible values is not empty, and the value
+ // is not in the set of possible values, use the default, because
+ // the set of possible values probably changed.
+ return setting.getDefault();
+ }
+ return value;
+ }
+
+ /**
* Get a Setting's String value based on Setting id.
*/
- // TODO: rename to something more descriptive.
+ // TODO: rename to something more descriptive like getString.
public String get(int id) {
Setting setting = mSettingsCache.get(id);
- SharedPreferences preferences = getSettingSource(setting);
+ return get(id, setting.getSource());
+ }
+
+ /**
+ * Get a Setting's String value based on Setting id and a source file id.
+ */
+ public String get(int id, String source) {
+ Setting setting = mSettingsCache.get(id);
+ SharedPreferences preferences = getSettingSource(source);
if (preferences != null) {
- return preferences.getString(setting.getKey(), setting.getDefault());
+ try {
+ String value = preferences.getString(setting.getKey(), setting.getDefault());
+ return sanitize(setting, value);
+ } catch (ClassCastException e) {
+ // If the api defines this Setting as a String, but the
+ // last set saved it as a different type, try to recover
+ // the value, but if impossible reset to default.
+ return recoverToString(id, source);
+ }
} else {
- return null;
+ throw new IllegalStateException(
+ "Setting source=" + source + " is unitialized.");
}
}
*/
public boolean getBoolean(int id) {
Setting setting = mSettingsCache.get(id);
- SharedPreferences preferences = getSettingSource(setting);
- boolean defaultValue = setting.getDefault().equals(VALUE_ON);
+ return getBoolean(id, setting.getSource());
+ }
+
+ /**
+ * Get a Setting's boolean value based on a Setting id and a source file id.
+ */
+ public boolean getBoolean(int id, String source) {
+ Setting setting = mSettingsCache.get(id);
+ SharedPreferences preferences = getSettingSource(source);
+ boolean defaultValue = VALUE_ON.equals(setting.getDefault());
if (preferences != null) {
- return preferences.getBoolean(setting.getKey(), defaultValue);
+ try {
+ return preferences.getBoolean(setting.getKey(), defaultValue);
+ } catch (ClassCastException e) {
+ // If the api defines this Setting as a boolean, but the
+ // last set saved it as a different type, try to recover
+ // the value, but if impossible reset to default.
+ return recoverToBoolean(id, source);
+ }
} else {
- return defaultValue;
+ throw new IllegalStateException(
+ "Setting source=" + source + " is unitialized.");
}
}
*/
public int getInt(int id) {
Setting setting = mSettingsCache.get(id);
- SharedPreferences preferences = getSettingSource(setting);
+ return getInt(id, setting.getSource());
+ }
+
+ /**
+ * Get a Setting's int value based on Setting id and a source file id.
+ */
+ public int getInt(int id, String source) {
+ Setting setting = mSettingsCache.get(id);
+ SharedPreferences preferences = getSettingSource(source);
int defaultValue = Integer.parseInt(setting.getDefault());
if (preferences != null) {
- return preferences.getInt(setting.getKey(), defaultValue);
+ try {
+ return preferences.getInt(setting.getKey(), defaultValue);
+ } catch (NumberFormatException e) {
+ // If the api defines this Setting as an Integer, but the
+ // last set saved it as a different type, try to recover
+ // the value, but if impossible reset to default.
+ return recoverToInteger(id, source);
+ }
} else {
- return defaultValue;
+ throw new IllegalStateException(
+ "Setting source=" + source + " is unitialized.");
}
}
// TODO: rename to something more descriptive.
public void set(int id, String value) {
Setting setting = mSettingsCache.get(id);
- SharedPreferences preferences = getSettingSource(setting);
+ set(id, setting.getSource(), value);
+ }
+
+ /**
+ * Set a Setting with a String value based on Setting id and a source file id.
+ */
+ public void set(int id, String source, String value) {
+ Setting setting = mSettingsCache.get(id);
+ value = sanitize(setting, value);
+ SharedPreferences preferences = getSettingSource(source);
if (preferences != null) {
preferences.edit().putString(setting.getKey(), value).apply();
+ } else {
+ throw new IllegalStateException(
+ "Setting source=" + source + " is unitialized.");
}
}
*/
public void setBoolean(int id, boolean value) {
Setting setting = mSettingsCache.get(id);
- SharedPreferences preferences = getSettingSource(setting);
+ setBoolean(id, setting.getSource(), value);
+ }
+ /**
+ * Set a Setting with a boolean value based on Setting id and a source file id.
+ */
+ public void setBoolean(int id, String source, boolean value) {
+ Setting setting = mSettingsCache.get(id);
+ SharedPreferences preferences = getSettingSource(source);
if (preferences != null) {
preferences.edit().putBoolean(setting.getKey(), value).apply();
+ } else {
+ throw new IllegalStateException(
+ "Setting source=" + source + " is unitialized.");
}
}
*/
public void setInt(int id, int value) {
Setting setting = mSettingsCache.get(id);
- SharedPreferences preferences = getSettingSource(setting);
+ setInt(id, setting.getSource(), value);
+ }
+
+ /**
+ * Set a Setting with an int value based on Setting id and a source file id.
+ */
+ public void setInt(int id, String source, int value) {
+ Setting setting = mSettingsCache.get(id);
+ SharedPreferences preferences = getSettingSource(source);
if (preferences != null) {
preferences.edit().putInt(setting.getKey(), value).apply();
+ } else {
+ throw new IllegalStateException(
+ "Setting source=" + source + " is unitialized.");
}
}
*/
public boolean isSet(int id) {
Setting setting = mSettingsCache.get(id);
- SharedPreferences preferences = getSettingSource(setting);
+ return isSet(id, setting.getSource());
+ }
+
+ /**
+ * Check if a Setting has ever been set based on Setting id and a source file id.
+ */
+ public boolean isSet(int id, String source) {
+ Setting setting = mSettingsCache.get(id);
+ SharedPreferences preferences = getSettingSource(source);
if (preferences != null) {
- return (preferences.getString(setting.getKey(), null) != null);
+ return preferences.contains(setting.getKey());
} else {
- return false;
+ throw new IllegalStateException(
+ "Setting source=" + setting.getSource() + " is unitialized.");
}
}
SharedPreferences preferences = getSettingSource(setting);
if (preferences != null) {
preferences.edit().putString(setting.getKey(), setting.getDefault());
+ } else {
+ throw new IllegalStateException(
+ "Setting source=" + setting.getSource() + " is unitialized.");
}
}
throw new IllegalArgumentException("Type " + type + " is not known.");
}
} else {
- return false;
+ throw new IllegalStateException(
+ "Setting source=" + setting.getSource() + " is unitialized.");
+ }
+ }
+
+ /**
+ * Remove a Setting from SharedPreferences.
+ */
+ public void remove(int id) {
+ Setting setting = mSettingsCache.get(id);
+ SharedPreferences preferences = getSettingSource(setting);
+ if (preferences != null) {
+ preferences.edit().remove(setting.getKey()).apply();
+ } else {
+ throw new IllegalStateException(
+ "Setting source=" + setting.getSource() + " is unitialized.");
}
}
public static Setting getLocationSetting(Context context) {
String defaultValue = context.getString(R.string.setting_none_value);
+ String[] values = null;
+ return new Setting(SOURCE_DEFAULT, TYPE_BOOLEAN, defaultValue, KEY_RECORD_LOCATION,
+ values, FLUSH_OFF);
+ }
+
+ public static Setting getPictureSizeBackSetting(Context context) {
+ String defaultValue = null;
String[] values = context.getResources().getStringArray(
- R.array.pref_camera_recordlocation_entryvalues);
- return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_RECORD_LOCATION,
- values, FLUSH_OFF);
+ R.array.pref_camera_picturesize_entryvalues);
+ return new Setting(SOURCE_DEFAULT, TYPE_STRING, defaultValue, KEY_PICTURE_SIZE_BACK,
+ values, FLUSH_OFF);
}
- public static Setting getPictureSizeSetting(Context context) {
+ public static Setting getPictureSizeFrontSetting(Context context) {
String defaultValue = null;
String[] values = context.getResources().getStringArray(
- R.array.pref_camera_picturesize_entryvalues);
- return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_PICTURE_SIZE,
- values, FLUSH_OFF);
+ R.array.pref_camera_picturesize_entryvalues);
+ return new Setting(SOURCE_DEFAULT, TYPE_STRING, defaultValue, KEY_PICTURE_SIZE_FRONT,
+ values, FLUSH_OFF);
}
public static Setting getDefaultCameraIdSetting(Context context,
values = capabilities.getSupportedCameraIds();
}
return new Setting(SOURCE_MODULE, TYPE_STRING, defaultValue, KEY_CAMERA_ID,
- values, FLUSH_ON);
- }
-
- public static Setting getWhiteBalanceSetting(Context context) {
- String defaultValue = context.getString(R.string.pref_camera_whitebalance_default);
- String[] values = context.getResources().getStringArray(
- R.array.pref_camera_whitebalance_entryvalues);
- return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue, KEY_WHITE_BALANCE,
- values, FLUSH_OFF);
+ values, FLUSH_ON);
}
public static Setting getHdrSetting(Context context) {
String defaultValue = context.getString(R.string.pref_camera_hdr_default);
String[] values = context.getResources().getStringArray(
- R.array.pref_camera_hdr_entryvalues);
+ R.array.pref_camera_hdr_entryvalues);
return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_CAMERA_HDR,
- values, FLUSH_OFF);
+ values, FLUSH_OFF);
}
public static Setting getHdrPlusSetting(Context context) {
String defaultValue = context.getString(R.string.pref_camera_hdr_plus_default);
String[] values = context.getResources().getStringArray(
- R.array.pref_camera_hdr_plus_entryvalues);
+ R.array.pref_camera_hdr_plus_entryvalues);
return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_CAMERA_HDR_PLUS,
- values, FLUSH_OFF);
+ values, FLUSH_OFF);
}
public static Setting getSceneModeSetting(Context context) {
String defaultValue = context.getString(R.string.pref_camera_scenemode_default);
String[] values = context.getResources().getStringArray(
- R.array.pref_camera_scenemode_entryvalues);
+ R.array.pref_camera_scenemode_entryvalues);
return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue, KEY_SCENE_MODE,
- values, FLUSH_OFF);
+ values, FLUSH_OFF);
}
public static Setting getFlashSetting(Context context) {
String defaultValue = context.getString(R.string.pref_camera_flashmode_default);
String[] values = context.getResources().getStringArray(
- R.array.pref_camera_flashmode_entryvalues);
+ R.array.pref_camera_flashmode_entryvalues);
return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue, KEY_FLASH_MODE,
- values, FLUSH_OFF);
+ values, FLUSH_OFF);
}
public static Setting getExposureSetting(Context context,
values = capabilities.getSupportedExposureValues();
}
return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue, KEY_EXPOSURE,
- values, FLUSH_ON);
+ values, FLUSH_ON);
}
public static Setting getHintSetting(Context context) {
String defaultValue = context.getString(R.string.setting_on_value);
String[] values = null;
return new Setting(SOURCE_GLOBAL, TYPE_BOOLEAN, defaultValue,
- KEY_CAMERA_FIRST_USE_HINT_SHOWN, values, FLUSH_OFF);
+ KEY_CAMERA_FIRST_USE_HINT_SHOWN, values, FLUSH_OFF);
}
public static Setting getFocusModeSetting(Context context) {
String defaultValue = null;
String[] values = context.getResources().getStringArray(
- R.array.pref_camera_focusmode_entryvalues);
+ R.array.pref_camera_focusmode_entryvalues);
return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue, KEY_FOCUS_MODE,
- values, FLUSH_OFF);
+ values, FLUSH_OFF);
}
- public static Setting getTimerSetting(Context context) {
- String defaultValue = context.getString(R.string.pref_camera_timer_default);
- String[] values = null; // TODO: get the values dynamically.
- return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_TIMER,
- values, FLUSH_OFF);
- }
-
- public static Setting getTimerSoundSetting(Context context) {
- String defaultValue = context.getString(R.string.pref_camera_timer_sound_default);
+ public static Setting getVideoQualityBackSetting(Context context) {
+ String defaultValue = context.getString(R.string.pref_video_quality_default);
String[] values = context.getResources().getStringArray(
- R.array.pref_camera_timer_sound_entryvalues);
- return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_TIMER_SOUND_EFFECTS,
- values, FLUSH_OFF);
+ R.array.pref_video_quality_entryvalues);
+ return new Setting(SOURCE_DEFAULT, TYPE_STRING, defaultValue, KEY_VIDEO_QUALITY_BACK,
+ values, FLUSH_OFF);
}
- public static Setting getVideoQualitySetting(Context context) {
+ public static Setting getVideoQualityFrontSetting(Context context) {
String defaultValue = context.getString(R.string.pref_video_quality_default);
String[] values = context.getResources().getStringArray(
- R.array.pref_video_quality_entryvalues);
- return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_VIDEO_QUALITY,
- values, FLUSH_OFF);
+ R.array.pref_video_quality_entryvalues);
+ return new Setting(SOURCE_DEFAULT, TYPE_STRING, defaultValue, KEY_VIDEO_QUALITY_FRONT,
+ values, FLUSH_OFF);
}
public static Setting getTimeLapseFrameIntervalSetting(Context context) {
String defaultValue = context.getString(
- R.string.pref_video_time_lapse_frame_interval_default);
+ R.string.pref_video_time_lapse_frame_interval_default);
String[] values = context.getResources().getStringArray(
- R.array.pref_video_time_lapse_frame_interval_entryvalues);
+ R.array.pref_video_time_lapse_frame_interval_entryvalues);
return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue,
- KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL, values, FLUSH_OFF);
+ KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL, values, FLUSH_OFF);
}
public static Setting getJpegQualitySetting(Context context) {
String defaultValue = context.getString(
- R.string.pref_camera_jpeg_quality_normal);
+ R.string.pref_camera_jpeg_quality_normal);
String[] values = context.getResources().getStringArray(
- R.array.pref_camera_jpeg_quality_entryvalues);
+ R.array.pref_camera_jpeg_quality_entryvalues);
return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue, KEY_JPEG_QUALITY,
- values, FLUSH_OFF);
+ values, FLUSH_OFF);
}
public static Setting getVideoFlashSetting(Context context) {
String defaultValue = context.getString(R.string.pref_camera_video_flashmode_default);
String[] values = context.getResources().getStringArray(
- R.array.pref_camera_video_flashmode_entryvalues);
+ R.array.pref_camera_video_flashmode_entryvalues);
return new Setting(SOURCE_CAMERA, TYPE_STRING, defaultValue,
- KEY_VIDEOCAMERA_FLASH_MODE, values, FLUSH_OFF);
+ KEY_VIDEOCAMERA_FLASH_MODE, values, FLUSH_OFF);
}
public static Setting getVideoEffectSetting(Context context) {
String defaultValue = context.getString(R.string.pref_video_effect_default);
String[] values = context.getResources().getStringArray(
- R.array.pref_video_effect_entryvalues);
+ R.array.pref_video_effect_entryvalues);
return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue, KEY_VIDEO_EFFECT,
- values, FLUSH_OFF);
+ values, FLUSH_OFF);
}
public static Setting getHintVideoSetting(Context context) {
String defaultValue = context.getString(R.string.setting_on_value);
String[] values = null;
return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue,
- KEY_VIDEO_FIRST_USE_HINT_SHOWN, values, FLUSH_OFF);
+ KEY_VIDEO_FIRST_USE_HINT_SHOWN, values, FLUSH_OFF);
}
public static Setting getStartupModuleSetting(Context context) {
String defaultValue = context.getString(R.string.pref_camera_startup_index_default);
String[] values = null;
return new Setting(SOURCE_DEFAULT, TYPE_INTEGER, defaultValue,
- KEY_STARTUP_MODULE_INDEX, values, FLUSH_OFF);
- }
-
- public static Setting getShimmyRemainingTimesSetting(Context context) {
- String defaultValue = context.getString(R.string.pref_shimmy_play_times);
- return new Setting(SOURCE_DEFAULT, TYPE_INTEGER, defaultValue,
- KEY_SHIMMY_REMAINING_PLAY_TIMES, null, FLUSH_OFF);
+ KEY_STARTUP_MODULE_INDEX, values, FLUSH_OFF);
}
public static Setting getLastUsedCameraModule(Context context) {
KEY_CAMERA_MODULE_LAST_USED, null, FLUSH_OFF);
}
- public static Setting getRefocusSetting(Context context) {
- String defaultValue = context.getString(R.string.setting_off_value);
+ public static Setting getPanoOrientationSetting(Context context) {
+ String defaultValue = context.getString(R.string.pano_orientation_horizontal);
String[] values = context.getResources().getStringArray(
- R.array.pref_camera_refocus_entryvalues);
+ R.array.pref_camera_pano_orientation_entryvalues);
return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue,
- KEY_CAMERA_REFOCUS, values, FLUSH_OFF);
+ KEY_CAMERA_PANO_ORIENTATION, values, FLUSH_OFF);
}
- public static Setting getPanoOrientationSetting(Context context) {
- String defaultValue = context.getString(R.string.pano_orientation_horizontal);
+ public static Setting getGridLinesSetting(Context context) {
+ String defaultValue = context.getString(R.string.setting_off_value);
String[] values = context.getResources().getStringArray(
- R.array.pref_camera_pano_orientation_entryvalues);
+ R.array.pref_camera_gridlines_entryvalues);
return new Setting(SOURCE_GLOBAL, TYPE_STRING, defaultValue,
- KEY_CAMERA_PANO_ORIENTATION, values, FLUSH_OFF);
+ KEY_CAMERA_GRID_LINES, values, FLUSH_OFF);
+ }
+
+ public static Setting getReleaseDialogLastShownVersionSetting(Context context) {
+ return new Setting(SOURCE_DEFAULT, TYPE_STRING, null,
+ KEY_RELEASE_DIALOG_LAST_SHOWN_VERSION, null, FLUSH_OFF);
+ }
+
+ public static Setting getFlashSupportedBackCameraSetting(Context context) {
+ String defaultValue = context.getString(R.string.setting_none_value);
+ return new Setting(SOURCE_GLOBAL, TYPE_BOOLEAN, defaultValue,
+ KEY_FLASH_SUPPORTED_BACK_CAMERA, null, FLUSH_OFF);
+ }
+
+ public static Setting getStrictUpgradeVersionSetting(Context context) {
+ String defaultValue = "0";
+ return new Setting(SOURCE_DEFAULT, TYPE_INTEGER, defaultValue,
+ KEY_STRICT_UPGRADE_VERSION, null, FLUSH_OFF);
+ }
+
+ public static Setting getRequestReturnHdrPlusSetting(Context context) {
+ String defaultValue = context.getString(R.string.setting_none_value);
+ return new Setting(SOURCE_MODULE, TYPE_BOOLEAN, VALUE_OFF,
+ KEY_REQUEST_RETURN_HDR_PLUS, null, FLUSH_OFF);
}
// Utilities.
/**
- * Returns whether the camera has been set to back facing
- * in settings.
+ * Returns whether the camera has been set to back facing in settings.
*/
public boolean isCameraBackFacing() {
String cameraFacing = get(SETTING_CAMERA_ID);
}
/**
- * Returns whether refocus mode is set on.
+ * Returns whether hdr plus mode is set on.
*/
- public boolean isRefocusOn() {
- String refocusOn = get(SettingsManager.SETTING_CAMERA_REFOCUS);
- return refocusOn.equals(SettingsManager.VALUE_ON);
+ public boolean isHdrPlusOn() {
+ String hdrOn = get(SettingsManager.SETTING_CAMERA_HDR_PLUS);
+ return hdrOn.equals(SettingsManager.VALUE_ON);
}
/**
- * Returns whether hdr plus mode is set on.
+ * Returns whether hdr mode is set on.
*/
- public boolean isHdrPlusOn() {
+ public boolean isHdrOn() {
String hdrOn = get(SettingsManager.SETTING_CAMERA_HDR);
return hdrOn.equals(SettingsManager.VALUE_ON);
}
- //TODO: refactor this into a separate utils module.
+ /**
+ * Returns whether the app should return to hdr plus mode if possible.
+ */
+ public boolean requestsReturnToHdrPlus() {
+ return getBoolean(SettingsManager.SETTING_REQUEST_RETURN_HDR_PLUS);
+ }
/**
- * Get a String value from first the ListPreference, and if not found
- * from the SettingsManager.
- *
- * This is a wrapper that adds backwards compatibility to views that
- * rely on PreferenceGroups.
+ * Returns whether grid lines are set on.
+ */
+ public boolean areGridLinesOn() {
+ String gridLinesOn = get(SettingsManager.SETTING_CAMERA_GRID_LINES);
+ return gridLinesOn.equals(SettingsManager.VALUE_ON);
+ }
+
+ /**
+ * Returns whether pano orientation is horizontal.
+ */
+ public boolean isPanoOrientationHorizontal() {
+ String orientation = get(SettingsManager.SETTING_CAMERA_PANO_ORIENTATION);
+ String horizontal = mContext.getString(R.string.pano_orientation_horizontal);
+ return orientation.equals(horizontal);
+ }
+
+ // TODO: refactor this into a separate utils module.
+
+ /**
+ * Get a String value from first the ListPreference, and if not found from
+ * the SettingsManager. This is a wrapper that adds backwards compatibility
+ * to views that rely on PreferenceGroups.
*/
public String getValueFromPreference(ListPreference pref) {
String value = pref.getValue();
}
/**
- * Set a String value first from the ListPreference, and if unable
- * from the SettingsManager.
- *
- * This is a wrapper that adds backwards compatibility to views that
- * rely on PreferenceGroups.
+ * Set a String value first from the ListPreference, and if unable from the
+ * SettingsManager. This is a wrapper that adds backwards compatibility to
+ * views that rely on PreferenceGroups.
*/
public void setValueFromPreference(ListPreference pref, String value) {
boolean set = pref.setValue(value);
/**
* Set a String value first from the ListPreference based on a
- * ListPreference index, and if unable use the ListPreference key
- * to set the value using the SettingsManager.
- *
- * This is a wrapper that adds backwards compatibility to views that
- * rely on PreferenceGroups.
+ * ListPreference index, and if unable use the ListPreference key to set the
+ * value using the SettingsManager. This is a wrapper that adds backwards
+ * compatibility to views that rely on PreferenceGroups.
*/
public void setValueIndexFromPreference(ListPreference pref, int index) {
boolean set = pref.setValueIndex(index);
}
}
}
+
+ /**
+ * Sets the settings for whether location recording should be enabled or
+ * not. Also makes sure to pass on the change to the location manager.
+ */
+ public void setLocation(boolean on, LocationManager locationManager) {
+ setBoolean(SettingsManager.SETTING_RECORD_LOCATION, on);
+ locationManager.recordLocation(on);
+ }
+
+ /**
+ * Reads the current location recording settings and passes it on to the
+ * given location manager.
+ */
+ public void syncLocationManager(LocationManager locationManager) {
+ boolean value = getBoolean(SettingsManager.SETTING_RECORD_LOCATION);
+ locationManager.recordLocation(value);
+ }
}