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