1/*
2 * Copyright (C) 2015 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
17package com.android.messaging.datamodel.action;
18
19import android.content.ContentValues;
20import android.os.Parcel;
21import android.os.Parcelable;
22
23import com.android.messaging.datamodel.BugleDatabaseOperations;
24import com.android.messaging.datamodel.BugleNotifications;
25import com.android.messaging.datamodel.DataModel;
26import com.android.messaging.datamodel.DatabaseHelper;
27import com.android.messaging.datamodel.DatabaseHelper.MessageColumns;
28import com.android.messaging.datamodel.DatabaseWrapper;
29import com.android.messaging.datamodel.MessagingContentProvider;
30import com.android.messaging.sms.MmsUtils;
31import com.android.messaging.util.LogUtil;
32
33/**
34 * Action used to mark all the messages in a conversation as read
35 */
36public class MarkAsReadAction extends Action implements Parcelable {
37    private static final String TAG = LogUtil.BUGLE_DATAMODEL_TAG;
38
39    private static final String KEY_CONVERSATION_ID = "conversation_id";
40
41    /**
42     * Mark all the messages as read for a particular conversation.
43     */
44    public static void markAsRead(final String conversationId) {
45        final MarkAsReadAction action = new MarkAsReadAction(conversationId);
46        action.start();
47    }
48
49    private MarkAsReadAction(final String conversationId) {
50        actionParameters.putString(KEY_CONVERSATION_ID, conversationId);
51    }
52
53    @Override
54    protected Object executeAction() {
55        final String conversationId = actionParameters.getString(KEY_CONVERSATION_ID);
56
57        // TODO: Consider doing this in background service to avoid delaying other actions
58        final DatabaseWrapper db = DataModel.get().getDatabase();
59
60        // Mark all messages in thread as read in telephony
61        final long threadId = BugleDatabaseOperations.getThreadId(db, conversationId);
62        if (threadId != -1) {
63            MmsUtils.updateSmsReadStatus(threadId, Long.MAX_VALUE);
64        }
65
66        // Update local db
67        db.beginTransaction();
68        try {
69            final ContentValues values = new ContentValues();
70            values.put(MessageColumns.CONVERSATION_ID, conversationId);
71            values.put(MessageColumns.READ, 1);
72            values.put(MessageColumns.SEEN, 1);     // if they read it, they saw it
73
74            final int count = db.update(DatabaseHelper.MESSAGES_TABLE, values,
75                    "(" + MessageColumns.READ + " !=1 OR " +
76                            MessageColumns.SEEN + " !=1 ) AND " +
77                            MessageColumns.CONVERSATION_ID + "=?",
78                    new String[] { conversationId });
79            if (count > 0) {
80                MessagingContentProvider.notifyMessagesChanged(conversationId);
81            }
82            db.setTransactionSuccessful();
83        } finally {
84            db.endTransaction();
85        }
86        // After marking messages as read, update the notifications. This will
87        // clear the now stale notifications.
88        BugleNotifications.update(false/*silent*/, BugleNotifications.UPDATE_ALL);
89        return null;
90    }
91
92    private MarkAsReadAction(final Parcel in) {
93        super(in);
94    }
95
96    public static final Parcelable.Creator<MarkAsReadAction> CREATOR
97            = new Parcelable.Creator<MarkAsReadAction>() {
98        @Override
99        public MarkAsReadAction createFromParcel(final Parcel in) {
100            return new MarkAsReadAction(in);
101        }
102
103        @Override
104        public MarkAsReadAction[] newArray(final int size) {
105            return new MarkAsReadAction[size];
106        }
107    };
108
109    @Override
110    public void writeToParcel(final Parcel parcel, final int flags) {
111        writeActionToParcel(parcel, flags);
112    }
113}
114