Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5923)

Unified Diff: chrome/browser/file_select_helper_mac.mm

Issue 634833003: mac: Zip packages when they are selected by the file opener. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Use AppendRelativePath(). Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/file_select_helper.cc ('k') | chrome/browser/file_select_helper_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/file_select_helper_mac.mm
diff --git a/chrome/browser/file_select_helper_mac.mm b/chrome/browser/file_select_helper_mac.mm
new file mode 100644
index 0000000000000000000000000000000000000000..4f0f4aad8cde97bc2e61bf08ee7a9c8b55451662
--- /dev/null
+++ b/chrome/browser/file_select_helper_mac.mm
@@ -0,0 +1,142 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/file_select_helper.h"
+
+#include <Cocoa/Cocoa.h>
+#include <sys/stat.h>
+
+#include "base/files/file.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/mac/foundation_util.h"
+#include "content/public/browser/browser_thread.h"
+#include "third_party/zlib/google/zip.h"
+#include "ui/shell_dialogs/selected_file_info.h"
+
+namespace {
+
+// Given the |path| of a package, returns the destination that the package
+// should be zipped to. Returns an empty path on any errors.
+base::FilePath ZipDestination(const base::FilePath& path) {
+ NSMutableString* dest =
+ [NSMutableString stringWithString:NSTemporaryDirectory()];
+
+ // Couldn't get the temporary directory.
+ if (!dest)
+ return base::FilePath();
+
+ [dest appendFormat:@"%@/zip_cache/%@",
+ [[NSBundle mainBundle] bundleIdentifier],
+ [[NSProcessInfo processInfo] globallyUniqueString]];
+
+ return base::mac::NSStringToFilePath(dest);
+}
+
+// Returns the path of the package and its components relative to the package's
+// parent directory.
+std::vector<base::FilePath> RelativePathsForPackage(
+ const base::FilePath& package) {
+ // Get the base directory.
+ base::FilePath base_dir = package.DirName();
+
+ // Add the package as the first relative path.
+ std::vector<base::FilePath> relative_paths;
+ relative_paths.push_back(package.BaseName());
+
+ // Add the components of the package as relative paths.
+ base::FileEnumerator file_enumerator(
+ package,
+ true /* recursive */,
+ base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES);
+ for (base::FilePath path = file_enumerator.Next(); !path.empty();
+ path = file_enumerator.Next()) {
+ base::FilePath relative_path;
+ bool success = base_dir.AppendRelativePath(path, &relative_path);
+ if (success)
+ relative_paths.push_back(relative_path);
+ }
+
+ return relative_paths;
+}
+
+} // namespace
+
+base::FilePath FileSelectHelper::ZipPackage(const base::FilePath& path) {
+ base::FilePath dest(ZipDestination(path));
+ if (dest.empty())
+ return dest;
+
+ if (!base::CreateDirectory(dest.DirName()))
+ return base::FilePath();
+
+ base::File file(dest, base::File::FLAG_CREATE | base::File::FLAG_WRITE);
+ if (!file.IsValid())
+ return base::FilePath();
+
+ std::vector<base::FilePath> files_to_zip(RelativePathsForPackage(path));
+ base::FilePath base_dir = path.DirName();
+ bool success = zip::ZipFiles(base_dir, files_to_zip, file.GetPlatformFile());
+
+ int result = -1;
+ if (success)
+ result = fchmod(file.GetPlatformFile(), S_IRUSR);
+
+ return result >= 0 ? dest : base::FilePath();
+}
+
+void FileSelectHelper::ProcessSelectedFilesMac(
+ const std::vector<ui::SelectedFileInfo>& files) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::FILE_USER_BLOCKING);
+
+ // Make a mutable copy of the input files.
+ std::vector<ui::SelectedFileInfo> files_out(files);
+ std::vector<base::FilePath> temporary_files;
+
+ for (auto& file_info : files_out) {
+ NSString* filename = base::mac::FilePathToNSString(file_info.local_path);
+ BOOL isPackage =
+ [[NSWorkspace sharedWorkspace] isFilePackageAtPath:filename];
+ if (isPackage && base::DirectoryExists(file_info.local_path)) {
+ base::FilePath result = ZipPackage(file_info.local_path);
+
+ if (!result.empty()) {
+ temporary_files.push_back(result);
+ file_info.local_path = result;
+ file_info.file_path = result;
+ file_info.display_name.append(".zip");
+ }
+ }
+ }
+
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&FileSelectHelper::ProcessSelectedFilesMacOnUIThread,
+ base::Unretained(this),
+ files_out,
+ temporary_files));
+}
+
+void FileSelectHelper::ProcessSelectedFilesMacOnUIThread(
+ const std::vector<ui::SelectedFileInfo>& files,
+ const std::vector<base::FilePath>& temporary_files) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ if (!temporary_files.empty()) {
+ temporary_files_.insert(
+ temporary_files_.end(), temporary_files.begin(), temporary_files.end());
+
+ // Typically, |temporary_files| are deleted after |web_contents_| is
+ // destroyed. If |web_contents_| is already NULL, then the temporary files
+ // need to be deleted now.
+ if (!web_contents_) {
+ DeleteTemporaryFiles();
+ RunFileChooserEnd();
+ return;
+ }
+ }
+
+ NotifyRenderViewHostAndEnd(files);
+}
« no previous file with comments | « chrome/browser/file_select_helper.cc ('k') | chrome/browser/file_select_helper_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698