Commit c559a502 authored by James Cook's avatar James Cook Committed by Commit Bot

lacros: Support platform_util::ShowItemInFolder

This code path is used by chrome://downloads, devtools, and elsewhere
to show a file in the operating system's native file explorer. Wire the
call in lacros to the equivalent call in ash via crosapi.

This is a new interface, instead of part of "SelectFile", because
SelectFile deals exclusively with opening/saving files. It's an
implementation detail on Chrome OS that the open/save dialog and the
general purpose file explorer share the same implementation.

Bug: 1139128
Test: Download a file, "Show in folder" in chrome://downloads works
Change-Id: I6234ea03e673ca4c9ca2566721e281d52041e101
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2488396
Commit-Queue: James Cook <jamescook@chromium.org>
Reviewed-by: default avatarDarin Fisher <darin@chromium.org>
Reviewed-by: default avatarGreg Kerr <kerrnel@chromium.org>
Reviewed-by: default avatarErik Chen <erikchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#819958}
parent 82f43667
......@@ -1010,6 +1010,8 @@ source_set("chromeos") {
"crosapi/fake_browser_manager.h",
"crosapi/feedback_ash.cc",
"crosapi/feedback_ash.h",
"crosapi/file_manager_ash.cc",
"crosapi/file_manager_ash.h",
"crosapi/keystore_service_ash.cc",
"crosapi/keystore_service_ash.h",
"crosapi/message_center_ash.cc",
......
......@@ -14,6 +14,7 @@
#include "chrome/browser/chromeos/crosapi/account_manager_ash.h"
#include "chrome/browser/chromeos/crosapi/browser_manager.h"
#include "chrome/browser/chromeos/crosapi/feedback_ash.h"
#include "chrome/browser/chromeos/crosapi/file_manager_ash.h"
#include "chrome/browser/chromeos/crosapi/keystore_service_ash.h"
#include "chrome/browser/chromeos/crosapi/message_center_ash.h"
#include "chrome/browser/chromeos/crosapi/screen_manager_ash.h"
......@@ -24,6 +25,7 @@
#include "chromeos/components/account_manager/account_manager.h"
#include "chromeos/components/account_manager/account_manager_factory.h"
#include "chromeos/crosapi/mojom/feedback.mojom.h"
#include "chromeos/crosapi/mojom/file_manager.mojom.h"
#include "chromeos/crosapi/mojom/keystore_service.mojom.h"
#include "chromeos/crosapi/mojom/message_center.mojom.h"
#include "chromeos/crosapi/mojom/screen_manager.mojom.h"
......@@ -75,6 +77,12 @@ void AshChromeServiceImpl::BindAccountManager(
account_manager, std::move(receiver));
}
void AshChromeServiceImpl::BindFileManager(
mojo::PendingReceiver<crosapi::mojom::FileManager> receiver) {
file_manager_ash_ =
std::make_unique<crosapi::FileManagerAsh>(std::move(receiver));
}
void AshChromeServiceImpl::BindKeystoreService(
mojo::PendingReceiver<crosapi::mojom::KeystoreService> receiver) {
keystore_service_ash_ =
......
......@@ -15,6 +15,7 @@ namespace crosapi {
class AccountManagerAsh;
class FeedbackAsh;
class FileManagerAsh;
class KeystoreServiceAsh;
class MessageCenterAsh;
class ScreenManagerAsh;
......@@ -31,6 +32,8 @@ class AshChromeServiceImpl : public mojom::AshChromeService {
// crosapi::mojom::AshChromeService:
void BindAccountManager(
mojo::PendingReceiver<mojom::AccountManager> receiver) override;
void BindFileManager(
mojo::PendingReceiver<mojom::FileManager> receiver) override;
void BindKeystoreService(
mojo::PendingReceiver<mojom::KeystoreService> receiver) override;
void BindMessageCenter(
......@@ -48,6 +51,7 @@ class AshChromeServiceImpl : public mojom::AshChromeService {
mojo::Receiver<mojom::AshChromeService> receiver_;
std::unique_ptr<AccountManagerAsh> account_manager_ash_;
std::unique_ptr<FileManagerAsh> file_manager_ash_;
std::unique_ptr<KeystoreServiceAsh> keystore_service_ash_;
std::unique_ptr<MessageCenterAsh> message_center_ash_;
std::unique_ptr<ScreenManagerAsh> screen_manager_ash_;
......
......@@ -145,12 +145,13 @@ bool IsLacrosWindow(const aura::Window* window) {
base::flat_map<base::Token, uint32_t> GetInterfaceVersions() {
static_assert(
crosapi::mojom::AshChromeService::Version_ == 4,
crosapi::mojom::AshChromeService::Version_ == 5,
"if you add a new crosapi, please add it to the version map here");
InterfaceVersions versions;
AddVersion<crosapi::mojom::AccountManager>(&versions);
AddVersion<crosapi::mojom::AshChromeService>(&versions);
AddVersion<crosapi::mojom::Feedback>(&versions);
AddVersion<crosapi::mojom::FileManager>(&versions);
AddVersion<crosapi::mojom::KeystoreService>(&versions);
AddVersion<crosapi::mojom::MessageCenter>(&versions);
AddVersion<crosapi::mojom::ScreenManager>(&versions);
......
// Copyright 2020 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/chromeos/crosapi/file_manager_ash.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/profiles/profile_manager.h"
namespace crosapi {
FileManagerAsh::FileManagerAsh(
mojo::PendingReceiver<mojom::FileManager> receiver)
: receiver_(this, std::move(receiver)) {}
FileManagerAsh::~FileManagerAsh() = default;
void FileManagerAsh::ShowItemInFolder(const base::FilePath& path) {
// Use platform_util instead of calling directly into file manager code
// because platform_util_ash.cc handles showing error dialogs for files and
// paths that cannot be opened.
platform_util::ShowItemInFolder(ProfileManager::GetActiveUserProfile(), path);
}
} // namespace crosapi
// Copyright 2020 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.
#ifndef CHROME_BROWSER_CHROMEOS_CROSAPI_FILE_MANAGER_ASH_H_
#define CHROME_BROWSER_CHROMEOS_CROSAPI_FILE_MANAGER_ASH_H_
#include "chromeos/crosapi/mojom/file_manager.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
namespace crosapi {
// Implements the crosapi file manager interface. Lives in ash-chrome on the UI
// thread. Allows lacros-chrome to make UI requests to the Chrome OS file
// manager, for example to open a folder or highlight a file.
class FileManagerAsh : public mojom::FileManager {
public:
explicit FileManagerAsh(mojo::PendingReceiver<mojom::FileManager> receiver);
FileManagerAsh(const FileManagerAsh&) = delete;
FileManagerAsh& operator=(const FileManagerAsh&) = delete;
~FileManagerAsh() override;
// crosapi::mojom::FileManager:
void ShowItemInFolder(const base::FilePath& path) override;
private:
mojo::Receiver<mojom::FileManager> receiver_;
};
} // namespace crosapi
#endif // CHROME_BROWSER_CHROMEOS_CROSAPI_FILE_MANAGER_ASH_H_
......@@ -4,8 +4,11 @@
#include "chrome/browser/platform_util.h"
#include "base/logging.h"
#include "base/notreached.h"
#include "chrome/browser/platform_util_internal.h"
#include "chromeos/crosapi/mojom/file_manager.mojom.h"
#include "chromeos/lacros/lacros_chrome_service_impl.h"
namespace platform_util {
namespace internal {
......@@ -17,8 +20,12 @@ void PlatformOpenVerifiedItem(const base::FilePath& path, OpenItemType type) {
} // namespace internal
void ShowItemInFolder(Profile* profile, const base::FilePath& full_path) {
// TODO(https://crbug.com/1139128): Add crosapi to show item in file manager.
NOTIMPLEMENTED();
auto* service = chromeos::LacrosChromeServiceImpl::Get();
if (!service->IsFileManagerAvailable()) {
DLOG(ERROR) << "Unsupported ash version.";
return;
}
service->file_manager_remote()->ShowItemInFolder(full_path);
}
void OpenExternal(Profile* profile, const GURL& url) {
......
......@@ -10,6 +10,7 @@ mojom("mojom") {
"bitmap.mojom",
"crosapi.mojom",
"feedback.mojom",
"file_manager.mojom",
"keystore_service.mojom",
"message_center.mojom",
"notification.mojom",
......
......@@ -6,6 +6,7 @@ module crosapi.mojom;
import "chromeos/crosapi/mojom/account_manager.mojom";
import "chromeos/crosapi/mojom/feedback.mojom";
import "chromeos/crosapi/mojom/file_manager.mojom";
import "chromeos/crosapi/mojom/keystore_service.mojom";
import "chromeos/crosapi/mojom/message_center.mojom";
import "chromeos/crosapi/mojom/screen_manager.mojom";
......@@ -33,8 +34,8 @@ struct LacrosInfo {
// milestone when you added it, to help us reason about compatibility between
// lacros-chrome and older ash-chrome binaries.
//
// Next version: 5
// Next method id: 8
// Next version: 6
// Next method id: 9
[Stable, Uuid="8b79c34f-2bf8-4499-979a-b17cac522c1e"]
interface AshChromeService {
// Binds Chrome OS Account Manager for Identity management.
......@@ -42,6 +43,11 @@ interface AshChromeService {
[MinVersion=4]
BindAccountManager@7(pending_receiver<AccountManager> receiver);
// Binds the FileManager interface for showing files, folders, etc.
// Added in M88.
[MinVersion=5]
BindFileManager@8(pending_receiver<FileManager> receiver);
// Binds the KeystoreService interface for challenging keys.
// Added in M87.
BindKeystoreService@2(pending_receiver<KeystoreService> receiver);
......
// Copyright 2020 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.
module crosapi.mojom;
import "mojo/public/mojom/base/file_path.mojom";
// Interacts with the file manager (the Chrome OS equivalent of macOS Finder or
// Windows Explorer). Implemented in ash-chrome.
[Stable, Uuid="61e61690-fb13-40c8-a167-d7fc18a8fe6b"]
interface FileManager {
// Opens the folder containing the item specified by |full_path| and selects
// the item. If the path is invalid or the file doesn't exist, an error dialog
// is shown.
ShowItemInFolder@0(mojo_base.mojom.FilePath path);
};
......@@ -159,6 +159,12 @@ class LacrosChromeServiceNeverBlockingState
ash_chrome_service_->BindAccountManager(std::move(pending_receiver));
}
void BindFileManagerReceiver(
mojo::PendingReceiver<crosapi::mojom::FileManager> pending_receiver) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
ash_chrome_service_->BindFileManager(std::move(pending_receiver));
}
base::WeakPtr<LacrosChromeServiceNeverBlockingState> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
......@@ -327,6 +333,16 @@ void LacrosChromeServiceImpl::BindReceiver(
LOG(WARNING) << "Connected to an older version of ash. Account consistency "
"will not be available";
}
if (IsFileManagerAvailable()) {
mojo::PendingReceiver<crosapi::mojom::FileManager> pending_receiver =
file_manager_remote_.BindNewPipeAndPassReceiver();
never_blocking_sequence_->PostTask(
FROM_HERE,
base::BindOnce(
&LacrosChromeServiceNeverBlockingState::BindFileManagerReceiver,
weak_sequenced_state_, std::move(pending_receiver)));
}
}
// static
......@@ -350,16 +366,20 @@ bool LacrosChromeServiceImpl::IsHidManagerAvailable() {
return AshChromeServiceVersion() >= 0;
}
bool LacrosChromeServiceImpl::IsFeedbackAvailable() {
return AshChromeServiceVersion() >= 3;
}
bool LacrosChromeServiceImpl::IsAccountManagerAvailable() {
return AshChromeServiceVersion() >= 4;
}
bool LacrosChromeServiceImpl::IsScreenManagerAvailable() {
return AshChromeServiceVersion() >= 0;
bool LacrosChromeServiceImpl::IsFileManagerAvailable() {
return AshChromeServiceVersion() >= 5;
}
bool LacrosChromeServiceImpl::IsFeedbackAvailable() {
return AshChromeServiceVersion() >= 3;
bool LacrosChromeServiceImpl::IsScreenManagerAvailable() {
return AshChromeServiceVersion() >= 0;
}
bool LacrosChromeServiceImpl::IsOnLacrosStartupAvailable() {
......
......@@ -145,6 +145,16 @@ class COMPONENT_EXPORT(CHROMEOS_LACROS) LacrosChromeServiceImpl {
return account_manager_remote_;
}
// file_manager_remote() can only be used if this method returns true.
bool IsFileManagerAvailable();
// Must be called on the affine sequence.
mojo::Remote<crosapi::mojom::FileManager>& file_manager_remote() {
DCHECK_CALLED_ON_VALID_SEQUENCE(affine_sequence_checker_);
DCHECK(IsFileManagerAvailable());
return file_manager_remote_;
}
// --------------------------------------------------------------------------
// Some clients will want to use mojo::Remotes on arbitrary sequences (e.g.
// background threads). The following methods allow the client to construct a
......@@ -196,23 +206,15 @@ class COMPONENT_EXPORT(CHROMEOS_LACROS) LacrosChromeServiceImpl {
// Parameters passed from ash-chrome.
crosapi::mojom::LacrosInitParamsPtr init_params_;
// This member allows lacros-chrome to use the SelectFile interface. This
// member is affine to the affine sequence. It is initialized in the
// constructor and it is immediately available for use.
// These members are affine to the affine sequence. They are initialized in
// the constructor and are immediately available for use.
mojo::Remote<crosapi::mojom::MessageCenter> message_center_remote_;
mojo::Remote<crosapi::mojom::SelectFile> select_file_remote_;
mojo::Remote<device::mojom::HidManager> hid_manager_remote_;
mojo::Remote<crosapi::mojom::Feedback> feedback_remote_;
// This member allows lacros-chrome to use the KeystoreService interface. This
// member is affine to the affine sequence. It is initialized in the
// constructor and it is immediately available for use.
mojo::Remote<crosapi::mojom::KeystoreService> keystore_service_remote_;
// This member allows lacros-chrome to use the AccountManager interface. This
// member is affine to the affine sequence. It is initialized in the
// constructor and it is immediately available for use.
mojo::Remote<crosapi::mojom::AccountManager> account_manager_remote_;
mojo::Remote<crosapi::mojom::FileManager> file_manager_remote_;
// This member is instantiated on the affine sequence alongside the
// constructor. All subsequent invocations of this member, including
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment