Loading services/people/java/com/android/server/people/data/AbstractProtoDiskReadWriter.java +4 −24 Original line number Original line Diff line number Diff line Loading @@ -85,8 +85,10 @@ abstract class AbstractProtoDiskReadWriter<T> { } } @WorkerThread @WorkerThread synchronized void delete(@NonNull String fileName) { void delete(@NonNull String fileName) { synchronized (this) { mScheduledFileDataMap.remove(fileName); mScheduledFileDataMap.remove(fileName); } final File file = getFile(fileName); final File file = getFile(fileName); if (!file.exists()) { if (!file.exists()) { return; return; Loading Loading @@ -135,28 +137,6 @@ abstract class AbstractProtoDiskReadWriter<T> { return parseFile(files[0]); return parseFile(files[0]); } } /** * Reads all files in directory and returns a map with file names as keys and parsed file * contents as values. */ @WorkerThread @Nullable Map<String, T> readAll() { File[] files = mRootDir.listFiles(File::isFile); if (files == null) { return null; } Map<String, T> results = new ArrayMap<>(); for (File file : files) { T result = parseFile(file); if (result != null) { results.put(file.getName(), result); } } return results; } /** /** * Schedules the specified data to be flushed to a file in the future. Subsequent * Schedules the specified data to be flushed to a file in the future. Subsequent * calls for the same file before the flush occurs will replace the previous data but will not * calls for the same file before the flush occurs will replace the previous data but will not Loading services/people/java/com/android/server/people/data/ConversationStore.java +58 −44 Original line number Original line Diff line number Diff line Loading @@ -90,7 +90,7 @@ class ConversationStore { * after the device powers on and the user has been unlocked. * after the device powers on and the user has been unlocked. */ */ @WorkerThread @WorkerThread synchronized void loadConversationsFromDisk() { void loadConversationsFromDisk() { ConversationInfosProtoDiskReadWriter conversationInfosProtoDiskReadWriter = ConversationInfosProtoDiskReadWriter conversationInfosProtoDiskReadWriter = getConversationInfosProtoDiskReadWriter(); getConversationInfosProtoDiskReadWriter(); if (conversationInfosProtoDiskReadWriter == null) { if (conversationInfosProtoDiskReadWriter == null) { Loading @@ -111,25 +111,30 @@ class ConversationStore { * powering off. * powering off. */ */ @MainThread @MainThread synchronized void saveConversationsToDisk() { void saveConversationsToDisk() { ConversationInfosProtoDiskReadWriter conversationInfosProtoDiskReadWriter = ConversationInfosProtoDiskReadWriter conversationInfosProtoDiskReadWriter = getConversationInfosProtoDiskReadWriter(); getConversationInfosProtoDiskReadWriter(); if (conversationInfosProtoDiskReadWriter != null) { if (conversationInfosProtoDiskReadWriter != null) { conversationInfosProtoDiskReadWriter.saveConversationsImmediately( List<ConversationInfo> conversations; new ArrayList<>(mConversationInfoMap.values())); synchronized (this) { conversations = new ArrayList<>(mConversationInfoMap.values()); } conversationInfosProtoDiskReadWriter.saveConversationsImmediately(conversations); } } } } @MainThread @MainThread synchronized void addOrUpdate(@NonNull ConversationInfo conversationInfo) { void addOrUpdate(@NonNull ConversationInfo conversationInfo) { updateConversationsInMemory(conversationInfo); updateConversationsInMemory(conversationInfo); scheduleUpdateConversationsOnDisk(); scheduleUpdateConversationsOnDisk(); } } @MainThread @MainThread @Nullable @Nullable synchronized ConversationInfo deleteConversation(@NonNull String shortcutId) { ConversationInfo deleteConversation(@NonNull String shortcutId) { ConversationInfo conversationInfo = mConversationInfoMap.remove(shortcutId); ConversationInfo conversationInfo; synchronized (this) { conversationInfo = mConversationInfoMap.remove(shortcutId); if (conversationInfo == null) { if (conversationInfo == null) { return null; return null; } } Loading @@ -153,12 +158,17 @@ class ConversationStore { if (notifChannelId != null) { if (notifChannelId != null) { mNotifChannelIdToShortcutIdMap.remove(notifChannelId); mNotifChannelIdToShortcutIdMap.remove(notifChannelId); } } } scheduleUpdateConversationsOnDisk(); scheduleUpdateConversationsOnDisk(); return conversationInfo; return conversationInfo; } } synchronized void forAllConversations(@NonNull Consumer<ConversationInfo> consumer) { void forAllConversations(@NonNull Consumer<ConversationInfo> consumer) { for (ConversationInfo ci : mConversationInfoMap.values()) { List<ConversationInfo> conversations; synchronized (this) { conversations = new ArrayList<>(mConversationInfoMap.values()); } for (ConversationInfo ci : conversations) { consumer.accept(ci); consumer.accept(ci); } } } } Loading @@ -184,16 +194,19 @@ class ConversationStore { } } @Nullable @Nullable ConversationInfo getConversationByNotificationChannelId(@NonNull String notifChannelId) { synchronized ConversationInfo getConversationByNotificationChannelId( @NonNull String notifChannelId) { return getConversation(mNotifChannelIdToShortcutIdMap.get(notifChannelId)); return getConversation(mNotifChannelIdToShortcutIdMap.get(notifChannelId)); } } synchronized void onDestroy() { void onDestroy() { synchronized (this) { mConversationInfoMap.clear(); mConversationInfoMap.clear(); mContactUriToShortcutIdMap.clear(); mContactUriToShortcutIdMap.clear(); mLocusIdToShortcutIdMap.clear(); mLocusIdToShortcutIdMap.clear(); mNotifChannelIdToShortcutIdMap.clear(); mNotifChannelIdToShortcutIdMap.clear(); mPhoneNumberToShortcutIdMap.clear(); mPhoneNumberToShortcutIdMap.clear(); } ConversationInfosProtoDiskReadWriter writer = getConversationInfosProtoDiskReadWriter(); ConversationInfosProtoDiskReadWriter writer = getConversationInfosProtoDiskReadWriter(); if (writer != null) { if (writer != null) { writer.deleteConversationsFile(); writer.deleteConversationsFile(); Loading @@ -201,22 +214,21 @@ class ConversationStore { } } @Nullable @Nullable synchronized byte[] getBackupPayload() { byte[] getBackupPayload() { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream conversationInfosOut = new DataOutputStream(baos); DataOutputStream conversationInfosOut = new DataOutputStream(baos); for (ConversationInfo conversationInfo : mConversationInfoMap.values()) { forAllConversations(conversationInfo -> { byte[] backupPayload = conversationInfo.getBackupPayload(); byte[] backupPayload = conversationInfo.getBackupPayload(); if (backupPayload == null) { if (backupPayload == null) { continue; return; } } try { try { conversationInfosOut.writeInt(backupPayload.length); conversationInfosOut.writeInt(backupPayload.length); conversationInfosOut.write(backupPayload); conversationInfosOut.write(backupPayload); } catch (IOException e) { } catch (IOException e) { Slog.e(TAG, "Failed to write conversation info to backup payload.", e); Slog.e(TAG, "Failed to write conversation info to backup payload.", e); return null; } } } }); try { try { conversationInfosOut.writeInt(CONVERSATION_INFOS_END_TOKEN); conversationInfosOut.writeInt(CONVERSATION_INFOS_END_TOKEN); } catch (IOException e) { } catch (IOException e) { Loading @@ -226,7 +238,7 @@ class ConversationStore { return baos.toByteArray(); return baos.toByteArray(); } } synchronized void restore(@NonNull byte[] payload) { void restore(@NonNull byte[] payload) { DataInputStream in = new DataInputStream(new ByteArrayInputStream(payload)); DataInputStream in = new DataInputStream(new ByteArrayInputStream(payload)); try { try { for (int conversationInfoSize = in.readInt(); for (int conversationInfoSize = in.readInt(); Loading @@ -245,7 +257,6 @@ class ConversationStore { } } } } @MainThread private synchronized void updateConversationsInMemory( private synchronized void updateConversationsInMemory( @NonNull ConversationInfo conversationInfo) { @NonNull ConversationInfo conversationInfo) { mConversationInfoMap.put(conversationInfo.getShortcutId(), conversationInfo); mConversationInfoMap.put(conversationInfo.getShortcutId(), conversationInfo); Loading Loading @@ -273,12 +284,15 @@ class ConversationStore { /** Schedules a dump of all conversations onto disk, overwriting existing values. */ /** Schedules a dump of all conversations onto disk, overwriting existing values. */ @MainThread @MainThread private synchronized void scheduleUpdateConversationsOnDisk() { private void scheduleUpdateConversationsOnDisk() { ConversationInfosProtoDiskReadWriter conversationInfosProtoDiskReadWriter = ConversationInfosProtoDiskReadWriter conversationInfosProtoDiskReadWriter = getConversationInfosProtoDiskReadWriter(); getConversationInfosProtoDiskReadWriter(); if (conversationInfosProtoDiskReadWriter != null) { if (conversationInfosProtoDiskReadWriter != null) { conversationInfosProtoDiskReadWriter.scheduleConversationsSave( List<ConversationInfo> conversations; new ArrayList<>(mConversationInfoMap.values())); synchronized (this) { conversations = new ArrayList<>(mConversationInfoMap.values()); } conversationInfosProtoDiskReadWriter.scheduleConversationsSave(conversations); } } } } Loading Loading
services/people/java/com/android/server/people/data/AbstractProtoDiskReadWriter.java +4 −24 Original line number Original line Diff line number Diff line Loading @@ -85,8 +85,10 @@ abstract class AbstractProtoDiskReadWriter<T> { } } @WorkerThread @WorkerThread synchronized void delete(@NonNull String fileName) { void delete(@NonNull String fileName) { synchronized (this) { mScheduledFileDataMap.remove(fileName); mScheduledFileDataMap.remove(fileName); } final File file = getFile(fileName); final File file = getFile(fileName); if (!file.exists()) { if (!file.exists()) { return; return; Loading Loading @@ -135,28 +137,6 @@ abstract class AbstractProtoDiskReadWriter<T> { return parseFile(files[0]); return parseFile(files[0]); } } /** * Reads all files in directory and returns a map with file names as keys and parsed file * contents as values. */ @WorkerThread @Nullable Map<String, T> readAll() { File[] files = mRootDir.listFiles(File::isFile); if (files == null) { return null; } Map<String, T> results = new ArrayMap<>(); for (File file : files) { T result = parseFile(file); if (result != null) { results.put(file.getName(), result); } } return results; } /** /** * Schedules the specified data to be flushed to a file in the future. Subsequent * Schedules the specified data to be flushed to a file in the future. Subsequent * calls for the same file before the flush occurs will replace the previous data but will not * calls for the same file before the flush occurs will replace the previous data but will not Loading
services/people/java/com/android/server/people/data/ConversationStore.java +58 −44 Original line number Original line Diff line number Diff line Loading @@ -90,7 +90,7 @@ class ConversationStore { * after the device powers on and the user has been unlocked. * after the device powers on and the user has been unlocked. */ */ @WorkerThread @WorkerThread synchronized void loadConversationsFromDisk() { void loadConversationsFromDisk() { ConversationInfosProtoDiskReadWriter conversationInfosProtoDiskReadWriter = ConversationInfosProtoDiskReadWriter conversationInfosProtoDiskReadWriter = getConversationInfosProtoDiskReadWriter(); getConversationInfosProtoDiskReadWriter(); if (conversationInfosProtoDiskReadWriter == null) { if (conversationInfosProtoDiskReadWriter == null) { Loading @@ -111,25 +111,30 @@ class ConversationStore { * powering off. * powering off. */ */ @MainThread @MainThread synchronized void saveConversationsToDisk() { void saveConversationsToDisk() { ConversationInfosProtoDiskReadWriter conversationInfosProtoDiskReadWriter = ConversationInfosProtoDiskReadWriter conversationInfosProtoDiskReadWriter = getConversationInfosProtoDiskReadWriter(); getConversationInfosProtoDiskReadWriter(); if (conversationInfosProtoDiskReadWriter != null) { if (conversationInfosProtoDiskReadWriter != null) { conversationInfosProtoDiskReadWriter.saveConversationsImmediately( List<ConversationInfo> conversations; new ArrayList<>(mConversationInfoMap.values())); synchronized (this) { conversations = new ArrayList<>(mConversationInfoMap.values()); } conversationInfosProtoDiskReadWriter.saveConversationsImmediately(conversations); } } } } @MainThread @MainThread synchronized void addOrUpdate(@NonNull ConversationInfo conversationInfo) { void addOrUpdate(@NonNull ConversationInfo conversationInfo) { updateConversationsInMemory(conversationInfo); updateConversationsInMemory(conversationInfo); scheduleUpdateConversationsOnDisk(); scheduleUpdateConversationsOnDisk(); } } @MainThread @MainThread @Nullable @Nullable synchronized ConversationInfo deleteConversation(@NonNull String shortcutId) { ConversationInfo deleteConversation(@NonNull String shortcutId) { ConversationInfo conversationInfo = mConversationInfoMap.remove(shortcutId); ConversationInfo conversationInfo; synchronized (this) { conversationInfo = mConversationInfoMap.remove(shortcutId); if (conversationInfo == null) { if (conversationInfo == null) { return null; return null; } } Loading @@ -153,12 +158,17 @@ class ConversationStore { if (notifChannelId != null) { if (notifChannelId != null) { mNotifChannelIdToShortcutIdMap.remove(notifChannelId); mNotifChannelIdToShortcutIdMap.remove(notifChannelId); } } } scheduleUpdateConversationsOnDisk(); scheduleUpdateConversationsOnDisk(); return conversationInfo; return conversationInfo; } } synchronized void forAllConversations(@NonNull Consumer<ConversationInfo> consumer) { void forAllConversations(@NonNull Consumer<ConversationInfo> consumer) { for (ConversationInfo ci : mConversationInfoMap.values()) { List<ConversationInfo> conversations; synchronized (this) { conversations = new ArrayList<>(mConversationInfoMap.values()); } for (ConversationInfo ci : conversations) { consumer.accept(ci); consumer.accept(ci); } } } } Loading @@ -184,16 +194,19 @@ class ConversationStore { } } @Nullable @Nullable ConversationInfo getConversationByNotificationChannelId(@NonNull String notifChannelId) { synchronized ConversationInfo getConversationByNotificationChannelId( @NonNull String notifChannelId) { return getConversation(mNotifChannelIdToShortcutIdMap.get(notifChannelId)); return getConversation(mNotifChannelIdToShortcutIdMap.get(notifChannelId)); } } synchronized void onDestroy() { void onDestroy() { synchronized (this) { mConversationInfoMap.clear(); mConversationInfoMap.clear(); mContactUriToShortcutIdMap.clear(); mContactUriToShortcutIdMap.clear(); mLocusIdToShortcutIdMap.clear(); mLocusIdToShortcutIdMap.clear(); mNotifChannelIdToShortcutIdMap.clear(); mNotifChannelIdToShortcutIdMap.clear(); mPhoneNumberToShortcutIdMap.clear(); mPhoneNumberToShortcutIdMap.clear(); } ConversationInfosProtoDiskReadWriter writer = getConversationInfosProtoDiskReadWriter(); ConversationInfosProtoDiskReadWriter writer = getConversationInfosProtoDiskReadWriter(); if (writer != null) { if (writer != null) { writer.deleteConversationsFile(); writer.deleteConversationsFile(); Loading @@ -201,22 +214,21 @@ class ConversationStore { } } @Nullable @Nullable synchronized byte[] getBackupPayload() { byte[] getBackupPayload() { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream conversationInfosOut = new DataOutputStream(baos); DataOutputStream conversationInfosOut = new DataOutputStream(baos); for (ConversationInfo conversationInfo : mConversationInfoMap.values()) { forAllConversations(conversationInfo -> { byte[] backupPayload = conversationInfo.getBackupPayload(); byte[] backupPayload = conversationInfo.getBackupPayload(); if (backupPayload == null) { if (backupPayload == null) { continue; return; } } try { try { conversationInfosOut.writeInt(backupPayload.length); conversationInfosOut.writeInt(backupPayload.length); conversationInfosOut.write(backupPayload); conversationInfosOut.write(backupPayload); } catch (IOException e) { } catch (IOException e) { Slog.e(TAG, "Failed to write conversation info to backup payload.", e); Slog.e(TAG, "Failed to write conversation info to backup payload.", e); return null; } } } }); try { try { conversationInfosOut.writeInt(CONVERSATION_INFOS_END_TOKEN); conversationInfosOut.writeInt(CONVERSATION_INFOS_END_TOKEN); } catch (IOException e) { } catch (IOException e) { Loading @@ -226,7 +238,7 @@ class ConversationStore { return baos.toByteArray(); return baos.toByteArray(); } } synchronized void restore(@NonNull byte[] payload) { void restore(@NonNull byte[] payload) { DataInputStream in = new DataInputStream(new ByteArrayInputStream(payload)); DataInputStream in = new DataInputStream(new ByteArrayInputStream(payload)); try { try { for (int conversationInfoSize = in.readInt(); for (int conversationInfoSize = in.readInt(); Loading @@ -245,7 +257,6 @@ class ConversationStore { } } } } @MainThread private synchronized void updateConversationsInMemory( private synchronized void updateConversationsInMemory( @NonNull ConversationInfo conversationInfo) { @NonNull ConversationInfo conversationInfo) { mConversationInfoMap.put(conversationInfo.getShortcutId(), conversationInfo); mConversationInfoMap.put(conversationInfo.getShortcutId(), conversationInfo); Loading Loading @@ -273,12 +284,15 @@ class ConversationStore { /** Schedules a dump of all conversations onto disk, overwriting existing values. */ /** Schedules a dump of all conversations onto disk, overwriting existing values. */ @MainThread @MainThread private synchronized void scheduleUpdateConversationsOnDisk() { private void scheduleUpdateConversationsOnDisk() { ConversationInfosProtoDiskReadWriter conversationInfosProtoDiskReadWriter = ConversationInfosProtoDiskReadWriter conversationInfosProtoDiskReadWriter = getConversationInfosProtoDiskReadWriter(); getConversationInfosProtoDiskReadWriter(); if (conversationInfosProtoDiskReadWriter != null) { if (conversationInfosProtoDiskReadWriter != null) { conversationInfosProtoDiskReadWriter.scheduleConversationsSave( List<ConversationInfo> conversations; new ArrayList<>(mConversationInfoMap.values())); synchronized (this) { conversations = new ArrayList<>(mConversationInfoMap.values()); } conversationInfosProtoDiskReadWriter.scheduleConversationsSave(conversations); } } } } Loading