1f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank/*
2f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank * Copyright (C) 2010 The Android Open Source Project
3f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank *
4f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank * Licensed under the Apache License, Version 2.0 (the "License");
5f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank * you may not use this file except in compliance with the License.
6f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank * You may obtain a copy of the License at
7f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank *
8f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank *      http://www.apache.org/licenses/LICENSE-2.0
9f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank *
10f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank * Unless required by applicable law or agreed to in writing, software
11f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank * distributed under the License is distributed on an "AS IS" BASIS,
12f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank * See the License for the specific language governing permissions and
14f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank * limitations under the License.
15f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank */
16f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank
17f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blankpackage com.android.email.service;
18f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank
19faf9ecc992c34de53969335f9fb403d2b17f3163Marc Blankimport android.content.Context;
20faf9ecc992c34de53969335f9fb403d2b17f3163Marc Blankimport android.content.Intent;
21faf9ecc992c34de53969335f9fb403d2b17f3163Marc Blank
22f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blankimport com.android.email.AccountTestCase;
23ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blankimport com.android.email.EmailConnectivityManager;
2475a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blankimport com.android.email.provider.ProviderTestUtils;
25f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blankimport com.android.email.service.AttachmentDownloadService.DownloadRequest;
26f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blankimport com.android.email.service.AttachmentDownloadService.DownloadSet;
2703cd72805dab0379ed255d151f1c17cc60655fc3Marc Blankimport com.android.email.service.EmailServiceUtils.NullEmailService;
28f5418f1f93b02e7fab9f15eb201800b65510998eMarc Blankimport com.android.emailcommon.provider.Account;
29a7bc0319a75184ad706bb35c049af107ac3688e6Marc Blankimport com.android.emailcommon.provider.EmailContent.Attachment;
30a7bc0319a75184ad706bb35c049af107ac3688e6Marc Blankimport com.android.emailcommon.provider.EmailContent.Message;
3153ea83ebf91f820692e8fa8e781f5cc982dd94dbBen Komaloimport com.android.emailcommon.provider.Mailbox;
320d4fc55861ed4393aa82f124f2865695ef564641Marc Blankimport com.android.emailcommon.service.EmailServiceStatus;
33f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank
3475a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blankimport java.io.File;
35f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blankimport java.util.Iterator;
36f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank
37f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank/**
38f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank * Tests of the AttachmentDownloadService
39f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank *
40f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank * You can run this entire test case with:
41f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank *   runtest -c com.android.email.service.AttachmentDownloadServiceTests email
42f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank */
43f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blankpublic class AttachmentDownloadServiceTests extends AccountTestCase {
44f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank    private AttachmentDownloadService mService;
45f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank    private Context mMockContext;
46f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank    private Account mAccount;
47f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank    private Mailbox mMailbox;
48f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank    private long mAccountId;
49f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank    private long mMailboxId;
5075a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank    private AttachmentDownloadService.AccountManagerStub mAccountManagerStub;
5175a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank    private MockDirectory mMockDirectory;
5275a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank
53f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank    private DownloadSet mDownloadSet;
54f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank
55f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank    @Override
56f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank    public void setUp() throws Exception {
57f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        super.setUp();
58f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        mMockContext = getMockContext();
59f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank
60f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        // Set up an account and mailbox
61f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        mAccount = ProviderTestUtils.setupAccount("account", false, mMockContext);
62ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        mAccount.mFlags |= Account.FLAGS_BACKGROUND_ATTACHMENTS;
63f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        mAccount.save(mMockContext);
64f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        mAccountId = mAccount.mId;
65ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank
66f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        mMailbox = ProviderTestUtils.setupMailbox("mailbox", mAccountId, true, mMockContext);
67f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        mMailboxId = mMailbox.mId;
68f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank
69f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        // Set up our download service to simulate a running environment
70f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        // Use the NullEmailService so that the loadAttachment calls become no-ops
71f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        mService = new AttachmentDownloadService();
72f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        mService.mContext = mMockContext;
73ffe6ef342a6d9ea958aaee11b57db54e52252ddeTodd Kennedy        mService.addServiceIntentForTest(mAccountId, new Intent(mContext,
7403cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank                NullEmailService.class));
7575a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        mAccountManagerStub = new AttachmentDownloadService.AccountManagerStub(null);
7675a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        mService.mAccountManagerStub = mAccountManagerStub;
77ffe6ef342a6d9ea958aaee11b57db54e52252ddeTodd Kennedy        mService.mConnectivityManager = new MockConnectivityManager(mContext, "mock");
78f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        mDownloadSet = mService.mDownloadSet;
7975a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        mMockDirectory =
8075a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank            new MockDirectory(mService.mContext.getCacheDir().getAbsolutePath());
81f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank    }
82f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank
83f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank    @Override
84f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank    public void tearDown() throws Exception {
85f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        super.tearDown();
86f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank    }
87f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank
88f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank    /**
89f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank     * This test creates attachments and places them in the DownloadSet; we then do various checks
90f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank     * that exercise its functionality.
91f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank     */
92f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank    public void testDownloadSet() {
93f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        // TODO: Make sure that this doesn't interfere with the "real" ADS that might be running
94f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        // on device
95f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        Message message = ProviderTestUtils.setupMessage("message", mAccountId, mMailboxId, false,
96f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank                true, mMockContext);
97f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        Attachment att1 = ProviderTestUtils.setupAttachment(message.mId, "filename1", 1000,
98f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank                Attachment.FLAG_DOWNLOAD_USER_REQUEST, true, mMockContext);
99f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        Attachment att2 = ProviderTestUtils.setupAttachment(message.mId, "filename2", 1000,
100f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank                Attachment.FLAG_DOWNLOAD_FORWARD, true, mMockContext);
101f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        Attachment att3 = ProviderTestUtils.setupAttachment(message.mId, "filename3", 1000,
102f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank                Attachment.FLAG_DOWNLOAD_FORWARD, true, mMockContext);
103f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        Attachment att4 = ProviderTestUtils.setupAttachment(message.mId, "filename4", 1000,
104f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank                Attachment.FLAG_DOWNLOAD_USER_REQUEST, true, mMockContext);
105f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        // Indicate that these attachments have changed; they will be added to the queue
106ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        mDownloadSet.onChange(mMockContext, att1);
107ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        mDownloadSet.onChange(mMockContext, att2);
108ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        mDownloadSet.onChange(mMockContext, att3);
109ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        mDownloadSet.onChange(mMockContext, att4);
110f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        Iterator<DownloadRequest> iterator = mDownloadSet.descendingIterator();
111f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        // Check the expected ordering; 1 & 4 are higher priority than 2 & 3
112f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        // 1 and 3 were created earlier than their priority equals
113f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        long[] expectedAttachmentIds = new long[] {att1.mId, att4.mId, att2.mId, att3.mId};
114f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        for (int i = 0; i < expectedAttachmentIds.length; i++) {
115f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank            assertTrue(iterator.hasNext());
116f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank            DownloadRequest req = iterator.next();
117f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank            assertEquals(expectedAttachmentIds[i], req.attachmentId);
118f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        }
119f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank
120f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        // Process the queue; attachment 1 should be marked "in progress", and should be in
121f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        // the in-progress map
122f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        mDownloadSet.processQueue();
123f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        DownloadRequest req = mDownloadSet.findDownloadRequest(att1.mId);
124f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        assertNotNull(req);
125f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        assertTrue(req.inProgress);
126f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        assertTrue(mDownloadSet.mDownloadsInProgress.containsKey(att1.mId));
127f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        // There should also be only one download in progress (testing the per-account limitation)
128f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        assertEquals(1, mDownloadSet.mDownloadsInProgress.size());
129f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        // End the "download" with a connection error; we should still have this in the queue,
130f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        // but it should no longer be in-progress
131f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        mDownloadSet.endDownload(att1.mId, EmailServiceStatus.CONNECTION_ERROR);
132f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        assertFalse(req.inProgress);
133f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        assertEquals(0, mDownloadSet.mDownloadsInProgress.size());
134f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank
135f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        mDownloadSet.processQueue();
136f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        // Things should be as they were earlier; att1 should be an in-progress download
137f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        req = mDownloadSet.findDownloadRequest(att1.mId);
138f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        assertNotNull(req);
139f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        assertTrue(req.inProgress);
140f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        assertTrue(mDownloadSet.mDownloadsInProgress.containsKey(att1.mId));
141f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        // Successfully download the attachment; there should be no downloads in progress, and
142f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        // att1 should no longer be in the queue
143f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        mDownloadSet.endDownload(att1.mId, EmailServiceStatus.SUCCESS);
144f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        assertEquals(0, mDownloadSet.mDownloadsInProgress.size());
145f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        assertNull(mDownloadSet.findDownloadRequest(att1.mId));
146f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank
147f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        // Test dequeue and isQueued
148f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        assertEquals(3, mDownloadSet.size());
149f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        mService.dequeue(att2.mId);
150f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        assertEquals(2, mDownloadSet.size());
151f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        assertTrue(mService.isQueued(att4.mId));
152f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        assertTrue(mService.isQueued(att3.mId));
153f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank
154f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        mDownloadSet.processQueue();
155f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        // att4 should be the download in progress
156f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        req = mDownloadSet.findDownloadRequest(att4.mId);
157f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        assertNotNull(req);
158f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        assertTrue(req.inProgress);
159f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank        assertTrue(mDownloadSet.mDownloadsInProgress.containsKey(att4.mId));
160f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank    }
16175a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank
16275a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank    /**
16375a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank     * A mock file directory containing a single (Mock)File.  The total space, usable space, and
16475a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank     * length of the single file can be set
16575a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank     */
166ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank    private static class MockDirectory extends File {
16775a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        private static final long serialVersionUID = 1L;
16875a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        private long mTotalSpace;
16975a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        private long mUsableSpace;
17075a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        private MockFile[] mFiles;
17175a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        private final MockFile mMockFile = new MockFile();
17275a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank
17375a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank
17475a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        public MockDirectory(String path) {
17575a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank            super(path);
17675a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank            mFiles = new MockFile[1];
17775a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank            mFiles[0] = mMockFile;
17875a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        }
17975a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank
18075a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        private void setTotalAndUsableSpace(long total, long usable) {
18175a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank            mTotalSpace = total;
18275a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank            mUsableSpace = usable;
18375a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        }
18475a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank
185323eea8ac8d5645612a38065c62996059aff58f6Marc Blank        @Override
18675a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        public long getTotalSpace() {
18775a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank            return mTotalSpace;
18875a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        }
18975a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank
190323eea8ac8d5645612a38065c62996059aff58f6Marc Blank        @Override
19175a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        public long getUsableSpace() {
19275a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank            return mUsableSpace;
19375a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        }
19475a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank
19575a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        public void setFileLength(long length) {
19675a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank            mMockFile.mLength = length;
19775a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        }
19875a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank
199323eea8ac8d5645612a38065c62996059aff58f6Marc Blank        @Override
20075a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        public File[] listFiles() {
20175a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank            return mFiles;
20275a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        }
20375a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank    }
20475a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank
20575a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank    /**
20675a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank     * A mock file that reports back a pre-set length
20775a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank     */
208ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank    private static class MockFile extends File {
20975a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        private static final long serialVersionUID = 1L;
21075a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        private long mLength = 0;
21175a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank
21275a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        public MockFile() {
21375a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank            super("_mock");
21475a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        }
21575a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank
216323eea8ac8d5645612a38065c62996059aff58f6Marc Blank        @Override
21775a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        public long length() {
21875a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank            return mLength;
21975a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        }
22075a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank    }
22175a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank
222ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank    private static class MockConnectivityManager extends EmailConnectivityManager {
223ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        public MockConnectivityManager(Context context, String name) {
224ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank            super(context, name);
225ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        }
226ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank
227ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        @Override
228ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        public void waitForConnectivity() {
229ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        }
230ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank
231ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        @Override
232faf9ecc992c34de53969335f9fb403d2b17f3163Marc Blank        public boolean isAutoSyncAllowed() {
233ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank            return true;
234ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        }
235ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank    }
236ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank
23775a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank    public void testCanPrefetchForAccount() {
23875a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        // First, test our "global" limits (based on free storage)
23975a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        // Mock storage @ 100 total and 26 available
24075a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        // Note that all file lengths in this test are in arbitrary units
24175a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        mMockDirectory.setTotalAndUsableSpace(100L, 26L);
24275a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        // Mock 2 accounts in total
24375a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        mAccountManagerStub.setNumberOfAccounts(2);
24475a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        // With 26% available, we should be ok to prefetch
2453a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank        assertTrue(mService.canPrefetchForAccount(mAccount, mMockDirectory));
24675a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        // Now change to 24 available
24775a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        mMockDirectory.setTotalAndUsableSpace(100L, 24L);
24875a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        // With 24% available, we should NOT be ok to prefetch
2493a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank        assertFalse(mService.canPrefetchForAccount(mAccount, mMockDirectory));
25075a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank
25175a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        // Now, test per-account storage
25275a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        // Mock storage @ 100 total and 50 available
25375a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        mMockDirectory.setTotalAndUsableSpace(100L, 50L);
254edb05ca5ee21a9f410416b427141be59be01f5d2Marc Blank        // Mock a file of length 12, but need to uncache previous amount first
255ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        mService.mAttachmentStorageMap.remove(mAccountId);
256edb05ca5ee21a9f410416b427141be59be01f5d2Marc Blank        mMockDirectory.setFileLength(11);
257edb05ca5ee21a9f410416b427141be59be01f5d2Marc Blank        // We can prefetch since 11 < 50/4
2583a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank        assertTrue(mService.canPrefetchForAccount(mAccount, mMockDirectory));
259edb05ca5ee21a9f410416b427141be59be01f5d2Marc Blank        // Mock a file of length 13, but need to uncache previous amount first
260ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        mService.mAttachmentStorageMap.remove(mAccountId);
261edb05ca5ee21a9f410416b427141be59be01f5d2Marc Blank        mMockDirectory.setFileLength(13);
262edb05ca5ee21a9f410416b427141be59be01f5d2Marc Blank        // We can't prefetch since 13 > 50/4
2633a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank        assertFalse(mService.canPrefetchForAccount(mAccount, mMockDirectory));
264ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank    }
265ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank
266ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank    public void testCanPrefetchForAccountNoBackgroundDownload() {
267ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        Account account = ProviderTestUtils.setupAccount("account2", false, mMockContext);
268ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        account.mFlags &= ~Account.FLAGS_BACKGROUND_ATTACHMENTS;
269ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        account.save(mMockContext);
270ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank
271ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        // First, test our "global" limits (based on free storage)
272ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        // Mock storage @ 100 total and 26 available
273ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        // Note that all file lengths in this test are in arbitrary units
274ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        mMockDirectory.setTotalAndUsableSpace(100L, 26L);
275ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        // Mock 2 accounts in total
276ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        mAccountManagerStub.setNumberOfAccounts(2);
277ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank
278ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        // With 26% available, we should be ok to prefetch,
279ed9938cd9caf4937eadb3e35333e2fe2b157bde5Marc Blank        // *but* bg download is disabled on the account.
2803a5c1fb274a9ce72d708d88509bf2607cb018dddMarc Blank        assertFalse(mService.canPrefetchForAccount(account, mMockDirectory));
28175a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank    }
282f19f9cf4d3e5229715da77fe05a1a2bbd8da3f41Marc Blank}
283