summaryrefslogtreecommitdiff
path: root/chromium/chrome/browser/printing/printer_manager_dialog_linux.cc
blob: 43736f963311359dc44af2ed075dbed092c2cf17 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// Copyright (c) 2012 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/printing/printer_manager_dialog.h"

#include <memory>

#include "base/bind.h"
#include "base/environment.h"
#include "base/files/file_util.h"
#include "base/nix/xdg_util.h"
#include "base/process/kill.h"
#include "base/process/launch.h"
#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_restrictions.h"

namespace {

// KDE printer config command ("system-config-printer-kde") causes the
// OptionWidget to crash (https://bugs.kde.org/show_bug.cgi?id=271957).
// Therefore, use GNOME printer config command for KDE.
const char* const kSystemConfigPrinterCommand[] = {"system-config-printer",
                                                   nullptr};

const char* const kGnomeControlCenterPrintersCommand[] = {
    "gnome-control-center", "printers", nullptr};

// Returns true if the dialog was opened successfully.
bool OpenPrinterConfigDialog(const char* const* command) {
  DCHECK(command);
  std::unique_ptr<base::Environment> env(base::Environment::Create());
  if (!base::ExecutableExistsInPath(env.get(), *command))
    return false;
  std::vector<std::string> argv;
  while (*command)
    argv.push_back(*command++);
  base::Process process = base::LaunchProcess(argv, base::LaunchOptions());
  if (!process.IsValid())
    return false;
  base::EnsureProcessGetsReaped(process.Pid());
  return true;
}

// Detect the command based on the deskop environment and open the printer
// manager dialog.
void DetectAndOpenPrinterConfigDialog() {
  base::ThreadRestrictions::AssertIOAllowed();
  std::unique_ptr<base::Environment> env(base::Environment::Create());

  bool opened = false;
  switch (base::nix::GetDesktopEnvironment(env.get())) {
    case base::nix::DESKTOP_ENVIRONMENT_GNOME:
      opened = OpenPrinterConfigDialog(kSystemConfigPrinterCommand) ||
               OpenPrinterConfigDialog(kGnomeControlCenterPrintersCommand);
      break;
    case base::nix::DESKTOP_ENVIRONMENT_KDE3:
    case base::nix::DESKTOP_ENVIRONMENT_KDE4:
    case base::nix::DESKTOP_ENVIRONMENT_KDE5:
    case base::nix::DESKTOP_ENVIRONMENT_UNITY:
    case base::nix::DESKTOP_ENVIRONMENT_XFCE:
      opened = OpenPrinterConfigDialog(kSystemConfigPrinterCommand);
      break;
    case base::nix::DESKTOP_ENVIRONMENT_OTHER:
      LOG(ERROR)
          << "Failed to detect the command to open printer config dialog";
      return;
  }
  LOG_IF(ERROR, !opened) << "Failed to open printer manager dialog ";
}

}  // namespace

namespace printing {

void PrinterManagerDialog::ShowPrinterManagerDialog() {
  base::PostTaskWithTraits(
      FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING},
      base::BindOnce(&DetectAndOpenPrinterConfigDialog));
}

}  // namespace printing