Commit 04f5f76a authored by Lambros Lambrou's avatar Lambros Lambrou Committed by Commit Bot

Launch PermissionWizard in native-messaging host

The Me2Me native-messaging host has a command-line option:
--check-permission
to check for host permissions. This CL updates this to run the
permission-wizard.

Bug: 1015201
Change-Id: Ie936de8fae413567b5260cde5fb62b0a5803712e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1913473
Commit-Queue: Lambros Lambrou <lambroslambrou@chromium.org>
Reviewed-by: default avatarGary Kacmarcik <garykac@chromium.org>
Cr-Commit-Position: refs/heads/master@{#714772}
parent 3466ef9c
......@@ -167,6 +167,8 @@ foreach(locale, remoting_locales_with_underscores) {
bundle_data("remoting_native_messaging_host_resources") {
sources = [
"//remoting/host/mac/remoting_me2me_host.icns",
# This image is used to badge the lock icon in the authentication dialogs,
# used for elevating privileges to set up the host. The exact filename is
# required by base::mac::GetAuthorizationRightsWithPrompt().
......
......@@ -50,6 +50,10 @@ source_set("common") {
"//services/network/public/mojom",
]
if (is_mac) {
deps += [ "//remoting/host/mac:permission_checking" ]
}
if (is_mac || is_ios) {
deps += [ "//remoting/host/mac:constants" ]
}
......
......@@ -51,9 +51,9 @@ void DaemonController::GetConfig(const GetConfigCallback& done) {
ServiceOrQueueRequest(request);
}
bool DaemonController::CheckPermission() {
void DaemonController::CheckPermission(BoolCallback callback) {
DCHECK(caller_task_runner_->BelongsToCurrentThread());
return delegate_->CheckPermission();
return delegate_->CheckPermission(std::move(callback));
}
void DaemonController::SetConfigAndStart(
......
......@@ -73,6 +73,9 @@ class DaemonController : public base::RefCountedThreadSafe<DaemonController> {
// starting/stopping the service.
typedef base::Callback<void (AsyncResult result)> CompletionCallback;
// Callback used to notify a Boolean result.
typedef base::OnceCallback<void(bool)> BoolCallback;
struct UsageStatsConsent {
// Indicates whether crash dump reporting is supported by the host.
bool supported;
......@@ -110,9 +113,10 @@ class DaemonController : public base::RefCountedThreadSafe<DaemonController> {
virtual std::unique_ptr<base::DictionaryValue> GetConfig() = 0;
// Checks to verify that the required OS permissions have been granted to
// the host process, querying the user if necessary. Returns true iff all
// required permissions have been granted.
virtual bool CheckPermission() = 0;
// the host process, querying the user if necessary. Notifies the callback
// when permission status is established, passing true iff all required
// permissions have been granted.
virtual void CheckPermission(BoolCallback callback) = 0;
// Starts the daemon process. This may require that the daemon be
// downloaded and installed. |done| is invoked on the calling thread when
......@@ -157,8 +161,9 @@ class DaemonController : public base::RefCountedThreadSafe<DaemonController> {
// Checks to see if the required OS permissions have been granted. This may
// show a dialog to the user requesting the permissions.
// Returns true iff all required permissions have been granted.
bool CheckPermission();
// Notifies the callback when permission status is established, passing true
// iff all required permissions have been granted.
void CheckPermission(BoolCallback callback);
// Start the daemon process. This may require that the daemon be
// downloaded and installed. |done| is called when the
......
......@@ -165,8 +165,9 @@ DaemonControllerDelegateLinux::GetConfig() {
return result;
}
bool DaemonControllerDelegateLinux::CheckPermission() {
return true;
void DaemonControllerDelegateLinux::CheckPermission(
DaemonController::BoolCallback callback) {
std::move(callback).Run(true);
}
void DaemonControllerDelegateLinux::SetConfigAndStart(
......
......@@ -20,7 +20,7 @@ class DaemonControllerDelegateLinux : public DaemonController::Delegate {
// DaemonController::Delegate interface.
DaemonController::State GetState() override;
std::unique_ptr<base::DictionaryValue> GetConfig() override;
bool CheckPermission() override;
void CheckPermission(DaemonController::BoolCallback) override;
void SetConfigAndStart(
std::unique_ptr<base::DictionaryValue> config,
bool consent,
......
......@@ -14,6 +14,10 @@
namespace remoting {
namespace mac {
class PermissionWizard;
}
class DaemonControllerDelegateMac : public DaemonController::Delegate {
public:
DaemonControllerDelegateMac();
......@@ -22,7 +26,7 @@ class DaemonControllerDelegateMac : public DaemonController::Delegate {
// DaemonController::Delegate interface.
DaemonController::State GetState() override;
std::unique_ptr<base::DictionaryValue> GetConfig() override;
bool CheckPermission() override;
void CheckPermission(DaemonController::BoolCallback) override;
void SetConfigAndStart(
std::unique_ptr<base::DictionaryValue> config,
bool consent,
......@@ -33,6 +37,8 @@ class DaemonControllerDelegateMac : public DaemonController::Delegate {
DaemonController::UsageStatsConsent GetUsageStatsConsent() override;
private:
std::unique_ptr<mac::PermissionWizard> permission_wizard_;
DISALLOW_COPY_AND_ASSIGN(DaemonControllerDelegateMac);
};
......
......@@ -19,14 +19,14 @@
#include "base/mac/scoped_authorizationref.h"
#include "base/mac/scoped_launch_data.h"
#include "base/memory/ptr_util.h"
#include "base/path_service.h"
#include "base/posix/eintr_wrapper.h"
#include "base/process/launch.h"
#include "base/process/process.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "remoting/base/string_resources.h"
#include "remoting/host/host_config.h"
#include "remoting/host/mac/constants_mac.h"
#include "remoting/host/mac/permission_checker.h"
#include "remoting/host/mac/permission_wizard.h"
#include "remoting/host/resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/l10n_util_mac.h"
......@@ -243,57 +243,14 @@ DaemonControllerDelegateMac::GetConfig() {
return config;
}
base::FilePath GetHostExePath() {
// Get path to directory that contains the NMH Application bundle.
base::FilePath nmh_dir;
base::PathService::Get(base::DIR_EXE, &nmh_dir);
// The NMH path ends with <nmh>.app/Contents/MacOS/, so we need to strip
// off the last 3 parent dirs to get to the app's directory.
auto host_path = nmh_dir.DirName().DirName().DirName();
// For installed builds, the host exe should be in this directory.
// TODO(garykac) This assumes that the location of the host exe is relative
// to the location of the NMH exe, which may not be true in the future. The
// relative path is needed for dev builds (where the binaries are written to
// the Chromium 'out' directory), but the release version should get this
// path from the build script to ensure that it matches where we install the
// host.
base::FilePath host_path_exe = host_path.Append("remoting_me2me_host");
if (!base::PathExists(host_path_exe)) {
// For local dev builds, the host exe is in an app container, so we have to
// navigate down to it.
host_path_exe = host_path.Append(
"remoting_me2me_host.app/Contents/MacOS/remoting_me2me_host");
if (!base::PathExists(host_path_exe))
LOG(ERROR) << "Path doesn't exist: " << host_path_exe;
}
return host_path_exe;
}
bool CheckHostPermission(std::string perm) {
base::CommandLine cmdLine(GetHostExePath());
cmdLine.AppendSwitch(perm);
base::LaunchOptions options;
options.disclaim_responsibility = true;
base::Process process = base::LaunchProcess(cmdLine, options);
if (!process.IsValid()) {
LOG(ERROR) << "Unable to launch host process";
return false;
}
int exit_code;
process.WaitForExit(&exit_code);
LOG(INFO) << "Permission '" << perm << "' is "
<< ((exit_code == 0) ? "granted" : "denied");
return exit_code == 0;
}
bool DaemonControllerDelegateMac::CheckPermission() {
if (CheckHostPermission("check-accessibility-permission")) {
return CheckHostPermission("check-screen-recording-permission");
}
return false;
void DaemonControllerDelegateMac::CheckPermission(
DaemonController::BoolCallback callback) {
auto checker = std::make_unique<mac::PermissionChecker>(
mac::HostMode::ME2ME, base::ThreadTaskRunnerHandle::Get());
permission_wizard_ =
std::make_unique<mac::PermissionWizard>(std::move(checker));
permission_wizard_->SetCompletionCallback(std::move(callback));
permission_wizard_->Start(base::ThreadTaskRunnerHandle::Get());
}
void DaemonControllerDelegateMac::SetConfigAndStart(
......
......@@ -439,8 +439,9 @@ DaemonControllerDelegateWin::GetUsageStatsConsent() {
return consent;
}
bool DaemonControllerDelegateWin::CheckPermission() {
return true;
void DaemonControllerDelegateWin::CheckPermission(
DaemonController::BoolCallback callback) {
std::move(callback).Run(true);
}
void DaemonControllerDelegateWin::SetConfigAndStart(
......
......@@ -18,7 +18,7 @@ class DaemonControllerDelegateWin : public DaemonController::Delegate {
// DaemonController::Delegate interface.
DaemonController::State GetState() override;
std::unique_ptr<base::DictionaryValue> GetConfig() override;
bool CheckPermission() override;
void CheckPermission(DaemonController::BoolCallback) override;
void SetConfigAndStart(
std::unique_ptr<base::DictionaryValue> config,
bool consent,
......
......@@ -110,8 +110,19 @@ int Me2MeNativeMessagingHostMain(int argc, char** argv) {
#if defined(OS_MACOSX)
if (command_line->HasSwitch(kCheckPermissionSwitchName)) {
bool perm = daemon_controller->CheckPermission();
return perm ? kSuccessExitCode : kNoPermissionExitCode;
int exit_code;
daemon_controller->CheckPermission(
// base::BindOnce cannot bind a capturing lambda, so the "captured"
// parameters are bound manually. This is safe because the run-loop is
// run to completion within this scope.
base::BindOnce(
[](int* exit_code, base::RunLoop* run_loop, bool perm) {
*exit_code = (perm ? kSuccessExitCode : kNoPermissionExitCode);
run_loop->Quit();
},
&exit_code, &run_loop));
run_loop.Run();
return exit_code;
}
#endif // defined(OS_MACOSX)
......
......@@ -175,7 +175,7 @@ class MockDaemonControllerDelegate : public DaemonController::Delegate {
// DaemonController::Delegate interface.
DaemonController::State GetState() override;
std::unique_ptr<base::DictionaryValue> GetConfig() override;
bool CheckPermission() override;
void CheckPermission(DaemonController::BoolCallback callback) override;
void SetConfigAndStart(
std::unique_ptr<base::DictionaryValue> config,
bool consent,
......@@ -202,8 +202,9 @@ MockDaemonControllerDelegate::GetConfig() {
return std::make_unique<base::DictionaryValue>();
}
bool MockDaemonControllerDelegate::CheckPermission() {
return true;
void MockDaemonControllerDelegate::CheckPermission(
DaemonController::BoolCallback callback) {
std::move(callback).Run(true);
}
void MockDaemonControllerDelegate::SetConfigAndStart(
......
......@@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string>native_messaging_host</string>
<string>remoting_me2me_host</string>
<key>CFBundleIdentifier</key>
<string>${BUNDLE_ID}</string>
<key>CFBundleInfoDictionaryVersion</key>
......
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