AbstractSyncService.java revision 1403386ebffa1b6093a506a6a24db4523acdc315
1ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank/* 2ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Copyright (C) 2008-2009 Marc Blank 3ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Licensed to The Android Open Source Project. 4ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * 5ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Licensed under the Apache License, Version 2.0 (the "License"); 6ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * you may not use this file except in compliance with the License. 7ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * You may obtain a copy of the License at 8ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * 9ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * http://www.apache.org/licenses/LICENSE-2.0 10ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * 11ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Unless required by applicable law or agreed to in writing, software 12ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * distributed under the License is distributed on an "AS IS" BASIS, 13ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * See the License for the specific language governing permissions and 15ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * limitations under the License. 16ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 17ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 18ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blankpackage com.android.exchange; 19ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 20ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blankimport com.android.email.mail.MessagingException; 2167698e240187c902bed123bf18d342ff25ec75c7Marc Blankimport com.android.email.provider.EmailContent.Account; 2267698e240187c902bed123bf18d342ff25ec75c7Marc Blankimport com.android.email.provider.EmailContent.Mailbox; 2377424af660458104b732bdcb718874b17d0cab3aMarc Blankimport com.android.exchange.utility.FileLogger; 24ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 25ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blankimport android.content.Context; 26ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blankimport android.net.ConnectivityManager; 27ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blankimport android.net.NetworkInfo; 28ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blankimport android.net.NetworkInfo.DetailedState; 29ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blankimport android.util.Log; 30ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 3167698e240187c902bed123bf18d342ff25ec75c7Marc Blankimport java.util.ArrayList; 3267698e240187c902bed123bf18d342ff25ec75c7Marc Blank 33ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank/** 34ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Base class for all protocol services SyncManager (extends Service, implements 35ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Runnable) instantiates subclasses to run a sync (either timed, or push, or 36ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * mail placed in outbox, etc.) EasSyncService is currently implemented; my goal 37ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * would be to move IMAP to this structure when it comes time to introduce push 38ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * functionality. 39ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 40ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blankpublic abstract class AbstractSyncService implements Runnable { 41ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 421b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank public String TAG = "AbstractSyncService"; 43ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 44ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public static final String SUMMARY_PROTOCOL = "_SUMMARY_"; 45ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public static final String SYNCED_PROTOCOL = "_SYNCING_"; 46ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public static final String MOVE_FAVORITES_PROTOCOL = "_MOVE_FAVORITES_"; 47c1e79c036cd2a40e8a6e66b8ea4d37d121d355baMarc Blank public static final int SECONDS = 1000; 48c1e79c036cd2a40e8a6e66b8ea4d37d121d355baMarc Blank public static final int MINUTES = 60*SECONDS; 49c1e79c036cd2a40e8a6e66b8ea4d37d121d355baMarc Blank public static final int HOURS = 60*MINUTES; 50c1e79c036cd2a40e8a6e66b8ea4d37d121d355baMarc Blank public static final int DAYS = 24*HOURS; 51c1e79c036cd2a40e8a6e66b8ea4d37d121d355baMarc Blank 52c1e79c036cd2a40e8a6e66b8ea4d37d121d355baMarc Blank public static final int CONNECT_TIMEOUT = 30*SECONDS; 53c1e79c036cd2a40e8a6e66b8ea4d37d121d355baMarc Blank public static final int NETWORK_WAIT = 15*SECONDS; 54c1e79c036cd2a40e8a6e66b8ea4d37d121d355baMarc Blank 55ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public static final String IMAP_PROTOCOL = "imap"; 56ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public static final String EAS_PROTOCOL = "eas"; 57ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public static final int EXIT_DONE = 0; 58ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public static final int EXIT_IO_ERROR = 1; 59ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public static final int EXIT_LOGIN_FAILURE = 2; 60ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public static final int EXIT_EXCEPTION = 3; 61ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 62ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public Mailbox mMailbox; 63ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank protected long mMailboxId; 64ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank protected Thread mThread; 65ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank protected int mExitStatus = EXIT_EXCEPTION; 66ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank protected String mMailboxName; 67ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public Account mAccount; 681b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank public Context mContext; 69ed5b71376cb6fc3f54d63268afbd798e0b0c0a1bMarc Blank public int mChangeCount = 0; 70ed5b71376cb6fc3f54d63268afbd798e0b0c0a1bMarc Blank public int mSyncReason = 0; 711b275b9408d5b856e2482fa3951827489e9585ccMarc Blank protected volatile boolean mStop = false; 72c1e79c036cd2a40e8a6e66b8ea4d37d121d355baMarc Blank protected Object mSynchronizer = new Object(); 73ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 74d95115d72be6797835e1286fb8f0d2e5a01cf3a8Marc Blank protected volatile long mRequestTime = 0; 75ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank protected ArrayList<PartRequest> mPartRequests = new ArrayList<PartRequest>(); 76ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank protected PartRequest mPendingPartRequest = null; 77ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 78ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank /** 79ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Sent by SyncManager to request that the service stop itself cleanly 80ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 81ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public abstract void stop(); 82ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 83ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank /** 84ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Sent by SyncManager to indicate a user request requiring service has been 85ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * added to the service's pending request queue 86ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 87ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public abstract void ping(); 88ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 89ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank /** 90ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Called to validate an account; abstract to allow each protocol to do what 91ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * is necessary. For consistency with the Email app's original 92ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * functionality, success is indicated by a failure to throw an Exception 93ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * (ugh). Parameters are self-explanatory 947c582a7fb883b3be728f270fbe5277676fe37cf9Marc Blank * 95ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * @param host 96ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * @param userName 97ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * @param password 98ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * @param port 99ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * @param ssl 100ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * @param context 101ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * @throws MessagingException 102ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 103ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public abstract void validateAccount(String host, String userName, String password, int port, 104ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank boolean ssl, Context context) throws MessagingException; 105ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 106ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public AbstractSyncService(Context _context, Mailbox _mailbox) { 107ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank mContext = _context; 108ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank mMailbox = _mailbox; 109ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank mMailboxId = _mailbox.mId; 110ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank mMailboxName = _mailbox.mServerId; 111ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank mAccount = Account.restoreAccountWithId(_context, _mailbox.mAccountKey); 112ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 113ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 114ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank // Will be required when subclasses are instantiated by name 115ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public AbstractSyncService(String prefix) { 116ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 117ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 118ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank /** 119ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * The UI can call this static method to perform account validation. This method wraps each 120ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * protocol's validateAccount method. Arguments are self-explanatory, except where noted. 1217c582a7fb883b3be728f270fbe5277676fe37cf9Marc Blank * 122ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * @param klass the protocol class (EasSyncService.class for example) 123ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * @param host 124ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * @param userName 125ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * @param password 126ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * @param port 127ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * @param ssl 128ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * @param context 129ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * @throws MessagingException 130ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 131ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank static public void validate(Class<? extends AbstractSyncService> klass, String host, 132ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank String userName, String password, int port, boolean ssl, Context context) 133ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank throws MessagingException { 134ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank AbstractSyncService svc; 135ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank try { 136ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank svc = klass.newInstance(); 137ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank svc.validateAccount(host, userName, password, port, ssl, context); 138ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } catch (IllegalAccessException e) { 139ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank throw new MessagingException("internal error", e); 140ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } catch (InstantiationException e) { 141ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank throw new MessagingException("internal error", e); 142ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 143ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 144ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 145ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public static class ValidationResult { 146ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank static final int NO_FAILURE = 0; 147ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank static final int CONNECTION_FAILURE = 1; 148ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank static final int VALIDATION_FAILURE = 2; 149ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank static final int EXCEPTION = 3; 150ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 151ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank static final ValidationResult succeeded = new ValidationResult(true, NO_FAILURE, null); 152ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank boolean success; 153ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank int failure = NO_FAILURE; 154ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank String reason = null; 155ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank Exception exception = null; 156ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 157ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank ValidationResult(boolean _success, int _failure, String _reason) { 158ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank success = _success; 159ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank failure = _failure; 160ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank reason = _reason; 161ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 162ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 163ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank ValidationResult(boolean _success) { 164ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank success = _success; 165ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 166ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 167ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank ValidationResult(Exception e) { 168ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank success = false; 169ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank failure = EXCEPTION; 170ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank exception = e; 171ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 172ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 173ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public boolean isSuccess() { 174ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank return success; 175ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 176ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 177ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public String getReason() { 178ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank return reason; 179ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 180ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 181ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 1821b275b9408d5b856e2482fa3951827489e9585ccMarc Blank public boolean isStopped() { 1831b275b9408d5b856e2482fa3951827489e9585ccMarc Blank return mStop; 1841b275b9408d5b856e2482fa3951827489e9585ccMarc Blank } 1851b275b9408d5b856e2482fa3951827489e9585ccMarc Blank 1861b275b9408d5b856e2482fa3951827489e9585ccMarc Blank public Object getSynchronizer() { 1871b275b9408d5b856e2482fa3951827489e9585ccMarc Blank return mSynchronizer; 1881b275b9408d5b856e2482fa3951827489e9585ccMarc Blank } 1891b275b9408d5b856e2482fa3951827489e9585ccMarc Blank 190ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank /** 1910a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank * Convenience methods to do user logging (i.e. connection activity). Saves a bunch of 192ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * repetitive code. 193ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 1940a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank public void userLog(String string, int code, String string2) { 1950a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank if (Eas.USER_LOG) { 1960a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank userLog(string + code + string2); 1970a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank } 1980a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank } 1990a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank 2000a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank public void userLog(String string, int code) { 2010a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank if (Eas.USER_LOG) { 2020a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank userLog(string + code); 2030a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank } 2040a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank } 2050a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank 2061403386ebffa1b6093a506a6a24db4523acdc315Marc Blank public void userLog(Exception e) { 2071403386ebffa1b6093a506a6a24db4523acdc315Marc Blank if (Eas.FILE_LOG) { 2081403386ebffa1b6093a506a6a24db4523acdc315Marc Blank FileLogger.log(e); 2091403386ebffa1b6093a506a6a24db4523acdc315Marc Blank } 2101403386ebffa1b6093a506a6a24db4523acdc315Marc Blank } 2111403386ebffa1b6093a506a6a24db4523acdc315Marc Blank 2120a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank /** 2130a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank * Standard logging for EAS. 2140a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank * If user logging is active, we concatenate any arguments and log them using Log.d 2150a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank * We also check for file logging, and log appropriately 2160a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank * @param strings strings to concatenate and log 2170a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank */ 2180a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank public void userLog(String ...strings) { 2197c582a7fb883b3be728f270fbe5277676fe37cf9Marc Blank if (Eas.USER_LOG) { 2200a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank String logText; 2210a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank if (strings.length == 1) { 2220a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank logText = strings[0]; 2230a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank } else { 2240a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank StringBuilder sb = new StringBuilder(64); 2250a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank for (String string: strings) { 2260a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank sb.append(string); 2270a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank } 2280a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank logText = sb.toString(); 2290a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank } 2300a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank Log.d(TAG, logText); 23177424af660458104b732bdcb718874b17d0cab3aMarc Blank if (Eas.FILE_LOG) { 2320a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank FileLogger.log(TAG, logText); 23377424af660458104b732bdcb718874b17d0cab3aMarc Blank } 234ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 235ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 236ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 237ed5b71376cb6fc3f54d63268afbd798e0b0c0a1bMarc Blank /** 238ed5b71376cb6fc3f54d63268afbd798e0b0c0a1bMarc Blank * Error log is used for serious issues that should always be logged 239ed5b71376cb6fc3f54d63268afbd798e0b0c0a1bMarc Blank * @param str the string to log 240ed5b71376cb6fc3f54d63268afbd798e0b0c0a1bMarc Blank */ 241ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public void errorLog(String str) { 242ed5b71376cb6fc3f54d63268afbd798e0b0c0a1bMarc Blank Log.e(TAG, str); 24377424af660458104b732bdcb718874b17d0cab3aMarc Blank if (Eas.FILE_LOG) { 24477424af660458104b732bdcb718874b17d0cab3aMarc Blank FileLogger.log(TAG, str); 24577424af660458104b732bdcb718874b17d0cab3aMarc Blank } 246ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 247ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 248ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank /** 2491b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank * Waits for up to 10 seconds for network connectivity; returns whether or not there is 2501b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank * network connectivity. 251ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * 2521b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank * @return whether there is network connectivity 253ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 2541b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank public boolean hasConnectivity() { 2551b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank ConnectivityManager cm = 2561b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE); 2571b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank int tries = 0; 2581b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank while (tries++ < 1) { 259ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank NetworkInfo info = cm.getActiveNetworkInfo(); 260ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank if (info != null && info.isConnected()) { 261ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank DetailedState state = info.getDetailedState(); 262ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank if (state == DetailedState.CONNECTED) { 2631b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank return true; 264ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 2651b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank } 2661b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank try { 2671b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank Thread.sleep(10*SECONDS); 2681b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank } catch (InterruptedException e) { 269ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 270ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 2711b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank return false; 272ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 273ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 274ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank /** 275ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * PartRequest handling (common functionality) 276ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Can be overridden if desired, but IMAP/EAS both use the next three methods as-is 277ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 2787c582a7fb883b3be728f270fbe5277676fe37cf9Marc Blank 279ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public void addPartRequest(PartRequest req) { 280ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank synchronized (mPartRequests) { 281ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank mPartRequests.add(req); 282d95115d72be6797835e1286fb8f0d2e5a01cf3a8Marc Blank mRequestTime = System.currentTimeMillis(); 283ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 284ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 285ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 286ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public void removePartRequest(PartRequest req) { 287ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank synchronized (mPartRequests) { 288ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank mPartRequests.remove(req); 289ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 290ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 291ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 292ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public PartRequest hasPartRequest(long emailId, String part) { 293ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank synchronized (mPartRequests) { 294ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank for (PartRequest pr : mPartRequests) { 295ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank if (pr.emailId == emailId && pr.loc.equals(part)) 296ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank return pr; 297ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 298ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 299ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank return null; 300ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 301ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 3021b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank // cancelPartRequest is sent in response to user input to stop an attachment load 3031b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank // that is in progress. This will almost certainly require code overriding the base 3041b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank // functionality, as sockets may need to be closed, etc. and this functionality will be 3051b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank // service dependent. This returns the canceled PartRequest or null 306ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public PartRequest cancelPartRequest(long emailId, String part) { 307ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank synchronized (mPartRequests) { 308ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank PartRequest p = null; 309ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank for (PartRequest pr : mPartRequests) { 310ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank if (pr.emailId == emailId && pr.loc.equals(part)) { 311ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank p = pr; 312ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank break; 313ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 314ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 315ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank if (p != null) { 316ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank mPartRequests.remove(p); 317ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank return p; 318ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 319ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 320ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank return null; 321ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 322ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank} 323