exo_parts.cc 5.33 KB
Newer Older
reveman's avatar
reveman committed
1
2
3
4
// Copyright 2015 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.

5
#include "chrome/browser/exo_parts.h"
reveman's avatar
reveman committed
6

7
8
#include "base/memory/ptr_util.h"

9
10
11
12
#if defined(USE_GLIB)
#include <glib.h>
#endif

reveman's avatar
reveman committed
13
#include "base/command_line.h"
14
#include "base/macros.h"
15
#include "base/memory/ptr_util.h"
reveman's avatar
reveman committed
16
#include "base/message_loop/message_loop.h"
17
#include "chrome/browser/chromeos/file_manager/path_util.h"
reveman's avatar
reveman committed
18
19
20
#include "chrome/browser/ui/ash/ash_util.h"
#include "chrome/common/chrome_switches.h"
#include "components/exo/display.h"
21
#include "components/exo/file_helper.h"
reveman's avatar
reveman committed
22
#include "components/exo/wayland/server.h"
23
#include "components/exo/wm_helper.h"
reveman's avatar
reveman committed
24
#include "content/public/browser/browser_thread.h"
25
#include "ui/arc/notification/arc_notification_surface_manager_impl.h"
reveman's avatar
reveman committed
26

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
namespace {

constexpr char kMimeTypeArcUriList[] = "application/x-arc-uri-list";

class ChromeFileHelper : public exo::FileHelper {
 public:
  ChromeFileHelper() {}
  ~ChromeFileHelper() override {}

  // exo::FileHelper:
  std::string GetMimeTypeForUriList() const override {
    return kMimeTypeArcUriList;
  }
  bool ConvertPathToUrl(const base::FilePath& path, GURL* out) override {
    return file_manager::util::ConvertPathToArcUrl(path, out);
  }
};

}  // namespace

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
#if defined(USE_GLIB)
namespace {

struct GLibWaylandSource : public GSource {
  // Note: The GLibWaylandSource is created and destroyed by GLib. So its
  // constructor/destructor may or may not get called.
  exo::wayland::Server* server;
  GPollFD* poll_fd;
};

gboolean WaylandSourcePrepare(GSource* source, gint* timeout_ms) {
  *timeout_ms = -1;
  return FALSE;
}

gboolean WaylandSourceCheck(GSource* source) {
  GLibWaylandSource* wayland_source = static_cast<GLibWaylandSource*>(source);
  return (wayland_source->poll_fd->revents & G_IO_IN) ? TRUE : FALSE;
}

gboolean WaylandSourceDispatch(GSource* source,
                               GSourceFunc unused_func,
                               gpointer data) {
  GLibWaylandSource* wayland_source = static_cast<GLibWaylandSource*>(source);
  wayland_source->server->Dispatch(base::TimeDelta());
  wayland_source->server->Flush();
  return TRUE;
}

GSourceFuncs g_wayland_source_funcs = {WaylandSourcePrepare, WaylandSourceCheck,
                                       WaylandSourceDispatch, nullptr};

}  // namespace

81
class ExoParts::WaylandWatcher {
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
 public:
  explicit WaylandWatcher(exo::wayland::Server* server)
      : wayland_poll_(new GPollFD),
        wayland_source_(static_cast<GLibWaylandSource*>(
            g_source_new(&g_wayland_source_funcs, sizeof(GLibWaylandSource)))) {
    wayland_poll_->fd = server->GetFileDescriptor();
    wayland_poll_->events = G_IO_IN;
    wayland_poll_->revents = 0;
    wayland_source_->server = server;
    wayland_source_->poll_fd = wayland_poll_.get();
    g_source_add_poll(wayland_source_, wayland_poll_.get());
    g_source_set_can_recurse(wayland_source_, TRUE);
    g_source_set_callback(wayland_source_, nullptr, nullptr, nullptr);
    g_source_attach(wayland_source_, g_main_context_default());
  }
  ~WaylandWatcher() {
    g_source_destroy(wayland_source_);
    g_source_unref(wayland_source_);
  }

 private:
  // The poll attached to |wayland_source_|.
104
  std::unique_ptr<GPollFD> wayland_poll_;
105
106
107
108
109
110
111

  // The GLib event source for wayland events.
  GLibWaylandSource* wayland_source_;

  DISALLOW_COPY_AND_ASSIGN(WaylandWatcher);
};
#else
112
class ExoParts::WaylandWatcher : public base::MessagePumpLibevent::Watcher {
reveman's avatar
reveman committed
113
 public:
114
115
  explicit WaylandWatcher(exo::wayland::Server* server)
      : controller_(FROM_HERE), server_(server) {
reveman's avatar
reveman committed
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
    base::MessageLoopForUI::current()->WatchFileDescriptor(
        server_->GetFileDescriptor(),
        true,  // persistent
        base::MessagePumpLibevent::WATCH_READ, &controller_, this);
  }

  // base::MessagePumpLibevent::Watcher:
  void OnFileCanReadWithoutBlocking(int fd) override {
    server_->Dispatch(base::TimeDelta());
    server_->Flush();
  }
  void OnFileCanWriteWithoutBlocking(int fd) override { NOTREACHED(); }

 private:
  base::MessagePumpLibevent::FileDescriptorWatcher controller_;
  exo::wayland::Server* const server_;

  DISALLOW_COPY_AND_ASSIGN(WaylandWatcher);
};
135
#endif
reveman's avatar
reveman committed
136

137
138
// static
std::unique_ptr<ExoParts> ExoParts::CreateIfNecessary() {
139
140
141
  // For mash, exosphere will not run in the browser process.
  if (ash_util::IsRunningInMash())
    return nullptr;
142
143
144
145
  if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kEnableWaylandServer)) {
    return nullptr;
  }
reveman's avatar
reveman committed
146

147
148
  return base::WrapUnique(new ExoParts());
}
reveman's avatar
reveman committed
149

150
151
152
153
154
155
ExoParts::~ExoParts() {
  wayland_watcher_.reset();
  wayland_server_.reset();
  exo::WMHelper::SetInstance(nullptr);
  wm_helper_.reset();
}
reveman's avatar
reveman committed
156

157
ExoParts::ExoParts() {
penghuang's avatar
penghuang committed
158
  arc_notification_surface_manager_ =
159
      base::MakeUnique<arc::ArcNotificationSurfaceManagerImpl>();
160
  DCHECK(!ash_util::IsRunningInMash());
161
  wm_helper_ = base::MakeUnique<exo::WMHelper>();
penghuang's avatar
penghuang committed
162
163
  exo::WMHelper::SetInstance(wm_helper_.get());
  display_ =
164
165
      base::MakeUnique<exo::Display>(arc_notification_surface_manager_.get(),
                                     base::MakeUnique<ChromeFileHelper>());
penghuang's avatar
penghuang committed
166
  wayland_server_ = exo::wayland::Server::Create(display_.get());
167
  // Wayland server creation can fail if XDG_RUNTIME_DIR is not set correctly.
168
169
  if (wayland_server_)
    wayland_watcher_ = base::MakeUnique<WaylandWatcher>(wayland_server_.get());
reveman's avatar
reveman committed
170
}