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