11ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang/* 21ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang * Copyright (C) 2010 The Android Open Source Project 31ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang * 41ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang * Licensed under the Apache License, Version 2.0 (the "License"); 51ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang * you may not use this file except in compliance with the License. 61ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang * You may obtain a copy of the License at 71ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang * 81ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang * http://www.apache.org/licenses/LICENSE-2.0 91ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang * 101ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang * Unless required by applicable law or agreed to in writing, software 111ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang * distributed under the License is distributed on an "AS IS" BASIS, 121ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang * See the License for the specific language governing permissions and 141ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang * limitations under the License. 151ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang */ 161ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 171ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Changpackage com.android.camera; 181ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 19535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kongimport android.app.backup.BackupManager; 201ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Changimport android.content.Context; 211ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Changimport android.content.SharedPreferences; 221ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Changimport android.content.SharedPreferences.OnSharedPreferenceChangeListener; 23a4d02612a128007d0d25cc42143018195e7df4dcAngus Kongimport android.preference.PreferenceManager; 241ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 251ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Changimport java.util.Map; 26d26dfad8d2f864d362230cc5357c9aa38f72138cChih-Chung Changimport java.util.Set; 271ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Changimport java.util.WeakHashMap; 281ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Changimport java.util.concurrent.CopyOnWriteArrayList; 291ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 30a4d02612a128007d0d25cc42143018195e7df4dcAngus Kongpublic class ComboPreferences implements 31a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong SharedPreferences, 32a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong OnSharedPreferenceChangeListener { 331ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang private SharedPreferences mPrefGlobal; // global preferences 341ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang private SharedPreferences mPrefLocal; // per-camera preferences 35535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong private BackupManager mBackupManager; 361ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang private CopyOnWriteArrayList<OnSharedPreferenceChangeListener> mListeners; 371ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang private static WeakHashMap<Context, ComboPreferences> sMap = 381ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang new WeakHashMap<Context, ComboPreferences>(); 391ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 401ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public ComboPreferences(Context context) { 41535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong mPrefGlobal = context.getSharedPreferences( 42535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong getGlobalSharedPreferencesName(context), Context.MODE_PRIVATE); 431ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mPrefGlobal.registerOnSharedPreferenceChangeListener(this); 44a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong 451ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang synchronized (sMap) { 461ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang sMap.put(context, this); 471ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 48535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong mBackupManager = new BackupManager(context); 491ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mListeners = new CopyOnWriteArrayList<OnSharedPreferenceChangeListener>(); 50a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong 51a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong // The global preferences was previously stored in the default 52a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong // shared preferences file. They should be stored in the camera-specific 53a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong // shared preferences file so we can backup them solely. 54a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong SharedPreferences oldprefs = 55a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong PreferenceManager.getDefaultSharedPreferences(context); 56a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong if (!mPrefGlobal.contains(CameraSettings.KEY_VERSION) 57a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong && oldprefs.contains(CameraSettings.KEY_VERSION)) { 58a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong moveGlobalPrefsFrom(oldprefs); 59a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong } 601ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 611ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 621ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public static ComboPreferences get(Context context) { 631ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang synchronized (sMap) { 641ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return sMap.get(context); 651ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 661ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 671ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 68535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong private static String getLocalSharedPreferencesName( 69535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong Context context, int cameraId) { 70535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong return context.getPackageName() + "_preferences_" + cameraId; 71535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong } 72535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong 73535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong private static String getGlobalSharedPreferencesName(Context context) { 74a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong return context.getPackageName() + "_preferences_camera"; 75a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong } 76a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong 77a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong private void movePrefFrom( 78a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong Map<String, ?> m, String key, SharedPreferences src) { 79a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong if (m.containsKey(key)) { 80a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong Object v = m.get(key); 81a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong if (v instanceof String) { 82a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong mPrefGlobal.edit().putString(key, (String) v).apply(); 83a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong } else if (v instanceof Integer) { 84a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong mPrefGlobal.edit().putInt(key, (Integer) v).apply(); 85a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong } else if (v instanceof Long) { 86a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong mPrefGlobal.edit().putLong(key, (Long) v).apply(); 87a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong } else if (v instanceof Float) { 88a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong mPrefGlobal.edit().putFloat(key, (Float) v).apply(); 89a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong } else if (v instanceof Boolean) { 90a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong mPrefGlobal.edit().putBoolean(key, (Boolean) v).apply(); 91a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong } 92a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong src.edit().remove(key).apply(); 93a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong } 94a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong } 95a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong 96a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong private void moveGlobalPrefsFrom(SharedPreferences src) { 97a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong Map<String, ?> prefMap = src.getAll(); 98a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong movePrefFrom(prefMap, CameraSettings.KEY_VERSION, src); 99a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong movePrefFrom(prefMap, CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL, src); 100a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong movePrefFrom(prefMap, CameraSettings.KEY_CAMERA_ID, src); 101a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong movePrefFrom(prefMap, CameraSettings.KEY_RECORD_LOCATION, src); 102a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong movePrefFrom(prefMap, CameraSettings.KEY_CAMERA_FIRST_USE_HINT_SHOWN, src); 103a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong movePrefFrom(prefMap, CameraSettings.KEY_VIDEO_FIRST_USE_HINT_SHOWN, src); 104a4d02612a128007d0d25cc42143018195e7df4dcAngus Kong movePrefFrom(prefMap, CameraSettings.KEY_VIDEO_EFFECT, src); 105535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong } 106535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong 107535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong public static String[] getSharedPreferencesNames(Context context) { 108535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong int numOfCameras = CameraHolder.instance().getNumberOfCameras(); 109535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong String prefNames[] = new String[numOfCameras + 1]; 110535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong prefNames[0] = getGlobalSharedPreferencesName(context); 111535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong for (int i = 0; i < numOfCameras; i++) { 112535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong prefNames[i + 1] = getLocalSharedPreferencesName(context, i); 113535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong } 114535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong return prefNames; 115535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong } 116535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong 1174a70e66b58207703f8a705548efcd5353106e452Wu-cheng Li // Sets the camera id and reads its preferences. Each camera has its own 1184a70e66b58207703f8a705548efcd5353106e452Wu-cheng Li // preferences. 1197add00693c1ec910bc8700fe046ee18cbe4e1148Wu-cheng Li public void setLocalId(Context context, int cameraId) { 120535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong String prefName = getLocalSharedPreferencesName(context, cameraId); 1211ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang if (mPrefLocal != null) { 1221ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mPrefLocal.unregisterOnSharedPreferenceChangeListener(this); 1231ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 1241ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mPrefLocal = context.getSharedPreferences( 1251ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang prefName, Context.MODE_PRIVATE); 1261ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mPrefLocal.registerOnSharedPreferenceChangeListener(this); 1271ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 1281ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 1291ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public SharedPreferences getGlobal() { 1301ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return mPrefGlobal; 1311ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 1321ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 1331ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public SharedPreferences getLocal() { 1341ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return mPrefLocal; 1351ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 1361ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 137913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 1381ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public Map<String, ?> getAll() { 1391ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang throw new UnsupportedOperationException(); // Can be implemented if needed. 1401ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 1411ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 1421ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang private static boolean isGlobal(String key) { 14313d91fc0fa66ef056397be20f013b51992e109deWu-cheng Li return key.equals(CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL) 14413d91fc0fa66ef056397be20f013b51992e109deWu-cheng Li || key.equals(CameraSettings.KEY_CAMERA_ID) 14598d615769af2b08bcddf02ee1b11f5288ec5cf92Wu-cheng Li || key.equals(CameraSettings.KEY_RECORD_LOCATION) 146d6e5029b2df45210834334f7c2e99dfc85e962f0Chih-yu Huang || key.equals(CameraSettings.KEY_CAMERA_FIRST_USE_HINT_SHOWN) 147d6e5029b2df45210834334f7c2e99dfc85e962f0Chih-yu Huang || key.equals(CameraSettings.KEY_VIDEO_FIRST_USE_HINT_SHOWN) 1488e3b1df4fcc770965d0796ac2046ef9e265d4bdbDoris Liu || key.equals(CameraSettings.KEY_VIDEO_EFFECT) 1498e3b1df4fcc770965d0796ac2046ef9e265d4bdbDoris Liu || key.equals(CameraSettings.KEY_TIMER) 1508e3b1df4fcc770965d0796ac2046ef9e265d4bdbDoris Liu || key.equals(CameraSettings.KEY_TIMER_SOUND_EFFECTS); 1511ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 1521ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 153913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 1541ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public String getString(String key, String defValue) { 1551ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang if (isGlobal(key) || !mPrefLocal.contains(key)) { 1561ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return mPrefGlobal.getString(key, defValue); 1571ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } else { 1581ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return mPrefLocal.getString(key, defValue); 1591ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 1601ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 1611ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 162913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 1631ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public int getInt(String key, int defValue) { 1641ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang if (isGlobal(key) || !mPrefLocal.contains(key)) { 1651ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return mPrefGlobal.getInt(key, defValue); 1661ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } else { 1671ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return mPrefLocal.getInt(key, defValue); 1681ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 1691ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 1701ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 171913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 1721ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public long getLong(String key, long defValue) { 1731ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang if (isGlobal(key) || !mPrefLocal.contains(key)) { 1741ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return mPrefGlobal.getLong(key, defValue); 1751ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } else { 1761ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return mPrefLocal.getLong(key, defValue); 1771ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 1781ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 1791ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 180913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 1811ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public float getFloat(String key, float defValue) { 1821ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang if (isGlobal(key) || !mPrefLocal.contains(key)) { 1831ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return mPrefGlobal.getFloat(key, defValue); 1841ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } else { 1851ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return mPrefLocal.getFloat(key, defValue); 1861ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 1871ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 1881ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 189913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 1901ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public boolean getBoolean(String key, boolean defValue) { 1911ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang if (isGlobal(key) || !mPrefLocal.contains(key)) { 1921ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return mPrefGlobal.getBoolean(key, defValue); 1931ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } else { 1941ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return mPrefLocal.getBoolean(key, defValue); 1951ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 1961ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 1971ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 198b13acb76f5b86f46dfe07830648ec14524e83d39Chih-Chung Chang // This method is not used. 199913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 200450254a7c9b30e4f36429b46895c944458f59962Chih-Chung Chang public Set<String> getStringSet(String key, Set<String> defValues) { 201d26dfad8d2f864d362230cc5357c9aa38f72138cChih-Chung Chang throw new UnsupportedOperationException(); 202d26dfad8d2f864d362230cc5357c9aa38f72138cChih-Chung Chang } 203d26dfad8d2f864d362230cc5357c9aa38f72138cChih-Chung Chang 204913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 2051ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public boolean contains(String key) { 2061ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang if (mPrefLocal.contains(key)) return true; 2071ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang if (mPrefGlobal.contains(key)) return true; 2081ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return false; 2091ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 2101ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 2111ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang private class MyEditor implements Editor { 2121ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang private Editor mEditorGlobal; 2131ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang private Editor mEditorLocal; 2141ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 2151ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang MyEditor() { 2161ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mEditorGlobal = mPrefGlobal.edit(); 2171ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mEditorLocal = mPrefLocal.edit(); 2181ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 2191ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 220913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 2211ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public boolean commit() { 2221ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang boolean result1 = mEditorGlobal.commit(); 2231ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang boolean result2 = mEditorLocal.commit(); 2241ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return result1 && result2; 2251ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 2261ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 227913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 2287bf93fe43dccbe31cfa6fe859ae7f9f946d8e923Brad Fitzpatrick public void apply() { 2294e5aa452a0e2438f9af1f08c56b1a7b414e561d9Brad Fitzpatrick mEditorGlobal.apply(); 2304e5aa452a0e2438f9af1f08c56b1a7b414e561d9Brad Fitzpatrick mEditorLocal.apply(); 23120ddc2054b04d40b4e15e0831d3df02f30b600e8Brad Fitzpatrick } 23220ddc2054b04d40b4e15e0831d3df02f30b600e8Brad Fitzpatrick 2331ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang // Note: clear() and remove() affects both local and global preferences. 234913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 2351ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public Editor clear() { 2361ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mEditorGlobal.clear(); 2371ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mEditorLocal.clear(); 2381ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return this; 2391ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 2401ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 241913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 2421ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public Editor remove(String key) { 2431ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mEditorGlobal.remove(key); 2441ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mEditorLocal.remove(key); 2451ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return this; 2461ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 2471ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 248913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 2491ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public Editor putString(String key, String value) { 2501ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang if (isGlobal(key)) { 2511ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mEditorGlobal.putString(key, value); 2521ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } else { 2531ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mEditorLocal.putString(key, value); 2541ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 2551ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return this; 2561ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 2571ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 258913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 2591ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public Editor putInt(String key, int value) { 2601ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang if (isGlobal(key)) { 2611ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mEditorGlobal.putInt(key, value); 2621ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } else { 2631ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mEditorLocal.putInt(key, value); 2641ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 2651ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return this; 2661ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 2671ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 268913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 2691ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public Editor putLong(String key, long value) { 2701ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang if (isGlobal(key)) { 2711ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mEditorGlobal.putLong(key, value); 2721ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } else { 2731ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mEditorLocal.putLong(key, value); 2741ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 2751ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return this; 2761ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 2771ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 278913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 2791ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public Editor putFloat(String key, float value) { 2801ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang if (isGlobal(key)) { 2811ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mEditorGlobal.putFloat(key, value); 2821ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } else { 2831ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mEditorLocal.putFloat(key, value); 2841ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 2851ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return this; 2861ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 2871ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 288913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 2891ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public Editor putBoolean(String key, boolean value) { 2901ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang if (isGlobal(key)) { 2911ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mEditorGlobal.putBoolean(key, value); 2921ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } else { 2931ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mEditorLocal.putBoolean(key, value); 2941ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 2951ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return this; 2961ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 297b13acb76f5b86f46dfe07830648ec14524e83d39Chih-Chung Chang 298b13acb76f5b86f46dfe07830648ec14524e83d39Chih-Chung Chang // This method is not used. 299913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 300b13acb76f5b86f46dfe07830648ec14524e83d39Chih-Chung Chang public Editor putStringSet(String key, Set<String> values) { 301b13acb76f5b86f46dfe07830648ec14524e83d39Chih-Chung Chang throw new UnsupportedOperationException(); 302b13acb76f5b86f46dfe07830648ec14524e83d39Chih-Chung Chang } 3031ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 3041ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 3051ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang // Note the remove() and clear() of the returned Editor may not work as 3061ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang // expected because it doesn't touch the global preferences at all. 307913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 3081ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public Editor edit() { 3091ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang return new MyEditor(); 3101ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 3111ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 312913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 3131ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public void registerOnSharedPreferenceChangeListener( 3141ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang OnSharedPreferenceChangeListener listener) { 3151ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mListeners.add(listener); 3161ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 3171ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 318913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 3191ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public void unregisterOnSharedPreferenceChangeListener( 3201ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang OnSharedPreferenceChangeListener listener) { 3211ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang mListeners.remove(listener); 3221ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 3231ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang 324913f3784d368a5e11fee5d5db2c355ef832685daWu-cheng Li @Override 3251ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, 3261ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang String key) { 3271ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang for (OnSharedPreferenceChangeListener listener : mListeners) { 3281ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang listener.onSharedPreferenceChanged(this, key); 3291ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 330535a8310aeb173bb3c0e29ff10c0ee036ba29d77Angus Kong mBackupManager.dataChanged(); 3311ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang } 3321ef634d277d550ed55b5b7089dfd56ed71815bd6Chih-Chung Chang} 333