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.DataModel;
25import com.android.messaging.datamodel.DatabaseHelper.MessageColumns;
26import com.android.messaging.datamodel.DatabaseWrapper;
27import com.android.messaging.datamodel.MessagingContentProvider;
28import com.android.messaging.datamodel.data.MessageData;
29import com.android.messaging.util.LogUtil;
30
31/**
32 * Action used to manually resend an outgoing message
33 */
34public class ResendMessageAction extends Action implements Parcelable {
35    private static final String TAG = LogUtil.BUGLE_DATAMODEL_TAG;
36
37    /**
38     * Manual send of existing message (no listener)
39     */
40    public static void resendMessage(final String messageId) {
41        final ResendMessageAction action = new ResendMessageAction(messageId);
42        action.start();
43    }
44
45    // Core parameters needed for all types of message
46    private static final String KEY_MESSAGE_ID = "message_id";
47
48    /**
49     * Constructor used for retrying sending in the background (only message id available)
50     */
51    ResendMessageAction(final String messageId) {
52        super();
53        actionParameters.putString(KEY_MESSAGE_ID, messageId);
54    }
55
56    /**
57     * Read message from database and change status to allow sending
58     */
59    @Override
60    protected Object executeAction() {
61        final String messageId = actionParameters.getString(KEY_MESSAGE_ID);
62
63        final DatabaseWrapper db = DataModel.get().getDatabase();
64
65        final MessageData message = BugleDatabaseOperations.readMessage(db, messageId);
66        // Check message can be resent
67        if (message != null && message.canResendMessage()) {
68            final boolean isMms = message.getIsMms();
69            long timestamp = System.currentTimeMillis();
70            if (isMms) {
71                // MMS expects timestamp rounded to nearest second
72                timestamp = 1000 * ((timestamp + 500) / 1000);
73            }
74
75            LogUtil.i(TAG, "ResendMessageAction: Resending message " + messageId
76                    + "; changed timestamp from " + message.getReceivedTimeStamp() + " to "
77                    + timestamp);
78
79            final ContentValues values = new ContentValues();
80            values.put(MessageColumns.STATUS, MessageData.BUGLE_STATUS_OUTGOING_YET_TO_SEND);
81            values.put(MessageColumns.RECEIVED_TIMESTAMP, timestamp);
82            values.put(MessageColumns.SENT_TIMESTAMP, timestamp);
83            values.put(MessageColumns.RETRY_START_TIMESTAMP, timestamp);
84
85            // Row must exist as was just loaded above (on ActionService thread)
86            BugleDatabaseOperations.updateMessageRow(db, message.getMessageId(), values);
87
88            MessagingContentProvider.notifyMessagesChanged(message.getConversationId());
89
90            // Whether we succeeded or failed we will check and maybe schedule some more work
91            ProcessPendingMessagesAction.scheduleProcessPendingMessagesAction(false, this);
92
93            return message;
94        } else {
95            String error = "ResendMessageAction: Cannot resend message " + messageId + "; ";
96            if (message != null) {
97                error += ("status = " + MessageData.getStatusDescription(message.getStatus()));
98            } else {
99                error += "not found in database";
100            }
101            LogUtil.e(TAG, error);
102        }
103
104        return null;
105    }
106
107    private ResendMessageAction(final Parcel in) {
108        super(in);
109    }
110
111    public static final Parcelable.Creator<ResendMessageAction> CREATOR
112            = new Parcelable.Creator<ResendMessageAction>() {
113        @Override
114        public ResendMessageAction createFromParcel(final Parcel in) {
115            return new ResendMessageAction(in);
116        }
117
118        @Override
119        public ResendMessageAction[] newArray(final int size) {
120            return new ResendMessageAction[size];
121        }
122    };
123
124    @Override
125    public void writeToParcel(final Parcel parcel, final int flags) {
126        writeActionToParcel(parcel, flags);
127    }
128}
129