1c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay/* 2c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay * Copyright (C) 2017 The Android Open Source Project 3c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay * 4c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay * Licensed under the Apache License, Version 2.0 (the "License"); 5c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay * you may not use this file except in compliance with the License. 6c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay * You may obtain a copy of the License at 7c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay * 8c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay * http://www.apache.org/licenses/LICENSE-2.0 9c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay * 10c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay * Unless required by applicable law or agreed to in writing, software 11c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay * distributed under the License is distributed on an "AS IS" BASIS, 12c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay * See the License for the specific language governing permissions and 14c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay * limitations under the License. 15c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay */ 16c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.contentpager.content; 18c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 19ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.contentpager.content.ContentPager.createArgs; 20ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.contentpager.content.TestContentProvider.PAGED_URI; 21ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.contentpager.content.TestContentProvider.PAGED_WINDOWED_URI; 22ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.contentpager.content.TestContentProvider.UNPAGED_URI; 23c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 24fa39e2bca1b284ad7c931d9194287770b7b507faAurimas Liutikasimport static org.junit.Assert.assertEquals; 25c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKayimport static org.junit.Assert.assertFalse; 26fa39e2bca1b284ad7c931d9194287770b7b507faAurimas Liutikasimport static org.junit.Assert.assertNotNull; 27fa39e2bca1b284ad7c931d9194287770b7b507faAurimas Liutikasimport static org.junit.Assert.assertTrue; 28c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 29c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKayimport android.app.Activity; 30c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKayimport android.content.ContentResolver; 31c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKayimport android.database.Cursor; 32c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKayimport android.net.Uri; 33c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKayimport android.os.Bundle; 34c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKayimport android.os.Handler; 35c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKayimport android.os.Looper; 36c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKayimport android.support.test.filters.MediumTest; 37c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKayimport android.support.test.rule.ActivityTestRule; 38c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKayimport android.support.test.runner.AndroidJUnit4; 39c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 40fb4b6f71b6a30ea0acc67fce323853e4beb096d7Aurimas Liutikasimport androidx.annotation.Nullable; 41fb4b6f71b6a30ea0acc67fce323853e4beb096d7Aurimas Liutikasimport androidx.contentpager.content.ContentPager.ContentCallback; 42fb4b6f71b6a30ea0acc67fce323853e4beb096d7Aurimas Liutikas 43c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKayimport org.junit.Before; 44c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKayimport org.junit.Rule; 45c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKayimport org.junit.Test; 46c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKayimport org.junit.runner.RunWith; 47c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 48c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKayimport java.util.Arrays; 49c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKayimport java.util.HashMap; 50c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKayimport java.util.List; 51c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKayimport java.util.Map; 52c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKayimport java.util.concurrent.TimeUnit; 53c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 54c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay@MediumTest 55c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay@RunWith(AndroidJUnit4.class) 56c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKaypublic class ContentPagerTest { 57c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 58c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay private ContentResolver mResolver; 59c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay private TestQueryRunner mRunner; 60c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay private TestContentCallback mCallback; 61c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay private ContentPager mPager; 62c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 63c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay @Rule 64c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay public ActivityTestRule<Activity> mActivityRule = new ActivityTestRule(TestActivity.class); 65c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 66c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay @Before 67c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay public void setUp() { 68c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mRunner = new TestQueryRunner(); 69c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mResolver = mActivityRule.getActivity().getContentResolver(); 70c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback = new TestContentCallback(); 71c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mPager = new ContentPager(mResolver, mRunner); 72c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay } 73c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 74c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay @Test 75c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay public void testRelaysProviderPagedResults() throws Throwable { 76c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay int offset = 0; 77c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay int limit = 10; 78c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 79c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay // NOTE: Paging on Android O is accompolished by way of ContentResolver#query that 80c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay // accepts a Bundle. That means on older platforms we either have to cook up 81c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay // a special way of paging that doesn't use the bundle (that's what we do here) 82c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay // or we simply skip testing how we deal with provider paged results. 83c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Uri uriWithTestPagingData = TestContentProvider.forcePagingSpec(PAGED_URI, offset, limit); 84c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 85c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Query query = mPager.query( 86c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay uriWithTestPagingData, 87c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay null, 88c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay createArgs(offset, limit), 89c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay null, 90c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback); 91c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 92c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback.assertNumPagesLoaded(1); 93c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback.assertPageLoaded(query); 94c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Cursor cursor = mCallback.getCursor(query); 95c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Bundle extras = cursor.getExtras(); 96c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 97c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertExpectedRecords(cursor, query.getOffset()); 98c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 99c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 100c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay ContentPager.CURSOR_DISPOSITION_PAGED, 101c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.CURSOR_DISPOSITION, -1)); 102c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 103c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 104c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay TestContentProvider.DEFAULT_RECORD_COUNT, 105c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentResolver.EXTRA_TOTAL_COUNT)); 106c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 107c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertHasHonoredArgs( 108c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras, 109c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay ContentResolver.QUERY_ARG_LIMIT, 110c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay ContentResolver.QUERY_ARG_OFFSET); 111c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 112c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 113c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 1, 114c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.Stats.EXTRA_PROVIDER_PAGED)); 115c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 116c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 1, 117c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.Stats.EXTRA_RESOLVED_QUERIES)); 118c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 119c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 1, 120c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.Stats.EXTRA_TOTAL_QUERIES)); 121c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay } 122c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 123c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay @Test 124c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay public void testLimitsPagedResultsToWindowSize() throws Throwable { 125c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay int offset = 0; 126c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay int limit = 10; 127c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 128c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay // NOTE: Paging on Android O is accompolished by way of ContentResolver#query that 129c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay // accepts a Bundle. That means on older platforms we either have to cook up 130c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay // a special way of paging that doesn't use the bundle (that's what we do here) 131c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay // or we simply skip testing how we deal with provider paged results. 132c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Uri uriWithTestPagingData = TestContentProvider.forcePagingSpec( 133c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay PAGED_WINDOWED_URI, offset, limit); 134c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 135c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Query query = mPager.query( 136c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay uriWithTestPagingData, 137c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay null, 138c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay createArgs(offset, limit), 139c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay null, 140c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback); 141c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 142c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback.assertNumPagesLoaded(1); 143c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback.assertPageLoaded(query); 144c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Cursor cursor = mCallback.getCursor(query); 145c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Bundle extras = cursor.getExtras(); 146c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 147c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertExpectedRecords(cursor, query.getOffset()); 148c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 149c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 150c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay ContentPager.CURSOR_DISPOSITION_REPAGED, 151c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.CURSOR_DISPOSITION, -1)); 152c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 153c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 154c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay TestContentProvider.DEFAULT_RECORD_COUNT, 155c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentResolver.EXTRA_TOTAL_COUNT)); 156c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 157c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 158c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals(limit, extras.getInt(ContentPager.EXTRA_REQUESTED_LIMIT)); 159c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 160c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals(7, extras.getInt(ContentPager.EXTRA_SUGGESTED_LIMIT)); 161c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 162c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertHasHonoredArgs( 163c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras, 164c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay ContentResolver.QUERY_ARG_LIMIT, 165c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay ContentResolver.QUERY_ARG_OFFSET); 166c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 167c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 168c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 1, 169c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.Stats.EXTRA_PROVIDER_PAGED)); 170c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 171c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 1, 172c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.Stats.EXTRA_RESOLVED_QUERIES)); 173c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 174c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 1, 175c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.Stats.EXTRA_TOTAL_QUERIES)); 176c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay } 177c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 178c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay @Test 179c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay public void testAdaptsUnpagedToPaged() throws Throwable { 180c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Query query = mPager.query( 181c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay UNPAGED_URI, 182c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay null, 183c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay createArgs(0, 10), 184c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay null, 185c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback); 186c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 187c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback.assertNumPagesLoaded(1); 188c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback.assertPageLoaded(query); 189c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Cursor cursor = mCallback.getCursor(query); 190c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Bundle extras = cursor.getExtras(); 191c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 192c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertExpectedRecords(cursor, query.getOffset()); 193c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 194c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 195c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay ContentPager.CURSOR_DISPOSITION_COPIED, 196c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.CURSOR_DISPOSITION)); 197c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 198c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 199c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay TestContentProvider.DEFAULT_RECORD_COUNT, 200c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentResolver.EXTRA_TOTAL_COUNT)); 201c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 202c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertHasHonoredArgs( 203c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras, 204c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay ContentResolver.QUERY_ARG_LIMIT, 205c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay ContentResolver.QUERY_ARG_OFFSET); 206c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 207c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 208c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 1, 209c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.Stats.EXTRA_COMPAT_PAGED)); 210c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 211c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 1, 212c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.Stats.EXTRA_RESOLVED_QUERIES)); 213c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 214c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 1, 215c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.Stats.EXTRA_TOTAL_QUERIES)); 216c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay } 217c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 218c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay @Test 219c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay public void testCachesUnpagedCursor() throws Throwable { 220c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mPager.query( 221c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay UNPAGED_URI, 222c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay null, 223c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay createArgs(0, 10), 224c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay null, 225c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback); 226c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 227c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mPager.query( 228c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay UNPAGED_URI, 229c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay null, 230c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay createArgs(10, 10), 231c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay null, 232c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback); 233c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 234c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay // Rerun the same query as the first...extra exercise to ensure we can return 235c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay // to previously loaded results. 236c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Query query = mPager.query( 237c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay UNPAGED_URI, 238c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay null, 239c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay createArgs(0, 10), 240c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay null, 241c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback); 242c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 243c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback.assertNumPagesLoaded(3); 244c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Cursor cursor = mCallback.getCursor(query); 245c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Bundle extras = cursor.getExtras(); 246c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 247c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 248c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 3, 249c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.Stats.EXTRA_COMPAT_PAGED)); 250c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 251c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 1, 252c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.Stats.EXTRA_RESOLVED_QUERIES)); 253c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 254c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 3, 255c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.Stats.EXTRA_TOTAL_QUERIES)); 256c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay } 257c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 258c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay @Test 259c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay public void testWrapsCursorsThatJustHappenToFitInPageRange() throws Throwable { 260c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 261c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay // NOTE: Paging on Android O is accompolished by way of ContentResolver#query that 262c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay // accepts a Bundle. That means on older platforms we either have to cook up 263c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay // a special way of paging that doesn't use the bundle (that's what we do here) 264c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay // or we simply skip testing how we deal with provider paged results. 265c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Uri uri = TestContentProvider.forceRecordCount(UNPAGED_URI, 22); 266c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 267c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Query query = mPager.query( 268c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay uri, 269c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay null, 270c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay createArgs(0, 44), 271c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay null, 272c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback); 273c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 274c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback.assertNumPagesLoaded(1); 275c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay // mCallback.assertPageLoaded(pageId); 276c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback.assertPageLoaded(query); 277c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Cursor cursor = mCallback.getCursor(query); 278c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Bundle extras = cursor.getExtras(); 279c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 280c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertExpectedRecords(cursor, query.getOffset()); 281c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 282c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 283c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay ContentPager.CURSOR_DISPOSITION_WRAPPED, 284c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.CURSOR_DISPOSITION)); 285c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 286c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 287c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 22, 288c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentResolver.EXTRA_TOTAL_COUNT)); 289c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 290c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertHasHonoredArgs( 291c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras, 292c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay ContentResolver.QUERY_ARG_LIMIT, 293c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay ContentResolver.QUERY_ARG_OFFSET); 294c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 295c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 296c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 1, 297c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.Stats.EXTRA_COMPAT_PAGED)); 298c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 299c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 1, 300c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.Stats.EXTRA_RESOLVED_QUERIES)); 301c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 302c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 1, 303c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.Stats.EXTRA_TOTAL_QUERIES)); 304c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay } 305c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 306c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay @Test 307c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay public void testCorrectlyCopiesRecords_EndOfResults() throws Throwable { 308c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay // finally, check the last page. 309c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay int limit = 100; 310c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay // This will be the size of the last page. Should be 67. 311c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay int leftOvers = TestContentProvider.DEFAULT_RECORD_COUNT % limit; 312c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay int offset = TestContentProvider.DEFAULT_RECORD_COUNT - leftOvers; 313c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 314c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Query query = mPager.query( 315c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay UNPAGED_URI, 316c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay null, 317c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay createArgs(offset, limit), 318c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay null, 319c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback); 320c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 321c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback.assertNumPagesLoaded(1); 322c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback.assertPageLoaded(query); 323c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Cursor cursor = mCallback.getCursor(query); 324c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals(leftOvers, cursor.getCount()); 325c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Bundle extras = cursor.getExtras(); 326c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 327c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertExpectedRecords(cursor, query.getOffset()); 328c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 329c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 330c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay ContentPager.CURSOR_DISPOSITION_COPIED, 331c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.CURSOR_DISPOSITION)); 332c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 333c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertHasHonoredArgs( 334c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras, 335c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay ContentResolver.QUERY_ARG_LIMIT, 336c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay ContentResolver.QUERY_ARG_OFFSET); 337c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 338c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 339c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 1, 340c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.Stats.EXTRA_COMPAT_PAGED)); 341c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 342c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 1, 343c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.Stats.EXTRA_RESOLVED_QUERIES)); 344c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals( 345c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 1, 346c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getInt(ContentPager.Stats.EXTRA_TOTAL_QUERIES)); 347c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay } 348c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 349c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay @Test 350c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay public void testCancelsRunningQueriesOnReset() throws Throwable { 351c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mRunner.runQuery = false; 352c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Query query = mPager.query( 353c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay UNPAGED_URI, 354c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay null, 355c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay createArgs(0, 10), 356c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay null, 357c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback); 358c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 359c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertTrue(mRunner.isRunning(query)); 360c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 361c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mPager.reset(); 362c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 363c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertFalse(mRunner.isRunning(query)); 364c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay } 365c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 366c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay @Test 367c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay public void testRelaysContentChangeNotificationsOnPagedCursors() throws Throwable { 368c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 369c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay TestContentObserver observer = new TestContentObserver( 370c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay new Handler(Looper.getMainLooper())); 371c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay observer.expectNotifications(1); 372c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 373c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Query query = mPager.query( 374c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay UNPAGED_URI, 375c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay null, 376c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay createArgs(10, 99), 377c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay null, 378c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCallback); 379c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 380c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay Cursor cursor = mCallback.getCursor(query); 381c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay cursor.registerContentObserver(observer); 382c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 383c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mResolver.notifyChange(UNPAGED_URI, null); 384c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 385c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertTrue(observer.mNotifiedLatch.await(1000, TimeUnit.MILLISECONDS)); 386c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay } 387c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 388c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay private void assertExpectedRecords(Cursor cursor, int offset) { 389c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay for (int row = 0; row < cursor.getCount(); row++) { 390c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertTrue(cursor.moveToPosition(row)); 391c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay int unpagedRow = offset + row; 392c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay for (int column = 0; column < cursor.getColumnCount(); column++) { 393c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay TestContentProvider.assertExpectedCellValue(cursor, unpagedRow, column); 394c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay } 395c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay } 396c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay } 397c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 398c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay private static void assertHasHonoredArgs(Bundle extras, String... expectedArgs) { 399c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay List<String> honored = Arrays.asList( 400c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay extras.getStringArray(ContentResolver.EXTRA_HONORED_ARGS)); 401c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 402c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay for (String arg : expectedArgs) { 403c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertTrue(honored.contains(arg)); 404c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay } 405c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay } 406c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 407c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay private static final class TestContentCallback implements ContentCallback { 408c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 409c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay private int mPagesLoaded; 410c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay private Map<Query, Cursor> mCursors = new HashMap<>(); 411c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 412c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay @Override 413c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay public void onCursorReady(Query query, Cursor cursor) { 414c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mPagesLoaded++; 415c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay mCursors.put(query, cursor); 416c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay } 417c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 418c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay private void assertPageLoaded(Query query) { 419c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertTrue(mCursors.containsKey(query)); 420c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertNotNull(mCursors.get(query)); 421c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay } 422c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 423c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay private void assertNumPagesLoaded(int expected) { 424c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay assertEquals(expected, mPagesLoaded); 425c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay } 426c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay 427c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay private @Nullable Cursor getCursor(Query query) { 428c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay return mCursors.get(query); 429c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay } 430c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay } 431c01ec9664a26a603d90b067d1ca7ca39950eb025Steve McKay} 432