blob: 8006016d2db4fc67083eed9642f88b85a190c629 [file] [log] [blame]
/*
* Copyright (C) 2008-2009 Marc Blank
* Licensed to The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.exchange;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.util.Log;
import com.android.emailcommon.provider.EmailContent.Message;
import com.android.emailcommon.provider.EmailContent.MessageColumns;
import com.android.emailcommon.provider.ProviderUnavailableException;
import java.util.ArrayList;
/**
* EmailSyncAlarmReceiver (USAR) is used by the SyncManager to start up-syncs of user-modified data
* back to the Exchange server.
*
* Here's how this works for Email, for example:
*
* 1) User modifies or deletes an email from the UI.
* 2) SyncManager, which has a ContentObserver watching the Message class, is alerted to a change
* 3) SyncManager sets an alarm (to be received by USAR) for a few seconds in the
* future (currently 15), the delay preventing excess syncing (think of it as a debounce mechanism).
* 4) ESAR Receiver's onReceive method is called
* 5) ESAR goes through all change and deletion records and compiles a list of mailboxes which have
* changes to be uploaded.
* 6) ESAR calls SyncManager to start syncs of those mailboxes
*
* If EmailProvider isn't available, the upsyncs will happen the next time ExchangeService starts
*
*/
public class EmailSyncAlarmReceiver extends BroadcastReceiver {
final String[] MAILBOX_DATA_PROJECTION = {MessageColumns.MAILBOX_KEY};
@Override
public void onReceive(final Context context, Intent intent) {
new Thread(new Runnable() {
public void run() {
handleReceive(context);
}
}).start();
}
private void handleReceive(Context context) {
ArrayList<Long> mailboxesToNotify = new ArrayList<Long>();
ContentResolver cr = context.getContentResolver();
int messageCount = 0;
// Get a selector for EAS accounts (we don't want to sync on changes to POP/IMAP messages)
String selector = ExchangeService.getEasAccountSelector();
try {
// Find all of the deletions
Cursor c = cr.query(Message.DELETED_CONTENT_URI, MAILBOX_DATA_PROJECTION, selector,
null, null);
if (c == null) throw new ProviderUnavailableException();
try {
// Keep track of which mailboxes to notify; we'll only notify each one once
while (c.moveToNext()) {
messageCount++;
long mailboxId = c.getLong(0);
if (!mailboxesToNotify.contains(mailboxId)) {
mailboxesToNotify.add(mailboxId);
}
}
} finally {
c.close();
}
// Now, find changed messages
c = cr.query(Message.UPDATED_CONTENT_URI, MAILBOX_DATA_PROJECTION, selector,
null, null);
if (c == null) throw new ProviderUnavailableException();
try {
// Keep track of which mailboxes to notify; we'll only notify each one once
while (c.moveToNext()) {
messageCount++;
long mailboxId = c.getLong(0);
if (!mailboxesToNotify.contains(mailboxId)) {
mailboxesToNotify.add(mailboxId);
}
}
} finally {
c.close();
}
// Request service from the mailbox
for (Long mailboxId: mailboxesToNotify) {
ExchangeService.serviceRequest(mailboxId, ExchangeService.SYNC_UPSYNC);
}
} catch (ProviderUnavailableException e) {
Log.e("EmailSyncAlarmReceiver", "EmailProvider unavailable; aborting alarm receiver");
}
}
}