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.net.Uri;
20 import android.os.Bundle;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.text.TextUtils;
24 
25 import com.android.messaging.datamodel.BugleDatabaseOperations;
26 import com.android.messaging.datamodel.DataModel;
27 import com.android.messaging.datamodel.DatabaseWrapper;
28 import com.android.messaging.datamodel.MessagingContentProvider;
29 import com.android.messaging.datamodel.data.MessageData;
30 import com.android.messaging.sms.MmsUtils;
31 import com.android.messaging.util.LogUtil;
32 
33 /**
34  * Action used to delete a single message.
35  */
36 public class DeleteMessageAction extends Action implements Parcelable {
37     private static final String TAG = LogUtil.BUGLE_DATAMODEL_TAG;
38 
deleteMessage(final String messageId)39     public static void deleteMessage(final String messageId) {
40         final DeleteMessageAction action = new DeleteMessageAction(messageId);
41         action.start();
42     }
43 
44     private static final String KEY_MESSAGE_ID = "message_id";
45 
DeleteMessageAction(final String messageId)46     private DeleteMessageAction(final String messageId) {
47         super();
48         actionParameters.putString(KEY_MESSAGE_ID, messageId);
49     }
50 
51     // Doing this work in the background so that we're not competing with sync
52     // which could bring the deleted message back to life between the time we deleted
53     // it locally and deleted it in telephony (sync is also done on doBackgroundWork).
54     //
55     // Previously this block of code deleted from telephony first but that can be very
56     // slow (on the order of seconds) so this was modified to first delete locally, trigger
57     // the UI update, then delete from telephony.
58     @Override
doBackgroundWork()59     protected Bundle doBackgroundWork() {
60         final DatabaseWrapper db = DataModel.get().getDatabase();
61 
62         // First find the thread id for this conversation.
63         final String messageId = actionParameters.getString(KEY_MESSAGE_ID);
64 
65         if (!TextUtils.isEmpty(messageId)) {
66             // Check message still exists
67             final MessageData message = BugleDatabaseOperations.readMessage(db, messageId);
68             if (message != null) {
69                 // Delete from local DB
70                 int count = BugleDatabaseOperations.deleteMessage(db, messageId);
71                 if (count > 0) {
72                     LogUtil.i(TAG, "DeleteMessageAction: Deleted local message "
73                             + messageId);
74                 } else {
75                     LogUtil.w(TAG, "DeleteMessageAction: Could not delete local message "
76                             + messageId);
77                 }
78                 MessagingContentProvider.notifyMessagesChanged(message.getConversationId());
79                 // We may have changed the conversation list
80                 MessagingContentProvider.notifyConversationListChanged();
81 
82                 final Uri messageUri = message.getSmsMessageUri();
83                 if (messageUri != null) {
84                     // Delete from telephony DB
85                     count = MmsUtils.deleteMessage(messageUri);
86                     if (count > 0) {
87                         LogUtil.i(TAG, "DeleteMessageAction: Deleted telephony message "
88                                 + messageUri);
89                     } else {
90                         LogUtil.w(TAG, "DeleteMessageAction: Could not delete message from "
91                                 + "telephony: messageId = " + messageId + ", telephony uri = "
92                                 + messageUri);
93                     }
94                 } else {
95                     LogUtil.i(TAG, "DeleteMessageAction: Local message " + messageId
96                             + " has no telephony uri.");
97                 }
98             } else {
99                 LogUtil.w(TAG, "DeleteMessageAction: Message " + messageId + " no longer exists");
100             }
101         }
102         return null;
103     }
104 
105     /**
106      * Delete the message.
107      */
108     @Override
executeAction()109     protected Object executeAction() {
110         requestBackgroundWork();
111         return null;
112     }
113 
DeleteMessageAction(final Parcel in)114     private DeleteMessageAction(final Parcel in) {
115         super(in);
116     }
117 
118     public static final Parcelable.Creator<DeleteMessageAction> CREATOR
119             = new Parcelable.Creator<DeleteMessageAction>() {
120         @Override
121         public DeleteMessageAction createFromParcel(final Parcel in) {
122             return new DeleteMessageAction(in);
123         }
124 
125         @Override
126         public DeleteMessageAction[] newArray(final int size) {
127             return new DeleteMessageAction[size];
128         }
129     };
130 
131     @Override
writeToParcel(final Parcel parcel, final int flags)132     public void writeToParcel(final Parcel parcel, final int flags) {
133         writeActionToParcel(parcel, flags);
134     }
135 }
136