OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/drive/drive_app_registry.h" | 5 #include "chrome/browser/chromeos/drive/drive_app_registry.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
14 #include "chrome/browser/chromeos/drive/file_system_util.h" | 14 #include "chrome/browser/chromeos/drive/file_system_util.h" |
15 #include "chrome/browser/chromeos/drive/job_scheduler.h" | 15 #include "chrome/browser/chromeos/drive/job_scheduler.h" |
16 #include "content/public/browser/browser_thread.h" | 16 #include "content/public/browser/browser_thread.h" |
17 #include "google_apis/drive/drive_api_parser.h" | 17 #include "google_apis/drive/drive_api_parser.h" |
18 | 18 |
19 using content::BrowserThread; | 19 using content::BrowserThread; |
20 | 20 |
| 21 namespace { |
| 22 |
| 23 // Add {selector -> app_id} mapping to |map|. |
| 24 void AddAppSelectorList(const ScopedVector<std::string>& selectors, |
| 25 const std::string& app_id, |
| 26 std::multimap<std::string, std::string>* map) { |
| 27 for (size_t i = 0; i < selectors.size(); ++i) |
| 28 map->insert(std::make_pair(*selectors[i], app_id)); |
| 29 } |
| 30 |
| 31 // Append list of app ids in |map| looked up by |selector| to |matched_apps|. |
| 32 void FindAppsForSelector(const std::string& selector, |
| 33 const std::multimap<std::string, std::string>& map, |
| 34 std::vector<std::string>* matched_apps) { |
| 35 typedef std::multimap<std::string, std::string>::const_iterator iterator; |
| 36 std::pair<iterator, iterator> range = map.equal_range(selector); |
| 37 for (iterator it = range.first; it != range.second; ++it) |
| 38 matched_apps->push_back(it->second); |
| 39 } |
| 40 |
| 41 } // namespace |
| 42 |
21 namespace drive { | 43 namespace drive { |
22 | 44 |
23 DriveAppInfo::DriveAppInfo() { | 45 DriveAppInfo::DriveAppInfo() { |
24 } | 46 } |
25 | 47 |
26 DriveAppInfo::DriveAppInfo( | 48 DriveAppInfo::DriveAppInfo( |
27 const std::string& app_id, | 49 const std::string& app_id, |
28 const google_apis::InstalledApp::IconList& app_icons, | 50 const google_apis::InstalledApp::IconList& app_icons, |
29 const google_apis::InstalledApp::IconList& document_icons, | 51 const google_apis::InstalledApp::IconList& document_icons, |
30 const std::string& app_name, | 52 const std::string& app_name, |
31 const GURL& create_url) | 53 const GURL& create_url) |
32 : app_id(app_id), | 54 : app_id(app_id), |
33 app_icons(app_icons), | 55 app_icons(app_icons), |
34 document_icons(document_icons), | 56 document_icons(document_icons), |
35 app_name(app_name), | 57 app_name(app_name), |
36 create_url(create_url) { | 58 create_url(create_url) { |
37 } | 59 } |
38 | 60 |
39 DriveAppInfo::~DriveAppInfo() { | 61 DriveAppInfo::~DriveAppInfo() { |
40 } | 62 } |
41 | 63 |
42 DriveAppRegistry::DriveAppRegistry(JobScheduler* scheduler) | 64 DriveAppRegistry::DriveAppRegistry(JobScheduler* scheduler) |
43 : scheduler_(scheduler), | 65 : scheduler_(scheduler), |
44 is_updating_(false), | 66 is_updating_(false), |
45 weak_ptr_factory_(this) { | 67 weak_ptr_factory_(this) { |
46 } | 68 } |
47 | 69 |
48 DriveAppRegistry::~DriveAppRegistry() { | 70 DriveAppRegistry::~DriveAppRegistry() { |
49 STLDeleteValues(&app_extension_map_); | |
50 STLDeleteValues(&app_mimetypes_map_); | |
51 } | 71 } |
52 | 72 |
53 void DriveAppRegistry::GetAppsForFile( | 73 void DriveAppRegistry::GetAppsForFile( |
54 const base::FilePath::StringType& file_extension, | 74 const base::FilePath::StringType& file_extension, |
55 const std::string& mime_type, | 75 const std::string& mime_type, |
56 ScopedVector<DriveAppInfo>* apps) const { | 76 ScopedVector<DriveAppInfo>* apps) const { |
57 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
58 | 78 |
59 std::vector<DriveAppInfo*> matched_apps; | 79 std::vector<std::string> matched_apps; |
60 if (!file_extension.empty()) { | 80 if (!file_extension.empty()) { |
61 const base::FilePath::StringType without_dot = file_extension.substr(1); | 81 const base::FilePath::StringType without_dot = file_extension.substr(1); |
62 FindAppsForSelector(without_dot, app_extension_map_, &matched_apps); | 82 FindAppsForSelector(without_dot, extension_map_, &matched_apps); |
63 } | 83 } |
64 if (!mime_type.empty()) | 84 if (!mime_type.empty()) |
65 FindAppsForSelector(mime_type, app_mimetypes_map_, &matched_apps); | 85 FindAppsForSelector(mime_type, mimetype_map_, &matched_apps); |
66 | 86 |
67 // Insert found Drive apps into |apps|, but skip duplicate results. | 87 // Insert found Drive apps into |apps|, but skip duplicate results. |
68 std::set<std::string> inserted_app_ids; | 88 std::set<std::string> inserted_app_ids; |
69 for (size_t i = 0; i < matched_apps.size(); ++i) { | 89 for (size_t i = 0; i < matched_apps.size(); ++i) { |
70 if (inserted_app_ids.count(matched_apps[i]->app_id) == 0) { | 90 if (inserted_app_ids.count(matched_apps[i]) == 0) { |
71 inserted_app_ids.insert(matched_apps[i]->app_id); | 91 inserted_app_ids.insert(matched_apps[i]); |
72 apps->push_back(new DriveAppInfo(*matched_apps[i])); | 92 std::map<std::string, DriveAppInfo>::const_iterator it = |
| 93 all_apps_.find(matched_apps[i]); |
| 94 DCHECK(it != all_apps_.end()); |
| 95 apps->push_back(new DriveAppInfo(it->second)); |
73 } | 96 } |
74 } | 97 } |
75 } | 98 } |
76 | 99 |
77 void DriveAppRegistry::Update() { | 100 void DriveAppRegistry::Update() { |
78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
79 | 102 |
80 if (is_updating_) // There is already an update in progress. | 103 if (is_updating_) // There is already an update in progress. |
81 return; | 104 return; |
82 is_updating_ = true; | 105 is_updating_ = true; |
(...skipping 14 matching lines...) Expand all Loading... |
97 if (error != FILE_ERROR_OK) { | 120 if (error != FILE_ERROR_OK) { |
98 // Failed to fetch the data from the server. We can do nothing here. | 121 // Failed to fetch the data from the server. We can do nothing here. |
99 return; | 122 return; |
100 } | 123 } |
101 | 124 |
102 DCHECK(app_list); | 125 DCHECK(app_list); |
103 UpdateFromAppList(*app_list); | 126 UpdateFromAppList(*app_list); |
104 } | 127 } |
105 | 128 |
106 void DriveAppRegistry::UpdateFromAppList(const google_apis::AppList& app_list) { | 129 void DriveAppRegistry::UpdateFromAppList(const google_apis::AppList& app_list) { |
107 STLDeleteValues(&app_extension_map_); | 130 all_apps_.clear(); |
108 STLDeleteValues(&app_mimetypes_map_); | 131 extension_map_.clear(); |
| 132 mimetype_map_.clear(); |
109 | 133 |
110 for (size_t i = 0; i < app_list.items().size(); ++i) { | 134 for (size_t i = 0; i < app_list.items().size(); ++i) { |
111 const google_apis::AppResource& app = *app_list.items()[i]; | 135 const google_apis::AppResource& app = *app_list.items()[i]; |
| 136 const std::string id = app.application_id(); |
112 | 137 |
113 google_apis::InstalledApp::IconList app_icons; | 138 google_apis::InstalledApp::IconList app_icons; |
114 google_apis::InstalledApp::IconList document_icons; | 139 google_apis::InstalledApp::IconList document_icons; |
115 for (size_t j = 0; j < app.icons().size(); ++j) { | 140 for (size_t j = 0; j < app.icons().size(); ++j) { |
116 const google_apis::DriveAppIcon& icon = *app.icons()[j]; | 141 const google_apis::DriveAppIcon& icon = *app.icons()[j]; |
117 if (icon.icon_url().is_empty()) | 142 if (icon.icon_url().is_empty()) |
118 continue; | 143 continue; |
119 if (icon.category() == google_apis::DriveAppIcon::APPLICATION) | 144 if (icon.category() == google_apis::DriveAppIcon::APPLICATION) |
120 app_icons.push_back(std::make_pair(icon.icon_side_length(), | 145 app_icons.push_back(std::make_pair(icon.icon_side_length(), |
121 icon.icon_url())); | 146 icon.icon_url())); |
122 if (icon.category() == google_apis::DriveAppIcon::DOCUMENT) | 147 if (icon.category() == google_apis::DriveAppIcon::DOCUMENT) |
123 document_icons.push_back(std::make_pair(icon.icon_side_length(), | 148 document_icons.push_back(std::make_pair(icon.icon_side_length(), |
124 icon.icon_url())); | 149 icon.icon_url())); |
125 } | 150 } |
126 | 151 |
127 AddAppSelectorList(app.name(), | 152 all_apps_[id] = DriveAppInfo(app.application_id(), |
128 app_icons, | 153 app_icons, |
129 document_icons, | 154 document_icons, |
130 app.application_id(), | 155 app.name(), |
131 app.create_url(), | 156 app.create_url()); |
132 app.primary_mimetypes(), | 157 |
133 &app_mimetypes_map_); | 158 // TODO(kinaba): consider taking primary/secondary distinction into account. |
134 AddAppSelectorList(app.name(), | 159 AddAppSelectorList(app.primary_mimetypes(), id, &mimetype_map_); |
135 app_icons, | 160 AddAppSelectorList(app.secondary_mimetypes(), id, &mimetype_map_); |
136 document_icons, | 161 AddAppSelectorList(app.primary_file_extensions(), id, &extension_map_); |
137 app.application_id(), | 162 AddAppSelectorList(app.secondary_file_extensions(), id, &extension_map_); |
138 app.create_url(), | |
139 app.secondary_mimetypes(), | |
140 &app_mimetypes_map_); | |
141 AddAppSelectorList(app.name(), | |
142 app_icons, | |
143 document_icons, | |
144 app.application_id(), | |
145 app.create_url(), | |
146 app.primary_file_extensions(), | |
147 &app_extension_map_); | |
148 AddAppSelectorList(app.name(), | |
149 app_icons, | |
150 document_icons, | |
151 app.application_id(), | |
152 app.create_url(), | |
153 app.secondary_file_extensions(), | |
154 &app_extension_map_); | |
155 } | 163 } |
156 } | 164 } |
157 | 165 |
158 // static. | |
159 void DriveAppRegistry::AddAppSelectorList( | |
160 const std::string& app_name, | |
161 const google_apis::InstalledApp::IconList& app_icons, | |
162 const google_apis::InstalledApp::IconList& document_icons, | |
163 const std::string& app_id, | |
164 const GURL& create_url, | |
165 const ScopedVector<std::string>& selectors, | |
166 DriveAppFileSelectorMap* map) { | |
167 for (ScopedVector<std::string>::const_iterator it = selectors.begin(); | |
168 it != selectors.end(); ++it) { | |
169 std::string* value = *it; | |
170 map->insert(std::make_pair( | |
171 *value, new DriveAppInfo(app_id, | |
172 app_icons, | |
173 document_icons, | |
174 app_name, | |
175 create_url))); | |
176 } | |
177 } | |
178 | |
179 void DriveAppRegistry::FindAppsForSelector( | |
180 const std::string& file_selector, | |
181 const DriveAppFileSelectorMap& map, | |
182 std::vector<DriveAppInfo*>* matched_apps) const { | |
183 for (DriveAppFileSelectorMap::const_iterator it = map.find(file_selector); | |
184 it != map.end() && it->first == file_selector; ++it) { | |
185 matched_apps->push_back(it->second); | |
186 } | |
187 } | |
188 | |
189 namespace util { | 166 namespace util { |
190 | 167 |
191 GURL FindPreferredIcon(const google_apis::InstalledApp::IconList& icons, | 168 GURL FindPreferredIcon(const google_apis::InstalledApp::IconList& icons, |
192 int preferred_size) { | 169 int preferred_size) { |
193 if (icons.empty()) | 170 if (icons.empty()) |
194 return GURL(); | 171 return GURL(); |
195 | 172 |
196 google_apis::InstalledApp::IconList sorted_icons = icons; | 173 google_apis::InstalledApp::IconList sorted_icons = icons; |
197 std::sort(sorted_icons.rbegin(), sorted_icons.rend()); | 174 std::sort(sorted_icons.rbegin(), sorted_icons.rend()); |
198 | 175 |
199 // Go forward while the size is larger or equal to preferred_size. | 176 // Go forward while the size is larger or equal to preferred_size. |
200 size_t i = 1; | 177 size_t i = 1; |
201 while (i < sorted_icons.size() && sorted_icons[i].first >= preferred_size) | 178 while (i < sorted_icons.size() && sorted_icons[i].first >= preferred_size) |
202 ++i; | 179 ++i; |
203 return sorted_icons[i - 1].second; | 180 return sorted_icons[i - 1].second; |
204 } | 181 } |
205 | 182 |
206 } // namespace util | 183 } // namespace util |
207 } // namespace drive | 184 } // namespace drive |
OLD | NEW |