Home | History | Annotate | Download | only in exchange
      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 
     50     public ContactsSyncAdapterService() {
     51         super();
     52     }
     53 
     54     private static class SyncAdapterImpl extends AbstractThreadedSyncAdapter {
     55         private Context mContext;
     56 
     57         public SyncAdapterImpl(Context context) {
     58             super(context, true /* autoInitialize */);
     59             mContext = context;
     60         }
     61 
     62         @Override
     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
     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
     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      */
     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 }