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.OnSharedPreferenceChangeListener; 22 import android.preference.PreferenceManager; 23 24 import java.util.Map; 25 import java.util.Set; 26 import java.util.WeakHashMap; 27 import java.util.concurrent.CopyOnWriteArrayList; 28 29 public class ComboPreferences implements SharedPreferences, OnSharedPreferenceChangeListener { 30 private SharedPreferences mPrefGlobal; // global preferences 31 private SharedPreferences mPrefLocal; // per-camera preferences 32 private CopyOnWriteArrayList<OnSharedPreferenceChangeListener> mListeners; 33 private static WeakHashMap<Context, ComboPreferences> sMap = 34 new WeakHashMap<Context, ComboPreferences>(); 35 ComboPreferences(Context context)36 public ComboPreferences(Context context) { 37 mPrefGlobal = PreferenceManager.getDefaultSharedPreferences(context); 38 mPrefGlobal.registerOnSharedPreferenceChangeListener(this); 39 synchronized (sMap) { 40 sMap.put(context, this); 41 } 42 mListeners = new CopyOnWriteArrayList<OnSharedPreferenceChangeListener>(); 43 } 44 get(Context context)45 public static ComboPreferences get(Context context) { 46 synchronized (sMap) { 47 return sMap.get(context); 48 } 49 } 50 51 // Sets the camera id and reads its preferences. Each camera has its own 52 // preferences. setLocalId(Context context, int cameraId)53 public void setLocalId(Context context, int cameraId) { 54 String prefName = context.getPackageName() + "_preferences_" + cameraId; 55 if (mPrefLocal != null) { 56 mPrefLocal.unregisterOnSharedPreferenceChangeListener(this); 57 } 58 mPrefLocal = context.getSharedPreferences( 59 prefName, Context.MODE_PRIVATE); 60 mPrefLocal.registerOnSharedPreferenceChangeListener(this); 61 } 62 getGlobal()63 public SharedPreferences getGlobal() { 64 return mPrefGlobal; 65 } 66 getLocal()67 public SharedPreferences getLocal() { 68 return mPrefLocal; 69 } 70 71 @Override getAll()72 public Map<String, ?> getAll() { 73 throw new UnsupportedOperationException(); // Can be implemented if needed. 74 } 75 isGlobal(String key)76 private static boolean isGlobal(String key) { 77 return key.equals(CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL) 78 || key.equals(CameraSettings.KEY_CAMERA_ID) 79 || key.equals(CameraSettings.KEY_RECORD_LOCATION) 80 || key.equals(CameraSettings.KEY_CAMERA_FIRST_USE_HINT_SHOWN) 81 || key.equals(CameraSettings.KEY_VIDEO_FIRST_USE_HINT_SHOWN) 82 || key.equals(CameraSettings.KEY_VIDEO_EFFECT); 83 } 84 85 @Override getString(String key, String defValue)86 public String getString(String key, String defValue) { 87 if (isGlobal(key) || !mPrefLocal.contains(key)) { 88 return mPrefGlobal.getString(key, defValue); 89 } else { 90 return mPrefLocal.getString(key, defValue); 91 } 92 } 93 94 @Override getInt(String key, int defValue)95 public int getInt(String key, int defValue) { 96 if (isGlobal(key) || !mPrefLocal.contains(key)) { 97 return mPrefGlobal.getInt(key, defValue); 98 } else { 99 return mPrefLocal.getInt(key, defValue); 100 } 101 } 102 103 @Override getLong(String key, long defValue)104 public long getLong(String key, long defValue) { 105 if (isGlobal(key) || !mPrefLocal.contains(key)) { 106 return mPrefGlobal.getLong(key, defValue); 107 } else { 108 return mPrefLocal.getLong(key, defValue); 109 } 110 } 111 112 @Override getFloat(String key, float defValue)113 public float getFloat(String key, float defValue) { 114 if (isGlobal(key) || !mPrefLocal.contains(key)) { 115 return mPrefGlobal.getFloat(key, defValue); 116 } else { 117 return mPrefLocal.getFloat(key, defValue); 118 } 119 } 120 121 @Override getBoolean(String key, boolean defValue)122 public boolean getBoolean(String key, boolean defValue) { 123 if (isGlobal(key) || !mPrefLocal.contains(key)) { 124 return mPrefGlobal.getBoolean(key, defValue); 125 } else { 126 return mPrefLocal.getBoolean(key, defValue); 127 } 128 } 129 130 // This method is not used. 131 @Override getStringSet(String key, Set<String> defValues)132 public Set<String> getStringSet(String key, Set<String> defValues) { 133 throw new UnsupportedOperationException(); 134 } 135 136 @Override contains(String key)137 public boolean contains(String key) { 138 if (mPrefLocal.contains(key)) return true; 139 if (mPrefGlobal.contains(key)) return true; 140 return false; 141 } 142 143 private class MyEditor implements Editor { 144 private Editor mEditorGlobal; 145 private Editor mEditorLocal; 146 MyEditor()147 MyEditor() { 148 mEditorGlobal = mPrefGlobal.edit(); 149 mEditorLocal = mPrefLocal.edit(); 150 } 151 152 @Override commit()153 public boolean commit() { 154 boolean result1 = mEditorGlobal.commit(); 155 boolean result2 = mEditorLocal.commit(); 156 return result1 && result2; 157 } 158 159 @Override apply()160 public void apply() { 161 mEditorGlobal.apply(); 162 mEditorLocal.apply(); 163 } 164 165 // Note: clear() and remove() affects both local and global preferences. 166 @Override clear()167 public Editor clear() { 168 mEditorGlobal.clear(); 169 mEditorLocal.clear(); 170 return this; 171 } 172 173 @Override remove(String key)174 public Editor remove(String key) { 175 mEditorGlobal.remove(key); 176 mEditorLocal.remove(key); 177 return this; 178 } 179 180 @Override putString(String key, String value)181 public Editor putString(String key, String value) { 182 if (isGlobal(key)) { 183 mEditorGlobal.putString(key, value); 184 } else { 185 mEditorLocal.putString(key, value); 186 } 187 return this; 188 } 189 190 @Override putInt(String key, int value)191 public Editor putInt(String key, int value) { 192 if (isGlobal(key)) { 193 mEditorGlobal.putInt(key, value); 194 } else { 195 mEditorLocal.putInt(key, value); 196 } 197 return this; 198 } 199 200 @Override putLong(String key, long value)201 public Editor putLong(String key, long value) { 202 if (isGlobal(key)) { 203 mEditorGlobal.putLong(key, value); 204 } else { 205 mEditorLocal.putLong(key, value); 206 } 207 return this; 208 } 209 210 @Override putFloat(String key, float value)211 public Editor putFloat(String key, float value) { 212 if (isGlobal(key)) { 213 mEditorGlobal.putFloat(key, value); 214 } else { 215 mEditorLocal.putFloat(key, value); 216 } 217 return this; 218 } 219 220 @Override putBoolean(String key, boolean value)221 public Editor putBoolean(String key, boolean value) { 222 if (isGlobal(key)) { 223 mEditorGlobal.putBoolean(key, value); 224 } else { 225 mEditorLocal.putBoolean(key, value); 226 } 227 return this; 228 } 229 230 // This method is not used. 231 @Override putStringSet(String key, Set<String> values)232 public Editor putStringSet(String key, Set<String> values) { 233 throw new UnsupportedOperationException(); 234 } 235 } 236 237 // Note the remove() and clear() of the returned Editor may not work as 238 // expected because it doesn't touch the global preferences at all. 239 @Override edit()240 public Editor edit() { 241 return new MyEditor(); 242 } 243 244 @Override registerOnSharedPreferenceChangeListener( OnSharedPreferenceChangeListener listener)245 public void registerOnSharedPreferenceChangeListener( 246 OnSharedPreferenceChangeListener listener) { 247 mListeners.add(listener); 248 } 249 250 @Override unregisterOnSharedPreferenceChangeListener( OnSharedPreferenceChangeListener listener)251 public void unregisterOnSharedPreferenceChangeListener( 252 OnSharedPreferenceChangeListener listener) { 253 mListeners.remove(listener); 254 } 255 256 @Override onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)257 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, 258 String key) { 259 for (OnSharedPreferenceChangeListener listener : mListeners) { 260 listener.onSharedPreferenceChanged(this, key); 261 } 262 } 263 } 264