Commit e0eb7942 authored by hidehiko's avatar hidehiko Committed by Commit bot

Extract ArcSupportMessageHost.

Currently ArcSupportHost is the ARC's implementation of
NativeMessageHost. Because of the system structure, the instance
is created and managed by the module outside of ARC.

This CL extracts the implementation of that part into
ArcSupportMessageHost so that the ArcSupportHost, which will
be the main interface to show UI things for ARC, can be managed
along with the ARC's life-time.

There is a plan to extract non authorization related part from
ArcAuthSerivce. Meanwhile, the instance is managed by
ArcAuthService, temporarily.

BUG=657687, 636218, 633258, b/31079732
TEST=Ran on test device. Ran trybots.

Review-Url: https://codereview.chromium.org/2436903003
Cr-Commit-Position: refs/heads/master@{#427277}
parent c157a5ad
...@@ -214,6 +214,8 @@ source_set("chromeos") { ...@@ -214,6 +214,8 @@ source_set("chromeos") {
"arc/downloads_watcher/arc_downloads_watcher_service.h", "arc/downloads_watcher/arc_downloads_watcher_service.h",
"arc/enterprise/arc_enterprise_reporting_service.cc", "arc/enterprise/arc_enterprise_reporting_service.cc",
"arc/enterprise/arc_enterprise_reporting_service.h", "arc/enterprise/arc_enterprise_reporting_service.h",
"arc/extensions/arc_support_message_host.cc",
"arc/extensions/arc_support_message_host.h",
"arc/fileapi/arc_content_file_system_async_file_util.cc", "arc/fileapi/arc_content_file_system_async_file_util.cc",
"arc/fileapi/arc_content_file_system_async_file_util.h", "arc/fileapi/arc_content_file_system_async_file_util.h",
"arc/fileapi/arc_content_file_system_backend_delegate.cc", "arc/fileapi/arc_content_file_system_backend_delegate.cc",
......
...@@ -484,6 +484,11 @@ void ArcAuthService::OnPrimaryUserProfilePrepared(Profile* profile) { ...@@ -484,6 +484,11 @@ void ArcAuthService::OnPrimaryUserProfilePrepared(Profile* profile) {
} }
profile_ = profile; profile_ = profile;
// Create the support host at initialization. Note that, practically,
// ARC support Chrome app is rarely used (only opt-in and re-auth flow).
// So, it may be better to initialize it lazily.
// TODO(hidehiko): Revisit to think about lazy initialization.
support_host_.reset(new ArcSupportHost());
SetState(State::STOPPED); SetState(State::STOPPED);
PrefServiceSyncableFromProfile(profile_)->AddSyncedPrefObserver( PrefServiceSyncableFromProfile(profile_)->AddSyncedPrefObserver(
...@@ -565,7 +570,6 @@ void ArcAuthService::ShowUI(UIPage page, const base::string16& status) { ...@@ -565,7 +570,6 @@ void ArcAuthService::ShowUI(UIPage page, const base::string16& status) {
ArcSupportHost::kHostAppId); ArcSupportHost::kHostAppId);
CHECK(extension && extensions::util::IsAppLaunchable( CHECK(extension && extensions::util::IsAppLaunchable(
ArcSupportHost::kHostAppId, profile_)); ArcSupportHost::kHostAppId, profile_));
OpenApplication(CreateAppLaunchParamsUserContainer( OpenApplication(CreateAppLaunchParamsUserContainer(
profile_, extension, WindowOpenDisposition::NEW_WINDOW, profile_, extension, WindowOpenDisposition::NEW_WINDOW,
extensions::SOURCE_CHROME_INTERNAL)); extensions::SOURCE_CHROME_INTERNAL));
...@@ -682,8 +686,8 @@ void ArcAuthService::RemoveObserver(Observer* observer) { ...@@ -682,8 +686,8 @@ void ArcAuthService::RemoveObserver(Observer* observer) {
void ArcAuthService::CloseUI() { void ArcAuthService::CloseUI() {
ui_page_ = UIPage::NO_PAGE; ui_page_ = UIPage::NO_PAGE;
ui_page_status_.clear(); ui_page_status_.clear();
for (auto& observer : observer_list_) if (support_host_)
observer.OnOptInUIClose(); support_host_->Close();
if (!g_disable_ui_for_testing) if (!g_disable_ui_for_testing)
ArcAuthNotification::Hide(); ArcAuthNotification::Hide();
} }
...@@ -691,8 +695,8 @@ void ArcAuthService::CloseUI() { ...@@ -691,8 +695,8 @@ void ArcAuthService::CloseUI() {
void ArcAuthService::SetUIPage(UIPage page, const base::string16& status) { void ArcAuthService::SetUIPage(UIPage page, const base::string16& status) {
ui_page_ = page; ui_page_ = page;
ui_page_status_ = status; ui_page_status_ = status;
for (auto& observer : observer_list_) if (support_host_)
observer.OnOptInUIShowPage(ui_page_, ui_page_status_); support_host_->ShowPage(ui_page_, ui_page_status_);
} }
// This is the special method to support enterprise mojo API. // This is the special method to support enterprise mojo API.
......
...@@ -36,6 +36,8 @@ namespace user_prefs { ...@@ -36,6 +36,8 @@ namespace user_prefs {
class PrefRegistrySyncable; class PrefRegistrySyncable;
} }
class ArcSupportHost;
namespace arc { namespace arc {
class ArcAndroidManagementChecker; class ArcAndroidManagementChecker;
...@@ -80,12 +82,6 @@ class ArcAuthService : public ArcService, ...@@ -80,12 +82,6 @@ class ArcAuthService : public ArcService,
// Called whenever Opt-In state of the ARC has been changed. // Called whenever Opt-In state of the ARC has been changed.
virtual void OnOptInChanged(State state) {} virtual void OnOptInChanged(State state) {}
// Called to notify that OptIn UI needs to be closed.
virtual void OnOptInUIClose() {}
// Called to notify that OptIn UI needs to show specific page.
virtual void OnOptInUIShowPage(UIPage page, const base::string16& status) {}
// Called to notify that ARC bridge is shut down. // Called to notify that ARC bridge is shut down.
virtual void OnShutdownBridge() {} virtual void OnShutdownBridge() {}
...@@ -207,8 +203,11 @@ class ArcAuthService : public ArcService, ...@@ -207,8 +203,11 @@ class ArcAuthService : public ArcService,
// Returns current page status, relevant to the specific page. // Returns current page status, relevant to the specific page.
const base::string16& ui_page_status() const { return ui_page_status_; } const base::string16& ui_page_status() const { return ui_page_status_; }
ArcSupportHost* support_host() { return support_host_.get(); }
private: private:
void StartArc(); void StartArc();
// TODO: move UI methods/fields to ArcSupportHost.
void ShowUI(UIPage page, const base::string16& status); void ShowUI(UIPage page, const base::string16& status);
void CloseUI(); void CloseUI();
void SetUIPage(UIPage page, const base::string16& status); void SetUIPage(UIPage page, const base::string16& status);
...@@ -248,6 +247,11 @@ class ArcAuthService : public ArcService, ...@@ -248,6 +247,11 @@ class ArcAuthService : public ArcService,
bool reenable_arc_ = false; bool reenable_arc_ = false;
base::OneShotTimer arc_sign_in_timer_; base::OneShotTimer arc_sign_in_timer_;
// Temporarily keeps the ArcSupportHost instance.
// This should be moved to ArcSessionManager when the refactoring is
// done.
std::unique_ptr<ArcSupportHost> support_host_;
std::unique_ptr<ArcAuthContext> context_; std::unique_ptr<ArcAuthContext> context_;
std::unique_ptr<ArcAuthCodeFetcher> auth_code_fetcher_; std::unique_ptr<ArcAuthCodeFetcher> auth_code_fetcher_;
std::unique_ptr<ArcAndroidManagementChecker> android_management_checker_; std::unique_ptr<ArcAndroidManagementChecker> android_management_checker_;
......
...@@ -114,8 +114,8 @@ class ArcAuthServiceTest : public testing::Test { ...@@ -114,8 +114,8 @@ class ArcAuthServiceTest : public testing::Test {
content::TestBrowserThreadBundle thread_bundle_; content::TestBrowserThreadBundle thread_bundle_;
std::unique_ptr<FakeArcBridgeService> bridge_service_; std::unique_ptr<FakeArcBridgeService> bridge_service_;
std::unique_ptr<ArcAuthService> auth_service_;
std::unique_ptr<TestingProfile> profile_; std::unique_ptr<TestingProfile> profile_;
std::unique_ptr<ArcAuthService> auth_service_;
chromeos::ScopedUserManagerEnabler user_manager_enabler_; chromeos::ScopedUserManagerEnabler user_manager_enabler_;
base::ScopedTempDir temp_dir_; base::ScopedTempDir temp_dir_;
......
...@@ -77,39 +77,28 @@ constexpr char kEventOnSendFeedbackClicked[] = "onSendFeedbackClicked"; ...@@ -77,39 +77,28 @@ constexpr char kEventOnSendFeedbackClicked[] = "onSendFeedbackClicked";
} // namespace } // namespace
// static
const char ArcSupportHost::kHostName[] = "com.google.arc_support";
// static // static
const char ArcSupportHost::kHostAppId[] = "cnbgggchhmkkdmeppjobngjoejnihlei"; const char ArcSupportHost::kHostAppId[] = "cnbgggchhmkkdmeppjobngjoejnihlei";
// static // static
const char ArcSupportHost::kStorageId[] = "arc_support"; const char ArcSupportHost::kStorageId[] = "arc_support";
// static
const char* const ArcSupportHost::kHostOrigin[] = {
"chrome-extension://cnbgggchhmkkdmeppjobngjoejnihlei/"};
// static
std::unique_ptr<extensions::NativeMessageHost> ArcSupportHost::Create() {
return std::unique_ptr<NativeMessageHost>(new ArcSupportHost());
}
ArcSupportHost::ArcSupportHost() { ArcSupportHost::ArcSupportHost() {
// TODO(hidehiko): Get rid of dependency to ArcAuthService.
arc::ArcAuthService* arc_auth_service = arc::ArcAuthService::Get(); arc::ArcAuthService* arc_auth_service = arc::ArcAuthService::Get();
DCHECK(arc_auth_service); DCHECK(arc_auth_service);
if (!arc_auth_service->IsAllowed()) if (!arc_auth_service->IsAllowed())
return; return;
arc_auth_service->AddObserver(this); // TODO(hidehiko): This if statement is only for testing. Clean up this.
display::Screen::GetScreen()->AddObserver(this); if (g_browser_process->local_state()) {
pref_local_change_registrar_.Init(g_browser_process->local_state());
pref_local_change_registrar_.Init(g_browser_process->local_state()); pref_local_change_registrar_.Add(
pref_local_change_registrar_.Add( metrics::prefs::kMetricsReportingEnabled,
metrics::prefs::kMetricsReportingEnabled, base::Bind(&ArcSupportHost::OnMetricsPreferenceChanged,
base::Bind(&ArcSupportHost::OnMetricsPreferenceChanged, base::Unretained(this)));
base::Unretained(this))); }
pref_change_registrar_.Init(arc_auth_service->profile()->GetPrefs()); pref_change_registrar_.Init(arc_auth_service->profile()->GetPrefs());
pref_change_registrar_.Add( pref_change_registrar_.Add(
...@@ -123,27 +112,50 @@ ArcSupportHost::ArcSupportHost() { ...@@ -123,27 +112,50 @@ ArcSupportHost::ArcSupportHost() {
} }
ArcSupportHost::~ArcSupportHost() { ArcSupportHost::~ArcSupportHost() {
display::Screen::GetScreen()->RemoveObserver(this); if (message_host_)
arc::ArcAuthService* arc_auth_service = arc::ArcAuthService::Get(); DisconnectMessageHost();
if (arc_auth_service)
arc_auth_service->RemoveObserver(this);
} }
void ArcSupportHost::Close() { void ArcSupportHost::Close() {
if (!client_) if (!message_host_) {
VLOG(2) << "ArcSupportHost::Close() is called "
<< "but message_host_ is not available.";
return;
}
base::DictionaryValue message;
message.SetString(kAction, kActionCloseWindow);
message_host_->SendMessage(message);
// Disconnect immediately, so that onWindowClosed event will not be
// delivered to here.
DisconnectMessageHost();
}
void ArcSupportHost::ShowPage(arc::ArcAuthService::UIPage page,
const base::string16& status) {
if (!message_host_) {
VLOG(2) << "ArcSupportHost::ShowPage() is called "
<< "but message_host_ is not available.";
return; return;
}
close_requested_ = true; base::DictionaryValue message;
base::DictionaryValue response; message.SetString(kAction, kActionShowPage);
response.SetString(kAction, kActionCloseWindow); message.SetInteger(kPage, static_cast<int>(page));
std::string response_string; message.SetString(kStatus, status);
base::JSONWriter::Write(response, &response_string); message_host_->SendMessage(message);
client_->PostMessageFromNativeHost(response_string);
} }
void ArcSupportHost::Start(Client* client) { void ArcSupportHost::SetMessageHost(arc::ArcSupportMessageHost* message_host) {
DCHECK(!client_); if (message_host_ == message_host)
client_ = client; return;
if (message_host_)
DisconnectMessageHost();
message_host_ = message_host;
message_host_->SetObserver(this);
display::Screen::GetScreen()->AddObserver(this);
if (!Initialize()) { if (!Initialize()) {
Close(); Close();
...@@ -156,12 +168,25 @@ void ArcSupportHost::Start(Client* client) { ...@@ -156,12 +168,25 @@ void ArcSupportHost::Start(Client* client) {
arc::ArcAuthService* arc_auth_service = arc::ArcAuthService::Get(); arc::ArcAuthService* arc_auth_service = arc::ArcAuthService::Get();
DCHECK(arc_auth_service); DCHECK(arc_auth_service);
OnOptInUIShowPage(arc_auth_service->ui_page(), ShowPage(arc_auth_service->ui_page(), arc_auth_service->ui_page_status());
arc_auth_service->ui_page_status()); }
void ArcSupportHost::UnsetMessageHost(
arc::ArcSupportMessageHost* message_host) {
if (message_host_ != message_host)
return;
DisconnectMessageHost();
}
void ArcSupportHost::DisconnectMessageHost() {
DCHECK(message_host_);
display::Screen::GetScreen()->RemoveObserver(this);
message_host_->SetObserver(nullptr);
message_host_ = nullptr;
} }
bool ArcSupportHost::Initialize() { bool ArcSupportHost::Initialize() {
DCHECK(client_); DCHECK(message_host_);
arc::ArcAuthService* arc_auth_service = arc::ArcAuthService::Get(); arc::ArcAuthService* arc_auth_service = arc::ArcAuthService::Get();
if (!arc_auth_service->IsAllowed()) if (!arc_auth_service->IsAllowed())
return false; return false;
...@@ -253,14 +278,11 @@ bool ArcSupportHost::Initialize() { ...@@ -253,14 +278,11 @@ bool ArcSupportHost::Initialize() {
"isOwnerProfile", "isOwnerProfile",
chromeos::ProfileHelper::IsOwnerProfile(arc_auth_service->profile())); chromeos::ProfileHelper::IsOwnerProfile(arc_auth_service->profile()));
base::DictionaryValue request; base::DictionaryValue message;
std::string request_string; message.SetString(kAction, kActionInitialize);
request.SetString(kAction, kActionInitialize); message.Set(kData, std::move(loadtime_data));
request.Set(kData, std::move(loadtime_data)); message.SetString(kDeviceId, device_id);
request.SetString(kDeviceId, device_id); message_host_->SendMessage(message);
base::JSONWriter::Write(request, &request_string);
client_->PostMessageFromNativeHost(request_string);
return true; return true;
} }
...@@ -270,11 +292,12 @@ void ArcSupportHost::OnDisplayRemoved(const display::Display& old_display) {} ...@@ -270,11 +292,12 @@ void ArcSupportHost::OnDisplayRemoved(const display::Display& old_display) {}
void ArcSupportHost::OnDisplayMetricsChanged(const display::Display& display, void ArcSupportHost::OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) { uint32_t changed_metrics) {
base::DictionaryValue request; if (!message_host_)
std::string request_string; return;
request.SetString(kAction, kActionSetWindowBounds);
base::JSONWriter::Write(request, &request_string); base::DictionaryValue message;
client_->PostMessageFromNativeHost(request_string); message.SetString(kAction, kActionSetWindowBounds);
message_host_->SendMessage(message);
} }
void ArcSupportHost::OnMetricsPreferenceChanged() { void ArcSupportHost::OnMetricsPreferenceChanged() {
...@@ -317,31 +340,14 @@ void ArcSupportHost::SendOptionMode(const std::string& action_name, ...@@ -317,31 +340,14 @@ void ArcSupportHost::SendOptionMode(const std::string& action_name,
void ArcSupportHost::SendPreferenceUpdate(const std::string& action_name, void ArcSupportHost::SendPreferenceUpdate(const std::string& action_name,
bool is_enabled, bool is_enabled,
bool is_managed) { bool is_managed) {
base::DictionaryValue request; if (!message_host_)
std::string request_string;
request.SetString(kAction, action_name);
request.SetBoolean(kEnabled, is_enabled);
request.SetBoolean(kManaged, is_managed);
base::JSONWriter::Write(request, &request_string);
client_->PostMessageFromNativeHost(request_string);
}
void ArcSupportHost::OnOptInUIClose() {
Close();
}
void ArcSupportHost::OnOptInUIShowPage(arc::ArcAuthService::UIPage page,
const base::string16& status) {
if (!client_)
return; return;
base::DictionaryValue response; base::DictionaryValue message;
response.SetString(kAction, kActionShowPage); message.SetString(kAction, action_name);
response.SetInteger(kPage, static_cast<int>(page)); message.SetBoolean(kEnabled, is_enabled);
response.SetString(kStatus, status); message.SetBoolean(kManaged, is_managed);
std::string response_string; message_host_->SendMessage(message);
base::JSONWriter::Write(response, &response_string);
client_->PostMessageFromNativeHost(response_string);
} }
void ArcSupportHost::EnableMetrics(bool is_enabled) { void ArcSupportHost::EnableMetrics(bool is_enabled) {
...@@ -362,17 +368,9 @@ void ArcSupportHost::EnableLocationService(bool is_enabled) { ...@@ -362,17 +368,9 @@ void ArcSupportHost::EnableLocationService(bool is_enabled) {
pref_service->SetBoolean(prefs::kArcLocationServiceEnabled, is_enabled); pref_service->SetBoolean(prefs::kArcLocationServiceEnabled, is_enabled);
} }
void ArcSupportHost::OnMessage(const std::string& message_string) { void ArcSupportHost::OnMessage(const base::DictionaryValue& message) {
std::unique_ptr<base::Value> message_value =
base::JSONReader::Read(message_string);
base::DictionaryValue* message;
if (!message_value || !message_value->GetAsDictionary(&message)) {
NOTREACHED();
return;
}
std::string event; std::string event;
if (!message->GetString(kEvent, &event)) { if (!message.GetString(kEvent, &event)) {
NOTREACHED(); NOTREACHED();
return; return;
} }
...@@ -382,11 +380,10 @@ void ArcSupportHost::OnMessage(const std::string& message_string) { ...@@ -382,11 +380,10 @@ void ArcSupportHost::OnMessage(const std::string& message_string) {
DCHECK(arc_auth_service); DCHECK(arc_auth_service);
if (event == kEventOnWindowClosed) { if (event == kEventOnWindowClosed) {
if (!close_requested_) arc_auth_service->CancelAuthCode();
arc_auth_service->CancelAuthCode();
} else if (event == kEventOnAuthSuccedded) { } else if (event == kEventOnAuthSuccedded) {
std::string code; std::string code;
if (message->GetString(kCode, &code)) { if (message.GetString(kCode, &code)) {
arc_auth_service->SetAuthCodeAndStartArc(code); arc_auth_service->SetAuthCodeAndStartArc(code);
} else { } else {
NOTREACHED(); NOTREACHED();
...@@ -395,11 +392,11 @@ void ArcSupportHost::OnMessage(const std::string& message_string) { ...@@ -395,11 +392,11 @@ void ArcSupportHost::OnMessage(const std::string& message_string) {
bool is_metrics_enabled; bool is_metrics_enabled;
bool is_backup_restore_enabled; bool is_backup_restore_enabled;
bool is_location_service_enabled; bool is_location_service_enabled;
if (message->GetBoolean(kIsMetricsEnabled, &is_metrics_enabled) && if (message.GetBoolean(kIsMetricsEnabled, &is_metrics_enabled) &&
message->GetBoolean(kIsBackupRestoreEnabled, message.GetBoolean(kIsBackupRestoreEnabled,
&is_backup_restore_enabled) && &is_backup_restore_enabled) &&
message->GetBoolean(kIsLocationServiceEnabled, message.GetBoolean(kIsLocationServiceEnabled,
&is_location_service_enabled)) { &is_location_service_enabled)) {
EnableMetrics(is_metrics_enabled); EnableMetrics(is_metrics_enabled);
EnableBackupRestore(is_backup_restore_enabled); EnableBackupRestore(is_backup_restore_enabled);
EnableLocationService(is_location_service_enabled); EnableLocationService(is_location_service_enabled);
...@@ -410,12 +407,7 @@ void ArcSupportHost::OnMessage(const std::string& message_string) { ...@@ -410,12 +407,7 @@ void ArcSupportHost::OnMessage(const std::string& message_string) {
} else if (event == kEventOnSendFeedbackClicked) { } else if (event == kEventOnSendFeedbackClicked) {
chrome::OpenFeedbackDialog(nullptr); chrome::OpenFeedbackDialog(nullptr);
} else { } else {
LOG(ERROR) << "Unknown message: " << message_string; LOG(ERROR) << "Unknown message: " << event;
NOTREACHED(); NOTREACHED();
} }
} }
scoped_refptr<base::SingleThreadTaskRunner> ArcSupportHost::task_runner()
const {
return base::ThreadTaskRunnerHandle::Get();
}
...@@ -7,37 +7,43 @@ ...@@ -7,37 +7,43 @@
#include "base/macros.h" #include "base/macros.h"
#include "chrome/browser/chromeos/arc/arc_auth_service.h" #include "chrome/browser/chromeos/arc/arc_auth_service.h"
#include "chrome/browser/chromeos/arc/extensions/arc_support_message_host.h"
#include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_change_registrar.h"
#include "extensions/browser/api/messaging/native_message_host.h" #include "extensions/browser/api/messaging/native_message_host.h"
#include "ui/display/display_observer.h" #include "ui/display/display_observer.h"
// Supports communication with Arc support dialog. // Native interface to control ARC support chrome App.
class ArcSupportHost : public extensions::NativeMessageHost, // TODO(hidehiko): Move more implementation for the UI control from
public arc::ArcAuthService::Observer, // ArcAuthService to this class.
// TODO(hidehiko,lhchavez,khmel): Extract preference observing into a
// standalone class so that it can be shared with OOBE flow.
// TODO(hidehiko,lhchavez): Move this into extensions/ directory, and put it
// into "arc" namespace. Add unittests at the time.
class ArcSupportHost : public arc::ArcSupportMessageHost::Observer,
public display::DisplayObserver { public display::DisplayObserver {
public: public:
static const char kHostName[];
static const char kHostAppId[]; static const char kHostAppId[];
static const char kStorageId[]; static const char kStorageId[];
static const char* const kHostOrigin[];
static std::unique_ptr<NativeMessageHost> Create();
ArcSupportHost();
~ArcSupportHost() override; ~ArcSupportHost() override;
// Called when the communication to arc_support Chrome App is ready.
void SetMessageHost(arc::ArcSupportMessageHost* message_host);
// Called when the communication to arc_support Chrome App is closed.
// The argument message_host is used to check if the given |message_host|
// is what this instance uses know, to avoid racy case.
// If |message_host| is different from the one this instance knows,
// this is no op.
void UnsetMessageHost(arc::ArcSupportMessageHost* message_host);
// Requests to close the extension window. // Requests to close the extension window.
void Close(); void Close();
void ShowPage(arc::ArcAuthService::UIPage page, const base::string16& status);
// Overrides NativeMessageHost: // arc::ArcSupportMessageHost::Observer override:
void Start(Client* client) override; void OnMessage(const base::DictionaryValue& message) override;
void OnMessage(const std::string& request_string) override;
scoped_refptr<base::SingleThreadTaskRunner> task_runner() const override;
// Overrides arc::ArcAuthService::Observer:
// TODO(hidehiko): Get rid of Observer interface.
void OnOptInUIClose() override;
void OnOptInUIShowPage(arc::ArcAuthService::UIPage page,
const base::string16& status) override;
// display::DisplayObserver: // display::DisplayObserver:
void OnDisplayAdded(const display::Display& new_display) override; void OnDisplayAdded(const display::Display& new_display) override;
...@@ -46,8 +52,6 @@ class ArcSupportHost : public extensions::NativeMessageHost, ...@@ -46,8 +52,6 @@ class ArcSupportHost : public extensions::NativeMessageHost,
uint32_t changed_metrics) override; uint32_t changed_metrics) override;
private: private:
ArcSupportHost();
bool Initialize(); bool Initialize();
void OnMetricsPreferenceChanged(); void OnMetricsPreferenceChanged();
void OnBackupAndRestorePreferenceChanged(); void OnBackupAndRestorePreferenceChanged();
...@@ -75,17 +79,10 @@ class ArcSupportHost : public extensions::NativeMessageHost, ...@@ -75,17 +79,10 @@ class ArcSupportHost : public extensions::NativeMessageHost,
void EnableBackupRestore(bool is_enabled); void EnableBackupRestore(bool is_enabled);
void EnableLocationService(bool is_enabled); void EnableLocationService(bool is_enabled);
// Unowned pointer. void DisconnectMessageHost();
Client* client_ = nullptr;
// The instance is created and managed by Chrome.
// Keep if Close() is requested from the browser. arc::ArcSupportMessageHost* message_host_ = nullptr;
// TODO(hidehiko): Remove this. This is temporarily introduced for checking
// if ArcAuthService::CancelAuthCode() needs to be invoked or not.
// ArcAuthService should know its own state and the transition so moving to
// there should simplify the structure. However, it is blocked by the current
// dependency. For the clean up, more refactoring is needed, which can be
// bigger changes.
bool close_requested_ = false;
// Used to track metrics preference. // Used to track metrics preference.
PrefChangeRegistrar pref_local_change_registrar_; PrefChangeRegistrar pref_local_change_registrar_;
......
// Copyright 2016 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/arc/extensions/arc_support_message_host.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/chromeos/arc/arc_auth_service.h"
#include "chrome/browser/chromeos/arc/arc_support_host.h"
namespace arc {
// static
const char ArcSupportMessageHost::kHostName[] = "com.google.arc_support";
// static
const char* const ArcSupportMessageHost::kHostOrigin[] = {
"chrome-extension://cnbgggchhmkkdmeppjobngjoejnihlei/"};
// static
std::unique_ptr<extensions::NativeMessageHost> ArcSupportMessageHost::Create() {
return std::unique_ptr<NativeMessageHost>(new ArcSupportMessageHost());
}
ArcSupportMessageHost::ArcSupportMessageHost() = default;
ArcSupportMessageHost::~ArcSupportMessageHost() {
// On shutdown, ArcAuthService may be already deleted. In that case,
// ArcAuthService::Get() returns nullptr. Note that, ArcSupportHost
// disconnects to this instance on shutdown already.
ArcAuthService* auth_service = ArcAuthService::Get();
if (auth_service) {
DCHECK(auth_service->support_host());
auth_service->support_host()->UnsetMessageHost(this);
}
}
void ArcSupportMessageHost::SendMessage(const base::Value& message) {
if (!client_)
return;
std::string message_string;
base::JSONWriter::Write(message, &message_string);
client_->PostMessageFromNativeHost(message_string);
}
void ArcSupportMessageHost::SetObserver(Observer* observer) {
// We assume that the observer instance is only ArcSupportHost, which is
// currently system unique. This is also used to reset the observere,
// so |observer| xor |observer_| needs to be nullptr.
DCHECK(!observer != !observer_);
observer_ = observer;
}
void ArcSupportMessageHost::Start(Client* client) {
DCHECK(!client_);
client_ = client;
ArcAuthService* auth_service = ArcAuthService::Get();
DCHECK(auth_service);
DCHECK(auth_service->support_host());
auth_service->support_host()->SetMessageHost(this);
}
void ArcSupportMessageHost::OnMessage(const std::string& message_string) {
if (!observer_)
return;
std::unique_ptr<base::Value> message_value =
base::JSONReader::Read(message_string);
base::DictionaryValue* message;
if (!message_value || !message_value->GetAsDictionary(&message)) {
NOTREACHED();
return;
}
observer_->OnMessage(*message);
}
scoped_refptr<base::SingleThreadTaskRunner> ArcSupportMessageHost::task_runner()
const {
return base::ThreadTaskRunnerHandle::Get();
}
} // namespace arc
// Copyright 2016 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_ARC_EXTENSIONS_ARC_SUPPORT_MESSAGE_HOST_H_
#define CHROME_BROWSER_CHROMEOS_ARC_EXTENSIONS_ARC_SUPPORT_MESSAGE_HOST_H_
#include <memory>
#include "base/macros.h"
#include "base/values.h"
#include "extensions/browser/api/messaging/native_message_host.h"
namespace arc {
// Implements message routing to communicate with arc_support Chrome App.
// Provides JSON (base::Value) APIs for the communication.
class ArcSupportMessageHost : public extensions::NativeMessageHost {
public:
class Observer {
public:
// Called when an message is sent from arc_support Chrome App.
virtual void OnMessage(const base::DictionaryValue& message) = 0;
protected:
virtual ~Observer() = default;
};
static const char kHostName[];
static const char* const kHostOrigin[];
// Called when the arc_support connects the "port". Returns the
// instance of ArcSupportMessageHost.
static std::unique_ptr<NativeMessageHost> Create();
~ArcSupportMessageHost() override;
// Sends a message to arc_support. If the client is not yet ready, the
// message will be just ignored.
void SendMessage(const base::Value& message);
// Registers (or unregisters if nullptr) the observer. Currently this class
// assumes that it has only one observer.
void SetObserver(Observer* observer);
private:
// Keep private. The instance will be created via Create().
ArcSupportMessageHost();
// extensions::NativeMessageHost overrides:
void Start(Client* client) override;
void OnMessage(const std::string& request_string) override;
scoped_refptr<base::SingleThreadTaskRunner> task_runner() const override;
Observer* observer_ = nullptr;
Client* client_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(ArcSupportMessageHost);
};
} // namespace arc
#endif // CHROME_BROWSER_CHROMEOS_ARC_EXTENSIONS_ARC_SUPPORT_MESSAGE_HOST_H_
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/arc/arc_support_host.h" #include "chrome/browser/chromeos/arc/extensions/arc_support_message_host.h"
#include "components/policy/core/common/policy_service.h" #include "components/policy/core/common/policy_service.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "extensions/common/constants.h" #include "extensions/common/constants.h"
...@@ -129,18 +129,13 @@ const char* const kRemotingIt2MeOrigins[] = { ...@@ -129,18 +129,13 @@ const char* const kRemotingIt2MeOrigins[] = {
"chrome-extension://hpodccmdligbeohchckkeajbfohibipg/"}; "chrome-extension://hpodccmdligbeohchckkeajbfohibipg/"};
static const BuiltInHost kBuiltInHost[] = { static const BuiltInHost kBuiltInHost[] = {
{"com.google.chrome.test.echo", // ScopedTestNativeMessagingHost::kHostName {"com.google.chrome.test.echo", // ScopedTestNativeMessagingHost::kHostName
kEchoHostOrigins, kEchoHostOrigins, arraysize(kEchoHostOrigins), &EchoHost::Create},
arraysize(kEchoHostOrigins), {"com.google.chrome.remote_assistance", kRemotingIt2MeOrigins,
&EchoHost::Create}, arraysize(kRemotingIt2MeOrigins), &CreateIt2MeHost},
{"com.google.chrome.remote_assistance", {arc::ArcSupportMessageHost::kHostName,
kRemotingIt2MeOrigins, arc::ArcSupportMessageHost::kHostOrigin, 1,
arraysize(kRemotingIt2MeOrigins), &arc::ArcSupportMessageHost::Create},
&CreateIt2MeHost},
{ArcSupportHost::kHostName,
ArcSupportHost::kHostOrigin,
1,
&ArcSupportHost::Create},
}; };
bool MatchesSecurityOrigin(const BuiltInHost& host, bool MatchesSecurityOrigin(const BuiltInHost& host,
......
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