summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/base/file_stream_context.cc29
-rw-r--r--net/base/file_stream_unittest.cc53
-rw-r--r--net/data/file_stream_unittest/red.pngbin0 -> 173 bytes
-rw-r--r--net/net.gyp1
-rw-r--r--net/test/run_all_unittests.cc2
5 files changed, 78 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
new file mode 100644
index 0000000..0806141
--- /dev/null
+++ b/net/data/file_stream_unittest/red.png
Binary files differ
diff --git a/net/net.gyp b/net/net.gyp
index 3e5b04b..4f16adb 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -2993,6 +2993,7 @@
'target_name': 'net_unittests_apk',
'type': 'none',
'dependencies': [
+ '../base/base.gyp:base_java_unittest_support',
'net_java',
'net_javatests',
'net_unittests',
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);