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 18 package com.android.exchange; 19 20 import android.content.BroadcastReceiver; 21 import android.content.ContentResolver; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.database.Cursor; 25 import android.util.Log; 26 27 import com.android.emailcommon.provider.EmailContent.Message; 28 import com.android.emailcommon.provider.EmailContent.MessageColumns; 29 import com.android.emailcommon.provider.ProviderUnavailableException; 30 31 import java.util.ArrayList; 32 33 /** 34 * EmailSyncAlarmReceiver (USAR) is used by the SyncManager to start up-syncs of user-modified data 35 * back to the Exchange server. 36 * 37 * Here's how this works for Email, for example: 38 * 39 * 1) User modifies or deletes an email from the UI. 40 * 2) SyncManager, which has a ContentObserver watching the Message class, is alerted to a change 41 * 3) SyncManager sets an alarm (to be received by USAR) for a few seconds in the 42 * future (currently 15), the delay preventing excess syncing (think of it as a debounce mechanism). 43 * 4) ESAR Receiver's onReceive method is called 44 * 5) ESAR goes through all change and deletion records and compiles a list of mailboxes which have 45 * changes to be uploaded. 46 * 6) ESAR calls SyncManager to start syncs of those mailboxes 47 * 48 * If EmailProvider isn't available, the upsyncs will happen the next time ExchangeService starts 49 * 50 */ 51 public class EmailSyncAlarmReceiver extends BroadcastReceiver { 52 final String[] MAILBOX_DATA_PROJECTION = {MessageColumns.MAILBOX_KEY}; 53 54 @Override 55 public void onReceive(final Context context, Intent intent) { 56 new Thread(new Runnable() { 57 public void run() { 58 handleReceive(context); 59 } 60 }).start(); 61 } 62 63 private void handleReceive(Context context) { 64 ArrayList<Long> mailboxesToNotify = new ArrayList<Long>(); 65 ContentResolver cr = context.getContentResolver(); 66 int messageCount = 0; 67 68 // Get a selector for EAS accounts (we don't want to sync on changes to POP/IMAP messages) 69 String selector = ExchangeService.getEasAccountSelector(); 70 71 try { 72 // Find all of the deletions 73 Cursor c = cr.query(Message.DELETED_CONTENT_URI, MAILBOX_DATA_PROJECTION, selector, 74 null, null); 75 if (c == null) throw new ProviderUnavailableException(); 76 try { 77 // Keep track of which mailboxes to notify; we'll only notify each one once 78 while (c.moveToNext()) { 79 messageCount++; 80 long mailboxId = c.getLong(0); 81 if (!mailboxesToNotify.contains(mailboxId)) { 82 mailboxesToNotify.add(mailboxId); 83 } 84 } 85 } finally { 86 c.close(); 87 } 88 89 // Now, find changed messages 90 c = cr.query(Message.UPDATED_CONTENT_URI, MAILBOX_DATA_PROJECTION, selector, 91 null, null); 92 if (c == null) throw new ProviderUnavailableException(); 93 try { 94 // Keep track of which mailboxes to notify; we'll only notify each one once 95 while (c.moveToNext()) { 96 messageCount++; 97 long mailboxId = c.getLong(0); 98 if (!mailboxesToNotify.contains(mailboxId)) { 99 mailboxesToNotify.add(mailboxId); 100 } 101 } 102 } finally { 103 c.close(); 104 } 105 106 // Request service from the mailbox 107 for (Long mailboxId: mailboxesToNotify) { 108 ExchangeService.serviceRequest(mailboxId, ExchangeService.SYNC_UPSYNC); 109 } 110 } catch (ProviderUnavailableException e) { 111 Log.e("EmailSyncAlarmReceiver", "EmailProvider unavailable; aborting alarm receiver"); 112 } 113 } 114 } 115