Add support for TrafficStats; use with IMAP/POP3

* All IMAP/POP3 functionality uses TrafficStats except for
  attachment loading (subsequenc CL)

Bug: 4988322

Change-Id: I91d826e0f7151a2101b642c868ab8c37e9660332
This commit is contained in:
Marc Blank 2011-07-07 14:27:59 -07:00
parent c456c257aa
commit 190b2fb8a1
3 changed files with 143 additions and 16 deletions

View File

@ -0,0 +1,113 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.emailcommon;
import android.content.Context;
import com.android.emailcommon.provider.Account;
import com.android.emailcommon.provider.HostAuth;
import com.android.emailcommon.utility.Utility;
/**
* Constants for tagging threads for traffic stats, and associated utilities
*
* Example usage:
* TrafficStats.setThreadStatsTag(accountId | PROTOCOL_IMAP | DATA_EMAIL | REASON_SYNC);
*/
public class TrafficFlags {
// Bits 0->15, account id
private static final int ACCOUNT_MASK = 0x0000FFFF;
// Bits 16&17, protocol (0 = POP3)
private static final int PROTOCOL_SHIFT = 16;
private static final int PROTOCOL_MASK = 3 << PROTOCOL_SHIFT;
public static final int PROTOCOL_POP3 = 0 << PROTOCOL_SHIFT;
public static final int PROTOCOL_IMAP = 1 << PROTOCOL_SHIFT;
public static final int PROTOCOL_EAS = 2 << PROTOCOL_SHIFT;
public static final int PROTOCOL_SMTP = 3 << PROTOCOL_SHIFT;
private static final String[] PROTOCOLS = new String[] {HostAuth.SCHEME_POP3,
HostAuth.SCHEME_IMAP, HostAuth.SCHEME_EAS, HostAuth.SCHEME_SMTP};
// Bits 18&19, type (0 = EMAIL)
private static final int DATA_SHIFT = 18;
private static final int DATA_MASK = 3 << DATA_SHIFT;
public static final int DATA_EMAIL = 0 << DATA_SHIFT;
public static final int DATA_CONTACTS = 1 << DATA_SHIFT;
public static final int DATA_CALENDAR = 2 << DATA_SHIFT;
// Bits 20&21, reason (if protocol != SMTP)
private static final int REASON_SHIFT = 20;
private static final int REASON_MASK = 3 << REASON_SHIFT;
public static final int REASON_SYNC = 0 << REASON_SHIFT;
public static final int REASON_ATTACHMENT_USER = 1 << REASON_SHIFT;
// Note: We don't yet use the PRECACHE reason (it's complicated...)
public static final int REASON_ATTACHMENT_PRECACHE = 2 << REASON_SHIFT;
private static final String[] REASONS = new String[] {"sync", "attachment", "precache"};
/**
* Get flags indicating sync of the passed-in account; note that, by default, these flags
* indicate an email sync; to change the type of sync, simply "or" in DATA_CONTACTS or
* DATA_CALENDAR (since DATA_EMAIL = 0)
*
* @param context the caller's context
* @param account the account being used
* @return flags for syncing this account
*/
public static int getSyncFlags(Context context, Account account) {
int protocolIndex = Utility.arrayIndex(PROTOCOLS, account.getProtocol(context));
return (int)account.mId | REASON_SYNC | (protocolIndex << PROTOCOL_SHIFT);
}
/**
* Get flags indicating attachment loading from the passed-in account
*
* @param context the caller's context
* @param account the account being used
* @return flags for loading an attachment in this account
*/
public static int getAttachmentFlags(Context context, Account account) {
int protocolIndex = Utility.arrayIndex(PROTOCOLS, account.getProtocol(context));
return (int)account.mId | REASON_ATTACHMENT_USER | (protocolIndex << PROTOCOL_SHIFT);
}
/**
* Get flags indicating sending SMTP email from the passed-in account
*
* @param context the caller's context
* @param account the account being used
* @return flags for sending SMTP email from this account
*/
public static int getSmtpFlags(Context context, Account account) {
return (int)account.mId | REASON_SYNC | PROTOCOL_SMTP;
}
public static String toString(int flags) {
StringBuilder sb = new StringBuilder();
sb.append("account ");
sb.append(flags & ACCOUNT_MASK);
sb.append(',');
sb.append(REASONS[(flags & REASON_MASK) >> REASON_SHIFT]);
sb.append(',');
sb.append(PROTOCOLS[(flags & PROTOCOL_MASK) >> PROTOCOL_SHIFT]);
int maskedData = flags & DATA_MASK;
if (maskedData != 0) {
sb.append(',');
sb.append(maskedData == DATA_CALENDAR ? "calendar" : "contacts");
}
return sb.toString();
}
}

View File

@ -16,20 +16,6 @@
package com.android.emailcommon.utility;
import com.android.emailcommon.Logging;
import com.android.emailcommon.provider.Account;
import com.android.emailcommon.provider.EmailContent;
import com.android.emailcommon.provider.EmailContent.AccountColumns;
import com.android.emailcommon.provider.EmailContent.Attachment;
import com.android.emailcommon.provider.EmailContent.AttachmentColumns;
import com.android.emailcommon.provider.EmailContent.HostAuthColumns;
import com.android.emailcommon.provider.EmailContent.MailboxColumns;
import com.android.emailcommon.provider.EmailContent.Message;
import com.android.emailcommon.provider.EmailContent.MessageColumns;
import com.android.emailcommon.provider.HostAuth;
import com.android.emailcommon.provider.Mailbox;
import com.android.emailcommon.provider.ProviderUnavailableException;
import android.app.Activity;
import android.app.Fragment;
import android.content.ContentResolver;
@ -57,6 +43,20 @@ import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.android.emailcommon.Logging;
import com.android.emailcommon.provider.Account;
import com.android.emailcommon.provider.EmailContent;
import com.android.emailcommon.provider.EmailContent.AccountColumns;
import com.android.emailcommon.provider.EmailContent.Attachment;
import com.android.emailcommon.provider.EmailContent.AttachmentColumns;
import com.android.emailcommon.provider.EmailContent.HostAuthColumns;
import com.android.emailcommon.provider.EmailContent.MailboxColumns;
import com.android.emailcommon.provider.EmailContent.Message;
import com.android.emailcommon.provider.EmailContent.MessageColumns;
import com.android.emailcommon.provider.HostAuth;
import com.android.emailcommon.provider.Mailbox;
import com.android.emailcommon.provider.ProviderUnavailableException;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileDescriptor;
@ -119,12 +119,17 @@ public class Utility {
}
public final static boolean arrayContains(Object[] a, Object o) {
int index = arrayIndex(a, o);
return (index >= 0);
}
public final static int arrayIndex(Object[] a, Object o) {
for (int i = 0, count = a.length; i < count; i++) {
if (a[i].equals(o)) {
return true;
return i;
}
}
return false;
return -1;
}
/**

View File

@ -21,6 +21,7 @@ import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.TrafficStats;
import android.net.Uri;
import android.os.Process;
import android.text.TextUtils;
@ -29,6 +30,7 @@ import android.util.Log;
import com.android.email.mail.Sender;
import com.android.email.mail.Store;
import com.android.emailcommon.Logging;
import com.android.emailcommon.TrafficFlags;
import com.android.emailcommon.internet.MimeBodyPart;
import com.android.emailcommon.internet.MimeHeader;
import com.android.emailcommon.internet.MimeMultipart;
@ -256,6 +258,7 @@ public class MessagingController implements Runnable {
// content synchronization (addition AND removal) since each store will likely need
// to implement it's own, unique synchronization methodology.
public void run() {
TrafficStats.setThreadStatsTag(TrafficFlags.getSyncFlags(mContext, account));
Cursor localFolderCursor = null;
try {
// Step 1: Get remote mailboxes
@ -348,6 +351,7 @@ public class MessagingController implements Runnable {
*/
private void synchronizeMailboxSynchronous(final Account account,
final Mailbox folder) {
TrafficStats.setThreadStatsTag(TrafficFlags.getSyncFlags(mContext, account));
mListeners.synchronizeMailboxStarted(account.mId, folder.mId);
if ((folder.mFlags & Mailbox.FLAG_HOLDS_MAIL) == 0) {
// We don't hold messages, so, nothing to synchronize
@ -1078,6 +1082,7 @@ public class MessagingController implements Runnable {
*/
private void processPendingActionsSynchronous(Account account)
throws MessagingException {
TrafficStats.setThreadStatsTag(TrafficFlags.getSyncFlags(mContext, account));
ContentResolver resolver = mContext.getContentResolver();
String[] accountIdArgs = new String[] { Long.toString(account.mId) };
@ -1859,6 +1864,7 @@ public class MessagingController implements Runnable {
mListeners.loadMessageForViewFailed(messageId, "null account or mailbox");
return;
}
TrafficStats.setThreadStatsTag(TrafficFlags.getSyncFlags(mContext, account));
Store remoteStore = Store.getInstance(account, mContext);
String remoteServerId = mailbox.mServerId;
@ -1931,6 +1937,8 @@ public class MessagingController implements Runnable {
background);
return;
}
TrafficStats.setThreadStatsTag(
TrafficFlags.getAttachmentFlags(mContext, account));
Store remoteStore = Store.getInstance(account, mContext);
Folder remoteFolder = remoteStore.getFolder(mailbox.mServerId);
@ -2008,6 +2016,7 @@ public class MessagingController implements Runnable {
*/
public void sendPendingMessagesSynchronous(final Account account,
long sentFolderId) {
TrafficStats.setThreadStatsTag(TrafficFlags.getSmtpFlags(mContext, account));
NotificationController nc = NotificationController.getInstance(mContext);
// 1. Loop through all messages in the account's outbox
long outboxId = Mailbox.findMailboxOfType(mContext, account.mId, Mailbox.TYPE_OUTBOX);