1/*
2 * Copyright (C) 2014 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
17package com.android.camera.settings;
18
19import android.content.SharedPreferences;
20
21import com.android.camera.debug.Log;
22
23/**
24 * The SettingsUpgrader class can be used to define an upgrade flow that
25 * executes upgrade logic to a target version when a version number has changed.
26 */
27public abstract class SettingsUpgrader {
28    private static final Log.Tag TAG = new Log.Tag("SettingsUpgrader");
29
30    private final String mVersionKey;
31    private final int mTargetVersion;
32
33    // These values were in use by the original preferences management, before
34    // SettingsManager, to represent string-based booleans via typed string
35    // resource arrays. We no longer utilize such value arrays, and reference
36    // these constants only within SettingsUpgraders to convert to new string-
37    // based booleans.
38    protected static final String OLD_SETTINGS_VALUE_NONE = "none";
39    protected static final String OLD_SETTINGS_VALUE_ON = "on";
40    protected static final String OLD_SETTINGS_VALUE_OFF = "off";
41
42    public SettingsUpgrader(String versionKey, int targetVersion) {
43        mVersionKey = versionKey;
44        mTargetVersion = targetVersion;
45    }
46
47    /**
48     * Execute an upgrade callback if an upgrade version has changed. Third
49     * party modules also use this to upgrade settings local to them.
50     */
51    public void upgrade(SettingsManager settingsManager) {
52        int lastVersion = getLastVersion(settingsManager);
53        if (lastVersion != mTargetVersion) {
54            upgrade(settingsManager, lastVersion, mTargetVersion);
55        }
56        settingsManager.set(SettingsManager.SCOPE_GLOBAL, mVersionKey, mTargetVersion);
57    }
58
59    /**
60     * Perform upgrades to bring any settings up to date to the version
61     * specified in currentVersion, where the settings were last upgraded to
62     * lastVersion. Typically an Upgrader will check whether lastVersion is less
63     * than some known version for a particular setting, and apply upgrade logic
64     * if lastVersion is less than that known version.
65     */
66    protected abstract void upgrade(SettingsManager settingsManager, int lastVersion,
67            int targetVersion);
68
69    /**
70     * Retrieve the last persisted version for the particular upgrader.
71     * Typically will be stored in SCOPE_GLOBAL in SettingsManager, but an
72     * Upgrader may need to perform an upgrade analysis on the version
73     * persistence itself and should do so here.
74     *
75     * @throws a {@link ClassCastException} if the value for Version is not a
76     *             String
77     */
78    protected int getLastVersion(SettingsManager settingsManager) {
79        return settingsManager.getInteger(SettingsManager.SCOPE_GLOBAL, mVersionKey);
80    }
81
82    /**
83     * A helper function that is used to remove a setting stored as a boolean,
84     * and return the value that was removed.
85     * <p>
86     * This is used in the upgrade path to change all underlying
87     * SharedPreferences values to Strings. It can be used by third party
88     * modules to upgrade their boolean settings to Strings.
89     */
90    protected boolean removeBoolean(SharedPreferences oldPreferencesLocation, String key) {
91        boolean value = oldPreferencesLocation.getBoolean(key, false);
92        oldPreferencesLocation.edit().remove(key).apply();
93        return value;
94    }
95
96    /**
97     * A helper function that is used to remove a setting stored as an Integer,
98     * and return the value that was removed.
99     * <p>
100     * This is used in the upgrade path to change all underlying
101     * SharedPreferences values to Strings. It can be used by third party
102     * modules to upgrade their Integer settings to Strings.
103     */
104    protected int removeInteger(SharedPreferences oldPreferencesLocation, String key) {
105        int value = oldPreferencesLocation.getInt(key, 0);
106        oldPreferencesLocation.edit().remove(key).apply();
107        return value;
108    }
109
110    /**
111     * A helper function that is used to remove a setting stored as a String,
112     * and return the value that was removed.
113     * <p>
114     * This is used in the upgrade path to change all underlying
115     * SharedPreferences values to Strings. It can be used by third party
116     * modules to upgrade their boolean settings to Strings.
117     */
118    protected String removeString(SharedPreferences oldPreferencesLocation, String key) {
119        String value = oldPreferencesLocation.getString(key, null);
120        oldPreferencesLocation.edit().remove(key).apply();
121        return value;
122    }
123
124}
125