b/11436795
If an attachment download fails due to a timeout, or
an exception being thrown from startDownload(), we'd call
cancelDownload() on it. But this didn't actually cancel,
it would remove it from the inProgres list, but leave it
in the list of all downloads, so we'd immediately retry it.
This is bad for two reasons:
1. It can starve out other attachment downloads that could
have been successful.
2. It will keep attempting to do network work, even if it's
hopeless, forever, draining battery.
Now, if an attachment download fails in this way, for the first
few times, we'll move it to the tail end of the list of
downloads we'd like to perform. If it fails more than 10 times,
we'll give up completely. Giving up is not permanent, if we
have a reason to attempt a download again (such as the user
tapping on it), then it will get added back to the download
service and retried.
Change-Id: I5364a7d8b4b25ce299b8dcf061db6e9ce12daf75
b/11436795
Some of the logging I enabled here actually causes an
exception to be thrown because the format didn't match
the args in the log command.
Change-Id: If86942e64927c0e8df7573ef099824899e20c289
b/11535121
Now we only delete messages with the same serverId and account
if the account is an exchange account.
Change-Id: Ic2ebb465ccdb38724b88daac8ac40771c7a24bed
b/11294681
We had some really broken logic about handling search
results.
In IMAP search, we would request, in a single pass,
FLAGS, ENVELOPE, STRUCTURE, and BODY_SANE. BODY_SANE means
the first N bytes of message content, whether it be from
the message text or attachments. This is different from how
sync works: In sync, we get FLAGS and ENVELOPE in one pass,
and in a later pass get STRUCTURE and first body part text
for each message.
If the total size of the message exceeded the maximum limit
for BODY_SANE, then we'd mark the message as partial, which
would cause us to create a dummy attachment in copyMessageToProvider().
This is a weird solution to the problem of POP messages not
being completely loaded, because in POP message body and
attachments can't be requested separately, so the dummy attachment
just signified that we needed to fetch more data.
This system fails completely on IMAP, because just fetching the
rest of the body will not get you the attachments.
But even if that code is disabled, attachments in search results
still didn't work properly. For reasons I don't yet understand,
if we requet both STRUCTURE and BODY_SANE at the same time, either
we don't received the full attachment metadata, or we ignore it, and
only use the attachments whose contents could actually fit in the
limit imposed by BODY_SANE. So attachments that didn't fit,
or didn't completely fit, would either be missing or corrupt
and unretriveable.
So, end result: It's not clear why we were trying to load
BODY_SANE all in one pass, unlike how it works for sync.
In fact, the way sync does it now makes a lot of sense: We
load FLAGS and ENVELOPE data (small) and put the in the DB
immediately so they can be displayed. In the second pass we
load the (potentially large) structure and message body. If this
is the right solution for sync, it's probably the right solution
for search. So now, that's what we do.
There is cleanup I'd like to do post MR1: Some code is duplicated
between sync and search that could be consolidated, but we're in
low risk mode now so I only changed search code.
Change-Id: I11475e290cda04b91f76d38ba952679e8e8964d5
b/11436795
Now, if we ever insert or update an attachment to have
a blank location, we'll log a warning with stack trace.
Also, logging from ADS now uses the same log tag as everything
else, so we'll be able to see it without needing to turn
on some funny log tag.
Change-Id: Ic566cd87e8893128d074b897d7594a01ae12bc8c
For now, it sends the device model name as friendly name, in lieu
of actually having a user-supplied friendly name. This is wrong
for at least two reasons:
1) We need to have an actual user-supplied friendly name, but that's
not easy to find.
2) This really shouldn't be a provider query -- it should be something
the Exchange can know locally (ideally this is a system preference
but that's not currently implemented). This workaround just lets
us have some reasonable value that we can update easily.
Bug: 11161234
Change-Id: If83ad768736de19c9d0e833d1f86a6ce9daf5039
In Gmail, we are adding a setting that automatically shows external
images instead of asking user first. Email app should preserve old
behavior.
Bug 11158252
Change-Id: I8b04a1ec31638d756dfee2da8ab2e8178a709416
b/11294681
The problem is that when we try to open an attachment for a
message in search results, it fails. The reason is that part of
loading the attachment, we need to open the remote folder the
message is in. For search results, the message's mailboxKey is
the special fake "search_results" folder, which doesn't actually
exist on the server.
For this change, I've added a new column called "mainMailboxKey".
For search results, this column will be populated with the real
mailbox the message is in. It will be blank for other messages.
This is a quick and low risk fix for this bug, but it's kind
of awkward. We would prefer to do one or both of the following
some time after MR1.
1. Make the "search_results" folder be a virtual folder, the same
way that unread, starred, and other virtual folders are. For these,
there is actually no mailbox row in the database, just some
queries that check various flags in the messages and behave
like folders in the UI. The messages actually still reside in the
real folders.
2. Remove the requirement to open the folder at all to load the
attachment.
Change-Id: I825ab846f78bf8b041a5d1d579260dc5d7b4c522
b/11294681
b/11325976
The problem is that when we get a message as part of a search
result, we'll end up deleting that message from the inbox (or
whatever folder it's currently in). This is because there is
a trigger that deletes messages if a new message is inserted
that has the same serverId and account.
Now, messages with duplicate serverId/account combinations are
allowed if one of the messages is in a SEARCH type folder.
Also, make a change so that when a message comes down in
a search result, we do also copy it into the primary mailbox
that message resides in, we only add it to the SEARCH folder.
Prior to this there was some code that intended to put
the search result message into the regular mailbox it's supposed
to be in, so that we'd have correct state in that message.
Unfortunately, there are several problems with this:
1. The code didn't work, it would make a copy in the regular
folder, and then unconditionally move it to the search folder.
2. If we leave this code in place, putting the message
temporarily into the regular folder still activates the duplicate
message deletion trigger, wiping out the original copy, even with
the update to the trigger.
3. It's unclear that it's even desirable to load the search
result message into the regular folder. It could be a very old
message that would not have been synced before, leaving a large
gap in your inbox, which is confusing and could interfere with
IMAP syncing.
Change-Id: I34671a3b677ab42a3efd0d170a6ebd9246ec493d
Handle the following edge cases when a manual refresh is triggered:
* No connectivity
* Low storage space
* Timeout (sync not started)
Bug: 11241113
Change-Id: I580235d633fcb65999c0bfe8bf383c9c8ba72110
b/11224731
There is a problem in ImapService.processPendingUploads().
It was trying to process updates to existing messages
as uploads. This is wrong, it means that marking a sent
messages as Read can cause it to be uploaded again,
resuling in a new message being created.
Change-Id: I502df52a7b315daeee10c1041db8f30dbfd2c04e
We used to do N+1 DB queries when our list has
N folders in it. Now just do 1 and be smarter about
how we read our values out of it.
Bug: 11112954
Change-Id: Icde0b979ca985e63d6ceba05c3a63f3a9b7e3566
b/11183568
We were surrounding the data parameters with
double quotes. Apparently some servers do not
accept this, and they aren't present in the
imap spec.
However, we've been running with the quotes
for several months now, and it seems to work
on most servers. I'm afraid of changing this
right now, it might cause other servers to fail.
So now we'll try the query without quotes, and
if we get an exception, fall back to the old
style query with the quotes.
Change-Id: Ifb7b1a6dd4a9f7bb6b38bd1611c64e2bddb2e188
b/11174975
There are already several database fixing steps that
occur when the database is opened, add another one
to correct uninitialzed mailbox parent keys.
This is because we use a two pass system for adding
mailbox rows, first to insert the rows, and second to
assign parentKeys to child rows. We need two passes
because we may insert a child row before its parent,
so the parent's rowId is unavailble. But if the process
dies before the second step is complete we'll be in
an inconsistent state.
Change-Id: Ifaeeaca7e82c1e99656033bc1a9f25d7acb67517
b/11158759
Make the default sync setting for drafts folders 0
(never automatically sync), and disable the settings
control so that it cannot be changed.
Also add a db upgrade step to set any existing drafts
folders to not sync, and clean up any Exchange synced
draft messages.
Change-Id: I256bde231d722089ef2a623482f570a20eccf1de
This is related to b/11081672.
The logging needed to track this down was tied to
MailActivityEmail.DEBUG, which is tied to a setting that
no longer exists.
Change-Id: I0a23508832ead6ab3cc613a82e0831986b0af49b
b/11081672
Prior to this, any time the AttachmentDownloadService
got a CONNECTION_ERROR, it would just instantly retry,
without any limit on the number of tries. This is bad
if the server is in a funny state, we'll just keep spamming
it with multiple connection attempts per second. Also,
this kills the client device's battery and responsiveness.
Now, it will retry instantly five times, and then retry on a
10 second delay 5 more times. After that it will give up.
Even if it gives up, if the user visits an email with an
attachment, or taps on an attachment to expand it, we'll
start the process over. So we shouldn't have permanent
apparently data loss, even if we fail on the first 10 tries.
I'm not certain that this is the best backoff/limit policy,
maybe we should add a delay after even the first connection
error. But I'm hesitant to change this at this point, it's
possible that something is relying on this behavior and
we don't have a lot of soak time left.
Change-Id: I53d75d5d214ccca887a89cf65b799fe640cc9bc5
Launch a 2-second delayed message to send a second notification on the folder change update
b/11027351
Change-Id: Ia0a22be79f4a74c6857517cc21e2313cea9cc0e9
b/11069575
The problem is that the UI_MESSAGE query strips out
any inlined attachments, but the UI_ATTACHMENTS query
does not. This means that we display all attachments
at the bottom, regardless of whether or not they're
inlined, but the formatting is wrong because when we measured
we only had the non-inlined attachments.
Maybe we should not display the inlined attachments at
the bottom, but right now if we do that, it's impossible
to save an inlined image. So for now, I'm just making
UI_MESSAGE query keep the inlined attachments so that
both queries have the same behavior.
Change-Id: I155f5bb74dbfbc8dbf02b56dca58fbca3da5da78
b/10968838
The main problem here is that Ui Attachment was always using
a content Uri that was generated using the attachment's account
Id and rowId. This works correctly for attachments in messages
we have received, but it does not work for drafts: Draft attachments
are not stored in the normal place, rather, they are stored in
the cache directory. There is an additional column in the
Attachment table, called cachedFile, which is not replicated in the
Ui attachment. That's okay though, if we have a cachedFile, then
when we are populating a Ui Attachment, we should just use that
for content Uri.
Also, I discoverd that for draft attachments, we were not correctly
setting the account key. That didn't turn out to be the problem,
but I'm fixing it anyway because it will cause problems later on.
Change-Id: I0143ba824f3a5bfcd77f32828931b94d6977626f
Some changes that allow a notification to open Account Settings for a specific
account
Bug: 10930585
Change-Id: Ib329e339b405ccbc0631d5ce6a23bf8fa6d62b83
On updates to content://com.google.android.email.provider/syncedMessage
request a sync for the folder the message is in.
We need to do this because Exchange sync adapter is marked as
android:supportsUploading="false" so notifySync() doesn't work.
Neither does adding a UPLOAD extra to the sync request. If we do that, the
request is dropped.
This means that the sync request will also downsync the folder but t's probably
a good thing anyway.
We could add our own version of UPLOAD extra if we really want to prevent downsync.
Bug: 10678136
Change-Id: I14f06c4da905560716773d31d59388d2e6d25635
I added these to real mailboxes for hierarchical folders, but we
also need them in combined view.
Bug: 10891994
Change-Id: Iaa291fb9a9cd6039fb4d347309ce3a37aa64392a
Use something similar to the sectioned inbox teaser.
This change allows displaying sender snippets in the teaser.
Bug: 9604590
Change-Id: Ib27f002ab8cbd2315d95d46eeb1735aa6b594db5
b/10211620
The problem here is that on app upgrade, we need to change
the types of all email accounts. To do this, we have to
create new accounts and delete the old ones. This resulted
in calendar and contacts data getting deleted.
But we were copying over the last sync keys from the old
account, so on the next sync, we would only get new data.
This means that all of the data that we had gotten on
a previous sync would never be sent again, so calendar
events and contacts would be missing forever.
Now, we just don't migrate the old sync keys. This means
that on the next sync, we'll get all data, and restore
our original state.
This is still not ideal, because it means that any locally
created data that has not yet been synced will be lost
(b/10805685), but it's much better than it was.
Change-Id: I150c4dbdf490a8f3880261e2469795896ebfeab5
b/10602459
It was possible to turn off syncing for an account in global
settings, but we'd continue displaying some sync frequency
in the in-app settings.
Now, we only display the sync frequency if sync is actually
enabled. If it's disabled we always display "never". Also,
when the user changes a sync setting, if it's set to "never",
we leave the frequency in the database as it is, but disable
sync for that account. If it's set to anything else, we store
that in the database and ensure that sync for the account is
enabled. This means we should not have any apparent disagreement
between in-app settings and global settings as to whether or
not syncing will happen.
Change-Id: I1cc54e76aafd25dc4db0f1b713e7d7cbc30bf77f
Also ignore messages without server ids for moves and
state changes.
Also cleanup to match needs of EAS upsync.
Bug: 10678136
Change-Id: Id4d5229b8479e61bd718b707b0d2bc77a9e68046
b/10653370
This prevents NPEs if a serviec happens to still be running
when an account is deleted.
This mirrors a similar pattern in the gmail app.
Change-Id: I6fd8ae5ffe41580df0a321ec22535403e3f32eee
b/10413188
There are still several issues with attachments generally,
but this fixes the most glaring problem: We were short circuiting
in a loop that needed to populate a hash table of remote message
Ids, so not all of them would be present. The later code intended
to load attachments expected it to be fully populated.
There are still several problems, notably that if downloading
doesn't work, it just spins forever, but this fixes the first
problem.
Change-Id: I2b23dcb841edabe108096933fea2350ef61a10f1
We need to track changes that need to be unsynced. Because
Exchange handles moves differently from other changes, we
create two different tables. The tables are structured as
change logs to better handle error cases.
Change-Id: I4df90c75f36707fa117aed9718508426e60e0749
If you went from search results to conversation view, then hit the
back button, we were taking you out of search results to the inbox,
because we didn't know you had search results.
Now, we're tracking this (through the use of a folder type), so we
take you where you should go.
Bug: 10591438
Change-Id: I12ad81323fe3e1f199d9dd06a1a4e18f765b01ee
b/10527550
I'm not yet sure why we're getting this started
in multiple threads, but the methods where the sync
occurs are now synchronized so they can't happen
at the same time.
Change-Id: Icf7afd336ed056bb42df84b8634117afa8f31213
b/10508861
Temporary fix for this.
For some reason, we're getting messages loaded with the wrong
date being stored. If we have a message with date = 0, and we
filter out anything older than 24 hours, then these messages
with the wrong date won't get loaded into our localMessageMap.
Then we won't recognize that message is already present locally,
and we will fetch a duplicate.
I don't yet know why we're getting the date wrong.
Change-Id: Ic91cd263198ee944eddbaf1d90080e8285a5df6a
These settings need to be migrated from the database, not the
SharedPreferences file that likely shouldn't even exist.
Everything added to Account.java was removed in
Ie6ec389b5b5d2e7ab1b299d0877811ae716526e2
when it was believed to be unnecessary.
Bug: 10211615
Change-Id: If6193758febda8a3272d82792492503549a44e32
It's possible to have multiple EmailProviders.
Also get rid of references to the multiprocess attribute.
Bug: 10388165
Change-Id: Ic6be363eaee20b3b5deddc7b3054d1a7419483a1
It wasn't working right anyway.
Also, fix a problem where account settings were
not being fully initialized.
Bug: 8384097
Change-Id: Ia60ace2ce618b64fe4ad5ef8d8ac547a086a26d5
b/10380970
This could happen if the response to the POP3
RETR request did not contain a content length.
Change-Id: I99ad93ec71ba917e0f36bee204d7f8d05c79c5ff
We were always allocating a one element array in
a loop. We can just keep create one array and
reuse it.
Change-Id: Ia44f0b711ef48fb87030c3f09f3f9fb654717b7a
The IMAP time based query only takes a date, not a
date/time. This means that if we want to load all
messages since, for example, Aug 11 at 3:00 PM,
we'll actually get all messages since Aug 11 at any time.
Our local query actually took into account the time, so
when we loaded a map of local messages, it would not
always include all of the same messages that the IMAP
query would. This meant that if we processed a message
that was in our IMAP query window but not our local query
window, we'd always think it was a new message even
if it wasn't.
It's easy enough to increase the size of our local query
window so that it will definitely include all of the
messages the IMAP query might return, but this adds
a new problem: It's no longer safe to delete any local
message that did not come back in our IMAP query result.
Since our local query may include a larger time window
than the IMAP query window, we need to check each message's
timestamp, and only delete it if it is inside the remote
query time window.
Change-Id: Ib3c1bbe8f3db05720d32a981483676afa6d6c38b
Deleting .db files can make malformed database issues
when WAL(write ahead logging) mode is enabled.
EmailProvider doesn't use WAL mode currently,
But it has to be fixed because it might cause the problem in the
future.
Change-Id: Ie0313c5d253f3080401b00b197e7cbf97f25423c
Conflicts:
src/com/android/email/provider/EmailProvider.java
Use DatabaseUtils.longForQuery() method instead of SQLiteDatabase.query().
This reduces processing cost of database cursor.
Change-Id: Ibe53645b32a4de1ab6518f879e564ddf8f75d822
Conflicts:
src/com/android/email/provider/EmailProvider.java