Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 805b216f authored by Danning Chen's avatar Danning Chen Committed by Android (Google) Code Review
Browse files

Merge "Reduce the lock protected scope in People Service ConversationStore"

parents 106f1b33 f7eba62b
Loading
Loading
Loading
Loading
+4 −24
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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
+58 −44
Original line number Original line Diff line number Diff line
@@ -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) {
@@ -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;
            }
            }
@@ -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);
        }
        }
    }
    }
@@ -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();
@@ -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) {
@@ -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();
@@ -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);
@@ -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);
        }
        }
    }
    }