| 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/chromeos/fileapi/cros_mount_point_provider.h" | 39 #include "webkit/chromeos/fileapi/cros_mount_point_provider.h" |
| 38 #include "webkit/fileapi/file_system_context.h" | 40 #include "webkit/fileapi/file_system_context.h" |
| 39 #include "webkit/fileapi/file_system_url.h" | 41 #include "webkit/fileapi/file_system_url.h" |
| 40 #include "webkit/fileapi/file_system_util.h" | 42 #include "webkit/fileapi/file_system_util.h" |
| 43 #include "webkit/fileapi/isolated_context.h" |
| 41 | 44 |
| 42 using content::BrowserContext; | 45 using content::BrowserContext; |
| 43 using content::BrowserThread; | 46 using content::BrowserThread; |
| 44 using content::ChildProcessSecurityPolicy; | 47 using content::ChildProcessSecurityPolicy; |
| 45 using content::SiteInstance; | 48 using content::SiteInstance; |
| 46 using content::WebContents; | 49 using content::WebContents; |
| 47 using extensions::Extension; | 50 using extensions::Extension; |
| 48 | 51 |
| 49 namespace file_handler_util { | 52 namespace file_handler_util { |
| 50 | 53 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 for (Extension::FileBrowserHandlerList::const_iterator action_iter = | 115 for (Extension::FileBrowserHandlerList::const_iterator action_iter = |
| 113 extension->file_browser_handlers()->begin(); | 116 extension->file_browser_handlers()->begin(); |
| 114 action_iter != extension->file_browser_handlers()->end(); | 117 action_iter != extension->file_browser_handlers()->end(); |
| 115 ++action_iter) { | 118 ++action_iter) { |
| 116 if (action_iter->get()->id() == action_id) | 119 if (action_iter->get()->id() == action_id) |
| 117 return action_iter->get(); | 120 return action_iter->get(); |
| 118 } | 121 } |
| 119 return NULL; | 122 return NULL; |
| 120 } | 123 } |
| 121 | 124 |
| 125 bool IsWebIntentAction(const std::string& action_id) { |
| 126 if (action_id.compare(0, 4, std::string("http")) == 0) |
| 127 return true; |
| 128 return false; |
| 129 } |
| 130 |
| 122 unsigned int GetAccessPermissionsForHandler(const Extension* extension, | 131 unsigned int GetAccessPermissionsForHandler(const Extension* extension, |
| 123 const std::string& action_id) { | 132 const std::string& action_id) { |
| 133 if (IsWebIntentAction(action_id)) |
| 134 return kReadOnlyFilePermissions; |
| 135 |
| 124 const FileBrowserHandler* action = | 136 const FileBrowserHandler* action = |
| 125 FindFileBrowserHandler(extension, action_id); | 137 FindFileBrowserHandler(extension, action_id); |
| 126 if (!action) | 138 if (!action) |
| 127 return 0; | 139 return 0; |
| 128 unsigned int result = 0; | 140 unsigned int result = 0; |
| 129 if (action->CanRead()) | 141 if (action->CanRead()) |
| 130 result |= kReadOnlyFilePermissions; | 142 result |= kReadOnlyFilePermissions; |
| 131 if (action->CanWrite()) | 143 if (action->CanWrite()) |
| 132 result |= kReadWriteFilePermissions; | 144 result |= kReadWriteFilePermissions; |
| 133 // TODO(tbarzic): We don't handle Create yet. | 145 // TODO(tbarzic): We don't handle Create yet. |
| 134 return result; | 146 return result; |
| 135 } | 147 } |
| 136 | 148 |
| 137 | |
| 138 std::string EscapedUtf8ToLower(const std::string& str) { | 149 std::string EscapedUtf8ToLower(const std::string& str) { |
| 139 string16 utf16 = UTF8ToUTF16( | 150 string16 utf16 = UTF8ToUTF16( |
| 140 net::UnescapeURLComponent(str, net::UnescapeRule::NORMAL)); | 151 net::UnescapeURLComponent(str, net::UnescapeRule::NORMAL)); |
| 141 return net::EscapeUrlEncodedData( | 152 return net::EscapeUrlEncodedData( |
| 142 UTF16ToUTF8(base::i18n::ToLower(utf16)), | 153 UTF16ToUTF8(base::i18n::ToLower(utf16)), |
| 143 false /* do not replace space with plus */); | 154 false /* do not replace space with plus */); |
| 144 } | 155 } |
| 145 | 156 |
| 146 bool GetFileBrowserHandlers(Profile* profile, | 157 bool GetFileBrowserHandlers(Profile* profile, |
| 147 const GURL& selected_file_url, | 158 const GURL& selected_file_url, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 const LastUsedHandler& b) { | 193 const LastUsedHandler& b) { |
| 183 return a.timestamp > b.timestamp; | 194 return a.timestamp > b.timestamp; |
| 184 } | 195 } |
| 185 | 196 |
| 186 // TODO(zelidrag): Wire this with ICU to make this sort I18N happy. | 197 // TODO(zelidrag): Wire this with ICU to make this sort I18N happy. |
| 187 bool SortByTaskName(const LastUsedHandler& a, const LastUsedHandler& b) { | 198 bool SortByTaskName(const LastUsedHandler& a, const LastUsedHandler& b) { |
| 188 return base::strcasecmp(a.handler->title().c_str(), | 199 return base::strcasecmp(a.handler->title().c_str(), |
| 189 b.handler->title().c_str()) > 0; | 200 b.handler->title().c_str()) > 0; |
| 190 } | 201 } |
| 191 | 202 |
| 203 // Does this LastUsedHandlerList contain entries with only a common timestamp? |
| 204 bool HasCommonTimestamp(LastUsedHandlerList* list) { |
| 205 DCHECK(!list->empty()); |
| 206 int common_timestamp = list->begin()->timestamp; |
| 207 for (LastUsedHandlerList::const_iterator iter = list->begin() + 1; |
| 208 iter != list->end(); ++iter) { |
| 209 if (common_timestamp != iter->timestamp) |
| 210 return false; |
| 211 } |
| 212 return true; |
| 213 } |
| 214 |
| 192 void SortLastUsedHandlerList(LastUsedHandlerList *list) { | 215 void SortLastUsedHandlerList(LastUsedHandlerList *list) { |
| 193 // Sort by the last used descending. | 216 if (list->size() <= 1) { |
| 194 std::sort(list->begin(), list->end(), SortByLastUsedTimestampDesc); | 217 // Ok, we're alreay sorted. |
| 195 if (list->size() > 1) { | 218 } else if (HasCommonTimestamp(list)) { |
| 196 // Sort the rest by name. | 219 // Sort only by name. |
| 220 std::sort(list->begin(), list->end(), SortByTaskName); |
| 221 } else { |
| 222 // Bring the last used descending to the front, and sort the rest by name. |
| 223 std::sort(list->begin(), list->end(), SortByLastUsedTimestampDesc); |
| 197 std::sort(list->begin() + 1, list->end(), SortByTaskName); | 224 std::sort(list->begin() + 1, list->end(), SortByTaskName); |
| 198 } | 225 } |
| 199 } | 226 } |
| 200 | 227 |
| 201 } // namespace | 228 } // namespace |
| 202 | 229 |
| 203 // Update file handler usage stats. | 230 // Update file handler usage stats. |
| 204 void UpdateFileHandlerUsageStats(Profile* profile, const std::string& task_id) { | 231 void UpdateFileHandlerUsageStats(Profile* profile, const std::string& task_id) { |
| 205 if (!profile || !profile->GetPrefs()) | 232 if (!profile || !profile->GetPrefs()) |
| 206 return; | 233 return; |
| (...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 787 int handler_pid_in, | 814 int handler_pid_in, |
| 788 extensions::ExtensionHost* host) { | 815 extensions::ExtensionHost* host) { |
| 789 int handler_pid = host ? host->render_process_host()->GetID() : | 816 int handler_pid = host ? host->render_process_host()->GetID() : |
| 790 handler_pid_in; | 817 handler_pid_in; |
| 791 | 818 |
| 792 if (handler_pid <= 0) { | 819 if (handler_pid <= 0) { |
| 793 ExecuteDoneOnUIThread(false); | 820 ExecuteDoneOnUIThread(false); |
| 794 return; | 821 return; |
| 795 } | 822 } |
| 796 | 823 |
| 824 // If we're a Web Intent action (to an extension), short-circuit and deliver |
| 825 // each file as an onLaunched event to the packaged app's background page. |
| 826 if (IsWebIntentAction(action_id_)) { |
| 827 for (FileDefinitionList::const_iterator iter = file_list.begin(); |
| 828 iter != file_list.end(); ++iter) { |
| 829 |
| 830 // TODO(thorogood): Literally entirely stolen |
| 831 // from platform_app_launcher.cc, around line 180. |
| 832 |
| 833 const FilePath file_path = iter->absolute_path; |
| 834 |
| 835 ExtensionProcessManager* process_manager = |
| 836 extensions::ExtensionSystem::Get(profile())->process_manager(); |
| 837 extensions::ExtensionHost* host = |
| 838 process_manager->GetBackgroundHostForExtension(extension_id_); |
| 839 |
| 840 content::ChildProcessSecurityPolicy* policy = |
| 841 content::ChildProcessSecurityPolicy::GetInstance(); |
| 842 int renderer_id = host->render_process_host()->GetID(); |
| 843 |
| 844 // Granting read file permission to allow reading file content. |
| 845 // If the renderer already has permission to read these paths, it is not |
| 846 // regranted, as this would overwrite any other permissions which the |
| 847 // renderer may already have. |
| 848 if (!policy->CanReadFile(renderer_id, file_path)) |
| 849 policy->GrantReadFile(renderer_id, file_path); |
| 850 |
| 851 std::string registered_name; |
| 852 fileapi::IsolatedContext* isolated_context = |
| 853 fileapi::IsolatedContext::GetInstance(); |
| 854 DCHECK(isolated_context); |
| 855 std::string filesystem_id = isolated_context->RegisterFileSystemForPath( |
| 856 fileapi::kFileSystemTypeIsolated, file_path, ®istered_name); |
| 857 // Granting read file system permission as well to allow file-system |
| 858 // read operations. |
| 859 policy->GrantReadFileSystem(renderer_id, filesystem_id); |
| 860 |
| 861 extensions::AppEventRouter::DispatchOnLaunchedEventWithFileEntry( |
| 862 profile(), |
| 863 GetExtension(), |
| 864 UTF8ToUTF16(action_id_), |
| 865 filesystem_id, |
| 866 registered_name); |
| 867 } |
| 868 |
| 869 ExecuteDoneOnUIThread(true); |
| 870 return; |
| 871 } |
| 872 |
| 797 extensions::EventRouter* event_router = profile()->GetExtensionEventRouter(); | 873 extensions::EventRouter* event_router = profile()->GetExtensionEventRouter(); |
| 798 if (!event_router) { | 874 if (!event_router) { |
| 799 ExecuteDoneOnUIThread(false); | 875 ExecuteDoneOnUIThread(false); |
| 800 return; | 876 return; |
| 801 } | 877 } |
| 802 | 878 |
| 803 SetupHandlerHostFileAccessPermissions(handler_pid); | 879 SetupHandlerHostFileAccessPermissions(handler_pid); |
| 804 | 880 |
| 805 scoped_ptr<ListValue> event_args(new ListValue()); | 881 scoped_ptr<ListValue> event_args(new ListValue()); |
| 806 event_args->Append(Value::CreateStringValue(action_id_)); | 882 event_args->Append(Value::CreateStringValue(action_id_)); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 878 handler_pid, | 954 handler_pid, |
| 879 handler_host_permissions_[i].first, | 955 handler_host_permissions_[i].first, |
| 880 handler_host_permissions_[i].second); | 956 handler_host_permissions_[i].second); |
| 881 } | 957 } |
| 882 | 958 |
| 883 // We don't need this anymore. | 959 // We don't need this anymore. |
| 884 handler_host_permissions_.clear(); | 960 handler_host_permissions_.clear(); |
| 885 } | 961 } |
| 886 | 962 |
| 887 } // namespace file_handler_util | 963 } // namespace file_handler_util |
| OLD | NEW |