Home | History | Annotate | Download | only in browser
      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
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/platform_util.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/file_util.h"
      9 #include "base/process/kill.h"
     10 #include "base/process/launch.h"
     11 #include "base/strings/utf_string_conversions.h"
     12 #include "content/public/browser/browser_thread.h"
     13 #include "url/gurl.h"
     14 
     15 using content::BrowserThread;
     16 
     17 namespace {
     18 
     19 void XDGUtil(const std::string& util, const std::string& arg) {
     20   std::vector<std::string> argv;
     21   argv.push_back(util);
     22   argv.push_back(arg);
     23 
     24   base::EnvironmentVector env;
     25   // xdg-open can fall back on mailcap which eventually might plumb through
     26   // to a command that needs a terminal.  Set the environment variable telling
     27   // it that we definitely don't have a terminal available and that it should
     28   // bring up a new terminal if necessary.  See "man mailcap".
     29   env.push_back(std::make_pair("MM_NOTTTY", "1"));
     30 
     31   // In Google Chrome, we do not let GNOME's bug-buddy intercept our crashes.
     32   // However, we do not want this environment variable to propagate to external
     33   // applications. See http://crbug.com/24120
     34   char* disable_gnome_bug_buddy = getenv("GNOME_DISABLE_CRASH_DIALOG");
     35   if (disable_gnome_bug_buddy &&
     36       disable_gnome_bug_buddy == std::string("SET_BY_GOOGLE_CHROME")) {
     37     env.push_back(std::make_pair("GNOME_DISABLE_CRASH_DIALOG", ""));
     38   }
     39 
     40   base::ProcessHandle handle;
     41   base::LaunchOptions options;
     42   options.environ = &env;
     43   if (base::LaunchProcess(argv, options, &handle))
     44     base::EnsureProcessGetsReaped(handle);
     45 }
     46 
     47 void XDGOpen(const std::string& path) {
     48   XDGUtil("xdg-open", path);
     49 }
     50 
     51 void XDGEmail(const std::string& email) {
     52   XDGUtil("xdg-email", email);
     53 }
     54 
     55 // TODO(estade): It would be nice to be able to select the file in the file
     56 // manager, but that probably requires extending xdg-open. For now just
     57 // show the folder.
     58 void ShowItemInFolderOnFileThread(const base::FilePath& full_path) {
     59   base::FilePath dir = full_path.DirName();
     60   if (!base::DirectoryExists(dir))
     61     return;
     62 
     63   XDGOpen(dir.value());
     64 }
     65 
     66 }  // namespace
     67 
     68 namespace platform_util {
     69 
     70 void ShowItemInFolder(const base::FilePath& full_path) {
     71   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     72   BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
     73       base::Bind(&ShowItemInFolderOnFileThread, full_path));
     74 }
     75 
     76 void OpenItem(const base::FilePath& full_path) {
     77   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     78   BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
     79       base::Bind(&XDGOpen, full_path.value()));
     80 }
     81 
     82 void OpenExternal(const GURL& url) {
     83   if (url.SchemeIs("mailto"))
     84     XDGEmail(url.spec());
     85   else
     86     XDGOpen(url.spec());
     87 }
     88 
     89 }  // namespace platform_util
     90