1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <vector>
6
7 #include "base/message_loop/message_loop.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/extensions/api/system_storage/storage_api_test_util.h"
10 #include "chrome/browser/extensions/api/system_storage/storage_info_provider.h"
11 #include "chrome/browser/extensions/extension_apitest.h"
12 #include "chrome/browser/extensions/extension_test_message_listener.h"
13 #include "components/storage_monitor/storage_monitor.h"
14 #include "components/storage_monitor/test_storage_monitor.h"
15
16 namespace {
17
18 using extensions::StorageUnitInfoList;
19 using extensions::test::TestStorageUnitInfo;
20 using extensions::test::kRemovableStorageData;
21 using storage_monitor::StorageMonitor;
22 using storage_monitor::TestStorageMonitor;
23
24 const struct TestStorageUnitInfo kTestingData[] = {
25 {"dcim:device:001", "0xbeaf", 4098, 1},
26 {"path:device:002", "/home", 4098, 2},
27 {"path:device:003", "/data", 10000, 3}
28 };
29
30 } // namespace
31
32 class TestStorageInfoProvider : public extensions::StorageInfoProvider {
33 public:
34 TestStorageInfoProvider(const struct TestStorageUnitInfo* testing_data,
35 size_t n);
36
37 private:
38 virtual ~TestStorageInfoProvider();
39
40 // StorageInfoProvider implementations.
41 virtual double GetStorageFreeSpaceFromTransientIdOnFileThread(
42 const std::string& transient_id) OVERRIDE;
43
44 std::vector<struct TestStorageUnitInfo> testing_data_;
45 };
46
TestStorageInfoProvider(const struct TestStorageUnitInfo * testing_data,size_t n)47 TestStorageInfoProvider::TestStorageInfoProvider(
48 const struct TestStorageUnitInfo* testing_data, size_t n)
49 : testing_data_(testing_data, testing_data + n) {
50 }
51
~TestStorageInfoProvider()52 TestStorageInfoProvider::~TestStorageInfoProvider() {
53 }
54
GetStorageFreeSpaceFromTransientIdOnFileThread(const std::string & transient_id)55 double TestStorageInfoProvider::GetStorageFreeSpaceFromTransientIdOnFileThread(
56 const std::string& transient_id) {
57 std::string device_id =
58 StorageMonitor::GetInstance()->GetDeviceIdForTransientId(
59 transient_id);
60 for (size_t i = 0; i < testing_data_.size(); ++i) {
61 if (testing_data_[i].device_id == device_id) {
62 return static_cast<double>(testing_data_[i].available_capacity);
63 }
64 }
65 return -1;
66 }
67
68 class SystemStorageApiTest : public ExtensionApiTest {
69 public:
SystemStorageApiTest()70 SystemStorageApiTest() {}
~SystemStorageApiTest()71 virtual ~SystemStorageApiTest() {}
72
SetUpOnMainThread()73 virtual void SetUpOnMainThread() OVERRIDE {
74 TestStorageMonitor::CreateForBrowserTests();
75 }
76
SetUpInProcessBrowserTestFixture()77 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
78 ExtensionApiTest::SetUpInProcessBrowserTestFixture();
79 message_loop_.reset(new base::MessageLoopForUI);
80 }
81
SetUpAllMockStorageDevices()82 void SetUpAllMockStorageDevices() {
83 for (size_t i = 0; i < arraysize(kTestingData); ++i) {
84 AttachRemovableStorage(kTestingData[i]);
85 }
86 }
87
AttachRemovableStorage(const struct TestStorageUnitInfo & removable_storage_info)88 void AttachRemovableStorage(
89 const struct TestStorageUnitInfo& removable_storage_info) {
90 StorageMonitor::GetInstance()->receiver()->ProcessAttach(
91 extensions::test::BuildStorageInfoFromTestStorageUnitInfo(
92 removable_storage_info));
93 }
94
DetachRemovableStorage(const std::string & id)95 void DetachRemovableStorage(const std::string& id) {
96 StorageMonitor::GetInstance()->receiver()->ProcessDetach(id);
97 }
98
99 private:
100 scoped_ptr<base::MessageLoop> message_loop_;
101 };
102
IN_PROC_BROWSER_TEST_F(SystemStorageApiTest,Storage)103 IN_PROC_BROWSER_TEST_F(SystemStorageApiTest, Storage) {
104 SetUpAllMockStorageDevices();
105 TestStorageInfoProvider* provider =
106 new TestStorageInfoProvider(kTestingData,
107 arraysize(kTestingData));
108 extensions::StorageInfoProvider::InitializeForTesting(provider);
109 std::vector<linked_ptr<ExtensionTestMessageListener> > device_ids_listeners;
110 for (size_t i = 0; i < arraysize(kTestingData); ++i) {
111 linked_ptr<ExtensionTestMessageListener> listener(
112 new ExtensionTestMessageListener(
113 StorageMonitor::GetInstance()->GetTransientIdForDeviceId(
114 kTestingData[i].device_id),
115 false));
116 device_ids_listeners.push_back(listener);
117 }
118 ASSERT_TRUE(RunPlatformAppTest("system/storage")) << message_;
119 for (size_t i = 0; i < device_ids_listeners.size(); ++i)
120 EXPECT_TRUE(device_ids_listeners[i]->WaitUntilSatisfied());
121 }
122
IN_PROC_BROWSER_TEST_F(SystemStorageApiTest,StorageAttachment)123 IN_PROC_BROWSER_TEST_F(SystemStorageApiTest, StorageAttachment) {
124 ResultCatcher catcher;
125 ExtensionTestMessageListener attach_listener("attach", false);
126 ExtensionTestMessageListener detach_listener("detach", false);
127
128 EXPECT_TRUE(LoadExtension(
129 test_data_dir_.AppendASCII("system/storage_attachment")));
130 // Simulate triggering onAttached event.
131 ASSERT_TRUE(attach_listener.WaitUntilSatisfied());
132
133 AttachRemovableStorage(kRemovableStorageData);
134
135 std::string removable_storage_transient_id =
136 StorageMonitor::GetInstance()->GetTransientIdForDeviceId(
137 kRemovableStorageData.device_id);
138 ExtensionTestMessageListener detach_device_id_listener(
139 removable_storage_transient_id, false);
140
141 // Simulate triggering onDetached event.
142 ASSERT_TRUE(detach_listener.WaitUntilSatisfied());
143 DetachRemovableStorage(kRemovableStorageData.device_id);
144
145 ASSERT_TRUE(detach_device_id_listener.WaitUntilSatisfied());
146
147 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
148 }
149