1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.camera; 18 19 import android.content.Context; 20 import android.content.SharedPreferences; 21 import android.content.SharedPreferences.Editor; 22 import android.content.SharedPreferences.OnSharedPreferenceChangeListener; 23 import android.preference.PreferenceManager; 24 25 import java.util.Map; 26 import java.util.Set; 27 import java.util.WeakHashMap; 28 import java.util.concurrent.CopyOnWriteArrayList; 29 30 public class ComboPreferences implements SharedPreferences, OnSharedPreferenceChangeListener { 31 private SharedPreferences mPrefGlobal; // global preferences 32 private SharedPreferences mPrefLocal; // per-camera preferences 33 private CopyOnWriteArrayList<OnSharedPreferenceChangeListener> mListeners; 34 private static WeakHashMap<Context, ComboPreferences> sMap = 35 new WeakHashMap<Context, ComboPreferences>(); 36 ComboPreferences(Context context)37 public ComboPreferences(Context context) { 38 mPrefGlobal = PreferenceManager.getDefaultSharedPreferences(context); 39 mPrefGlobal.registerOnSharedPreferenceChangeListener(this); 40 synchronized (sMap) { 41 sMap.put(context, this); 42 } 43 mListeners = new CopyOnWriteArrayList<OnSharedPreferenceChangeListener>(); 44 } 45 get(Context context)46 public static ComboPreferences get(Context context) { 47 synchronized (sMap) { 48 return sMap.get(context); 49 } 50 } 51 setLocalId(Context context, int cameraId)52 public void setLocalId(Context context, int cameraId) { 53 String prefName = context.getPackageName() + "_preferences_" + cameraId; 54 if (mPrefLocal != null) { 55 mPrefLocal.unregisterOnSharedPreferenceChangeListener(this); 56 } 57 mPrefLocal = context.getSharedPreferences( 58 prefName, Context.MODE_PRIVATE); 59 mPrefLocal.registerOnSharedPreferenceChangeListener(this); 60 } 61 getGlobal()62 public SharedPreferences getGlobal() { 63 return mPrefGlobal; 64 } 65 getLocal()66 public SharedPreferences getLocal() { 67 return mPrefLocal; 68 } 69 getAll()70 public Map<String, ?> getAll() { 71 throw new UnsupportedOperationException(); // Can be implemented if needed. 72 } 73 isGlobal(String key)74 private static boolean isGlobal(String key) { 75 return key.equals(CameraSettings.KEY_CAMERA_ID) 76 || key.equals(CameraSettings.KEY_RECORD_LOCATION); 77 } 78 getString(String key, String defValue)79 public String getString(String key, String defValue) { 80 if (isGlobal(key) || !mPrefLocal.contains(key)) { 81 return mPrefGlobal.getString(key, defValue); 82 } else { 83 return mPrefLocal.getString(key, defValue); 84 } 85 } 86 getInt(String key, int defValue)87 public int getInt(String key, int defValue) { 88 if (isGlobal(key) || !mPrefLocal.contains(key)) { 89 return mPrefGlobal.getInt(key, defValue); 90 } else { 91 return mPrefLocal.getInt(key, defValue); 92 } 93 } 94 getLong(String key, long defValue)95 public long getLong(String key, long defValue) { 96 if (isGlobal(key) || !mPrefLocal.contains(key)) { 97 return mPrefGlobal.getLong(key, defValue); 98 } else { 99 return mPrefLocal.getLong(key, defValue); 100 } 101 } 102 getFloat(String key, float defValue)103 public float getFloat(String key, float defValue) { 104 if (isGlobal(key) || !mPrefLocal.contains(key)) { 105 return mPrefGlobal.getFloat(key, defValue); 106 } else { 107 return mPrefLocal.getFloat(key, defValue); 108 } 109 } 110 getBoolean(String key, boolean defValue)111 public boolean getBoolean(String key, boolean defValue) { 112 if (isGlobal(key) || !mPrefLocal.contains(key)) { 113 return mPrefGlobal.getBoolean(key, defValue); 114 } else { 115 return mPrefLocal.getBoolean(key, defValue); 116 } 117 } 118 119 // This method is not used. getStringSet(String key, Set<String> defValues)120 public Set<String> getStringSet(String key, Set<String> defValues) { 121 throw new UnsupportedOperationException(); 122 } 123 contains(String key)124 public boolean contains(String key) { 125 if (mPrefLocal.contains(key)) return true; 126 if (mPrefGlobal.contains(key)) return true; 127 return false; 128 } 129 130 private class MyEditor implements Editor { 131 private Editor mEditorGlobal; 132 private Editor mEditorLocal; 133 MyEditor()134 MyEditor() { 135 mEditorGlobal = mPrefGlobal.edit(); 136 mEditorLocal = mPrefLocal.edit(); 137 } 138 commit()139 public boolean commit() { 140 boolean result1 = mEditorGlobal.commit(); 141 boolean result2 = mEditorLocal.commit(); 142 return result1 && result2; 143 } 144 apply()145 public void apply() { 146 mEditorGlobal.apply(); 147 mEditorLocal.apply(); 148 } 149 150 // Note: clear() and remove() affects both local and global preferences. clear()151 public Editor clear() { 152 mEditorGlobal.clear(); 153 mEditorLocal.clear(); 154 return this; 155 } 156 remove(String key)157 public Editor remove(String key) { 158 mEditorGlobal.remove(key); 159 mEditorLocal.remove(key); 160 return this; 161 } 162 putString(String key, String value)163 public Editor putString(String key, String value) { 164 if (isGlobal(key)) { 165 mEditorGlobal.putString(key, value); 166 } else { 167 mEditorLocal.putString(key, value); 168 } 169 return this; 170 } 171 putInt(String key, int value)172 public Editor putInt(String key, int value) { 173 if (isGlobal(key)) { 174 mEditorGlobal.putInt(key, value); 175 } else { 176 mEditorLocal.putInt(key, value); 177 } 178 return this; 179 } 180 putLong(String key, long value)181 public Editor putLong(String key, long value) { 182 if (isGlobal(key)) { 183 mEditorGlobal.putLong(key, value); 184 } else { 185 mEditorLocal.putLong(key, value); 186 } 187 return this; 188 } 189 putFloat(String key, float value)190 public Editor putFloat(String key, float value) { 191 if (isGlobal(key)) { 192 mEditorGlobal.putFloat(key, value); 193 } else { 194 mEditorLocal.putFloat(key, value); 195 } 196 return this; 197 } 198 putBoolean(String key, boolean value)199 public Editor putBoolean(String key, boolean value) { 200 if (isGlobal(key)) { 201 mEditorGlobal.putBoolean(key, value); 202 } else { 203 mEditorLocal.putBoolean(key, value); 204 } 205 return this; 206 } 207 208 // This method is not used. putStringSet(String key, Set<String> values)209 public Editor putStringSet(String key, Set<String> values) { 210 throw new UnsupportedOperationException(); 211 } 212 } 213 214 // Note the remove() and clear() of the returned Editor may not work as 215 // expected because it doesn't touch the global preferences at all. edit()216 public Editor edit() { 217 return new MyEditor(); 218 } 219 registerOnSharedPreferenceChangeListener( OnSharedPreferenceChangeListener listener)220 public void registerOnSharedPreferenceChangeListener( 221 OnSharedPreferenceChangeListener listener) { 222 mListeners.add(listener); 223 } 224 unregisterOnSharedPreferenceChangeListener( OnSharedPreferenceChangeListener listener)225 public void unregisterOnSharedPreferenceChangeListener( 226 OnSharedPreferenceChangeListener listener) { 227 mListeners.remove(listener); 228 } 229 onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)230 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, 231 String key) { 232 for (OnSharedPreferenceChangeListener listener : mListeners) { 233 listener.onSharedPreferenceChanged(this, key); 234 } 235 } 236 } 237