AbstractSyncAdapter.java revision c8e4352ea6cfa67f15140512e84af8ccede222d2
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
18package com.android.exchange.adapter;
19
20import com.android.emailcommon.provider.EmailContent.Account;
21import com.android.emailcommon.provider.EmailContent.Mailbox;
22import com.android.exchange.Eas;
23import com.android.exchange.EasSyncService;
24
25import android.content.ContentResolver;
26import android.content.Context;
27
28import java.io.IOException;
29import java.io.InputStream;
30
31/**
32 * Parent class of all sync adapters (EasMailbox, EasCalendar, and EasContacts)
33 *
34 */
35public abstract class AbstractSyncAdapter {
36
37    public static final int SECONDS = 1000;
38    public static final int MINUTES = SECONDS*60;
39    public static final int HOURS = MINUTES*60;
40    public static final int DAYS = HOURS*24;
41    public static final int WEEKS = DAYS*7;
42
43    protected static final String PIM_WINDOW_SIZE = "4";
44
45    public Mailbox mMailbox;
46    public EasSyncService mService;
47    public Context mContext;
48    public Account mAccount;
49    public final ContentResolver mContentResolver;
50    public final android.accounts.Account mAccountManagerAccount;
51
52    // Create the data for local changes that need to be sent up to the server
53    public abstract boolean sendLocalChanges(Serializer s)
54        throws IOException;
55    // Parse incoming data from the EAS server, creating, modifying, and deleting objects as
56    // required through the EmailProvider
57    public abstract boolean parse(InputStream is)
58        throws IOException;
59    // The name used to specify the collection type of the target (Email, Calendar, or Contacts)
60    public abstract String getCollectionName();
61    public abstract void cleanup();
62    public abstract boolean isSyncable();
63    // Add sync options (filter, body type - html vs plain, and truncation)
64    public abstract void sendSyncOptions(Double protocolVersion, Serializer s)
65        throws IOException;
66    /**
67     * Delete all records of this class in this account
68     */
69    public abstract void wipe();
70
71    public boolean isLooping() {
72        return false;
73    }
74
75    public AbstractSyncAdapter(EasSyncService service) {
76        mService = service;
77        mMailbox = service.mMailbox;
78        mContext = service.mContext;
79        mAccount = service.mAccount;
80        mAccountManagerAccount = new android.accounts.Account(mAccount.mEmailAddress,
81                Eas.EXCHANGE_ACCOUNT_MANAGER_TYPE);
82        mContentResolver = mContext.getContentResolver();
83    }
84
85    public void userLog(String ...strings) {
86        mService.userLog(strings);
87    }
88
89    public void incrementChangeCount() {
90        mService.mChangeCount++;
91    }
92
93    /**
94     * Set sync options common to PIM's (contacts and calendar)
95     * @param protocolVersion the protocol version under which we're syncing
96     * @param the filter to use (or null)
97     * @param s the Serializer
98     * @throws IOException
99     */
100    protected void setPimSyncOptions(Double protocolVersion, String filter, Serializer s)
101            throws IOException {
102        s.tag(Tags.SYNC_DELETES_AS_MOVES);
103        s.tag(Tags.SYNC_GET_CHANGES);
104        s.data(Tags.SYNC_WINDOW_SIZE, PIM_WINDOW_SIZE);
105        s.start(Tags.SYNC_OPTIONS);
106        // Set the filter (lookback), if provided
107        if (filter != null) {
108            s.data(Tags.SYNC_FILTER_TYPE, filter);
109        }
110        // Set the truncation amount and body type
111        if (protocolVersion >= Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) {
112            s.start(Tags.BASE_BODY_PREFERENCE);
113            // Plain text
114            s.data(Tags.BASE_TYPE, Eas.BODY_PREFERENCE_TEXT);
115            s.data(Tags.BASE_TRUNCATION_SIZE, Eas.EAS12_TRUNCATION_SIZE);
116            s.end();
117        } else {
118            s.data(Tags.SYNC_TRUNCATION, Eas.EAS2_5_TRUNCATION_SIZE);
119        }
120        s.end();
121    }
122
123    /**
124     * Returns the current SyncKey; override if the SyncKey is stored elsewhere (as for Contacts)
125     * @return the current SyncKey for the Mailbox
126     * @throws IOException
127     */
128    public String getSyncKey() throws IOException {
129        if (mMailbox.mSyncKey == null) {
130            userLog("Reset SyncKey to 0");
131            mMailbox.mSyncKey = "0";
132        }
133        return mMailbox.mSyncKey;
134    }
135
136    public void setSyncKey(String syncKey, boolean inCommands) throws IOException {
137        mMailbox.mSyncKey = syncKey;
138    }
139
140    /**
141     * Sync failures can use SyncStatusException, which includes the actual error status and
142     * server id
143     */
144    static class SyncStatusException extends IOException {
145        private static final long serialVersionUID = 1L;
146
147        public final int mStatus;
148        public final String mServerId;
149
150        protected SyncStatusException(String serverId, int status) {
151            mServerId = serverId;
152            mStatus = status;
153        }
154    }
155}
156
157