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 #include "chrome/browser/chromeos/extensions/file_manager/file_manager_util.h" | 4 #include "chrome/browser/chromeos/extensions/file_manager/file_manager_util.h" |
5 | 5 |
6 #include "ash/shell.h" | 6 #include "ash/shell.h" |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/json/json_reader.h" | 10 #include "base/json/json_file_value_serializer.h" |
11 #include "base/json/json_writer.h" | 11 #include "base/json/json_writer.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
14 #include "base/path_service.h" | 14 #include "base/path_service.h" |
15 #include "base/string_util.h" | 15 #include "base/string_util.h" |
16 #include "base/utf_string_conversions.h" | 16 #include "base/utf_string_conversions.h" |
17 #include "base/values.h" | 17 #include "base/values.h" |
18 #include "chrome/browser/chromeos/drive/drive.pb.h" | 18 #include "chrome/browser/chromeos/drive/drive.pb.h" |
19 #include "chrome/browser/chromeos/drive/drive_file_system.h" | 19 #include "chrome/browser/chromeos/drive/drive_file_system.h" |
20 #include "chrome/browser/chromeos/drive/drive_file_system_util.h" | 20 #include "chrome/browser/chromeos/drive/drive_file_system_util.h" |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 | 234 |
235 result->SetString("transferState", | 235 result->SetString("transferState", |
236 OperationTransferStateToString(status.transfer_state)); | 236 OperationTransferStateToString(status.transfer_state)); |
237 result->SetString("transferType", | 237 result->SetString("transferType", |
238 OperationTypeToString(status.operation_type)); | 238 OperationTypeToString(status.operation_type)); |
239 result->SetInteger("processed", static_cast<int>(status.progress_current)); | 239 result->SetInteger("processed", static_cast<int>(status.progress_current)); |
240 result->SetInteger("total", static_cast<int>(status.progress_total)); | 240 result->SetInteger("total", static_cast<int>(status.progress_total)); |
241 return result.release(); | 241 return result.release(); |
242 } | 242 } |
243 | 243 |
244 void OpenNewTab(const GURL& url, Profile* profile) { | 244 void OpenNewTab(Profile* profile, const GURL& url) { |
245 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 245 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
246 Browser* browser = chrome::FindOrCreateTabbedBrowser( | 246 Browser* browser = chrome::FindOrCreateTabbedBrowser( |
247 profile ? profile : ProfileManager::GetDefaultProfileOrOffTheRecord(), | 247 profile ? profile : ProfileManager::GetDefaultProfileOrOffTheRecord(), |
248 chrome::HOST_DESKTOP_TYPE_ASH); | 248 chrome::HOST_DESKTOP_TYPE_ASH); |
249 chrome::AddSelectedTabWithURL(browser, url, content::PAGE_TRANSITION_LINK); | 249 chrome::AddSelectedTabWithURL(browser, url, content::PAGE_TRANSITION_LINK); |
250 // If the current browser is not tabbed then the new tab will be created | 250 // If the current browser is not tabbed then the new tab will be created |
251 // in a different browser. Make sure it is visible. | 251 // in a different browser. Make sure it is visible. |
252 browser->window()->Show(); | 252 browser->window()->Show(); |
253 } | 253 } |
254 | 254 |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 OpenFileBrowserImpl(path, REUSE_SAME_PATH, ""); | 493 OpenFileBrowserImpl(path, REUSE_SAME_PATH, ""); |
494 return true; | 494 return true; |
495 } | 495 } |
496 return ExecuteBuiltinHandler(browser, path, action_id); | 496 return ExecuteBuiltinHandler(browser, path, action_id); |
497 } | 497 } |
498 | 498 |
499 ExecuteHandler(profile, extension_id, action_id, url); | 499 ExecuteHandler(profile, extension_id, action_id, url); |
500 return true; | 500 return true; |
501 } | 501 } |
502 | 502 |
503 // Reads an entire file into a string. Fails is the file is 4K or longer. | 503 // Reads JSON from a Google Docs file and extracts a document url. When the file |
504 bool ReadSmallFileToString(const base::FilePath& path, std::string* contents) { | 504 // is not in GDoc format, returns a file URL for |file_path| as fallback. |
505 FILE* file = file_util::OpenFile(path, "rb"); | 505 GURL ReadUrlFromGDocOnBlockingPool(const base::FilePath& file_path) { |
506 if (!file) { | 506 const int64 kMaxGDocSize = 4096; |
507 return false; | 507 int64 file_size = 0; |
| 508 if (!file_util::GetFileSize(file_path, &file_size) || |
| 509 file_size > kMaxGDocSize) { |
| 510 DLOG(INFO) << "File too large to be a GDoc file " << file_path.value(); |
| 511 return net::FilePathToFileURL(file_path); |
508 } | 512 } |
509 | 513 |
510 char buf[1 << 12]; // 4K | 514 JSONFileValueSerializer reader(file_path); |
511 size_t len = fread(buf, 1, sizeof(buf), file); | 515 std::string error_message; |
512 if (len > 0) { | 516 scoped_ptr<base::Value> root_value(reader.Deserialize(NULL, &error_message)); |
513 contents->append(buf, len); | 517 if (!root_value.get()) { |
514 } | 518 DLOG(INFO) << "Failed to parse " << file_path.value() << "as JSON." |
515 file_util::CloseFile(file); | 519 << " error = " << error_message; |
516 | 520 return net::FilePathToFileURL(file_path); |
517 return len < sizeof(buf); | |
518 } | |
519 | |
520 // Reads JSON from a Google Docs file, extracts a document url and opens it | |
521 // in a tab. | |
522 void ReadUrlFromGDocOnBlockingPool(const base::FilePath& file_path) { | |
523 std::string contents; | |
524 if (!ReadSmallFileToString(file_path, &contents)) { | |
525 LOG(ERROR) << "Error reading " << file_path.value(); | |
526 return; | |
527 } | 521 } |
528 | 522 |
529 scoped_ptr<base::Value> root_value; | 523 base::DictionaryValue* dictionary_value = NULL; |
530 root_value.reset(base::JSONReader::Read(contents)); | |
531 | |
532 DictionaryValue* dictionary_value; | |
533 std::string edit_url_string; | 524 std::string edit_url_string; |
534 if (!root_value.get() || | 525 if (!root_value->GetAsDictionary(&dictionary_value) || |
535 !root_value->GetAsDictionary(&dictionary_value) || | |
536 !dictionary_value->GetString("url", &edit_url_string)) { | 526 !dictionary_value->GetString("url", &edit_url_string)) { |
537 LOG(ERROR) << "Invalid JSON in " << file_path.value(); | 527 DLOG(INFO) << "Non GDoc JSON in " << file_path.value(); |
538 return; | 528 return net::FilePathToFileURL(file_path); |
539 } | 529 } |
540 | 530 |
541 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 531 return GURL(edit_url_string); |
542 base::Bind(OpenNewTab, GURL(edit_url_string), (Profile*)NULL)); | |
543 } | 532 } |
544 | 533 |
545 // Used to implement ViewItem(). | 534 // Used to implement ViewItem(). |
546 void ContinueViewItem(Profile* profile, | 535 void ContinueViewItem(Profile* profile, |
547 const base::FilePath& path, | 536 const base::FilePath& path, |
548 base::PlatformFileError error) { | 537 base::PlatformFileError error) { |
549 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 538 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
550 | 539 |
551 if (error == base::PLATFORM_FILE_OK) { | 540 if (error == base::PLATFORM_FILE_OK) { |
552 // A directory exists at |path|. Open it with FileBrowser. | 541 // A directory exists at |path|. Open it with FileBrowser. |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
860 // For things supported natively by the browser, we should open it | 849 // For things supported natively by the browser, we should open it |
861 // in a tab. | 850 // in a tab. |
862 if (IsSupportedBrowserExtension(file_extension.data()) || | 851 if (IsSupportedBrowserExtension(file_extension.data()) || |
863 ShouldBeOpenedWithPlugin(profile, file_extension.data())) { | 852 ShouldBeOpenedWithPlugin(profile, file_extension.data())) { |
864 GURL page_url = net::FilePathToFileURL(path); | 853 GURL page_url = net::FilePathToFileURL(path); |
865 // Override drive resource to point to internal handler instead of file URL. | 854 // Override drive resource to point to internal handler instead of file URL. |
866 if (drive::util::IsUnderDriveMountPoint(path)) { | 855 if (drive::util::IsUnderDriveMountPoint(path)) { |
867 page_url = drive::util::FilePathToDriveURL( | 856 page_url = drive::util::FilePathToDriveURL( |
868 drive::util::ExtractDrivePath(path)); | 857 drive::util::ExtractDrivePath(path)); |
869 } | 858 } |
870 OpenNewTab(page_url, NULL); | 859 OpenNewTab(profile, page_url); |
871 return true; | 860 return true; |
872 } | 861 } |
873 | 862 |
874 if (IsSupportedGDocsExtension(file_extension.data())) { | 863 if (IsSupportedGDocsExtension(file_extension.data())) { |
875 if (drive::util::IsUnderDriveMountPoint(path)) { | 864 if (drive::util::IsUnderDriveMountPoint(path)) { |
876 // The file is on Google Docs. Open with drive URL. | 865 // The file is on Google Docs. Open with drive URL. |
877 GURL url = drive::util::FilePathToDriveURL( | 866 GURL url = drive::util::FilePathToDriveURL( |
878 drive::util::ExtractDrivePath(path)); | 867 drive::util::ExtractDrivePath(path)); |
879 OpenNewTab(url, NULL); | 868 OpenNewTab(profile, url); |
880 } else { | 869 } else { |
881 // The file is local (downloaded from an attachment or otherwise copied). | 870 // The file is local (downloaded from an attachment or otherwise copied). |
882 // Parse the file to extract the Docs url and open this url. | 871 // Parse the file to extract the Docs url and open this url. |
883 BrowserThread::PostBlockingPoolTask( | 872 base::PostTaskAndReplyWithResult( |
884 FROM_HERE, base::Bind(&ReadUrlFromGDocOnBlockingPool, path)); | 873 BrowserThread::GetBlockingPool(), |
| 874 FROM_HERE, |
| 875 base::Bind(&ReadUrlFromGDocOnBlockingPool, path), |
| 876 base::Bind(&OpenNewTab, static_cast<Profile*>(NULL))); |
885 } | 877 } |
886 return true; | 878 return true; |
887 } | 879 } |
888 | 880 |
889 if (!IsFileManagerPackaged()) { | 881 if (!IsFileManagerPackaged()) { |
890 if (internal_task_id == kFileBrowserPlayTaskId) { | 882 if (internal_task_id == kFileBrowserPlayTaskId) { |
891 GURL url; | 883 GURL url; |
892 if (!ConvertFileToFileSystemUrl(profile, path, kFileBrowserDomain, &url)) | 884 if (!ConvertFileToFileSystemUrl(profile, path, kFileBrowserDomain, &url)) |
893 return false; | 885 return false; |
894 MediaPlayer* mediaplayer = MediaPlayer::GetInstance(); | 886 MediaPlayer* mediaplayer = MediaPlayer::GetInstance(); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 for (google_apis::OperationProgressStatusList::const_iterator iter = | 954 for (google_apis::OperationProgressStatusList::const_iterator iter = |
963 list.begin(); | 955 list.begin(); |
964 iter != list.end(); ++iter) { | 956 iter != list.end(); ++iter) { |
965 result_list->Append( | 957 result_list->Append( |
966 ProgessStatusToDictionaryValue(profile, extension_id, *iter)); | 958 ProgessStatusToDictionaryValue(profile, extension_id, *iter)); |
967 } | 959 } |
968 return result_list.release(); | 960 return result_list.release(); |
969 } | 961 } |
970 | 962 |
971 } // namespace file_manager_util | 963 } // namespace file_manager_util |
OLD | NEW |