• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
onReceive(final Context context, Intent intent)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 
handleReceive(Context context)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