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 drive { | 21 namespace drive { |
22 | 22 |
23 namespace { | |
24 | |
25 // Webstore URL prefix. | |
26 const char kStoreProductUrl[] = "https://chrome.google.com/webstore/"; | |
27 | |
28 // Extracts Web store id from its web store URL. | |
29 std::string GetWebStoreIdFromUrl(const GURL& url) { | |
30 if (!StartsWithASCII(url.spec(), kStoreProductUrl, false)) { | |
31 LOG(WARNING) << "Unrecognized product URL " << url.spec(); | |
32 return std::string(); | |
33 } | |
34 | |
35 base::FilePath path(url.path()); | |
36 std::vector<base::FilePath::StringType> components; | |
37 path.GetComponents(&components); | |
38 DCHECK_LE(2U, components.size()); // Coming from kStoreProductUrl | |
39 | |
40 // Return the last part of the path | |
41 return components[components.size() - 1]; | |
42 } | |
43 | |
44 } // namespace | |
45 | |
46 DriveAppInfo::DriveAppInfo() { | 23 DriveAppInfo::DriveAppInfo() { |
47 } | 24 } |
48 | 25 |
49 DriveAppInfo::DriveAppInfo( | 26 DriveAppInfo::DriveAppInfo( |
50 const std::string& app_id, | 27 const std::string& app_id, |
51 const google_apis::InstalledApp::IconList& app_icons, | 28 const google_apis::InstalledApp::IconList& app_icons, |
52 const google_apis::InstalledApp::IconList& document_icons, | 29 const google_apis::InstalledApp::IconList& document_icons, |
53 const std::string& web_store_id, | |
54 const std::string& app_name, | 30 const std::string& app_name, |
55 const std::string& object_type, | |
56 bool is_primary_selector, | |
57 const GURL& create_url) | 31 const GURL& create_url) |
58 : app_id(app_id), | 32 : app_id(app_id), |
59 app_icons(app_icons), | 33 app_icons(app_icons), |
60 document_icons(document_icons), | 34 document_icons(document_icons), |
61 web_store_id(web_store_id), | |
62 app_name(app_name), | 35 app_name(app_name), |
63 object_type(object_type), | |
64 is_primary_selector(is_primary_selector), | |
65 create_url(create_url) { | 36 create_url(create_url) { |
66 } | 37 } |
67 | 38 |
68 DriveAppInfo::~DriveAppInfo() { | 39 DriveAppInfo::~DriveAppInfo() { |
69 } | 40 } |
70 | 41 |
71 DriveAppRegistry::DriveAppRegistry(JobScheduler* scheduler) | 42 DriveAppRegistry::DriveAppRegistry(JobScheduler* scheduler) |
72 : scheduler_(scheduler), | 43 : scheduler_(scheduler), |
73 is_updating_(false), | 44 is_updating_(false), |
74 weak_ptr_factory_(this) { | 45 weak_ptr_factory_(this) { |
(...skipping 26 matching lines...) Expand all Loading... |
101 apps->push_back(new DriveAppInfo(*matched_apps[i])); | 72 apps->push_back(new DriveAppInfo(*matched_apps[i])); |
102 } | 73 } |
103 } | 74 } |
104 } | 75 } |
105 | 76 |
106 void DriveAppRegistry::Update() { | 77 void DriveAppRegistry::Update() { |
107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
108 | 79 |
109 if (is_updating_) // There is already an update in progress. | 80 if (is_updating_) // There is already an update in progress. |
110 return; | 81 return; |
111 | |
112 is_updating_ = true; | 82 is_updating_ = true; |
113 | 83 |
114 scheduler_->GetAppList( | 84 scheduler_->GetAppList(base::Bind(&DriveAppRegistry::UpdateAfterGetAppList, |
115 base::Bind(&DriveAppRegistry::UpdateAfterGetAppList, | 85 weak_ptr_factory_.GetWeakPtr())); |
116 weak_ptr_factory_.GetWeakPtr())); | |
117 } | 86 } |
118 | 87 |
119 void DriveAppRegistry::UpdateAfterGetAppList( | 88 void DriveAppRegistry::UpdateAfterGetAppList( |
120 google_apis::GDataErrorCode gdata_error, | 89 google_apis::GDataErrorCode gdata_error, |
121 scoped_ptr<google_apis::AppList> app_list) { | 90 scoped_ptr<google_apis::AppList> app_list) { |
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
123 | 92 |
124 DCHECK(is_updating_); | 93 DCHECK(is_updating_); |
125 is_updating_ = false; | 94 is_updating_ = false; |
126 | 95 |
127 FileError error = GDataToFileError(gdata_error); | 96 FileError error = GDataToFileError(gdata_error); |
128 if (error != FILE_ERROR_OK) { | 97 if (error != FILE_ERROR_OK) { |
129 // Failed to fetch the data from the server. We can do nothing here. | 98 // Failed to fetch the data from the server. We can do nothing here. |
130 return; | 99 return; |
131 } | 100 } |
132 | 101 |
133 DCHECK(app_list); | 102 DCHECK(app_list); |
134 UpdateFromAppList(*app_list); | 103 UpdateFromAppList(*app_list); |
135 } | 104 } |
136 | 105 |
137 void DriveAppRegistry::UpdateFromAppList( | 106 void DriveAppRegistry::UpdateFromAppList(const google_apis::AppList& app_list) { |
138 const google_apis::AppList& app_list) { | |
139 STLDeleteValues(&app_extension_map_); | 107 STLDeleteValues(&app_extension_map_); |
140 STLDeleteValues(&app_mimetypes_map_); | 108 STLDeleteValues(&app_mimetypes_map_); |
141 | 109 |
142 for (size_t i = 0; i < app_list.items().size(); ++i) { | 110 for (size_t i = 0; i < app_list.items().size(); ++i) { |
143 const google_apis::AppResource& app = *app_list.items()[i]; | 111 const google_apis::AppResource& app = *app_list.items()[i]; |
144 | 112 |
145 if (app.product_url().is_empty()) | |
146 continue; | |
147 std::string web_store_id = GetWebStoreIdFromUrl(app.product_url()); | |
148 if (web_store_id.empty()) | |
149 continue; | |
150 | |
151 google_apis::InstalledApp::IconList app_icons; | 113 google_apis::InstalledApp::IconList app_icons; |
152 google_apis::InstalledApp::IconList document_icons; | 114 google_apis::InstalledApp::IconList document_icons; |
153 for (size_t j = 0; j < app.icons().size(); ++j) { | 115 for (size_t j = 0; j < app.icons().size(); ++j) { |
154 const google_apis::DriveAppIcon& icon = *app.icons()[j]; | 116 const google_apis::DriveAppIcon& icon = *app.icons()[j]; |
155 if (icon.icon_url().is_empty()) | 117 if (icon.icon_url().is_empty()) |
156 continue; | 118 continue; |
157 if (icon.category() == google_apis::DriveAppIcon::APPLICATION) | 119 if (icon.category() == google_apis::DriveAppIcon::APPLICATION) |
158 app_icons.push_back(std::make_pair(icon.icon_side_length(), | 120 app_icons.push_back(std::make_pair(icon.icon_side_length(), |
159 icon.icon_url())); | 121 icon.icon_url())); |
160 if (icon.category() == google_apis::DriveAppIcon::DOCUMENT) | 122 if (icon.category() == google_apis::DriveAppIcon::DOCUMENT) |
161 document_icons.push_back(std::make_pair(icon.icon_side_length(), | 123 document_icons.push_back(std::make_pair(icon.icon_side_length(), |
162 icon.icon_url())); | 124 icon.icon_url())); |
163 } | 125 } |
164 | 126 |
165 AddAppSelectorList(web_store_id, | 127 AddAppSelectorList(app.name(), |
166 app.name(), | |
167 app_icons, | 128 app_icons, |
168 document_icons, | 129 document_icons, |
169 app.object_type(), | |
170 app.application_id(), | 130 app.application_id(), |
171 true, // primary | |
172 app.create_url(), | 131 app.create_url(), |
173 app.primary_mimetypes(), | 132 app.primary_mimetypes(), |
174 &app_mimetypes_map_); | 133 &app_mimetypes_map_); |
175 AddAppSelectorList(web_store_id, | 134 AddAppSelectorList(app.name(), |
176 app.name(), | |
177 app_icons, | 135 app_icons, |
178 document_icons, | 136 document_icons, |
179 app.object_type(), | |
180 app.application_id(), | 137 app.application_id(), |
181 false, // primary | |
182 app.create_url(), | 138 app.create_url(), |
183 app.secondary_mimetypes(), | 139 app.secondary_mimetypes(), |
184 &app_mimetypes_map_); | 140 &app_mimetypes_map_); |
185 AddAppSelectorList(web_store_id, | 141 AddAppSelectorList(app.name(), |
186 app.name(), | |
187 app_icons, | 142 app_icons, |
188 document_icons, | 143 document_icons, |
189 app.object_type(), | |
190 app.application_id(), | 144 app.application_id(), |
191 true, // primary | |
192 app.create_url(), | 145 app.create_url(), |
193 app.primary_file_extensions(), | 146 app.primary_file_extensions(), |
194 &app_extension_map_); | 147 &app_extension_map_); |
195 AddAppSelectorList(web_store_id, | 148 AddAppSelectorList(app.name(), |
196 app.name(), | |
197 app_icons, | 149 app_icons, |
198 document_icons, | 150 document_icons, |
199 app.object_type(), | |
200 app.application_id(), | 151 app.application_id(), |
201 false, // primary | |
202 app.create_url(), | 152 app.create_url(), |
203 app.secondary_file_extensions(), | 153 app.secondary_file_extensions(), |
204 &app_extension_map_); | 154 &app_extension_map_); |
205 } | 155 } |
206 } | 156 } |
207 | 157 |
208 // static. | 158 // static. |
209 void DriveAppRegistry::AddAppSelectorList( | 159 void DriveAppRegistry::AddAppSelectorList( |
210 const std::string& web_store_id, | |
211 const std::string& app_name, | 160 const std::string& app_name, |
212 const google_apis::InstalledApp::IconList& app_icons, | 161 const google_apis::InstalledApp::IconList& app_icons, |
213 const google_apis::InstalledApp::IconList& document_icons, | 162 const google_apis::InstalledApp::IconList& document_icons, |
214 const std::string& object_type, | |
215 const std::string& app_id, | 163 const std::string& app_id, |
216 bool is_primary_selector, | |
217 const GURL& create_url, | 164 const GURL& create_url, |
218 const ScopedVector<std::string>& selectors, | 165 const ScopedVector<std::string>& selectors, |
219 DriveAppFileSelectorMap* map) { | 166 DriveAppFileSelectorMap* map) { |
220 for (ScopedVector<std::string>::const_iterator it = selectors.begin(); | 167 for (ScopedVector<std::string>::const_iterator it = selectors.begin(); |
221 it != selectors.end(); ++it) { | 168 it != selectors.end(); ++it) { |
222 std::string* value = *it; | 169 std::string* value = *it; |
223 map->insert(std::make_pair( | 170 map->insert(std::make_pair( |
224 *value, new DriveAppInfo(app_id, | 171 *value, new DriveAppInfo(app_id, |
225 app_icons, | 172 app_icons, |
226 document_icons, | 173 document_icons, |
227 web_store_id, | |
228 app_name, | 174 app_name, |
229 object_type, | |
230 is_primary_selector, | |
231 create_url))); | 175 create_url))); |
232 } | 176 } |
233 } | 177 } |
234 | 178 |
235 void DriveAppRegistry::FindAppsForSelector( | 179 void DriveAppRegistry::FindAppsForSelector( |
236 const std::string& file_selector, | 180 const std::string& file_selector, |
237 const DriveAppFileSelectorMap& map, | 181 const DriveAppFileSelectorMap& map, |
238 std::vector<DriveAppInfo*>* matched_apps) const { | 182 std::vector<DriveAppInfo*>* matched_apps) const { |
239 for (DriveAppFileSelectorMap::const_iterator it = map.find(file_selector); | 183 for (DriveAppFileSelectorMap::const_iterator it = map.find(file_selector); |
240 it != map.end() && it->first == file_selector; ++it) { | 184 it != map.end() && it->first == file_selector; ++it) { |
241 matched_apps->push_back(it->second); | 185 matched_apps->push_back(it->second); |
242 } | 186 } |
243 } | 187 } |
244 | 188 |
245 namespace util { | 189 namespace util { |
246 | 190 |
247 GURL FindPreferredIcon( | 191 GURL FindPreferredIcon(const google_apis::InstalledApp::IconList& icons, |
248 const google_apis::InstalledApp::IconList& icons, | 192 int preferred_size) { |
249 int preferred_size) { | |
250 if (icons.empty()) | 193 if (icons.empty()) |
251 return GURL(); | 194 return GURL(); |
252 | 195 |
253 google_apis::InstalledApp::IconList sorted_icons = icons; | 196 google_apis::InstalledApp::IconList sorted_icons = icons; |
254 std::sort(sorted_icons.begin(), sorted_icons.end()); | 197 std::sort(sorted_icons.rbegin(), sorted_icons.rend()); |
255 GURL result = sorted_icons.rbegin()->second; | 198 |
256 for (google_apis::InstalledApp::IconList::const_reverse_iterator | 199 // Go forward while the size is larger or equal to preferred_size. |
257 iter = sorted_icons.rbegin(); | 200 size_t i = 1; |
258 iter != sorted_icons.rend() && iter->first >= preferred_size; ++iter) { | 201 while (i < sorted_icons.size() && sorted_icons[i].first >= preferred_size) |
259 result = iter->second; | 202 ++i; |
260 } | 203 return sorted_icons[i - 1].second; |
261 return result; | |
262 } | 204 } |
263 | 205 |
264 } // namespace util | 206 } // namespace util |
265 } // namespace drive | 207 } // namespace drive |
OLD | NEW |