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.os.Parcel; 20 import android.os.Parcelable; 21 22 import com.android.messaging.datamodel.BugleDatabaseOperations; 23 import com.android.messaging.datamodel.DataModel; 24 import com.android.messaging.datamodel.DatabaseWrapper; 25 import com.android.messaging.datamodel.action.ActionMonitor.ActionCompletedListener; 26 import com.android.messaging.datamodel.data.ConversationListItemData; 27 import com.android.messaging.datamodel.data.MessageData; 28 import com.android.messaging.util.Assert; 29 import com.android.messaging.util.Assert.RunsOnMainThread; 30 import com.android.messaging.util.LogUtil; 31 import com.google.common.annotations.VisibleForTesting; 32 33 public class ReadDraftDataAction extends Action implements Parcelable { 34 35 /** 36 * Interface for ReadDraftDataAction listeners 37 */ 38 public interface ReadDraftDataActionListener { 39 @RunsOnMainThread onReadDraftDataSucceeded(final ReadDraftDataAction action, final Object data, final MessageData message, final ConversationListItemData conversation)40 abstract void onReadDraftDataSucceeded(final ReadDraftDataAction action, 41 final Object data, final MessageData message, 42 final ConversationListItemData conversation); 43 @RunsOnMainThread onReadDraftDataFailed(final ReadDraftDataAction action, final Object data)44 abstract void onReadDraftDataFailed(final ReadDraftDataAction action, final Object data); 45 } 46 47 /** 48 * Read draft message and associated data (with listener) 49 */ readDraftData(final String conversationId, final MessageData incomingDraft, final Object data, final ReadDraftDataActionListener listener)50 public static ReadDraftDataActionMonitor readDraftData(final String conversationId, 51 final MessageData incomingDraft, final Object data, 52 final ReadDraftDataActionListener listener) { 53 final ReadDraftDataActionMonitor monitor = new ReadDraftDataActionMonitor(data, 54 listener); 55 final ReadDraftDataAction action = new ReadDraftDataAction(conversationId, 56 incomingDraft, monitor.getActionKey()); 57 action.start(monitor); 58 return monitor; 59 } 60 61 private static final String KEY_CONVERSATION_ID = "conversationId"; 62 private static final String KEY_INCOMING_DRAFT = "draftMessage"; 63 ReadDraftDataAction(final String conversationId, final MessageData incomingDraft, final String actionKey)64 private ReadDraftDataAction(final String conversationId, final MessageData incomingDraft, 65 final String actionKey) { 66 super(actionKey); 67 actionParameters.putString(KEY_CONVERSATION_ID, conversationId); 68 actionParameters.putParcelable(KEY_INCOMING_DRAFT, incomingDraft); 69 } 70 71 @VisibleForTesting 72 class DraftData { 73 public final MessageData message; 74 public final ConversationListItemData conversation; 75 DraftData(final MessageData message, final ConversationListItemData conversation)76 DraftData(final MessageData message, final ConversationListItemData conversation) { 77 this.message = message; 78 this.conversation = conversation; 79 } 80 } 81 82 @Override executeAction()83 protected Object executeAction() { 84 final DatabaseWrapper db = DataModel.get().getDatabase(); 85 final String conversationId = actionParameters.getString(KEY_CONVERSATION_ID); 86 final MessageData incomingDraft = actionParameters.getParcelable(KEY_INCOMING_DRAFT); 87 final ConversationListItemData conversation = 88 ConversationListItemData.getExistingConversation(db, conversationId); 89 MessageData message = null; 90 if (conversation != null) { 91 if (incomingDraft == null) { 92 message = BugleDatabaseOperations.readDraftMessageData(db, conversationId, 93 conversation.getSelfId()); 94 } 95 if (message == null) { 96 message = MessageData.createDraftMessage(conversationId, conversation.getSelfId(), 97 incomingDraft); 98 LogUtil.d(LogUtil.BUGLE_TAG, "ReadDraftMessage: created draft. " 99 + "conversationId=" + conversationId 100 + " selfId=" + conversation.getSelfId()); 101 } else { 102 LogUtil.d(LogUtil.BUGLE_TAG, "ReadDraftMessage: read draft. " 103 + "conversationId=" + conversationId 104 + " selfId=" + conversation.getSelfId()); 105 } 106 return new DraftData(message, conversation); 107 } 108 return null; 109 } 110 111 /** 112 * An operation that notifies a listener upon completion 113 */ 114 public static class ReadDraftDataActionMonitor extends ActionMonitor 115 implements ActionCompletedListener { 116 117 private final ReadDraftDataActionListener mListener; 118 ReadDraftDataActionMonitor(final Object data, final ReadDraftDataActionListener completed)119 ReadDraftDataActionMonitor(final Object data, 120 final ReadDraftDataActionListener completed) { 121 super(STATE_CREATED, generateUniqueActionKey("ReadDraftDataAction"), data); 122 setCompletedListener(this); 123 mListener = completed; 124 } 125 126 @Override onActionSucceeded(final ActionMonitor monitor, final Action action, final Object data, final Object result)127 public void onActionSucceeded(final ActionMonitor monitor, 128 final Action action, final Object data, final Object result) { 129 final DraftData draft = (DraftData) result; 130 if (draft == null) { 131 mListener.onReadDraftDataFailed((ReadDraftDataAction) action, data); 132 } else { 133 mListener.onReadDraftDataSucceeded((ReadDraftDataAction) action, data, 134 draft.message, draft.conversation); 135 } 136 } 137 138 @Override onActionFailed(final ActionMonitor monitor, final Action action, final Object data, final Object result)139 public void onActionFailed(final ActionMonitor monitor, 140 final Action action, final Object data, final Object result) { 141 Assert.fail("Reading draft should not fail"); 142 } 143 } 144 ReadDraftDataAction(final Parcel in)145 private ReadDraftDataAction(final Parcel in) { 146 super(in); 147 } 148 149 public static final Parcelable.Creator<ReadDraftDataAction> CREATOR 150 = new Parcelable.Creator<ReadDraftDataAction>() { 151 @Override 152 public ReadDraftDataAction createFromParcel(final Parcel in) { 153 return new ReadDraftDataAction(in); 154 } 155 156 @Override 157 public ReadDraftDataAction[] newArray(final int size) { 158 return new ReadDraftDataAction[size]; 159 } 160 }; 161 162 @Override writeToParcel(final Parcel parcel, final int flags)163 public void writeToParcel(final Parcel parcel, final int flags) { 164 writeActionToParcel(parcel, flags); 165 } 166 } 167