• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.exchange;
18 
19 import android.accounts.Account;
20 import android.accounts.OperationCanceledException;
21 import android.app.Service;
22 import android.content.AbstractThreadedSyncAdapter;
23 import android.content.ContentProviderClient;
24 import android.content.ContentResolver;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.content.SyncResult;
28 import android.database.Cursor;
29 import android.os.Bundle;
30 import android.os.IBinder;
31 import android.provider.CalendarContract.Events;
32 import android.util.Log;
33 
34 import com.android.emailcommon.provider.EmailContent;
35 import com.android.emailcommon.provider.EmailContent.AccountColumns;
36 import com.android.emailcommon.provider.EmailContent.MailboxColumns;
37 import com.android.emailcommon.provider.Mailbox;
38 
39 public class CalendarSyncAdapterService extends Service {
40     private static final String TAG = "EAS CalendarSyncAdapterService";
41     private static SyncAdapterImpl sSyncAdapter = null;
42     private static final Object sSyncAdapterLock = new Object();
43 
44     private static final String ACCOUNT_AND_TYPE_CALENDAR =
45         MailboxColumns.ACCOUNT_KEY + "=? AND " + MailboxColumns.TYPE + '=' + Mailbox.TYPE_CALENDAR;
46     private static final String DIRTY_IN_ACCOUNT =
47         Events.DIRTY + "=1 AND " + Events.ACCOUNT_NAME + "=?";
48     private static final String[] ID_SYNC_KEY_PROJECTION =
49         new String[] {MailboxColumns.ID, MailboxColumns.SYNC_KEY};
50     private static final int ID_SYNC_KEY_MAILBOX_ID = 0;
51     private static final int ID_SYNC_KEY_SYNC_KEY = 1;
52 
CalendarSyncAdapterService()53     public CalendarSyncAdapterService() {
54         super();
55     }
56 
57     private static class SyncAdapterImpl extends AbstractThreadedSyncAdapter {
58         private Context mContext;
59 
SyncAdapterImpl(Context context)60         public SyncAdapterImpl(Context context) {
61             super(context, true /* autoInitialize */);
62             mContext = context;
63         }
64 
65         @Override
onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult)66         public void onPerformSync(Account account, Bundle extras,
67                 String authority, ContentProviderClient provider, SyncResult syncResult) {
68             try {
69                 CalendarSyncAdapterService.performSync(mContext, account, extras,
70                         authority, provider, syncResult);
71             } catch (OperationCanceledException e) {
72             }
73         }
74     }
75 
76     @Override
onCreate()77     public void onCreate() {
78         super.onCreate();
79         synchronized (sSyncAdapterLock) {
80             if (sSyncAdapter == null) {
81                 sSyncAdapter = new SyncAdapterImpl(getApplicationContext());
82             }
83         }
84     }
85 
86     @Override
onBind(Intent intent)87     public IBinder onBind(Intent intent) {
88         return sSyncAdapter.getSyncAdapterBinder();
89     }
90 
91     /**
92      * Partial integration with system SyncManager; we tell our EAS ExchangeService to start a
93      * calendar sync when we get the signal from SyncManager.
94      * The missing piece at this point is integration with the push/ping mechanism in EAS; this will
95      * be put in place at a later time.
96      */
performSync(Context context, Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult)97     private static void performSync(Context context, Account account, Bundle extras,
98             String authority, ContentProviderClient provider, SyncResult syncResult)
99             throws OperationCanceledException {
100         ContentResolver cr = context.getContentResolver();
101         boolean logging = Eas.USER_LOG;
102         if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD)) {
103             Cursor c = cr.query(Events.CONTENT_URI,
104                     new String[] {Events._ID}, DIRTY_IN_ACCOUNT, new String[] {account.name}, null);
105             try {
106                 if (!c.moveToFirst()) {
107                     if (logging) {
108                         Log.d(TAG, "No changes for " + account.name);
109                     }
110                     return;
111                 }
112             } finally {
113                 c.close();
114             }
115         }
116 
117         // Find the (EmailProvider) account associated with this email address
118         Cursor accountCursor =
119             cr.query(com.android.emailcommon.provider.Account.CONTENT_URI,
120                     EmailContent.ID_PROJECTION, AccountColumns.EMAIL_ADDRESS + "=?",
121                     new String[] {account.name}, null);
122         try {
123             if (accountCursor.moveToFirst()) {
124                 long accountId = accountCursor.getLong(0);
125                 // Now, find the calendar mailbox associated with the account
126                 Cursor mailboxCursor = cr.query(Mailbox.CONTENT_URI, ID_SYNC_KEY_PROJECTION,
127                         ACCOUNT_AND_TYPE_CALENDAR, new String[] {Long.toString(accountId)}, null);
128                 try {
129                      if (mailboxCursor.moveToFirst()) {
130                         if (logging) {
131                             Log.d(TAG, "Upload sync requested for " + account.name);
132                         }
133                         String syncKey = mailboxCursor.getString(ID_SYNC_KEY_SYNC_KEY);
134                         if ((syncKey == null) || (syncKey.equals("0"))) {
135                             if (logging) {
136                                 Log.d(TAG, "Can't sync; mailbox in initial state");
137                             }
138                             return;
139                         }
140                         // Ask for a sync from our sync manager
141                         ExchangeService.serviceRequest(mailboxCursor.getLong(
142                                 ID_SYNC_KEY_MAILBOX_ID), ExchangeService.SYNC_UPSYNC);
143                     }
144                 } finally {
145                     mailboxCursor.close();
146                 }
147             }
148         } finally {
149             accountCursor.close();
150         }
151     }
152 }