/** * If values are passed in, replaces any cached cursor with one containing new values, and then * closes the previously cached one (if any, and if not in use) If values are not passed in, * removes the row from cache If the row was locked, unlock it * * @param id the id of the row * @param values new ContentValues for the row (or null if row should simply be removed) * @param wasLocked whether or not the row was locked; if so, the lock will be removed */ private void unlockImpl(String id, ContentValues values, boolean wasLocked) { Cursor c = get(id); if (c != null) { if (MailActivityEmail.DEBUG && DEBUG_CACHE) { LogUtils.d(mLogTag, "=========== Unlocking cache for: " + id); } if (values != null && !sLockCache) { MatrixCursor cursor = getMatrixCursor(id, mBaseProjection, values); if (cursor != null) { if (MailActivityEmail.DEBUG && DEBUG_CACHE) { LogUtils.d(mLogTag, "=========== Recaching with new values: " + id); } cursor.moveToFirst(); mLruCache.put(id, cursor); } else { mLruCache.remove(id); } } else { mLruCache.remove(id); } // If there are no cursors using the old cached cursor, close it if (!sActiveCursors.contains(c)) { c.close(); } } if (wasLocked) { mLockMap.subtract(id); } }
private void refreshEntry(Context context, CacheEntry entry) throws IOException, MessagingException { LogUtils.d(Logging.LOG_TAG, "AuthenticationCache refreshEntry %d", entry.mAccountId); try { final AuthenticationResult result = mAuthenticator.requestRefresh(context, entry.mProviderId, entry.mRefreshToken); // Don't set the refresh token here, it's not returned by the refresh response, // so setting it here would make it blank. entry.mAccessToken = result.mAccessToken; entry.mExpirationTime = result.mExpiresInSeconds * DateUtils.SECOND_IN_MILLIS + System.currentTimeMillis(); saveEntry(context, entry); } catch (AuthenticationFailedException e) { // This is fatal. Clear the tokens and rethrow the exception. LogUtils.d(Logging.LOG_TAG, "authentication failed, clearning"); clearEntry(context, entry); throw e; } catch (MessagingException e) { LogUtils.d(Logging.LOG_TAG, "messaging exception"); throw e; } catch (IOException e) { LogUtils.d(Logging.LOG_TAG, "IO exception"); throw e; } }
public synchronized Cursor putCursorImpl( Cursor c, String id, String[] projection, CacheToken token) { try { if (!token.isValid()) { if (MailActivityEmail.DEBUG && DEBUG_CACHE) { LogUtils.d(mLogTag, "============ Stale token for " + id); } mStats.mStaleCount++; return c; } if (c != null && Arrays.equals(projection, mBaseProjection) && !sLockCache) { if (MailActivityEmail.DEBUG && DEBUG_CACHE) { LogUtils.d(mLogTag, "============ Caching cursor for: " + id); } // If we've already cached this cursor, invalidate the older one Cursor existingCursor = get(id); if (existingCursor != null) { unlockImpl(id, null, false); } mLruCache.put(id, c); return new CachedCursor(c, this, id); } return c; } finally { mTokenList.remove(token); } }
/** * Add a single attachment part to the message * * <p>This will skip adding attachments if they are already found in the attachments table. The * heuristic for this will fail (false-positive) if two identical attachments are included in a * single POP3 message. TODO: Fix that, by (elsewhere) simulating an mLocation value based on the * attachments position within the list of multipart/mixed elements. This would make every POP3 * attachment unique, and might also simplify the code (since we could just look at the positions, * and ignore the filename, etc.) * * <p>TODO: Take a closer look at encoding and deal with it if necessary. * * @param context a context for file operations * @param localMessage the attachments will be built against this message * @param part a single attachment part from POP or IMAP */ public static void addOneAttachment( final Context context, final EmailContent.Message localMessage, final Part part) throws MessagingException, IOException { final Attachment localAttachment = mimePartToAttachment(part); localAttachment.mMessageKey = localMessage.mId; localAttachment.mAccountKey = localMessage.mAccountKey; if (DEBUG_ATTACHMENTS) { LogUtils.d(Logging.LOG_TAG, "Add attachment " + localAttachment); } // To prevent duplication - do we already have a matching attachment? // The fields we'll check for equality are: // mFileName, mMimeType, mContentId, mMessageKey, mLocation // NOTE: This will false-positive if you attach the exact same file, twice, to a POP3 // message. We can live with that - you'll get one of the copies. final Uri uri = ContentUris.withAppendedId(Attachment.MESSAGE_ID_URI, localMessage.mId); final Cursor cursor = context.getContentResolver().query(uri, Attachment.CONTENT_PROJECTION, null, null, null); boolean attachmentFoundInDb = false; try { while (cursor.moveToNext()) { final Attachment dbAttachment = new Attachment(); dbAttachment.restore(cursor); // We test each of the fields here (instead of in SQL) because they may be // null, or may be strings. if (!TextUtils.equals(dbAttachment.mFileName, localAttachment.mFileName) || !TextUtils.equals(dbAttachment.mMimeType, localAttachment.mMimeType) || !TextUtils.equals(dbAttachment.mContentId, localAttachment.mContentId) || !TextUtils.equals(dbAttachment.mLocation, localAttachment.mLocation)) { continue; } // We found a match, so use the existing attachment id, and stop looking/looping attachmentFoundInDb = true; localAttachment.mId = dbAttachment.mId; if (DEBUG_ATTACHMENTS) { LogUtils.d(Logging.LOG_TAG, "Skipped, found db attachment " + dbAttachment); } break; } } finally { cursor.close(); } // Save the attachment (so far) in order to obtain an id if (!attachmentFoundInDb) { localAttachment.save(context); } // If an attachment body was actually provided, we need to write the file now saveAttachmentBody(context, part, localAttachment, localMessage.mAccountKey); if (localMessage.mAttachments == null) { localMessage.mAttachments = new ArrayList<Attachment>(); } localMessage.mAttachments.add(localAttachment); localMessage.mFlagAttachment = true; }
/*package*/ boolean remove(CacheToken token) { boolean result = super.remove(token); if (MailActivityEmail.DEBUG && DEBUG_TOKENS) { if (result) { LogUtils.d(mLogTag, "============ Removing token for: " + token.mId); } else { LogUtils.d(mLogTag, "============ No token found for: " + token.mId); } } return result; }
public static void dumpStats() { Statistics totals = new Statistics("Totals"); for (ContentCache cache : sContentCaches) { if (cache != null) { LogUtils.d(cache.mName, cache.mStats.toString()); totals.addCacheStatistics(cache); } } LogUtils.d(totals.mName, totals.toString()); }
private static Bitmap createImageThumbnail(InputStream data) { try { Bitmap bitmap = BitmapFactory.decodeStream(data); return bitmap; } catch (OutOfMemoryError oome) { LogUtils.d(Logging.LOG_TAG, "createImageThumbnail failed with " + oome.getMessage()); return null; } catch (Exception e) { LogUtils.d(Logging.LOG_TAG, "createImageThumbnail failed with " + e.getMessage()); return null; } }
/** * Set the requested security level based on the aggregate set of requests. If the set is empty, * we release our device administration. If the set is non-empty, we only proceed if we are * already active as an admin. */ public void setActivePolicies() { DevicePolicyManager dpm = getDPM(); // compute aggregate set of policies Policy aggregatePolicy = getAggregatePolicy(); // if empty set, detach from policy manager if (aggregatePolicy == Policy.NO_POLICY) { if (DebugUtils.DEBUG) { LogUtils.d(TAG, "setActivePolicies: none, remove admin"); } dpm.removeActiveAdmin(mAdminName); } else if (isActiveAdmin()) { if (DebugUtils.DEBUG) { LogUtils.d(TAG, "setActivePolicies: " + aggregatePolicy); } // set each policy in the policy manager // password mode & length dpm.setPasswordQuality(mAdminName, aggregatePolicy.getDPManagerPasswordQuality()); dpm.setPasswordMinimumLength(mAdminName, aggregatePolicy.mPasswordMinLength); // screen lock time dpm.setMaximumTimeToLock(mAdminName, aggregatePolicy.mMaxScreenLockTime * 1000); // local wipe (failed passwords limit) dpm.setMaximumFailedPasswordsForWipe(mAdminName, aggregatePolicy.mPasswordMaxFails); // password expiration (days until a password expires). API takes mSec. dpm.setPasswordExpirationTimeout( mAdminName, aggregatePolicy.getDPManagerPasswordExpirationTimeout()); // password history length (number of previous passwords that may not be reused) dpm.setPasswordHistoryLength(mAdminName, aggregatePolicy.mPasswordHistory); // password minimum complex characters. // Note, in Exchange, "complex chars" simply means "non alpha", but in the DPM, // setting the quality to complex also defaults min symbols=1 and min numeric=1. // We always / safely clear minSymbols & minNumeric to zero (there is no policy // configuration in which we explicitly require a minimum number of digits or symbols.) dpm.setPasswordMinimumSymbols(mAdminName, 0); dpm.setPasswordMinimumNumeric(mAdminName, 0); dpm.setPasswordMinimumNonLetter(mAdminName, aggregatePolicy.mPasswordComplexChars); // Device capabilities try { // If we are running in a managed policy, it is a securityException to even // call setCameraDisabled(), if is disabled is false. We have to swallow // the exception here. dpm.setCameraDisabled(mAdminName, aggregatePolicy.mDontAllowCamera); } catch (SecurityException e) { LogUtils.d(TAG, "SecurityException in setCameraDisabled, nothing changed"); } // encryption required dpm.setStorageEncryption(mAdminName, aggregatePolicy.mRequireEncryption); } }
/** Writes a single line to the server using \r\n termination. */ public void writeLine(String s, String sensitiveReplacement) throws IOException { if (MailActivityEmail.DEBUG) { if (sensitiveReplacement != null && !Logging.DEBUG_SENSITIVE) { LogUtils.d(Logging.LOG_TAG, ">>> " + sensitiveReplacement); } else { LogUtils.d(Logging.LOG_TAG, ">>> " + s); } } OutputStream out = getOutputStream(); out.write(s.getBytes()); out.write('\r'); out.write('\n'); out.flush(); }
public void render(Attachment paramAttachment, boolean paramBoolean) { Attachment localAttachment = this.mAttachment; this.mAttachment = paramAttachment; this.mActionHandler.setAttachment(this.mAttachment); if (!paramAttachment.isDownloading()) ; for (boolean bool = false; ; bool = this.mSaveClicked) { this.mSaveClicked = bool; String str = LOG_TAG; Object[] arrayOfObject = new Object[6]; arrayOfObject[0] = paramAttachment.name; arrayOfObject[1] = Integer.valueOf(paramAttachment.state); arrayOfObject[2] = Integer.valueOf(paramAttachment.destination); arrayOfObject[3] = Integer.valueOf(paramAttachment.downloadedSize); arrayOfObject[4] = paramAttachment.contentUri; arrayOfObject[5] = paramAttachment.contentType; LogUtils.d( str, "got attachment list row: name=%s state/dest=%d/%d dled=%d contentUri=%s MIME=%s", arrayOfObject); if ((localAttachment == null) || (!TextUtils.equals(paramAttachment.name, localAttachment.name))) this.mTitle.setText(paramAttachment.name); if ((localAttachment == null) || (paramAttachment.size != localAttachment.size)) { this.mAttachmentSizeText = AttachmentUtils.convertToHumanReadableSize(getContext(), paramAttachment.size); this.mDisplayType = AttachmentUtils.getDisplayType(getContext(), paramAttachment); updateSubtitleText(null); } updateActions(); this.mActionHandler.updateStatus(paramBoolean); return; } }
public static void alwaysLog(String str) { if (!Eas.USER_LOG) { LogUtils.d(TAG, str); } else { log(str); } }
private boolean parseStore() throws IOException { EmailSyncAdapter adapter = new EmailSyncAdapter(mService); EasEmailSyncParser parser = new EasEmailSyncParser(this, adapter); ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); boolean res = false; while (nextTag(Tags.SEARCH_STORE) != END) { if (tag == Tags.SEARCH_STATUS) { getValue(); } else if (tag == Tags.SEARCH_TOTAL) { mTotalResults = getValueInt(); } else if (tag == Tags.SEARCH_RESULT) { parseResult(parser, ops); } else { skipTag(); } } try { adapter.mContentResolver.applyBatch(EmailContent.AUTHORITY, ops); /// M: get the current result count. mCurrentResults = ops.size(); if (Eas.USER_LOG) { mService.userLog("Saved " + ops.size() + " search results"); } } catch (RemoteException e) { LogUtils.d(Logging.LOG_TAG, "RemoteException while saving search results."); } catch (OperationApplicationException e) { } return res; }
private CacheEntry getEntry(Context context, Account account) { CacheEntry entry; if (account.isSaved() && !account.isTemporary()) { entry = mCache.get(account.mId); if (entry == null) { LogUtils.d(Logging.LOG_TAG, "initializing entry from database"); final HostAuth hostAuth = account.getOrCreateHostAuthRecv(context); final Credential credential = hostAuth.getOrCreateCredential(context); entry = new CacheEntry( account.mId, credential.mProviderId, credential.mAccessToken, credential.mRefreshToken, credential.mExpiration); mCache.put(account.mId, entry); } } else { // This account is temporary, just create a temporary entry. Don't store // it in the cache, it won't be findable because we don't yet have an account Id. final HostAuth hostAuth = account.getOrCreateHostAuthRecv(context); final Credential credential = hostAuth.getCredential(context); entry = new CacheEntry( account.mId, credential.mProviderId, credential.mAccessToken, credential.mRefreshToken, credential.mExpiration); } return entry; }
@Override public void loadMore(long messageId) throws RemoteException { /// M: We Can't load more in low storage state @{ if (StorageLowState.checkIfStorageLow(mContext)) { LogUtils.e(Logging.LOG_TAG, "Can't load more due to low storage"); return; } /// @} // Load a message for view... try { // 1. Resample the message, in case it disappeared or synced while // this command was in queue final EmailContent.Message message = EmailContent.Message.restoreMessageWithId(mContext, messageId); if (message == null) { return; } if (message.mFlagLoaded == EmailContent.Message.FLAG_LOADED_COMPLETE) { // We should NEVER get here return; } // 2. Open the remote folder. // TODO combine with common code in loadAttachment final Account account = Account.restoreAccountWithId(mContext, message.mAccountKey); final Mailbox mailbox = Mailbox.restoreMailboxWithId(mContext, message.mMailboxKey); if (account == null || mailbox == null) { // mListeners.loadMessageForViewFailed(messageId, "null account or mailbox"); return; } TrafficStats.setThreadStatsTag(TrafficFlags.getSyncFlags(mContext, account)); final Store remoteStore = Store.getInstance(account, mContext); final String remoteServerId; // If this is a search result, use the protocolSearchInfo field to get the // correct remote location if (!TextUtils.isEmpty(message.mProtocolSearchInfo)) { remoteServerId = message.mProtocolSearchInfo; } else { remoteServerId = mailbox.mServerId; } final Folder remoteFolder = remoteStore.getFolder(remoteServerId); remoteFolder.open(OpenMode.READ_WRITE); // 3. Set up to download the entire message final Message remoteMessage = remoteFolder.getMessage(message.mServerId); final FetchProfile fp = new FetchProfile(); fp.add(FetchProfile.Item.BODY); remoteFolder.fetch(new Message[] {remoteMessage}, fp, null); // 4. Write to provider Utilities.copyOneMessageToProvider( mContext, remoteMessage, account, mailbox, EmailContent.Message.FLAG_LOADED_COMPLETE); } catch (MessagingException me) { if (Logging.LOGD) LogUtils.v(Logging.LOG_TAG, "", me); } catch (RuntimeException rte) { LogUtils.d(Logging.LOG_TAG, "RTE During loadMore"); } }
/** * Parse a message from the server stream. * * @return the parsed Message * @throws IOException */ private EmailContent.Message addParser(final int endingTag) throws IOException, CommandStatusException { EmailContent.Message msg = new EmailContent.Message(); msg.mAccountKey = mAccount.mId; msg.mMailboxKey = mMailbox.mId; msg.mFlagLoaded = EmailContent.Message.FLAG_LOADED_COMPLETE; // Default to 1 (success) in case we don't get this tag int status = 1; while (nextTag(endingTag) != END) { switch (tag) { case Tags.SYNC_SERVER_ID: msg.mServerId = getValue(); LogUtils.d(TAG, "ServerId: %s", msg.mServerId); break; case Tags.SYNC_STATUS: status = getValueInt(); break; case Tags.SYNC_APPLICATION_DATA: addData(msg, tag); break; default: skipTag(); } } // For sync, status 1 = success if (status != 1) { throw new CommandStatusException(status, msg.mServerId); } return msg; }
@Override public void onCreate(Bundle savedState) { super.onCreate(savedState); parseArguments(); setBaseUri(); LogUtils.d(LOG_TAG, "onCreate in ConversationViewFragment (this=%s)", this); // Not really, we just want to get a crack to store a reference to the change_folder item setHasOptionsMenu(true); if (savedState != null) { mViewState = savedState.getParcelable(BUNDLE_VIEW_STATE); mUserVisible = savedState.getBoolean(BUNDLE_USER_VISIBLE); mIsDetached = savedState.getBoolean(BUNDLE_DETACHED, false); mHasConversationBeenTransformed = savedState.getBoolean(BUNDLE_KEY_HAS_CONVERSATION_BEEN_TRANSFORMED, false); mHasConversationTransformBeenReverted = savedState.getBoolean(BUNDLE_KEY_HAS_CONVERSATION_BEEN_REVERTED, false); } else { mViewState = getNewViewState(); mHasConversationBeenTransformed = false; mHasConversationTransformBeenReverted = false; } }
/** * API: Remote wipe (from server). This is final, there is no confirmation. It will only return to * the caller if there is an unexpected failure. The wipe includes external storage. */ public void remoteWipe() { DevicePolicyManager dpm = getDPM(); if (dpm.isAdminActive(mAdminName)) { dpm.wipeData(DevicePolicyManager.WIPE_EXTERNAL_STORAGE); } else { LogUtils.d(Logging.LOG_TAG, "Could not remote wipe because not device admin."); } }
private void clearEntry(Context context, CacheEntry entry) { LogUtils.d(Logging.LOG_TAG, "clearEntry"); entry.mAccessToken = ""; entry.mRefreshToken = ""; entry.mExpirationTime = 0; saveEntry(context, entry); mCache.remove(entry.mAccountId); }
protected void onConversationSeen() { LogUtils.d(LOG_TAG, "AbstractConversationViewFragment#onConversationSeen()"); // Ignore unsafe calls made after a fragment is detached from an activity final ControllableActivity activity = (ControllableActivity) getActivity(); if (activity == null) { LogUtils.w(LOG_TAG, "ignoring onConversationSeen for conv=%s", mConversation.id); return; } mViewState.setInfoForConversation(mConversation); LogUtils.d( LOG_TAG, "onConversationSeen() - mSuppressMarkingViewed = %b", mSuppressMarkingViewed); // In most circumstances we want to mark the conversation as viewed and read, since the // user has read it. However, if the user has already marked the conversation unread, we // do not want a later mark-read operation to undo this. So we check this variable which // is set in #markUnread() which suppresses automatic mark-read. if (!mSuppressMarkingViewed) { // mark viewed/read if not previously marked viewed by this conversation view, // or if unread messages still exist in the message list cursor // we don't want to keep marking viewed on rotation or restore // but we do want future re-renders to mark read (e.g. "New message from X" case) final MessageCursor cursor = getMessageCursor(); LogUtils.d( LOG_TAG, "onConversationSeen() - mConversation.isViewed() = %b, " + "cursor null = %b, cursor.isConversationRead() = %b", mConversation.isViewed(), cursor == null, cursor != null && cursor.isConversationRead()); if (!mConversation.isViewed() || (cursor != null && !cursor.isConversationRead())) { // Mark the conversation viewed and read. activity .getConversationUpdater() .markConversationsRead(Arrays.asList(mConversation), true, true); // and update the Message objects in the cursor so the next time a cursor update // happens with these messages marked read, we know to ignore it if (cursor != null && !cursor.isClosed()) { cursor.markMessagesRead(); } } } activity.getListHandler().onConversationSeen(); }
public static void log(String tag, String str) { if (Eas.USER_LOG) { LogUtils.d(tag, str); if (Eas.FILE_LOG) { FileLogger.log(tag, str); } } }
public CacheToken add(String id) { CacheToken token = new CacheToken(id); super.add(token); if (MailActivityEmail.DEBUG && DEBUG_TOKENS) { LogUtils.d(mLogTag, "============ Taking token for: " + token.mId); } return token; }
/*package*/ void invalidate() { if (MailActivityEmail.DEBUG && DEBUG_TOKENS) { LogUtils.d(mLogTag, "============ List invalidated"); } for (CacheToken token : this) { token.invalidate(); } clear(); }
/** * Lock a given row, such that no new valid CacheTokens can be created for the passed-in id. * * @param id the id of the row to lock */ public synchronized void lock(String id) { // Prevent new valid tokens from being created mLockMap.add(id); // Invalidate current tokens int count = mTokenList.invalidateTokens(id); if (MailActivityEmail.DEBUG && DEBUG_TOKENS) { LogUtils.d( mTokenList.mLogTag, "============ Lock invalidated " + count + " tokens for: " + id); } }
private void bodyParser(EmailContent.Message msg) throws IOException { String bodyType = Eas.BODY_PREFERENCE_TEXT; String body = ""; while (nextTag(Tags.BASE_BODY) != END) { switch (tag) { case Tags.BASE_TYPE: bodyType = getValue(); break; case Tags.BASE_DATA: body = getValue(); break; case Tags.BASE_TRUNCATED: // M: Message is partial loaded if AirSyncBaseBody::Truncated is True; // Otherwise message is complete loaded if False String bodyTruncated = getValue(); if ("1".equals(bodyTruncated) || "true".equals(bodyTruncated)) { msg.mFlagLoaded = EmailContent.Message.FLAG_LOADED_PARTIAL; } else { msg.mFlagLoaded = EmailContent.Message.FLAG_LOADED_COMPLETE; } LogUtils.d(TAG, "_____________ EAS 12+ body truncated: " + bodyTruncated); break; default: skipTag(); } } // We always ask for TEXT or HTML; there's no third option if (bodyType.equals(Eas.BODY_PREFERENCE_HTML)) { msg.mHtml = body; } else { msg.mText = body; } /** * M: What if a mail with bodyTruncated tag, but both body html and text are empty? In this * case, client should set a suitable load flag: FLAG_LOADED_COMPLETE. @{ */ if (TextUtils.isEmpty(msg.mHtml) && TextUtils.isEmpty(msg.mText)) { LogUtils.d(TAG, " for empty mailbody, reset load complete tag."); msg.mFlagLoaded = EmailContent.Message.FLAG_LOADED_COMPLETE; } /** @} */ }
@Override public void onLoadFinished( Loader<ObjectCursor<ConversationMessage>> loader, ObjectCursor<ConversationMessage> data) { // ignore truly duplicate results // this can happen when restoring after rotation if (mCursor == data) { return; } else { final MessageCursor messageCursor = (MessageCursor) data; // bind the cursor to this fragment so it can access to the current list controller messageCursor.setController(AbstractConversationViewFragment.this); if (LogUtils.isLoggable(LOG_TAG, LogUtils.DEBUG)) { LogUtils.d(LOG_TAG, "LOADED CONVERSATION= %s", messageCursor.getDebugDump()); } // We have no messages: exit conversation view. if (messageCursor.getCount() == 0 && (!CursorStatus.isWaitingForResults(messageCursor.getStatus()) || mIsDetached)) { if (mUserVisible) { onError(); } else { // we expect that the pager adapter will remove this // conversation fragment on its own due to a separate // conversation cursor update (we might get here if the // message list update fires first. nothing to do // because we expect to be torn down soon.) LogUtils.i( LOG_TAG, "CVF: offscreen conv has no messages, ignoring update" + " in anticipation of conv cursor update. c=%s", mConversation.uri); } // existing mCursor will imminently be closed, must stop referencing it // since we expect to be kicked out soon, it doesn't matter what mCursor // becomes mCursor = null; return; } // ignore cursors that are still loading results if (!messageCursor.isLoaded()) { // existing mCursor will imminently be closed, must stop referencing it // in this case, the new cursor is also no good, and since don't expect to get // here except in initial load situations, it's safest to just ensure the // reference is null mCursor = null; return; } final MessageCursor oldCursor = mCursor; mCursor = messageCursor; onMessageCursorLoadFinished(loader, mCursor, oldCursor); } }
@Override public void dismiss() { if (hasFocus()) { LogUtils.d( LOG_TAG, "Oops! ConverationSpecialItem dismiss with Focus %s but isFocusable is %s.", hasFocus(), isFocusable()); clearFocus(); } }
/** * Attempts to open a connection using the Uri supplied for connection parameters. Will attempt an * SSL connection if indicated. */ public void open() throws MessagingException, CertificateValidationException { if (MailActivityEmail.DEBUG) { LogUtils.d( Logging.LOG_TAG, "*** " + mDebugLabel + " open " + getHost() + ":" + String.valueOf(getPort())); } try { SocketAddress socketAddress = new InetSocketAddress(getHost(), getPort()); if (canTrySslSecurity()) { mSocket = SSLUtils.getSSLSocketFactory(mContext, mHostAuth, canTrustAllCertificates()) .createSocket(); } else { mSocket = new Socket(); } mSocket.connect(socketAddress, SOCKET_CONNECT_TIMEOUT); // After the socket connects to an SSL server, confirm that the hostname is as expected if (canTrySslSecurity() && !canTrustAllCertificates()) { verifyHostname(mSocket, getHost()); } mIn = new BufferedInputStream(mSocket.getInputStream(), 1024); mOut = new BufferedOutputStream(mSocket.getOutputStream(), 512); mSocket.setSoTimeout(SOCKET_READ_TIMEOUT); } catch (SSLException e) { if (MailActivityEmail.DEBUG) { LogUtils.d(Logging.LOG_TAG, e.toString()); } throw new CertificateValidationException(e.getMessage(), e); } catch (IOException ioe) { if (MailActivityEmail.DEBUG) { LogUtils.d(Logging.LOG_TAG, ioe.toString()); } throw new MessagingException(MessagingException.IOERROR, ioe.toString()); } catch (IllegalArgumentException iae) { if (MailActivityEmail.DEBUG) { LogUtils.d(Logging.LOG_TAG, iae.toString()); } throw new MessagingException(MessagingException.UNSPECIFIED_EXCEPTION, iae.toString()); } }
/// M: update UI status, for Loading/LoadMore/NetworkError. public void updateLoadingStatus(boolean start) { LogUtils.d( LogTag.getLogTag(), "updateLoadingStatus show loading progress dialog ? [%s]", start); mNetworkError.setVisibility(View.GONE); if (start) { mLoading.setVisibility(View.VISIBLE); mLoadMore.setVisibility(View.GONE); } else { mLoading.setVisibility(View.GONE); mLoadMore.setVisibility(View.VISIBLE); } }
@Override public void onClick(View v) { final int id = v.getId(); final Folder f = (Folder) v.getTag(); if (id == R.id.error_action_button) { mClickListener.onFooterViewErrorActionClick(f, mErrorStatus); } else if (id == R.id.load_more) { LogUtils.d( LogTag.getLogTag(), "LoadMore triggered folder [%s]", f != null ? f.loadMoreUri : "null"); mClickListener.onFooterViewLoadMoreClick(f); } }
/** * Invalidate the entire cache; the arguments are used for logging only, and indicate the write * operation that caused the invalidation * * @param operation a string describing the operation causing the invalidate (or null) * @param uri the uri causing the invalidate (or null) * @param selection the selection used with the uri (or null) */ public synchronized void invalidate(String operation, Uri uri, String selection) { if (DEBUG_CACHE && (operation != null)) { LogUtils.d( mLogTag, "============ INVALIDATED BY " + operation + ": " + uri + ", SELECTION: " + selection); } mStats.mInvalidateCount++; // Close all cached cursors that are no longer in use mLruCache.evictAll(); // Invalidate all current tokens mTokenList.invalidate(); }