1b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey/* 2b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey * Copyright (C) 2013 The Android Open Source Project 3b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey * 4b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 5b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey * you may not use this file except in compliance with the License. 6b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey * You may obtain a copy of the License at 7b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey * 8b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 9b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey * 10b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey * Unless required by applicable law or agreed to in writing, software 11b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 12b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey * See the License for the specific language governing permissions and 14b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey * limitations under the License. 15b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey */ 16b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 17b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkeypackage android.support.v4.content; 18b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 19b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkeyimport static android.provider.OpenableColumns.DISPLAY_NAME; 20b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkeyimport static android.provider.OpenableColumns.SIZE; 21b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 22b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkeyimport android.content.ContentResolver; 23b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkeyimport android.database.Cursor; 24b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkeyimport android.net.Uri; 25b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkeyimport android.os.Environment; 26b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkeyimport android.support.v4.content.FileProvider.SimplePathStrategy; 27b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkeyimport android.test.AndroidTestCase; 28b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkeyimport android.test.MoreAsserts; 29b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 30b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkeyimport java.io.File; 31b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkeyimport java.io.FileNotFoundException; 32b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkeyimport java.io.FileOutputStream; 33b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkeyimport java.io.InputStream; 34b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkeyimport java.io.OutputStream; 35b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 36b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkeyimport libcore.io.IoUtils; 37b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkeyimport libcore.io.Streams; 38b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 39b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey/** 40b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey * Tests for {@link FileProvider} 41b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey */ 42b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkeypublic class FileProviderTest extends AndroidTestCase { 43b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey private static final String TEST_AUTHORITY = "moocow"; 44b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 45b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey private static final String TEST_FILE = "file.test"; 46b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey private static final byte[] TEST_DATA = new byte[] { (byte) 0xf0, 0x00, 0x0d }; 47b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey private static final byte[] TEST_DATA_ALT = new byte[] { (byte) 0x33, 0x66 }; 48b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 49b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey private ContentResolver mResolver; 50b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 51b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey @Override 52b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey protected void setUp() throws Exception { 53b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey super.setUp(); 54b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 55b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey mResolver = getContext().getContentResolver(); 56b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 57b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 58b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey public void testStrategyUriSimple() throws Exception { 59b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final SimplePathStrategy strat = new SimplePathStrategy("authority"); 60b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.addRoot("tag", mContext.getFilesDir()); 61b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 62b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey File file = buildPath(mContext.getFilesDir(), "file.test"); 63b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals("content://authority/tag/file.test", 64b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.getUriForFile(file).toString()); 65b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 66b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey file = buildPath(mContext.getFilesDir(), "subdir", "file.test"); 67b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals("content://authority/tag/subdir/file.test", 68b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.getUriForFile(file).toString()); 69b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 70b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey file = buildPath(Environment.getExternalStorageDirectory(), "file.test"); 71b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey try { 72b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.getUriForFile(file); 73b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey fail("somehow got uri for file outside roots?"); 74b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } catch (IllegalArgumentException e) { 75b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 76b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 77b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 78b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey public void testStrategyUriJumpOutside() throws Exception { 79b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final SimplePathStrategy strat = new SimplePathStrategy("authority"); 80b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.addRoot("tag", mContext.getFilesDir()); 81b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 82b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey File file = buildPath(mContext.getFilesDir(), "..", "file.test"); 83b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey try { 84b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.getUriForFile(file); 85b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey fail("file escaped!"); 86b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } catch (IllegalArgumentException e) { 87b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 88b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 89b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 90b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey public void testStrategyUriShortestRoot() throws Exception { 91b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey SimplePathStrategy strat = new SimplePathStrategy("authority"); 92b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.addRoot("tag1", mContext.getFilesDir()); 93b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.addRoot("tag2", new File("/")); 94b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 95b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey File file = buildPath(mContext.getFilesDir(), "file.test"); 96b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals("content://authority/tag1/file.test", 97b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.getUriForFile(file).toString()); 98b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 99b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat = new SimplePathStrategy("authority"); 100b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.addRoot("tag1", new File("/")); 101b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.addRoot("tag2", mContext.getFilesDir()); 102b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 103b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey file = buildPath(mContext.getFilesDir(), "file.test"); 104b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals("content://authority/tag2/file.test", 105b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.getUriForFile(file).toString()); 106b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 107b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 108b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey public void testStrategyFileSimple() throws Exception { 109b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final SimplePathStrategy strat = new SimplePathStrategy("authority"); 110b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.addRoot("tag", mContext.getFilesDir()); 111b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 112b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey File file = buildPath(mContext.getFilesDir(), "file.test"); 113b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(file.getPath(), 114b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.getFileForUri(Uri.parse("content://authority/tag/file.test")).getPath()); 115b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 116b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey file = buildPath(mContext.getFilesDir(), "subdir", "file.test"); 117b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(file.getPath(), strat.getFileForUri( 118b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey Uri.parse("content://authority/tag/subdir/file.test")).getPath()); 119b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 120b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 121b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey public void testStrategyFileJumpOutside() throws Exception { 122b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final SimplePathStrategy strat = new SimplePathStrategy("authority"); 123b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.addRoot("tag", mContext.getFilesDir()); 124b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 125b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey try { 126b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.getFileForUri(Uri.parse("content://authority/tag/../file.test")); 127b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey fail("file escaped!"); 128b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } catch (SecurityException e) { 129b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 130b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 131b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 132b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey public void testStrategyEscaping() throws Exception { 133b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final SimplePathStrategy strat = new SimplePathStrategy("authority"); 134b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.addRoot("t/g", mContext.getFilesDir()); 135b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 136b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey File file = buildPath(mContext.getFilesDir(), "lol\"wat?foo&bar", "wat.txt"); 137b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final String expected = "content://authority/t%2Fg/lol%22wat%3Ffoo%26bar/wat.txt"; 138b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 139b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(expected, 140b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.getUriForFile(file).toString()); 141b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(file.getPath(), 142b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.getFileForUri(Uri.parse(expected)).getPath()); 143b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 144b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 145b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey public void testStrategyExtraParams() throws Exception { 146b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final SimplePathStrategy strat = new SimplePathStrategy("authority"); 147b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.addRoot("tag", mContext.getFilesDir()); 148b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 149b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey File file = buildPath(mContext.getFilesDir(), "file.txt"); 150b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(file.getPath(), strat.getFileForUri( 151b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey Uri.parse("content://authority/tag/file.txt?extra=foo")).getPath()); 152b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 153b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 154b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey public void testStrategyExtraSeparators() throws Exception { 155b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final SimplePathStrategy strat = new SimplePathStrategy("authority"); 156b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.addRoot("tag", mContext.getFilesDir()); 157b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 158b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey // When canonicalized, the path separators are trimmed 159b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey File inFile = new File(mContext.getFilesDir(), "//foo//bar//"); 160b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey File outFile = new File(mContext.getFilesDir(), "/foo/bar"); 161b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final String expected = "content://authority/tag/foo/bar"; 162b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 163b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(expected, 164b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.getUriForFile(inFile).toString()); 165b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(outFile.getPath(), 166b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey strat.getFileForUri(Uri.parse(expected)).getPath()); 167b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 168b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 169b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey public void testQueryProjectionNull() throws Exception { 170b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final File file = new File(mContext.getFilesDir(), TEST_FILE); 171b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final Uri uri = stageFileAndGetUri(file, TEST_DATA); 172b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 173b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey // Verify that null brings out default columns 174b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey Cursor cursor = mResolver.query(uri, null, null, null, null); 175b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey try { 176b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(1, cursor.getCount()); 177b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey cursor.moveToFirst(); 178b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(TEST_FILE, cursor.getString(cursor.getColumnIndex(DISPLAY_NAME))); 179b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(TEST_DATA.length, cursor.getLong(cursor.getColumnIndex(SIZE))); 180b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } finally { 181b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey cursor.close(); 182b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 183b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 184b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 185b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey public void testQueryProjectionOrder() throws Exception { 186b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final File file = new File(mContext.getFilesDir(), TEST_FILE); 187b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final Uri uri = stageFileAndGetUri(file, TEST_DATA); 188b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 189b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey // Verify that swapped order works 190b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey Cursor cursor = mResolver.query(uri, new String[] { 191b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey SIZE, DISPLAY_NAME }, null, null, null); 192b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey try { 193b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(1, cursor.getCount()); 194b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey cursor.moveToFirst(); 195b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(TEST_DATA.length, cursor.getLong(0)); 196b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(TEST_FILE, cursor.getString(1)); 197b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } finally { 198b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey cursor.close(); 199b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 200b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 201b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey cursor = mResolver.query(uri, new String[] { 202b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey DISPLAY_NAME, SIZE }, null, null, null); 203b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey try { 204b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(1, cursor.getCount()); 205b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey cursor.moveToFirst(); 206b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(TEST_FILE, cursor.getString(0)); 207b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(TEST_DATA.length, cursor.getLong(1)); 208b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } finally { 209b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey cursor.close(); 210b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 211b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 212b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 213b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey public void testQueryExtraColumn() throws Exception { 214b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final File file = new File(mContext.getFilesDir(), TEST_FILE); 215b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final Uri uri = stageFileAndGetUri(file, TEST_DATA); 216b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 217b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey // Verify that extra column doesn't gook things up 218b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey Cursor cursor = mResolver.query(uri, new String[] { 219b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey SIZE, "foobar", DISPLAY_NAME }, null, null, null); 220b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey try { 221b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(1, cursor.getCount()); 222b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey cursor.moveToFirst(); 223b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(TEST_DATA.length, cursor.getLong(0)); 224b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(TEST_FILE, cursor.getString(1)); 225b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } finally { 226b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey cursor.close(); 227b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 228b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 229b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 230b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey public void testReadFile() throws Exception { 231b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final File file = new File(mContext.getFilesDir(), TEST_FILE); 232b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final Uri uri = stageFileAndGetUri(file, TEST_DATA); 233b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 234b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertContentsEquals(TEST_DATA, uri); 235b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 236b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 237b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey public void testWriteFile() throws Exception { 238b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final File file = new File(mContext.getFilesDir(), TEST_FILE); 239b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final Uri uri = stageFileAndGetUri(file, TEST_DATA); 240b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 241b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertContentsEquals(TEST_DATA, uri); 242b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 243b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final OutputStream out = mResolver.openOutputStream(uri); 244b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey try { 245b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey out.write(TEST_DATA_ALT); 246b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } finally { 247b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey IoUtils.closeQuietly(out); 248b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 249b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 250b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertContentsEquals(TEST_DATA_ALT, uri); 251b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 252b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 253b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey public void testWriteMissingFile() throws Exception { 254b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final File file = new File(mContext.getFilesDir(), TEST_FILE); 255b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final Uri uri = stageFileAndGetUri(file, null); 256b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 257b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey try { 258b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertContentsEquals(new byte[0], uri); 259b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey fail("Somehow read missing file?"); 260b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } catch(FileNotFoundException e) { 261b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 262b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 263b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final OutputStream out = mResolver.openOutputStream(uri); 264b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey try { 265b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey out.write(TEST_DATA_ALT); 266b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } finally { 267b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey IoUtils.closeQuietly(out); 268b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 269b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 270b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertContentsEquals(TEST_DATA_ALT, uri); 271b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 272b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 273b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey public void testDelete() throws Exception { 274b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final File file = new File(mContext.getFilesDir(), TEST_FILE); 275b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final Uri uri = stageFileAndGetUri(file, TEST_DATA); 276b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 277b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertContentsEquals(TEST_DATA, uri); 278b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 279b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(1, mResolver.delete(uri, null, null)); 280b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals(0, mResolver.delete(uri, null, null)); 281b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 282b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey try { 283b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertContentsEquals(new byte[0], uri); 284b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey fail("Somehow read missing file?"); 285b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } catch(FileNotFoundException e) { 286b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 287b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 288b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 289b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey public void testMetaDataTargets() { 290b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey Uri actual; 291b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 292b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey actual = FileProvider.getUriForFile(mContext, TEST_AUTHORITY, 293b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey new File("/proc/version")); 294b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals("content://moocow/test_root/proc/version", actual.toString()); 295b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 296b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey actual = FileProvider.getUriForFile(mContext, TEST_AUTHORITY, 297b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey new File("/proc/1/mountinfo")); 298b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals("content://moocow/test_init/mountinfo", actual.toString()); 299b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 300b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey actual = FileProvider.getUriForFile(mContext, TEST_AUTHORITY, 301b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey buildPath(mContext.getFilesDir(), "meow")); 302b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals("content://moocow/test_files/meow", actual.toString()); 303b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 304b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey actual = FileProvider.getUriForFile(mContext, TEST_AUTHORITY, 305b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey buildPath(mContext.getFilesDir(), "thumbs", "rawr")); 306b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals("content://moocow/test_thumbs/rawr", actual.toString()); 307b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 308b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey actual = FileProvider.getUriForFile(mContext, TEST_AUTHORITY, 309b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey buildPath(mContext.getCacheDir(), "up", "down")); 310b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals("content://moocow/test_cache/up/down", actual.toString()); 311b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 312b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey actual = FileProvider.getUriForFile(mContext, TEST_AUTHORITY, 313b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey buildPath(Environment.getExternalStorageDirectory(), "Android", "obb", "foobar")); 314b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey assertEquals("content://moocow/test_external/Android/obb/foobar", actual.toString()); 315b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 316b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 317b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey private void assertContentsEquals(byte[] expected, Uri actual) throws Exception { 318b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final InputStream in = mResolver.openInputStream(actual); 319b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey try { 320b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey MoreAsserts.assertEquals(expected, Streams.readFully(in)); 321b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } finally { 322b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey IoUtils.closeQuietly(in); 323b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 324b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 325b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 326b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey private Uri stageFileAndGetUri(File file, byte[] data) throws Exception { 327b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey if (data != null) { 328b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey final FileOutputStream out = new FileOutputStream(file); 329b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey try { 330b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey out.write(data); 331b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } finally { 332b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey out.close(); 333b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 334b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } else { 335b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey file.delete(); 336b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 337b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey return FileProvider.getUriForFile(mContext, TEST_AUTHORITY, file); 338b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 339b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey 340b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey private static File buildPath(File base, String... segments) { 341b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey File cur = base; 342b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey for (String segment : segments) { 343b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey if (cur == null) { 344b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey cur = new File(segment); 345b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } else { 346b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey cur = new File(cur, segment); 347b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 348b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 349b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey return cur; 350b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey } 351b49cb25e1450ae36d2559e9753c6d5064e530fccJeff Sharkey} 352