Home | History | Annotate | Download | only in exchange
      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