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 
17 package com.android.messaging.datamodel.action;
18 
19 import android.content.ContentValues;
20 import android.os.Parcel;
21 import android.os.Parcelable;
22 
23 import com.android.messaging.datamodel.DataModel;
24 import com.android.messaging.datamodel.DatabaseHelper;
25 import com.android.messaging.datamodel.DatabaseWrapper;
26 import com.android.messaging.datamodel.data.MessageData;
27 import com.android.messaging.util.LogUtil;
28 
29 /**
30  * Action used to fixup actively downloading or sending status at startup - just in case we
31  * crash - never run this when a message might actually be sending or downloading.
32  */
33 public class FixupMessageStatusOnStartupAction extends Action implements Parcelable {
34     private static final String TAG = LogUtil.BUGLE_DATAMODEL_TAG;
35 
fixupMessageStatus()36     public static void fixupMessageStatus() {
37         final FixupMessageStatusOnStartupAction action = new FixupMessageStatusOnStartupAction();
38         action.start();
39     }
40 
FixupMessageStatusOnStartupAction()41     private FixupMessageStatusOnStartupAction() {
42     }
43 
44     @Override
executeAction()45     protected Object executeAction() {
46         // Now mark any messages in active sending or downloading state as inactive
47         final DatabaseWrapper db = DataModel.get().getDatabase();
48         db.beginTransaction();
49         int downloadFailedCnt = 0;
50         int sendFailedCnt = 0;
51         try {
52             // For both sending and downloading messages, let's assume they failed.
53             // For MMS sent/downloaded via platform, the sent/downloaded pending intent
54             // may come back. That will update the message. User may see the message
55             // in wrong status within a short window if that happens. But this should
56             // rarely happen. This is a simple solution to situations like app gets killed
57             // while the pending intent is still in the fly. Alternatively, we could
58             // keep the status for platform sent/downloaded MMS and timeout these messages.
59             // But that is much more complex.
60             final ContentValues values = new ContentValues();
61             values.put(DatabaseHelper.MessageColumns.STATUS,
62                     MessageData.BUGLE_STATUS_INCOMING_DOWNLOAD_FAILED);
63             downloadFailedCnt += db.update(DatabaseHelper.MESSAGES_TABLE, values,
64                     DatabaseHelper.MessageColumns.STATUS + " IN (?, ?)",
65                     new String[]{
66                             Integer.toString(MessageData.BUGLE_STATUS_INCOMING_AUTO_DOWNLOADING),
67                             Integer.toString(MessageData.BUGLE_STATUS_INCOMING_MANUAL_DOWNLOADING)
68                     });
69             values.clear();
70 
71             values.clear();
72             values.put(DatabaseHelper.MessageColumns.STATUS,
73                     MessageData.BUGLE_STATUS_OUTGOING_FAILED);
74             sendFailedCnt = db.update(DatabaseHelper.MESSAGES_TABLE, values,
75                     DatabaseHelper.MessageColumns.STATUS + " IN (?, ?)",
76                     new String[]{
77                             Integer.toString(MessageData.BUGLE_STATUS_OUTGOING_SENDING),
78                             Integer.toString(MessageData.BUGLE_STATUS_OUTGOING_RESENDING)
79                     });
80 
81             db.setTransactionSuccessful();
82         } finally {
83             db.endTransaction();
84         }
85 
86         LogUtil.i(TAG, "Fixup: Send failed - " + sendFailedCnt
87                 + " Download failed - " + downloadFailedCnt);
88 
89         // Don't send contentObserver notifications as displayed text should not change
90         return null;
91     }
92 
FixupMessageStatusOnStartupAction(final Parcel in)93     private FixupMessageStatusOnStartupAction(final Parcel in) {
94         super(in);
95     }
96 
97     public static final Parcelable.Creator<FixupMessageStatusOnStartupAction> CREATOR
98             = new Parcelable.Creator<FixupMessageStatusOnStartupAction>() {
99         @Override
100         public FixupMessageStatusOnStartupAction createFromParcel(final Parcel in) {
101             return new FixupMessageStatusOnStartupAction(in);
102         }
103 
104         @Override
105         public FixupMessageStatusOnStartupAction[] newArray(final int size) {
106             return new FixupMessageStatusOnStartupAction[size];
107         }
108     };
109 
110     @Override
writeToParcel(final Parcel parcel, final int flags)111     public void writeToParcel(final Parcel parcel, final int flags) {
112         writeActionToParcel(parcel, flags);
113     }
114 }
115