| 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 |