Chromium Code Reviews| 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/extensions/file_handler_util.h" | 5 #include "chrome/browser/chromeos/extensions/file_handler_util.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/i18n/case_conversion.h" | 9 #include "base/i18n/case_conversion.h" |
| 10 #include "base/json/json_writer.h" | 10 #include "base/json/json_writer.h" |
| 11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 12 #include "base/stringprintf.h" | 12 #include "base/stringprintf.h" |
| 13 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
| 14 #include "chrome/browser/chromeos/gdata/gdata_util.h" | 14 #include "chrome/browser/chromeos/gdata/gdata_util.h" |
| 15 #include "chrome/browser/chromeos/extensions/file_manager_util.h" | 15 #include "chrome/browser/chromeos/extensions/file_manager_util.h" |
| 16 #include "chrome/browser/chromeos/gdata/drive_task_executor.h" | 16 #include "chrome/browser/chromeos/gdata/drive_task_executor.h" |
| 17 #include "chrome/browser/extensions/api/app_runtime/app_runtime_api.h" | |
| 17 #include "chrome/browser/extensions/event_router.h" | 18 #include "chrome/browser/extensions/event_router.h" |
| 18 #include "chrome/browser/extensions/extension_host.h" | 19 #include "chrome/browser/extensions/extension_host.h" |
| 20 #include "chrome/browser/extensions/extension_process_manager.h" | |
| 19 #include "chrome/browser/extensions/extension_service.h" | 21 #include "chrome/browser/extensions/extension_service.h" |
| 20 #include "chrome/browser/extensions/extension_system.h" | 22 #include "chrome/browser/extensions/extension_system.h" |
| 21 #include "chrome/browser/extensions/extension_tab_util.h" | 23 #include "chrome/browser/extensions/extension_tab_util.h" |
| 22 #include "chrome/browser/extensions/lazy_background_task_queue.h" | 24 #include "chrome/browser/extensions/lazy_background_task_queue.h" |
| 23 #include "chrome/browser/prefs/scoped_user_pref_update.h" | 25 #include "chrome/browser/prefs/scoped_user_pref_update.h" |
| 24 #include "chrome/browser/profiles/profile.h" | 26 #include "chrome/browser/profiles/profile.h" |
| 25 #include "chrome/browser/profiles/profile_manager.h" | 27 #include "chrome/browser/profiles/profile_manager.h" |
| 26 #include "chrome/browser/ui/browser.h" | 28 #include "chrome/browser/ui/browser.h" |
| 27 #include "chrome/browser/ui/browser_finder.h" | 29 #include "chrome/browser/ui/browser_finder.h" |
| 28 #include "chrome/browser/ui/browser_tabstrip.h" | 30 #include "chrome/browser/ui/browser_tabstrip.h" |
| 29 #include "chrome/common/extensions/file_browser_handler.h" | 31 #include "chrome/common/extensions/file_browser_handler.h" |
| 30 #include "chrome/common/pref_names.h" | 32 #include "chrome/common/pref_names.h" |
| 31 #include "content/public/browser/browser_thread.h" | 33 #include "content/public/browser/browser_thread.h" |
| 32 #include "content/public/browser/child_process_security_policy.h" | 34 #include "content/public/browser/child_process_security_policy.h" |
| 33 #include "content/public/browser/render_process_host.h" | 35 #include "content/public/browser/render_process_host.h" |
| 34 #include "content/public/browser/site_instance.h" | 36 #include "content/public/browser/site_instance.h" |
| 35 #include "content/public/browser/web_contents.h" | 37 #include "content/public/browser/web_contents.h" |
| 36 #include "net/base/escape.h" | 38 #include "net/base/escape.h" |
| 37 #include "webkit/fileapi/file_system_context.h" | 39 #include "webkit/fileapi/file_system_context.h" |
| 38 #include "webkit/fileapi/file_system_mount_point_provider.h" | 40 #include "webkit/fileapi/file_system_mount_point_provider.h" |
| 39 #include "webkit/fileapi/file_system_util.h" | 41 #include "webkit/fileapi/file_system_util.h" |
| 42 #include "webkit/fileapi/isolated_context.h" | |
| 40 | 43 |
| 41 using content::BrowserContext; | 44 using content::BrowserContext; |
| 42 using content::BrowserThread; | 45 using content::BrowserThread; |
| 43 using content::ChildProcessSecurityPolicy; | 46 using content::ChildProcessSecurityPolicy; |
| 44 using content::SiteInstance; | 47 using content::SiteInstance; |
| 45 using content::WebContents; | 48 using content::WebContents; |
| 46 using extensions::Extension; | 49 using extensions::Extension; |
| 47 | 50 |
| 48 namespace file_handler_util { | 51 namespace file_handler_util { |
| 49 | 52 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 111 for (Extension::FileBrowserHandlerList::const_iterator action_iter = | 114 for (Extension::FileBrowserHandlerList::const_iterator action_iter = |
| 112 extension->file_browser_handlers()->begin(); | 115 extension->file_browser_handlers()->begin(); |
| 113 action_iter != extension->file_browser_handlers()->end(); | 116 action_iter != extension->file_browser_handlers()->end(); |
| 114 ++action_iter) { | 117 ++action_iter) { |
| 115 if (action_iter->get()->id() == action_id) | 118 if (action_iter->get()->id() == action_id) |
| 116 return action_iter->get(); | 119 return action_iter->get(); |
| 117 } | 120 } |
| 118 return NULL; | 121 return NULL; |
| 119 } | 122 } |
| 120 | 123 |
| 124 bool IsWebIntentAction(const std::string& action_id) { | |
| 125 if (action_id.compare(0, 4, std::string("http")) == 0) | |
| 126 return true; | |
| 127 return false; | |
| 128 } | |
| 129 | |
| 121 unsigned int GetAccessPermissionsForHandler(const Extension* extension, | 130 unsigned int GetAccessPermissionsForHandler(const Extension* extension, |
| 122 const std::string& action_id) { | 131 const std::string& action_id) { |
| 132 if (IsWebIntentAction(action_id)) | |
| 133 return kReadOnlyFilePermissions; | |
| 134 | |
| 123 const FileBrowserHandler* action = | 135 const FileBrowserHandler* action = |
| 124 FindFileBrowserHandler(extension, action_id); | 136 FindFileBrowserHandler(extension, action_id); |
| 125 if (!action) | 137 if (!action) |
| 126 return 0; | 138 return 0; |
| 127 unsigned int result = 0; | 139 unsigned int result = 0; |
| 128 if (action->CanRead()) | 140 if (action->CanRead()) |
| 129 result |= kReadOnlyFilePermissions; | 141 result |= kReadOnlyFilePermissions; |
| 130 if (action->CanWrite()) | 142 if (action->CanWrite()) |
| 131 result |= kReadWriteFilePermissions; | 143 result |= kReadWriteFilePermissions; |
| 132 // TODO(tbarzic): We don't handle Create yet. | 144 // TODO(tbarzic): We don't handle Create yet. |
| 133 return result; | 145 return result; |
| 134 } | 146 } |
| 135 | 147 |
| 136 | |
| 137 std::string EscapedUtf8ToLower(const std::string& str) { | 148 std::string EscapedUtf8ToLower(const std::string& str) { |
| 138 string16 utf16 = UTF8ToUTF16( | 149 string16 utf16 = UTF8ToUTF16( |
| 139 net::UnescapeURLComponent(str, net::UnescapeRule::NORMAL)); | 150 net::UnescapeURLComponent(str, net::UnescapeRule::NORMAL)); |
| 140 return net::EscapeUrlEncodedData( | 151 return net::EscapeUrlEncodedData( |
| 141 UTF16ToUTF8(base::i18n::ToLower(utf16)), | 152 UTF16ToUTF8(base::i18n::ToLower(utf16)), |
| 142 false /* do not replace space with plus */); | 153 false /* do not replace space with plus */); |
| 143 } | 154 } |
| 144 | 155 |
| 145 bool GetFileBrowserHandlers(Profile* profile, | 156 bool GetFileBrowserHandlers(Profile* profile, |
| 146 const GURL& selected_file_url, | 157 const GURL& selected_file_url, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 181 const LastUsedHandler& b) { | 192 const LastUsedHandler& b) { |
| 182 return a.timestamp > b.timestamp; | 193 return a.timestamp > b.timestamp; |
| 183 } | 194 } |
| 184 | 195 |
| 185 // TODO(zelidrag): Wire this with ICU to make this sort I18N happy. | 196 // TODO(zelidrag): Wire this with ICU to make this sort I18N happy. |
| 186 bool SortByTaskName(const LastUsedHandler& a, const LastUsedHandler& b) { | 197 bool SortByTaskName(const LastUsedHandler& a, const LastUsedHandler& b) { |
| 187 return base::strcasecmp(a.handler->title().c_str(), | 198 return base::strcasecmp(a.handler->title().c_str(), |
| 188 b.handler->title().c_str()) > 0; | 199 b.handler->title().c_str()) > 0; |
| 189 } | 200 } |
| 190 | 201 |
| 202 // Does this LastUsedHandlerList contain entries with only a common timestamp? | |
| 203 bool HasCommonTimestamp(LastUsedHandlerList* list) { | |
| 204 DCHECK(!list->empty()); | |
| 205 int common_timestamp = list->begin()->timestamp; | |
| 206 for (LastUsedHandlerList::const_iterator iter = list->begin() + 1; | |
| 207 iter != list->end(); ++iter) { | |
| 208 if (common_timestamp != iter->timestamp) | |
| 209 return false; | |
| 210 } | |
| 211 return true; | |
| 212 } | |
| 213 | |
| 191 void SortLastUsedHandlerList(LastUsedHandlerList *list) { | 214 void SortLastUsedHandlerList(LastUsedHandlerList *list) { |
| 192 // Sort by the last used descending. | 215 if (list->size() <= 1) { |
|
benwells
2012/08/27 08:02:59
Could you add a comment to explain the logic used
thorogood
2012/08/28 00:04:04
I've put the comment in front of the if statement,
| |
| 193 std::sort(list->begin(), list->end(), SortByLastUsedTimestampDesc); | 216 // Ok, we're alreay sorted. |
| 194 if (list->size() > 1) { | 217 } else if (HasCommonTimestamp(list)) { |
| 195 // Sort the rest by name. | 218 // Sort only by name. |
| 219 std::sort(list->begin(), list->end(), SortByTaskName); | |
| 220 } else { | |
| 221 // Bring the last used descending to the front, and sort the rest by name. | |
| 222 std::sort(list->begin(), list->end(), SortByLastUsedTimestampDesc); | |
| 196 std::sort(list->begin() + 1, list->end(), SortByTaskName); | 223 std::sort(list->begin() + 1, list->end(), SortByTaskName); |
| 197 } | 224 } |
| 198 } | 225 } |
| 199 | 226 |
| 200 } // namespace | 227 } // namespace |
| 201 | 228 |
| 202 // Update file handler usage stats. | 229 // Update file handler usage stats. |
| 203 void UpdateFileHandlerUsageStats(Profile* profile, const std::string& task_id) { | 230 void UpdateFileHandlerUsageStats(Profile* profile, const std::string& task_id) { |
| 204 if (!profile || !profile->GetPrefs()) | 231 if (!profile || !profile->GetPrefs()) |
| 205 return; | 232 return; |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 797 int handler_pid_in, | 824 int handler_pid_in, |
| 798 extensions::ExtensionHost* host) { | 825 extensions::ExtensionHost* host) { |
| 799 int handler_pid = host ? host->render_process_host()->GetID() : | 826 int handler_pid = host ? host->render_process_host()->GetID() : |
| 800 handler_pid_in; | 827 handler_pid_in; |
| 801 | 828 |
| 802 if (handler_pid <= 0) { | 829 if (handler_pid <= 0) { |
| 803 ExecuteDoneOnUIThread(false); | 830 ExecuteDoneOnUIThread(false); |
| 804 return; | 831 return; |
| 805 } | 832 } |
| 806 | 833 |
| 834 // If we're a Web Intent action (to an extension), short-circuit and deliver | |
| 835 // each file as an onLaunched event to the packaged app's background page. | |
| 836 if (IsWebIntentAction(action_id_)) { | |
|
benwells
2012/08/27 08:02:59
This is a bit of a monster function now. This bloc
thorogood
2012/08/29 06:34:46
I've modified platform_app_launcher to allow launc
| |
| 837 for (FileDefinitionList::const_iterator iter = file_list.begin(); | |
| 838 iter != file_list.end(); ++iter) { | |
| 839 | |
| 840 // TODO(thorogood): Literally entirely stolen | |
| 841 // from platform_app_launcher.cc, around line 180. | |
| 842 | |
| 843 const FilePath file_path = iter->absolute_path; | |
| 844 | |
| 845 ExtensionProcessManager* process_manager = | |
| 846 extensions::ExtensionSystem::Get(profile())->process_manager(); | |
| 847 extensions::ExtensionHost* host = | |
| 848 process_manager->GetBackgroundHostForExtension(extension_id_); | |
| 849 | |
| 850 content::ChildProcessSecurityPolicy* policy = | |
| 851 content::ChildProcessSecurityPolicy::GetInstance(); | |
| 852 int renderer_id = host->render_process_host()->GetID(); | |
| 853 | |
| 854 // Granting read file permission to allow reading file content. | |
| 855 // If the renderer already has permission to read these paths, it is not | |
| 856 // regranted, as this would overwrite any other permissions which the | |
| 857 // renderer may already have. | |
| 858 if (!policy->CanReadFile(renderer_id, file_path)) | |
| 859 policy->GrantReadFile(renderer_id, file_path); | |
| 860 | |
| 861 std::string registered_name; | |
| 862 fileapi::IsolatedContext* isolated_context = | |
| 863 fileapi::IsolatedContext::GetInstance(); | |
| 864 DCHECK(isolated_context); | |
| 865 std::string filesystem_id = isolated_context->RegisterFileSystemForPath( | |
| 866 fileapi::kFileSystemTypeIsolated, file_path, ®istered_name); | |
| 867 // Granting read file system permission as well to allow file-system | |
| 868 // read operations. | |
| 869 policy->GrantReadFileSystem(renderer_id, filesystem_id); | |
| 870 | |
| 871 extensions::AppEventRouter::DispatchOnLaunchedEventWithFileEntry( | |
| 872 profile(), | |
| 873 GetExtension(), | |
| 874 UTF8ToUTF16(action_id_), | |
| 875 filesystem_id, | |
| 876 registered_name); | |
| 877 } | |
| 878 | |
| 879 ExecuteDoneOnUIThread(true); | |
| 880 return; | |
| 881 } | |
| 882 | |
| 807 extensions::EventRouter* event_router = profile()->GetExtensionEventRouter(); | 883 extensions::EventRouter* event_router = profile()->GetExtensionEventRouter(); |
| 808 if (!event_router) { | 884 if (!event_router) { |
| 809 ExecuteDoneOnUIThread(false); | 885 ExecuteDoneOnUIThread(false); |
| 810 return; | 886 return; |
| 811 } | 887 } |
| 812 | 888 |
| 813 SetupHandlerHostFileAccessPermissions(handler_pid); | 889 SetupHandlerHostFileAccessPermissions(handler_pid); |
| 814 | 890 |
| 815 scoped_ptr<ListValue> event_args(new ListValue()); | 891 scoped_ptr<ListValue> event_args(new ListValue()); |
| 816 event_args->Append(Value::CreateStringValue(action_id_)); | 892 event_args->Append(Value::CreateStringValue(action_id_)); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 888 handler_pid, | 964 handler_pid, |
| 889 handler_host_permissions_[i].first, | 965 handler_host_permissions_[i].first, |
| 890 handler_host_permissions_[i].second); | 966 handler_host_permissions_[i].second); |
| 891 } | 967 } |
| 892 | 968 |
| 893 // We don't need this anymore. | 969 // We don't need this anymore. |
| 894 handler_host_permissions_.clear(); | 970 handler_host_permissions_.clear(); |
| 895 } | 971 } |
| 896 | 972 |
| 897 } // namespace file_handler_util | 973 } // namespace file_handler_util |
| OLD | NEW |