EasOutboxService.java revision 1ba0fd37a158c1477025aa530206fefdc4b3fe5b
1/* 2 * Copyright (C) 2008-2009 Marc Blank 3 * Licensed to The Android Open Source Project. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package com.android.exchange; 19 20import com.android.email.mail.MessagingException; 21import com.android.email.mail.transport.Rfc822Output; 22import com.android.email.provider.EmailContent.Mailbox; 23import com.android.email.provider.EmailContent.Message; 24import com.android.email.provider.EmailContent.MessageColumns; 25import com.android.email.provider.EmailContent.SyncColumns; 26 27import org.apache.http.HttpResponse; 28import org.apache.http.entity.InputStreamEntity; 29 30import android.content.ContentUris; 31import android.content.ContentValues; 32import android.content.Context; 33import android.database.Cursor; 34 35import java.io.File; 36import java.io.FileInputStream; 37import java.io.FileOutputStream; 38import java.io.IOException; 39import java.net.HttpURLConnection; 40 41public class EasOutboxService extends EasSyncService { 42 43 public static final int SEND_FAILED = 1; 44 public static final String MAILBOX_KEY_AND_NOT_SEND_FAILED = 45 MessageColumns.MAILBOX_KEY + "=? and " + SyncColumns.SERVER_ID + "!=" + SEND_FAILED; 46 47 public EasOutboxService(Context _context, Mailbox _mailbox) { 48 super(_context, _mailbox); 49 mContext = _context; 50 } 51 52 /** 53 * Send a single message via EAS 54 * Note that we mark messages SEND_FAILED when there is a permanent failure, rather than an 55 * IOException, which is handled by SyncManager with retries, backoffs, etc. 56 * 57 * @param cacheDir the cache directory for this context 58 * @param msgId the _id of the message to send 59 * @throws IOException 60 */ 61 void sendMessage(File cacheDir, long msgId) throws IOException, MessagingException { 62 File tmpFile = File.createTempFile("eas_", "tmp", cacheDir); 63 // Write the output to a temporary file 64 try { 65 FileOutputStream fileStream = new FileOutputStream(tmpFile); 66 Rfc822Output.writeTo(mContext, msgId, fileStream); 67 fileStream.close(); 68 // Now, get an input stream to our new file and create an entity with it 69 FileInputStream inputStream = new FileInputStream(tmpFile); 70 InputStreamEntity inputEntity = 71 new InputStreamEntity(inputStream, tmpFile.length()); 72 // Send the post to the server 73 HttpResponse resp = 74 sendHttpClientPost("SendMail&SaveInSent=T", inputEntity); 75 inputStream.close(); 76 int code = resp.getStatusLine().getStatusCode(); 77 if (code == HttpURLConnection.HTTP_OK) { 78 userLog("Deleting message..."); 79 mContext.getContentResolver().delete(ContentUris.withAppendedId( 80 Message.CONTENT_URI, msgId), null, null); 81 } else { 82 // This case handles post-connection failures (i.e. errors coming back from the 83 // server) 84 // TODO Handle login failures? 85 ContentValues cv = new ContentValues(); 86 cv.put(SyncColumns.SERVER_ID, SEND_FAILED); 87 Message.update(mContext, Message.CONTENT_URI, msgId, cv); 88 } 89 // TODO Implement the upcoming EmailServiceCallback for messageSent 90 // sendMessageResult(messageId, result); 91 } finally { 92 // Clean up the temporary file 93 if (tmpFile.exists()) { 94 tmpFile.delete(); 95 } 96 } 97 } 98 99 @Override 100 public void run() { 101 mThread = Thread.currentThread(); 102 File cacheDir = mContext.getCacheDir(); 103 try { 104 Cursor c = mContext.getContentResolver().query(Message.CONTENT_URI, 105 Message.ID_COLUMN_PROJECTION, MAILBOX_KEY_AND_NOT_SEND_FAILED, 106 new String[] {Long.toString(mMailbox.mId)}, null); 107 try { 108 while (c.moveToNext()) { 109 long msgId = c.getLong(0); 110 if (msgId != 0) { 111 sendMessage(cacheDir, msgId); 112 } 113 } 114 } finally { 115 c.close(); 116 } 117 } catch (Exception e) { 118 mExitStatus = EXIT_EXCEPTION; 119 } finally { 120 userLog(mMailbox.mDisplayName, ": sync finished"); 121 SyncManager.done(this); 122 } 123 } 124}