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 207372782488977df778a33d990401ce9e397f646bMarc Blankimport com.android.emailcommon.provider.Account; 2191e6d2a4ff733417090b06f8644615a0fb9160c0Ben Komaloimport com.android.emailcommon.provider.HostAuth; 224d8774462ace9a45154b2df418b9f2fe7a9c685dBen Komaloimport com.android.emailcommon.provider.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; 297b4c3ab965df57afdcddc5bce109467458c409f4Marc Blankimport android.os.Bundle; 30ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blankimport android.util.Log; 31ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 32b20a744b01fef0082b106f44612a3d0fec361800Marc Blankimport java.util.concurrent.LinkedBlockingQueue; 3367698e240187c902bed123bf18d342ff25ec75c7Marc Blank 34ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank/** 35ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Base class for all protocol services SyncManager (extends Service, implements 36ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Runnable) instantiates subclasses to run a sync (either timed, or push, or 37ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * mail placed in outbox, etc.) EasSyncService is currently implemented; my goal 38ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * would be to move IMAP to this structure when it comes time to introduce push 39ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * functionality. 40ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 41ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blankpublic abstract class AbstractSyncService implements Runnable { 42ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 431b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank public String TAG = "AbstractSyncService"; 44ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 45c1e79c036cd2a40e8a6e66b8ea4d37d121d355baMarc Blank public static final int SECONDS = 1000; 46c1e79c036cd2a40e8a6e66b8ea4d37d121d355baMarc Blank public static final int MINUTES = 60*SECONDS; 47c1e79c036cd2a40e8a6e66b8ea4d37d121d355baMarc Blank public static final int HOURS = 60*MINUTES; 48c1e79c036cd2a40e8a6e66b8ea4d37d121d355baMarc Blank public static final int DAYS = 24*HOURS; 49c1e79c036cd2a40e8a6e66b8ea4d37d121d355baMarc Blank 50c1e79c036cd2a40e8a6e66b8ea4d37d121d355baMarc Blank public static final int CONNECT_TIMEOUT = 30*SECONDS; 51c1e79c036cd2a40e8a6e66b8ea4d37d121d355baMarc Blank public static final int NETWORK_WAIT = 15*SECONDS; 52c1e79c036cd2a40e8a6e66b8ea4d37d121d355baMarc Blank 53ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public static final String EAS_PROTOCOL = "eas"; 54ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public static final int EXIT_DONE = 0; 55ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public static final int EXIT_IO_ERROR = 1; 56ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public static final int EXIT_LOGIN_FAILURE = 2; 57ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public static final int EXIT_EXCEPTION = 3; 5820da011530088036d2bf45d3836d6986a4b5d423Marc Blank public static final int EXIT_SECURITY_FAILURE = 4; 5977186bb1a174432ef272584374942d8b9228e39cMarc Blank public static final int EXIT_ACCESS_DENIED = 5; 60ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 61ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public Mailbox mMailbox; 62ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank protected long mMailboxId; 63ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank protected int mExitStatus = EXIT_EXCEPTION; 64ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank protected String mMailboxName; 65ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public Account mAccount; 661b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank public Context mContext; 67ed5b71376cb6fc3f54d63268afbd798e0b0c0a1bMarc Blank public int mChangeCount = 0; 68feb60882fdf4ea57d65717b55c265e91dae9f9ceMarc Blank public volatile int mSyncReason = 0; 691b275b9408d5b856e2482fa3951827489e9585ccMarc Blank protected volatile boolean mStop = false; 70d0bb59f5d1c7e1d8b6c2350d3ad769a2073a0230Marc Blank protected volatile Thread mThread; 71d0bb59f5d1c7e1d8b6c2350d3ad769a2073a0230Marc Blank protected final Object mSynchronizer = new Object(); 72ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 73d95115d72be6797835e1286fb8f0d2e5a01cf3a8Marc Blank protected volatile long mRequestTime = 0; 74b20a744b01fef0082b106f44612a3d0fec361800Marc Blank protected LinkedBlockingQueue<Request> mRequestQueue = new LinkedBlockingQueue<Request>(); 75ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 76ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank /** 77ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Sent by SyncManager to request that the service stop itself cleanly 78ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 79ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public abstract void stop(); 80ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 81ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank /** 825b4baf900a589e0ed00289631f6d0e1f85a95ecdMarc Blank * Sent by SyncManager to indicate that an alarm has fired for this service, and that its 835b4baf900a589e0ed00289631f6d0e1f85a95ecdMarc Blank * pending (network) operation has timed out. The service is NOT automatically stopped, 845b4baf900a589e0ed00289631f6d0e1f85a95ecdMarc Blank * although the behavior is service dependent. 855b4baf900a589e0ed00289631f6d0e1f85a95ecdMarc Blank * 865b4baf900a589e0ed00289631f6d0e1f85a95ecdMarc Blank * @return true if the operation was stopped normally; false if the thread needed to be 875b4baf900a589e0ed00289631f6d0e1f85a95ecdMarc Blank * interrupted. 88ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 895b4baf900a589e0ed00289631f6d0e1f85a95ecdMarc Blank public abstract boolean alarm(); 90e8ea6833e0541f0a0a3ceb1d78c84ac9ce359210Marc Blank 91e8ea6833e0541f0a0a3ceb1d78c84ac9ce359210Marc Blank /** 92e8ea6833e0541f0a0a3ceb1d78c84ac9ce359210Marc Blank * Sent by SyncManager to request that the service reset itself cleanly; the meaning of this 93e8ea6833e0541f0a0a3ceb1d78c84ac9ce359210Marc Blank * operation is service dependent. 94e8ea6833e0541f0a0a3ceb1d78c84ac9ce359210Marc Blank */ 95e8ea6833e0541f0a0a3ceb1d78c84ac9ce359210Marc Blank public abstract void reset(); 96ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 97ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank /** 98ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * Called to validate an account; abstract to allow each protocol to do what 99ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * is necessary. For consistency with the Email app's original 100ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * functionality, success is indicated by a failure to throw an Exception 101ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * (ugh). Parameters are self-explanatory 1027c582a7fb883b3be728f270fbe5277676fe37cf9Marc Blank * 10391e6d2a4ff733417090b06f8644615a0fb9160c0Ben Komalo * @param hostAuth 1047b4c3ab965df57afdcddc5bce109467458c409f4Marc Blank * @return a Bundle containing a result code and, depending on the result, a PolicySet or an 1057b4c3ab965df57afdcddc5bce109467458c409f4Marc Blank * error message 106ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 10791e6d2a4ff733417090b06f8644615a0fb9160c0Ben Komalo public abstract Bundle validateAccount(HostAuth hostAuth, Context context); 108ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 109ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public AbstractSyncService(Context _context, Mailbox _mailbox) { 110ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank mContext = _context; 111ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank mMailbox = _mailbox; 112ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank mMailboxId = _mailbox.mId; 113ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank mMailboxName = _mailbox.mServerId; 114ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank mAccount = Account.restoreAccountWithId(_context, _mailbox.mAccountKey); 115ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 116ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 117ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank // Will be required when subclasses are instantiated by name 118ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public AbstractSyncService(String prefix) { 119ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 120ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 121ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank /** 122ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * The UI can call this static method to perform account validation. This method wraps each 123ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * protocol's validateAccount method. Arguments are self-explanatory, except where noted. 1247c582a7fb883b3be728f270fbe5277676fe37cf9Marc Blank * 125ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * @param klass the protocol class (EasSyncService.class for example) 12691e6d2a4ff733417090b06f8644615a0fb9160c0Ben Komalo * @param hostAuth 127ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * @param context 1287b4c3ab965df57afdcddc5bce109467458c409f4Marc Blank * @return a Bundle containing a result code and, depending on the result, a PolicySet or an 1297b4c3ab965df57afdcddc5bce109467458c409f4Marc Blank * error message 130ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 13191e6d2a4ff733417090b06f8644615a0fb9160c0Ben Komalo public static Bundle validate(Class<? extends AbstractSyncService> klass, 13291e6d2a4ff733417090b06f8644615a0fb9160c0Ben Komalo HostAuth hostAuth, Context context) { 133ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank AbstractSyncService svc; 134ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank try { 135ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank svc = klass.newInstance(); 13691e6d2a4ff733417090b06f8644615a0fb9160c0Ben Komalo return svc.validateAccount(hostAuth, context); 137ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } catch (IllegalAccessException e) { 138ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } catch (InstantiationException e) { 139ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 1407b4c3ab965df57afdcddc5bce109467458c409f4Marc Blank return null; 141ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 142ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 143ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public static class ValidationResult { 144ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank static final int NO_FAILURE = 0; 145ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank static final int CONNECTION_FAILURE = 1; 146ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank static final int VALIDATION_FAILURE = 2; 147ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank static final int EXCEPTION = 3; 148ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 149ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank static final ValidationResult succeeded = new ValidationResult(true, NO_FAILURE, null); 150ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank boolean success; 151ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank int failure = NO_FAILURE; 152ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank String reason = null; 153ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank Exception exception = null; 154ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 155ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank ValidationResult(boolean _success, int _failure, String _reason) { 156ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank success = _success; 157ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank failure = _failure; 158ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank reason = _reason; 159ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 160ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 161ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank ValidationResult(boolean _success) { 162ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank success = _success; 163ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 164ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 165ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank ValidationResult(Exception e) { 166ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank success = false; 167ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank failure = EXCEPTION; 168ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank exception = e; 169ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 170ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 171ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public boolean isSuccess() { 172ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank return success; 173ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 174ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 175ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public String getReason() { 176ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank return reason; 177ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 178ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 179ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 1801b275b9408d5b856e2482fa3951827489e9585ccMarc Blank public boolean isStopped() { 1811b275b9408d5b856e2482fa3951827489e9585ccMarc Blank return mStop; 1821b275b9408d5b856e2482fa3951827489e9585ccMarc Blank } 1831b275b9408d5b856e2482fa3951827489e9585ccMarc Blank 1841b275b9408d5b856e2482fa3951827489e9585ccMarc Blank public Object getSynchronizer() { 1851b275b9408d5b856e2482fa3951827489e9585ccMarc Blank return mSynchronizer; 1861b275b9408d5b856e2482fa3951827489e9585ccMarc Blank } 1871b275b9408d5b856e2482fa3951827489e9585ccMarc Blank 188ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank /** 1890a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank * Convenience methods to do user logging (i.e. connection activity). Saves a bunch of 190ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * repetitive code. 191ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 1920a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank public void userLog(String string, int code, String string2) { 1930a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank if (Eas.USER_LOG) { 1940a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank userLog(string + code + string2); 1950a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank } 1960a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank } 1970a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank 1980a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank public void userLog(String string, int code) { 1990a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank if (Eas.USER_LOG) { 2000a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank userLog(string + code); 2010a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank } 2020a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank } 2030a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank 2041431215b5fc40d0d6498b0fe602ad4d1b8a66ff3Marc Blank public void userLog(String str, Exception e) { 2051431215b5fc40d0d6498b0fe602ad4d1b8a66ff3Marc Blank if (Eas.USER_LOG) { 2061431215b5fc40d0d6498b0fe602ad4d1b8a66ff3Marc Blank Log.e(TAG, str, e); 2071431215b5fc40d0d6498b0fe602ad4d1b8a66ff3Marc Blank } else { 2081431215b5fc40d0d6498b0fe602ad4d1b8a66ff3Marc Blank Log.e(TAG, str + e); 2091431215b5fc40d0d6498b0fe602ad4d1b8a66ff3Marc Blank } 2101403386ebffa1b6093a506a6a24db4523acdc315Marc Blank if (Eas.FILE_LOG) { 2111403386ebffa1b6093a506a6a24db4523acdc315Marc Blank FileLogger.log(e); 2121403386ebffa1b6093a506a6a24db4523acdc315Marc Blank } 2131403386ebffa1b6093a506a6a24db4523acdc315Marc Blank } 2141403386ebffa1b6093a506a6a24db4523acdc315Marc Blank 2150a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank /** 2160a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank * Standard logging for EAS. 2170a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank * If user logging is active, we concatenate any arguments and log them using Log.d 2180a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank * We also check for file logging, and log appropriately 2190a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank * @param strings strings to concatenate and log 2200a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank */ 2210a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank public void userLog(String ...strings) { 2227c582a7fb883b3be728f270fbe5277676fe37cf9Marc Blank if (Eas.USER_LOG) { 2230a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank String logText; 2240a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank if (strings.length == 1) { 2250a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank logText = strings[0]; 2260a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank } else { 2270a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank StringBuilder sb = new StringBuilder(64); 2280a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank for (String string: strings) { 2290a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank sb.append(string); 2300a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank } 2310a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank logText = sb.toString(); 2320a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank } 2330a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank Log.d(TAG, logText); 23477424af660458104b732bdcb718874b17d0cab3aMarc Blank if (Eas.FILE_LOG) { 2350a4d05f0d8753c67364f7167e62cea82aef9a81eMarc Blank FileLogger.log(TAG, logText); 23677424af660458104b732bdcb718874b17d0cab3aMarc Blank } 237ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 238ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 239ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 240ed5b71376cb6fc3f54d63268afbd798e0b0c0a1bMarc Blank /** 241ed5b71376cb6fc3f54d63268afbd798e0b0c0a1bMarc Blank * Error log is used for serious issues that should always be logged 242ed5b71376cb6fc3f54d63268afbd798e0b0c0a1bMarc Blank * @param str the string to log 243ed5b71376cb6fc3f54d63268afbd798e0b0c0a1bMarc Blank */ 244ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank public void errorLog(String str) { 245ed5b71376cb6fc3f54d63268afbd798e0b0c0a1bMarc Blank Log.e(TAG, str); 24677424af660458104b732bdcb718874b17d0cab3aMarc Blank if (Eas.FILE_LOG) { 24777424af660458104b732bdcb718874b17d0cab3aMarc Blank FileLogger.log(TAG, str); 24877424af660458104b732bdcb718874b17d0cab3aMarc Blank } 249ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 250ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 251ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank /** 2521b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank * Waits for up to 10 seconds for network connectivity; returns whether or not there is 2531b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank * network connectivity. 254ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank * 2551b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank * @return whether there is network connectivity 256ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 2571b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank public boolean hasConnectivity() { 2581b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank ConnectivityManager cm = 25991e5c5bfa6a12679c7611160ad848d4fa2fc73adMarc Blank (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE); 2601b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank int tries = 0; 2611b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank while (tries++ < 1) { 26291e5c5bfa6a12679c7611160ad848d4fa2fc73adMarc Blank // Use the same test as in ExchangeService#waitForConnectivity 26391e5c5bfa6a12679c7611160ad848d4fa2fc73adMarc Blank // TODO: Create common code for this test in emailcommon 264ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank NetworkInfo info = cm.getActiveNetworkInfo(); 26591e5c5bfa6a12679c7611160ad848d4fa2fc73adMarc Blank if (info != null) { 26691e5c5bfa6a12679c7611160ad848d4fa2fc73adMarc Blank return true; 2671b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank } 2681b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank try { 2691b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank Thread.sleep(10*SECONDS); 2701b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank } catch (InterruptedException e) { 271ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 272ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 2731b06024587a4499bcf3f9005337e8f7cae5ffa26Marc Blank return false; 274ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 275ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 276ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank /** 2777531be7774769c84b499b1de5dc46da3a9468316Marc Blank * Request handling (common functionality) 2787531be7774769c84b499b1de5dc46da3a9468316Marc Blank * Can be overridden if desired 279ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank */ 2807c582a7fb883b3be728f270fbe5277676fe37cf9Marc Blank 2817531be7774769c84b499b1de5dc46da3a9468316Marc Blank public void addRequest(Request req) { 282b20a744b01fef0082b106f44612a3d0fec361800Marc Blank mRequestQueue.offer(req); 283ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 284ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank 2857531be7774769c84b499b1de5dc46da3a9468316Marc Blank public void removeRequest(Request req) { 286b20a744b01fef0082b106f44612a3d0fec361800Marc Blank mRequestQueue.remove(req); 287ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank } 288b20a744b01fef0082b106f44612a3d0fec361800Marc Blank 289b20a744b01fef0082b106f44612a3d0fec361800Marc Blank public boolean hasPendingRequests() { 290b20a744b01fef0082b106f44612a3d0fec361800Marc Blank return !mRequestQueue.isEmpty(); 291057faf66b737bbc7df2eaf77ee7a63827785e1b9Marc Blank } 292b20a744b01fef0082b106f44612a3d0fec361800Marc Blank 293057faf66b737bbc7df2eaf77ee7a63827785e1b9Marc Blank public void clearRequests() { 294057faf66b737bbc7df2eaf77ee7a63827785e1b9Marc Blank mRequestQueue.clear(); 295057faf66b737bbc7df2eaf77ee7a63827785e1b9Marc Blank } 296ab30d429e0c6069604aead9b5e6845b6b91b6a02Marc Blank} 297