diff options
author | qinmin@chromium.org <qinmin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-20 07:04:55 +0000 |
---|---|---|
committer | qinmin@chromium.org <qinmin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-20 07:04:55 +0000 |
commit | f12d1e1552d00cc2f4f38a37460dedd4737c5b05 (patch) | |
tree | 87e58f7df0bfb7b28983e559c3ce5cc958766a18 /net | |
parent | 5a9fb0198579da5c478c846c401c13d1f6f9e6e2 (diff) | |
download | chromium_src-f12d1e1552d00cc2f4f38a37460dedd4737c5b05.zip chromium_src-f12d1e1552d00cc2f4f38a37460dedd4737c5b05.tar.gz chromium_src-f12d1e1552d00cc2f4f38a37460dedd4737c5b05.tar.bz2 |
Fix chrome upload with content uri
For android, the upload file dialog returns files with content uri scheme(content://).
This CL makes it possible for upload to work with this new file type.
It fixes both the form and fileapi based uploads.
BUG=278640
Review URL: https://codereview.chromium.org/75533002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@236192 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/base/file_stream_context.cc | 29 | ||||
-rw-r--r-- | net/base/file_stream_unittest.cc | 53 | ||||
-rw-r--r-- | net/data/file_stream_unittest/red.png | bin | 0 -> 173 bytes | |||
-rw-r--r-- | net/test/run_all_unittests.cc | 2 |
4 files changed, 77 insertions, 7 deletions
diff --git a/net/base/file_stream_context.cc b/net/base/file_stream_context.cc index 2e77475..e7fe100 100644 --- a/net/base/file_stream_context.cc +++ b/net/base/file_stream_context.cc @@ -11,6 +11,10 @@ #include "net/base/file_stream_net_log_parameters.h" #include "net/base/net_errors.h" +#if defined(OS_ANDROID) +#include "base/android/content_uri_utils.h" +#endif + namespace { void CallInt64ToInt(const net::CompletionCallback& callback, int64 result) { @@ -193,13 +197,24 @@ void FileStream::Context::BeginOpenEvent(const base::FilePath& path) { FileStream::Context::OpenResult FileStream::Context::OpenFileImpl( const base::FilePath& path, int open_flags) { - // FileStream::Context actually closes the file asynchronously, independently - // from FileStream's destructor. It can cause problems for users wanting to - // delete the file right after FileStream deletion. Thus we are always - // adding SHARE_DELETE flag to accommodate such use case. - open_flags |= base::PLATFORM_FILE_SHARE_DELETE; - base::PlatformFile file = - base::CreatePlatformFile(path, open_flags, NULL, NULL); + base::PlatformFile file; +#if defined(OS_ANDROID) + if (path.IsContentUri()) { + // Check that only Read flags are set. + DCHECK_EQ(open_flags & ~base::PLATFORM_FILE_ASYNC, + base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ); + file = base::OpenContentUriForRead(path); + } else { +#endif // defined(OS_ANDROID) + // FileStream::Context actually closes the file asynchronously, + // independently from FileStream's destructor. It can cause problems for + // users wanting to delete the file right after FileStream deletion. Thus + // we are always adding SHARE_DELETE flag to accommodate such use case. + open_flags |= base::PLATFORM_FILE_SHARE_DELETE; + file = base::CreatePlatformFile(path, open_flags, NULL, NULL); +#if defined(OS_ANDROID) + } +#endif // defined(OS_ANDROID) if (file == base::kInvalidPlatformFileValue) return OpenResult(file, IOResult::FromOSError(GetLastErrno())); diff --git a/net/base/file_stream_unittest.cc b/net/base/file_stream_unittest.cc index c76f3d9..e721569 100644 --- a/net/base/file_stream_unittest.cc +++ b/net/base/file_stream_unittest.cc @@ -21,6 +21,10 @@ #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" +#if defined(OS_ANDROID) +#include "base/test/test_file_util.h" +#endif + namespace net { namespace { @@ -1173,6 +1177,55 @@ TEST_F(FileStreamTest, AsyncReadError) { base::ClosePlatformFile(file); } +#if defined(OS_ANDROID) +TEST_F(FileStreamTest, ContentUriAsyncRead) { + base::FilePath test_dir; + PathService::Get(base::DIR_SOURCE_ROOT, &test_dir); + test_dir = test_dir.AppendASCII("net"); + test_dir = test_dir.AppendASCII("data"); + test_dir = test_dir.AppendASCII("file_stream_unittest"); + ASSERT_TRUE(base::PathExists(test_dir)); + base::FilePath image_file = test_dir.Append(FILE_PATH_LITERAL("red.png")); + + // Insert the image into MediaStore. MediaStore will do some conversions, and + // return the content URI. + base::FilePath path = file_util::InsertImageIntoMediaStore(image_file); + EXPECT_TRUE(path.IsContentUri()); + EXPECT_TRUE(base::PathExists(path)); + int64 file_size; + EXPECT_TRUE(file_util::GetFileSize(path, &file_size)); + EXPECT_LT(0, file_size); + + FileStream stream(NULL, base::MessageLoopProxy::current()); + int flags = base::PLATFORM_FILE_OPEN | + base::PLATFORM_FILE_READ | + base::PLATFORM_FILE_ASYNC; + TestCompletionCallback callback; + int rv = stream.Open(path, flags, callback.callback()); + EXPECT_EQ(ERR_IO_PENDING, rv); + EXPECT_EQ(OK, callback.WaitForResult()); + + int64 total_bytes_avail = stream.Available(); + EXPECT_EQ(file_size, total_bytes_avail); + + int total_bytes_read = 0; + + std::string data_read; + for (;;) { + scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4); + rv = stream.Read(buf.get(), buf->size(), callback.callback()); + if (rv == ERR_IO_PENDING) + rv = callback.WaitForResult(); + EXPECT_LE(0, rv); + if (rv <= 0) + break; + total_bytes_read += rv; + data_read.append(buf->data(), rv); + } + EXPECT_EQ(file_size, total_bytes_read); +} +#endif + } // namespace } // namespace net diff --git a/net/data/file_stream_unittest/red.png b/net/data/file_stream_unittest/red.png Binary files differnew file mode 100644 index 0000000..0806141 --- /dev/null +++ b/net/data/file_stream_unittest/red.png diff --git a/net/test/run_all_unittests.cc b/net/test/run_all_unittests.cc index 3a51ba0..9b5dad2 100644 --- a/net/test/run_all_unittests.cc +++ b/net/test/run_all_unittests.cc @@ -13,6 +13,7 @@ #if defined(OS_ANDROID) #include "base/android/jni_android.h" +#include "base/test/test_file_util.h" #include "net/android/net_jni_registrar.h" #endif @@ -31,6 +32,7 @@ int main(int argc, char** argv) { // Register JNI bindings for android. Doing it early as the test suite setup // may initiate a call to Java. net::android::RegisterJni(base::android::AttachCurrentThread()); + file_util::RegisterContentUriTestUtils(base::android::AttachCurrentThread()); #endif NetTestSuite test_suite(argc, argv); |