Skip to content

Commit bfc1622

Browse files
committed
refactor: use ShowItemHelper on linux
1 parent 1d1d04f commit bfc1622

File tree

1 file changed

+92
-1
lines changed

1 file changed

+92
-1
lines changed

shell/common/platform_util_linux.cc

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,19 @@
1010
#include "base/environment.h"
1111
#include "base/files/file_util.h"
1212
#include "base/nix/xdg_util.h"
13+
#include "base/no_destructor.h"
1314
#include "base/process/kill.h"
1415
#include "base/process/launch.h"
16+
#include "chrome/browser/chrome_notification_types.h"
1517
#include "chrome/browser/ui/gtk/gtk_util.h"
18+
#include "components/dbus/thread_linux/dbus_thread_linux.h"
19+
#include "content/public/browser/browser_thread.h"
20+
#include "content/public/browser/notification_observer.h"
21+
#include "content/public/browser/notification_registrar.h"
22+
#include "content/public/browser/notification_service.h"
23+
#include "dbus/bus.h"
24+
#include "dbus/message.h"
25+
#include "dbus/object_proxy.h"
1626
#include "url/gurl.h"
1727

1828
#define ELECTRON_TRASH "ELECTRON_TRASH"
@@ -73,6 +83,87 @@ bool XDGEmail(const std::string& email, const bool wait_for_exit) {
7383
platform_util::OpenCallback());
7484
}
7585

86+
const char kFreedesktopFileManagerName[] = "org.freedesktop.FileManager1";
87+
const char kFreedesktopFileManagerPath[] = "/org/freedesktop/FileManager1";
88+
89+
const char kMethodShowItems[] = "ShowItems";
90+
91+
class ShowItemHelper : public content::NotificationObserver {
92+
public:
93+
static ShowItemHelper& GetInstance() {
94+
static base::NoDestructor<ShowItemHelper> instance;
95+
return *instance;
96+
}
97+
98+
ShowItemHelper() {
99+
registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
100+
content::NotificationService::AllSources());
101+
}
102+
103+
ShowItemHelper(const ShowItemHelper&) = delete;
104+
ShowItemHelper& operator=(const ShowItemHelper&) = delete;
105+
106+
void Observe(int type,
107+
const content::NotificationSource& source,
108+
const content::NotificationDetails& details) override {
109+
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
110+
DCHECK_EQ(chrome::NOTIFICATION_APP_TERMINATING, type);
111+
// The browser process is about to exit. Clean up while we still can.
112+
if (bus_)
113+
bus_->ShutdownOnDBusThreadAndBlock();
114+
bus_.reset();
115+
filemanager_proxy_ = nullptr;
116+
}
117+
118+
void ShowItemInFolder(const base::FilePath& full_path) {
119+
if (!bus_) {
120+
// Sets up the D-Bus connection.
121+
dbus::Bus::Options bus_options;
122+
bus_options.bus_type = dbus::Bus::SESSION;
123+
bus_options.connection_type = dbus::Bus::PRIVATE;
124+
bus_options.dbus_task_runner = dbus_thread_linux::GetTaskRunner();
125+
bus_ = base::MakeRefCounted<dbus::Bus>(bus_options);
126+
}
127+
128+
if (!filemanager_proxy_) {
129+
filemanager_proxy_ =
130+
bus_->GetObjectProxy(kFreedesktopFileManagerName,
131+
dbus::ObjectPath(kFreedesktopFileManagerPath));
132+
}
133+
134+
dbus::MethodCall show_items_call(kFreedesktopFileManagerName,
135+
kMethodShowItems);
136+
dbus::MessageWriter writer(&show_items_call);
137+
138+
writer.AppendArrayOfStrings(
139+
{"file://" + full_path.value()}); // List of file(s) to highlight.
140+
writer.AppendString({}); // startup-id
141+
142+
filemanager_proxy_->CallMethod(
143+
&show_items_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
144+
base::BindOnce(&ShowItemHelper::ShowItemInFolderResponse,
145+
weak_ptr_factory_.GetWeakPtr(), full_path));
146+
}
147+
148+
private:
149+
void ShowItemInFolderResponse(const base::FilePath& full_path,
150+
dbus::Response* response) {
151+
if (response)
152+
return;
153+
154+
LOG(ERROR) << "Error calling " << kMethodShowItems;
155+
// If the FileManager1 call fails, at least open the parent folder.
156+
platform_util::OpenPath(full_path.DirName(), platform_util::OpenCallback());
157+
}
158+
159+
content::NotificationRegistrar registrar_;
160+
161+
scoped_refptr<dbus::Bus> bus_;
162+
dbus::ObjectProxy* filemanager_proxy_ = nullptr;
163+
164+
base::WeakPtrFactory<ShowItemHelper> weak_ptr_factory_{this};
165+
};
166+
76167
} // namespace
77168

78169
namespace platform_util {
@@ -82,7 +173,7 @@ void ShowItemInFolder(const base::FilePath& full_path) {
82173
if (!base::DirectoryExists(dir))
83174
return;
84175

85-
XDGOpen(dir.value(), false, platform_util::OpenCallback());
176+
ShowItemHelper::GetInstance().ShowItemInFolder(full_path);
86177
}
87178

88179
void OpenPath(const base::FilePath& full_path, OpenCallback callback) {

0 commit comments

Comments
 (0)