Loading core/java/android/app/SharedPreferencesImpl.java +48 −30 Original line number Original line Diff line number Diff line Loading @@ -34,8 +34,6 @@ import dalvik.system.BlockGuard; import libcore.io.IoUtils; import libcore.io.IoUtils; import com.google.android.collect.Maps; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException; import java.io.BufferedInputStream; import java.io.BufferedInputStream; Loading Loading @@ -139,7 +137,7 @@ final class SharedPreferencesImpl implements SharedPreferences { Log.w(TAG, "Attempt to read preferences file " + mFile + " without permission"); Log.w(TAG, "Attempt to read preferences file " + mFile + " without permission"); } } Map map = null; Map<String, Object> map = null; StructStat stat = null; StructStat stat = null; try { try { stat = Os.stat(mFile.getPath()); stat = Os.stat(mFile.getPath()); Loading @@ -148,7 +146,7 @@ final class SharedPreferencesImpl implements SharedPreferences { try { try { str = new BufferedInputStream( str = new BufferedInputStream( new FileInputStream(mFile), 16*1024); new FileInputStream(mFile), 16*1024); map = XmlUtils.readMapXml(str); map = (Map<String, Object>) XmlUtils.readMapXml(str); } catch (Exception e) { } catch (Exception e) { Log.w(TAG, "Cannot read " + mFile.getAbsolutePath(), e); Log.w(TAG, "Cannot read " + mFile.getAbsolutePath(), e); } finally { } finally { Loading Loading @@ -214,12 +212,14 @@ final class SharedPreferencesImpl implements SharedPreferences { } } } } @Override public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) { public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) { synchronized(mLock) { synchronized(mLock) { mListeners.put(listener, CONTENT); mListeners.put(listener, CONTENT); } } } } @Override public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) { public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) { synchronized(mLock) { synchronized(mLock) { mListeners.remove(listener); mListeners.remove(listener); Loading @@ -241,6 +241,7 @@ final class SharedPreferencesImpl implements SharedPreferences { } } } } @Override public Map<String, ?> getAll() { public Map<String, ?> getAll() { synchronized (mLock) { synchronized (mLock) { awaitLoadedLocked(); awaitLoadedLocked(); Loading @@ -249,6 +250,7 @@ final class SharedPreferencesImpl implements SharedPreferences { } } } } @Override @Nullable @Nullable public String getString(String key, @Nullable String defValue) { public String getString(String key, @Nullable String defValue) { synchronized (mLock) { synchronized (mLock) { Loading @@ -258,6 +260,7 @@ final class SharedPreferencesImpl implements SharedPreferences { } } } } @Override @Nullable @Nullable public Set<String> getStringSet(String key, @Nullable Set<String> defValues) { public Set<String> getStringSet(String key, @Nullable Set<String> defValues) { synchronized (mLock) { synchronized (mLock) { Loading @@ -267,6 +270,7 @@ final class SharedPreferencesImpl implements SharedPreferences { } } } } @Override public int getInt(String key, int defValue) { public int getInt(String key, int defValue) { synchronized (mLock) { synchronized (mLock) { awaitLoadedLocked(); awaitLoadedLocked(); Loading @@ -274,6 +278,7 @@ final class SharedPreferencesImpl implements SharedPreferences { return v != null ? v : defValue; return v != null ? v : defValue; } } } } @Override public long getLong(String key, long defValue) { public long getLong(String key, long defValue) { synchronized (mLock) { synchronized (mLock) { awaitLoadedLocked(); awaitLoadedLocked(); Loading @@ -281,6 +286,7 @@ final class SharedPreferencesImpl implements SharedPreferences { return v != null ? v : defValue; return v != null ? v : defValue; } } } } @Override public float getFloat(String key, float defValue) { public float getFloat(String key, float defValue) { synchronized (mLock) { synchronized (mLock) { awaitLoadedLocked(); awaitLoadedLocked(); Loading @@ -288,6 +294,7 @@ final class SharedPreferencesImpl implements SharedPreferences { return v != null ? v : defValue; return v != null ? v : defValue; } } } } @Override public boolean getBoolean(String key, boolean defValue) { public boolean getBoolean(String key, boolean defValue) { synchronized (mLock) { synchronized (mLock) { awaitLoadedLocked(); awaitLoadedLocked(); Loading @@ -296,6 +303,7 @@ final class SharedPreferencesImpl implements SharedPreferences { } } } } @Override public boolean contains(String key) { public boolean contains(String key) { synchronized (mLock) { synchronized (mLock) { awaitLoadedLocked(); awaitLoadedLocked(); Loading @@ -303,6 +311,7 @@ final class SharedPreferencesImpl implements SharedPreferences { } } } } @Override public Editor edit() { public Editor edit() { // TODO: remove the need to call awaitLoadedLocked() when // TODO: remove the need to call awaitLoadedLocked() when // requesting an editor. will require some work on the // requesting an editor. will require some work on the Loading Loading @@ -347,71 +356,81 @@ final class SharedPreferencesImpl implements SharedPreferences { } } public final class EditorImpl implements Editor { public final class EditorImpl implements Editor { private final Object mLock = new Object(); private final Object mEditorLock = new Object(); @GuardedBy("mLock") @GuardedBy("mEditorLock") private final Map<String, Object> mModified = Maps.newHashMap(); private final Map<String, Object> mModified = new HashMap<>(); @GuardedBy("mLock") @GuardedBy("mEditorLock") private boolean mClear = false; private boolean mClear = false; @Override public Editor putString(String key, @Nullable String value) { public Editor putString(String key, @Nullable String value) { synchronized (mLock) { synchronized (mEditorLock) { mModified.put(key, value); mModified.put(key, value); return this; return this; } } } } @Override public Editor putStringSet(String key, @Nullable Set<String> values) { public Editor putStringSet(String key, @Nullable Set<String> values) { synchronized (mLock) { synchronized (mEditorLock) { mModified.put(key, mModified.put(key, (values == null) ? null : new HashSet<String>(values)); (values == null) ? null : new HashSet<String>(values)); return this; return this; } } } } @Override public Editor putInt(String key, int value) { public Editor putInt(String key, int value) { synchronized (mLock) { synchronized (mEditorLock) { mModified.put(key, value); mModified.put(key, value); return this; return this; } } } } @Override public Editor putLong(String key, long value) { public Editor putLong(String key, long value) { synchronized (mLock) { synchronized (mEditorLock) { mModified.put(key, value); mModified.put(key, value); return this; return this; } } } } @Override public Editor putFloat(String key, float value) { public Editor putFloat(String key, float value) { synchronized (mLock) { synchronized (mEditorLock) { mModified.put(key, value); mModified.put(key, value); return this; return this; } } } } @Override public Editor putBoolean(String key, boolean value) { public Editor putBoolean(String key, boolean value) { synchronized (mLock) { synchronized (mEditorLock) { mModified.put(key, value); mModified.put(key, value); return this; return this; } } } } @Override public Editor remove(String key) { public Editor remove(String key) { synchronized (mLock) { synchronized (mEditorLock) { mModified.put(key, this); mModified.put(key, this); return this; return this; } } } } @Override public Editor clear() { public Editor clear() { synchronized (mLock) { synchronized (mEditorLock) { mClear = true; mClear = true; return this; return this; } } } } @Override public void apply() { public void apply() { final long startTime = System.currentTimeMillis(); final long startTime = System.currentTimeMillis(); final MemoryCommitResult mcr = commitToMemory(); final MemoryCommitResult mcr = commitToMemory(); final Runnable awaitCommit = new Runnable() { final Runnable awaitCommit = new Runnable() { @Override public void run() { public void run() { try { try { mcr.writtenToDiskLatch.await(); mcr.writtenToDiskLatch.await(); Loading @@ -429,6 +448,7 @@ final class SharedPreferencesImpl implements SharedPreferences { QueuedWork.addFinisher(awaitCommit); QueuedWork.addFinisher(awaitCommit); Runnable postWriteRunnable = new Runnable() { Runnable postWriteRunnable = new Runnable() { @Override public void run() { public void run() { awaitCommit.run(); awaitCommit.run(); QueuedWork.removeFinisher(awaitCommit); QueuedWork.removeFinisher(awaitCommit); Loading Loading @@ -471,13 +491,13 @@ final class SharedPreferencesImpl implements SharedPreferences { listeners = new HashSet<OnSharedPreferenceChangeListener>(mListeners.keySet()); listeners = new HashSet<OnSharedPreferenceChangeListener>(mListeners.keySet()); } } synchronized (mLock) { synchronized (mEditorLock) { boolean changesMade = false; boolean changesMade = false; if (mClear) { if (mClear) { if (!mMap.isEmpty()) { if (!mapToWriteToDisk.isEmpty()) { changesMade = true; changesMade = true; mMap.clear(); mapToWriteToDisk.clear(); } } mClear = false; mClear = false; } } Loading @@ -489,18 +509,18 @@ final class SharedPreferencesImpl implements SharedPreferences { // setting a value to "null" for a given key is specified to be // setting a value to "null" for a given key is specified to be // equivalent to calling remove on that key. // equivalent to calling remove on that key. if (v == this || v == null) { if (v == this || v == null) { if (!mMap.containsKey(k)) { if (!mapToWriteToDisk.containsKey(k)) { continue; continue; } } mMap.remove(k); mapToWriteToDisk.remove(k); } else { } else { if (mMap.containsKey(k)) { if (mapToWriteToDisk.containsKey(k)) { Object existingValue = mMap.get(k); Object existingValue = mapToWriteToDisk.get(k); if (existingValue != null && existingValue.equals(v)) { if (existingValue != null && existingValue.equals(v)) { continue; continue; } } } } mMap.put(k, v); mapToWriteToDisk.put(k, v); } } changesMade = true; changesMade = true; Loading @@ -522,6 +542,7 @@ final class SharedPreferencesImpl implements SharedPreferences { mapToWriteToDisk); mapToWriteToDisk); } } @Override public boolean commit() { public boolean commit() { long startTime = 0; long startTime = 0; Loading Loading @@ -564,11 +585,7 @@ final class SharedPreferencesImpl implements SharedPreferences { } } } else { } else { // Run this function on the main thread. // Run this function on the main thread. ActivityThread.sMainThreadHandler.post(new Runnable() { ActivityThread.sMainThreadHandler.post(() -> notifyListeners(mcr)); public void run() { notifyListeners(mcr); } }); } } } } } } Loading @@ -594,6 +611,7 @@ final class SharedPreferencesImpl implements SharedPreferences { final boolean isFromSyncCommit = (postWriteRunnable == null); final boolean isFromSyncCommit = (postWriteRunnable == null); final Runnable writeToDiskRunnable = new Runnable() { final Runnable writeToDiskRunnable = new Runnable() { @Override public void run() { public void run() { synchronized (mWritingToDiskLock) { synchronized (mWritingToDiskLock) { writeToFile(mcr, isFromSyncCommit); writeToFile(mcr, isFromSyncCommit); Loading Loading @@ -646,7 +664,7 @@ final class SharedPreferencesImpl implements SharedPreferences { return str; return str; } } // Note: must hold mWritingToDiskLock @GuardedBy("mWritingToDiskLock") private void writeToFile(MemoryCommitResult mcr, boolean isFromSyncCommit) { private void writeToFile(MemoryCommitResult mcr, boolean isFromSyncCommit) { long startTime = 0; long startTime = 0; long existsTime = 0; long existsTime = 0; Loading Loading
core/java/android/app/SharedPreferencesImpl.java +48 −30 Original line number Original line Diff line number Diff line Loading @@ -34,8 +34,6 @@ import dalvik.system.BlockGuard; import libcore.io.IoUtils; import libcore.io.IoUtils; import com.google.android.collect.Maps; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException; import java.io.BufferedInputStream; import java.io.BufferedInputStream; Loading Loading @@ -139,7 +137,7 @@ final class SharedPreferencesImpl implements SharedPreferences { Log.w(TAG, "Attempt to read preferences file " + mFile + " without permission"); Log.w(TAG, "Attempt to read preferences file " + mFile + " without permission"); } } Map map = null; Map<String, Object> map = null; StructStat stat = null; StructStat stat = null; try { try { stat = Os.stat(mFile.getPath()); stat = Os.stat(mFile.getPath()); Loading @@ -148,7 +146,7 @@ final class SharedPreferencesImpl implements SharedPreferences { try { try { str = new BufferedInputStream( str = new BufferedInputStream( new FileInputStream(mFile), 16*1024); new FileInputStream(mFile), 16*1024); map = XmlUtils.readMapXml(str); map = (Map<String, Object>) XmlUtils.readMapXml(str); } catch (Exception e) { } catch (Exception e) { Log.w(TAG, "Cannot read " + mFile.getAbsolutePath(), e); Log.w(TAG, "Cannot read " + mFile.getAbsolutePath(), e); } finally { } finally { Loading Loading @@ -214,12 +212,14 @@ final class SharedPreferencesImpl implements SharedPreferences { } } } } @Override public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) { public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) { synchronized(mLock) { synchronized(mLock) { mListeners.put(listener, CONTENT); mListeners.put(listener, CONTENT); } } } } @Override public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) { public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) { synchronized(mLock) { synchronized(mLock) { mListeners.remove(listener); mListeners.remove(listener); Loading @@ -241,6 +241,7 @@ final class SharedPreferencesImpl implements SharedPreferences { } } } } @Override public Map<String, ?> getAll() { public Map<String, ?> getAll() { synchronized (mLock) { synchronized (mLock) { awaitLoadedLocked(); awaitLoadedLocked(); Loading @@ -249,6 +250,7 @@ final class SharedPreferencesImpl implements SharedPreferences { } } } } @Override @Nullable @Nullable public String getString(String key, @Nullable String defValue) { public String getString(String key, @Nullable String defValue) { synchronized (mLock) { synchronized (mLock) { Loading @@ -258,6 +260,7 @@ final class SharedPreferencesImpl implements SharedPreferences { } } } } @Override @Nullable @Nullable public Set<String> getStringSet(String key, @Nullable Set<String> defValues) { public Set<String> getStringSet(String key, @Nullable Set<String> defValues) { synchronized (mLock) { synchronized (mLock) { Loading @@ -267,6 +270,7 @@ final class SharedPreferencesImpl implements SharedPreferences { } } } } @Override public int getInt(String key, int defValue) { public int getInt(String key, int defValue) { synchronized (mLock) { synchronized (mLock) { awaitLoadedLocked(); awaitLoadedLocked(); Loading @@ -274,6 +278,7 @@ final class SharedPreferencesImpl implements SharedPreferences { return v != null ? v : defValue; return v != null ? v : defValue; } } } } @Override public long getLong(String key, long defValue) { public long getLong(String key, long defValue) { synchronized (mLock) { synchronized (mLock) { awaitLoadedLocked(); awaitLoadedLocked(); Loading @@ -281,6 +286,7 @@ final class SharedPreferencesImpl implements SharedPreferences { return v != null ? v : defValue; return v != null ? v : defValue; } } } } @Override public float getFloat(String key, float defValue) { public float getFloat(String key, float defValue) { synchronized (mLock) { synchronized (mLock) { awaitLoadedLocked(); awaitLoadedLocked(); Loading @@ -288,6 +294,7 @@ final class SharedPreferencesImpl implements SharedPreferences { return v != null ? v : defValue; return v != null ? v : defValue; } } } } @Override public boolean getBoolean(String key, boolean defValue) { public boolean getBoolean(String key, boolean defValue) { synchronized (mLock) { synchronized (mLock) { awaitLoadedLocked(); awaitLoadedLocked(); Loading @@ -296,6 +303,7 @@ final class SharedPreferencesImpl implements SharedPreferences { } } } } @Override public boolean contains(String key) { public boolean contains(String key) { synchronized (mLock) { synchronized (mLock) { awaitLoadedLocked(); awaitLoadedLocked(); Loading @@ -303,6 +311,7 @@ final class SharedPreferencesImpl implements SharedPreferences { } } } } @Override public Editor edit() { public Editor edit() { // TODO: remove the need to call awaitLoadedLocked() when // TODO: remove the need to call awaitLoadedLocked() when // requesting an editor. will require some work on the // requesting an editor. will require some work on the Loading Loading @@ -347,71 +356,81 @@ final class SharedPreferencesImpl implements SharedPreferences { } } public final class EditorImpl implements Editor { public final class EditorImpl implements Editor { private final Object mLock = new Object(); private final Object mEditorLock = new Object(); @GuardedBy("mLock") @GuardedBy("mEditorLock") private final Map<String, Object> mModified = Maps.newHashMap(); private final Map<String, Object> mModified = new HashMap<>(); @GuardedBy("mLock") @GuardedBy("mEditorLock") private boolean mClear = false; private boolean mClear = false; @Override public Editor putString(String key, @Nullable String value) { public Editor putString(String key, @Nullable String value) { synchronized (mLock) { synchronized (mEditorLock) { mModified.put(key, value); mModified.put(key, value); return this; return this; } } } } @Override public Editor putStringSet(String key, @Nullable Set<String> values) { public Editor putStringSet(String key, @Nullable Set<String> values) { synchronized (mLock) { synchronized (mEditorLock) { mModified.put(key, mModified.put(key, (values == null) ? null : new HashSet<String>(values)); (values == null) ? null : new HashSet<String>(values)); return this; return this; } } } } @Override public Editor putInt(String key, int value) { public Editor putInt(String key, int value) { synchronized (mLock) { synchronized (mEditorLock) { mModified.put(key, value); mModified.put(key, value); return this; return this; } } } } @Override public Editor putLong(String key, long value) { public Editor putLong(String key, long value) { synchronized (mLock) { synchronized (mEditorLock) { mModified.put(key, value); mModified.put(key, value); return this; return this; } } } } @Override public Editor putFloat(String key, float value) { public Editor putFloat(String key, float value) { synchronized (mLock) { synchronized (mEditorLock) { mModified.put(key, value); mModified.put(key, value); return this; return this; } } } } @Override public Editor putBoolean(String key, boolean value) { public Editor putBoolean(String key, boolean value) { synchronized (mLock) { synchronized (mEditorLock) { mModified.put(key, value); mModified.put(key, value); return this; return this; } } } } @Override public Editor remove(String key) { public Editor remove(String key) { synchronized (mLock) { synchronized (mEditorLock) { mModified.put(key, this); mModified.put(key, this); return this; return this; } } } } @Override public Editor clear() { public Editor clear() { synchronized (mLock) { synchronized (mEditorLock) { mClear = true; mClear = true; return this; return this; } } } } @Override public void apply() { public void apply() { final long startTime = System.currentTimeMillis(); final long startTime = System.currentTimeMillis(); final MemoryCommitResult mcr = commitToMemory(); final MemoryCommitResult mcr = commitToMemory(); final Runnable awaitCommit = new Runnable() { final Runnable awaitCommit = new Runnable() { @Override public void run() { public void run() { try { try { mcr.writtenToDiskLatch.await(); mcr.writtenToDiskLatch.await(); Loading @@ -429,6 +448,7 @@ final class SharedPreferencesImpl implements SharedPreferences { QueuedWork.addFinisher(awaitCommit); QueuedWork.addFinisher(awaitCommit); Runnable postWriteRunnable = new Runnable() { Runnable postWriteRunnable = new Runnable() { @Override public void run() { public void run() { awaitCommit.run(); awaitCommit.run(); QueuedWork.removeFinisher(awaitCommit); QueuedWork.removeFinisher(awaitCommit); Loading Loading @@ -471,13 +491,13 @@ final class SharedPreferencesImpl implements SharedPreferences { listeners = new HashSet<OnSharedPreferenceChangeListener>(mListeners.keySet()); listeners = new HashSet<OnSharedPreferenceChangeListener>(mListeners.keySet()); } } synchronized (mLock) { synchronized (mEditorLock) { boolean changesMade = false; boolean changesMade = false; if (mClear) { if (mClear) { if (!mMap.isEmpty()) { if (!mapToWriteToDisk.isEmpty()) { changesMade = true; changesMade = true; mMap.clear(); mapToWriteToDisk.clear(); } } mClear = false; mClear = false; } } Loading @@ -489,18 +509,18 @@ final class SharedPreferencesImpl implements SharedPreferences { // setting a value to "null" for a given key is specified to be // setting a value to "null" for a given key is specified to be // equivalent to calling remove on that key. // equivalent to calling remove on that key. if (v == this || v == null) { if (v == this || v == null) { if (!mMap.containsKey(k)) { if (!mapToWriteToDisk.containsKey(k)) { continue; continue; } } mMap.remove(k); mapToWriteToDisk.remove(k); } else { } else { if (mMap.containsKey(k)) { if (mapToWriteToDisk.containsKey(k)) { Object existingValue = mMap.get(k); Object existingValue = mapToWriteToDisk.get(k); if (existingValue != null && existingValue.equals(v)) { if (existingValue != null && existingValue.equals(v)) { continue; continue; } } } } mMap.put(k, v); mapToWriteToDisk.put(k, v); } } changesMade = true; changesMade = true; Loading @@ -522,6 +542,7 @@ final class SharedPreferencesImpl implements SharedPreferences { mapToWriteToDisk); mapToWriteToDisk); } } @Override public boolean commit() { public boolean commit() { long startTime = 0; long startTime = 0; Loading Loading @@ -564,11 +585,7 @@ final class SharedPreferencesImpl implements SharedPreferences { } } } else { } else { // Run this function on the main thread. // Run this function on the main thread. ActivityThread.sMainThreadHandler.post(new Runnable() { ActivityThread.sMainThreadHandler.post(() -> notifyListeners(mcr)); public void run() { notifyListeners(mcr); } }); } } } } } } Loading @@ -594,6 +611,7 @@ final class SharedPreferencesImpl implements SharedPreferences { final boolean isFromSyncCommit = (postWriteRunnable == null); final boolean isFromSyncCommit = (postWriteRunnable == null); final Runnable writeToDiskRunnable = new Runnable() { final Runnable writeToDiskRunnable = new Runnable() { @Override public void run() { public void run() { synchronized (mWritingToDiskLock) { synchronized (mWritingToDiskLock) { writeToFile(mcr, isFromSyncCommit); writeToFile(mcr, isFromSyncCommit); Loading Loading @@ -646,7 +664,7 @@ final class SharedPreferencesImpl implements SharedPreferences { return str; return str; } } // Note: must hold mWritingToDiskLock @GuardedBy("mWritingToDiskLock") private void writeToFile(MemoryCommitResult mcr, boolean isFromSyncCommit) { private void writeToFile(MemoryCommitResult mcr, boolean isFromSyncCommit) { long startTime = 0; long startTime = 0; long existsTime = 0; long existsTime = 0; Loading