• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 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 com.android.email.Email;
20 import com.android.email.provider.EmailContent;
21 import com.android.email.provider.EmailContent.AccountColumns;
22 import com.android.email.provider.EmailContent.Mailbox;
23 import com.android.email.provider.EmailContent.MailboxColumns;
24 
25 import android.accounts.Account;
26 import android.accounts.OperationCanceledException;
27 import android.app.Service;
28 import android.content.AbstractThreadedSyncAdapter;
29 import android.content.ContentProviderClient;
30 import android.content.ContentResolver;
31 import android.content.Context;
32 import android.content.Intent;
33 import android.content.SyncResult;
34 import android.database.Cursor;
35 import android.net.Uri;
36 import android.os.Bundle;
37 import android.os.IBinder;
38 import android.provider.ContactsContract.RawContacts;
39 import android.util.Log;
40 
41 public class ContactsSyncAdapterService extends Service {
42     private static final String TAG = "EAS ContactsSyncAdapterService";
43     private static SyncAdapterImpl sSyncAdapter = null;
44     private static final Object sSyncAdapterLock = new Object();
45 
46     private static final String[] ID_PROJECTION = new String[] {EmailContent.RECORD_ID};
47     private static final String ACCOUNT_AND_TYPE_CONTACTS =
48         MailboxColumns.ACCOUNT_KEY + "=? AND " + MailboxColumns.TYPE + '=' + Mailbox.TYPE_CONTACTS;
49 
ContactsSyncAdapterService()50     public ContactsSyncAdapterService() {
51         super();
52     }
53 
54     private static class SyncAdapterImpl extends AbstractThreadedSyncAdapter {
55         private Context mContext;
56 
SyncAdapterImpl(Context context)57         public SyncAdapterImpl(Context context) {
58             super(context, true /* autoInitialize */);
59             mContext = context;
60         }
61 
62         @Override
onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult)63         public void onPerformSync(Account account, Bundle extras,
64                 String authority, ContentProviderClient provider, SyncResult syncResult) {
65             try {
66                 ContactsSyncAdapterService.performSync(mContext, account, extras,
67                         authority, provider, syncResult);
68             } catch (OperationCanceledException e) {
69             }
70         }
71     }
72 
73     @Override
onCreate()74     public void onCreate() {
75         super.onCreate();
76         synchronized (sSyncAdapterLock) {
77             if (sSyncAdapter == null) {
78                 sSyncAdapter = new SyncAdapterImpl(getApplicationContext());
79             }
80         }
81     }
82 
83     @Override
onBind(Intent intent)84     public IBinder onBind(Intent intent) {
85         return sSyncAdapter.getSyncAdapterBinder();
86     }
87 
88     /**
89      * Partial integration with system SyncManager; we tell our EAS SyncManager to start a contacts
90      * sync when we get the signal from the system SyncManager.
91      * The missing piece at this point is integration with the push/ping mechanism in EAS; this will
92      * be put in place at a later time.
93      */
performSync(Context context, Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult)94     private static void performSync(Context context, Account account, Bundle extras,
95             String authority, ContentProviderClient provider, SyncResult syncResult)
96             throws OperationCanceledException {
97         ContentResolver cr = context.getContentResolver();
98         Log.i(TAG, "performSync");
99         if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD)) {
100             Uri uri = RawContacts.CONTENT_URI.buildUpon()
101                 .appendQueryParameter(RawContacts.ACCOUNT_NAME, account.name)
102                 .appendQueryParameter(RawContacts.ACCOUNT_TYPE, Email.EXCHANGE_ACCOUNT_MANAGER_TYPE)
103                 .build();
104             Cursor c = cr.query(uri,
105                     new String[] {RawContacts._ID}, RawContacts.DIRTY + "=1", null, null);
106             try {
107                 if (!c.moveToFirst()) {
108                     Log.i(TAG, "Upload sync; no changes");
109                     return;
110                 }
111             } finally {
112                 c.close();
113             }
114         }
115 
116         // Find the (EmailProvider) account associated with this email address
117         Cursor accountCursor =
118             cr.query(com.android.email.provider.EmailContent.Account.CONTENT_URI, ID_PROJECTION,
119                 AccountColumns.EMAIL_ADDRESS + "=?", new String[] {account.name}, null);
120         try {
121             if (accountCursor.moveToFirst()) {
122                 long accountId = accountCursor.getLong(0);
123                 // Now, find the contacts mailbox associated with the account
124                 Cursor mailboxCursor = cr.query(Mailbox.CONTENT_URI, ID_PROJECTION,
125                         ACCOUNT_AND_TYPE_CONTACTS, new String[] {Long.toString(accountId)}, null);
126                 try {
127                      if (mailboxCursor.moveToFirst()) {
128                         Log.i(TAG, "Contact sync requested for " + account.name);
129                         // Ask for a sync from our sync manager
130                         SyncManager.serviceRequest(mailboxCursor.getLong(0),
131                                 SyncManager.SYNC_UPSYNC);
132                     }
133                 } finally {
134                     mailboxCursor.close();
135                 }
136             }
137         } finally {
138             accountCursor.close();
139         }
140     }
141 }