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