summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbenhansen <benhansen@google.com>2015-12-18 11:26:33 -0800
committerCommit bot <commit-bot@chromium.org>2015-12-18 19:28:21 +0000
commit97f351d4cd4c16638fcaebc791d883dddb4fb848 (patch)
treed0dbd09b5c8abd4a09d39ef78ceef7bc1a57f88b
parentd5ced07756084491d67575fabf0e2a6c88266586 (diff)
downloadchromium_src-97f351d4cd4c16638fcaebc791d883dddb4fb848.zip
chromium_src-97f351d4cd4c16638fcaebc791d883dddb4fb848.tar.gz
chromium_src-97f351d4cd4c16638fcaebc791d883dddb4fb848.tar.bz2
arc: Add settings bridge
Synchronize font and spoken feedback enabled settings from Chrome to Android on Android start and keep settings in sync by listening for Chrome preference changes. Related changes: * ag/822770 * ag/822726 BUG=561003 TEST=./unit_tests --gtest_filter='Arc*' TEST=Build both sides. Change font size in chrome://settings or enable spoken feedback (Ctrl+Alt+Z). Observe change in Android. Review URL: https://codereview.chromium.org/1539633002 Cr-Commit-Position: refs/heads/master@{#366145}
-rw-r--r--chrome/browser/chromeos/arc/arc_settings_bridge_impl.cc158
-rw-r--r--chrome/browser/chromeos/arc/arc_settings_bridge_impl.h93
-rw-r--r--chrome/browser/chromeos/arc/arc_settings_bridge_unittest.cc53
-rw-r--r--chrome/browser/chromeos/chrome_browser_main_chromeos.cc5
-rw-r--r--chrome/chrome_browser_chromeos.gypi2
-rw-r--r--chrome/chrome_tests_unit.gypi9
-rw-r--r--components/arc.gypi2
-rw-r--r--components/arc/BUILD.gn2
-rw-r--r--components/arc/arc_bridge_service.h12
-rw-r--r--components/arc/arc_bridge_service_impl.cc21
-rw-r--r--components/arc/arc_bridge_service_impl.h5
-rw-r--r--components/arc/arc_service_manager.cc9
-rw-r--r--components/arc/arc_service_manager.h4
-rw-r--r--components/arc/common/arc_bridge.mojom11
-rw-r--r--components/arc/settings/arc_settings_bridge.cc11
-rw-r--r--components/arc/settings/arc_settings_bridge.h26
-rw-r--r--components/arc/test/fake_arc_bridge_instance.cc4
-rw-r--r--components/arc/test/fake_arc_bridge_instance.h6
-rw-r--r--components/arc/test/fake_arc_bridge_service.cc7
-rw-r--r--components/arc/test/fake_arc_bridge_service.h4
20 files changed, 440 insertions, 4 deletions
diff --git a/chrome/browser/chromeos/arc/arc_settings_bridge_impl.cc b/chrome/browser/chromeos/arc/arc_settings_bridge_impl.cc
new file mode 100644
index 0000000..6285044
--- /dev/null
+++ b/chrome/browser/chromeos/arc/arc_settings_bridge_impl.cc
@@ -0,0 +1,158 @@
+// 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.
+
+#include "chrome/browser/chromeos/arc/arc_settings_bridge_impl.h"
+
+#include <algorithm>
+
+#include "base/prefs/pref_service.h"
+#include "base/strings/stringprintf.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/common/pref_names.h"
+
+namespace arc {
+
+namespace fontsizes {
+
+double ConvertFontSizeChromeToAndroid(int default_size,
+ int default_fixed_size,
+ int minimum_size) {
+ // kWebKitDefaultFixedFontSize is automatically set to be 3 pixels smaller
+ // than kWebKitDefaultFontSize when Chrome's settings page's main font
+ // dropdown control is adjusted. If the user specifically sets a higher
+ // fixed font size we will want to take into account the adjustment.
+ default_fixed_size += 3;
+ int max_chrome_size =
+ std::max(std::max(default_fixed_size, default_size), minimum_size);
+
+ double android_scale = kAndroidFontScaleSmall;
+ if (max_chrome_size >= kChromeFontSizeVeryLarge) {
+ android_scale = kAndroidFontScaleHuge;
+ } else if (max_chrome_size >= kChromeFontSizeLarge) {
+ android_scale = kAndroidFontScaleLarge;
+ } else if (max_chrome_size >= kChromeFontSizeNormal) {
+ android_scale = kAndroidFontScaleNormal;
+ }
+
+ return android_scale;
+}
+
+} // namespace fontsizes
+
+ArcSettingsBridgeImpl::~ArcSettingsBridgeImpl() {
+ ArcBridgeService* bridge_service = ArcBridgeService::Get();
+ DCHECK(bridge_service);
+ bridge_service->RemoveObserver(this);
+}
+
+void ArcSettingsBridgeImpl::StartObservingBridgeServiceChanges() {
+ ArcBridgeService* bridge_service = ArcBridgeService::Get();
+ DCHECK(bridge_service);
+ bridge_service->AddObserver(this);
+}
+
+void ArcSettingsBridgeImpl::StartObservingPrefChanges() {
+ Profile* profile = ProfileManager::GetActiveUserProfile();
+ registrar_.Init(profile->GetPrefs());
+
+ AddPrefToObserve(prefs::kWebKitDefaultFixedFontSize);
+ AddPrefToObserve(prefs::kWebKitDefaultFontSize);
+ AddPrefToObserve(prefs::kWebKitMinimumFontSize);
+ AddPrefToObserve(prefs::kAccessibilitySpokenFeedbackEnabled);
+}
+
+void ArcSettingsBridgeImpl::SyncAllPrefs() const {
+ SyncFontSize();
+ SyncSpokenFeedbackEnabled();
+}
+
+void ArcSettingsBridgeImpl::StopObservingPrefChanges() {
+ registrar_.RemoveAll();
+}
+
+void ArcSettingsBridgeImpl::AddPrefToObserve(const std::string& pref_name) {
+ registrar_.Add(pref_name, base::Bind(&ArcSettingsBridgeImpl::OnPrefChanged,
+ base::Unretained(this)));
+}
+
+void ArcSettingsBridgeImpl::OnPrefChanged(const std::string& pref_name) const {
+ if (pref_name == prefs::kAccessibilitySpokenFeedbackEnabled) {
+ SyncSpokenFeedbackEnabled();
+ } else if (pref_name == prefs::kWebKitDefaultFixedFontSize ||
+ pref_name == prefs::kWebKitDefaultFontSize ||
+ pref_name == prefs::kWebKitMinimumFontSize) {
+ SyncFontSize();
+ } else {
+ LOG(ERROR) << "Unknown pref changed.";
+ }
+}
+
+void ArcSettingsBridgeImpl::OnStateChanged(ArcBridgeService::State state) {
+ // ArcBridgeService::State::READY is emitted before ArcSettings app is ready
+ // to send broadcasts. Instead we wait for a later boot phase in
+ // OnInstanceBootPhase.
+ if (state == ArcBridgeService::State::STOPPING) {
+ StopObservingPrefChanges();
+ }
+}
+
+void ArcSettingsBridgeImpl::OnInstanceBootPhase(InstanceBootPhase phase) {
+ if (phase == INSTANCE_BOOT_PHASE_ACTIVITY_MANAGER_READY) {
+ StartObservingPrefChanges();
+ SyncAllPrefs();
+ }
+}
+
+void ArcSettingsBridgeImpl::SyncSpokenFeedbackEnabled() const {
+ const PrefService::Preference* pref = registrar_.prefs()->FindPreference(
+ prefs::kAccessibilitySpokenFeedbackEnabled);
+ DCHECK(pref);
+ bool enabled = false;
+ bool value_exists = pref->GetValue()->GetAsBoolean(&enabled);
+ DCHECK(value_exists);
+ base::DictionaryValue extras;
+ extras.SetBoolean("enabled", enabled);
+ SendSettingsBroadcast("org.chromium.arc.settings.SET_SPOKEN_FEEDBACK_ENABLED",
+ extras);
+}
+
+int ArcSettingsBridgeImpl::GetIntegerPref(const std::string& pref_name) const {
+ const PrefService::Preference* pref =
+ registrar_.prefs()->FindPreference(pref_name);
+ DCHECK(pref);
+ int val = -1;
+ bool value_exists = pref->GetValue()->GetAsInteger(&val);
+ DCHECK(value_exists);
+ return val;
+}
+
+void ArcSettingsBridgeImpl::SyncFontSize() const {
+ int default_size = GetIntegerPref(prefs::kWebKitDefaultFontSize);
+ int default_fixed_size = GetIntegerPref(prefs::kWebKitDefaultFixedFontSize);
+ int minimum_size = GetIntegerPref(prefs::kWebKitMinimumFontSize);
+
+ double android_scale = fontsizes::ConvertFontSizeChromeToAndroid(
+ default_size, default_fixed_size, minimum_size);
+
+ base::DictionaryValue extras;
+ extras.SetDouble("scale", android_scale);
+ SendSettingsBroadcast("org.chromium.arc.settings.SET_FONT_SCALE", extras);
+}
+
+void ArcSettingsBridgeImpl::SendSettingsBroadcast(
+ const std::string& action,
+ const base::DictionaryValue& extras) const {
+ ArcBridgeService* bridge_service = ArcBridgeService::Get();
+ if (!bridge_service ||
+ bridge_service->state() != ArcBridgeService::State::READY) {
+ LOG(ERROR) << "Bridge service is not ready.";
+ return;
+ }
+
+ bridge_service->SendBroadcast(action, "org.chromium.arc.settings",
+ "org.chromium.arc.settings.SettingsReceiver",
+ extras);
+}
+
+} // namespace arc
diff --git a/chrome/browser/chromeos/arc/arc_settings_bridge_impl.h b/chrome/browser/chromeos/arc/arc_settings_bridge_impl.h
new file mode 100644
index 0000000..e245a1b
--- /dev/null
+++ b/chrome/browser/chromeos/arc/arc_settings_bridge_impl.h
@@ -0,0 +1,93 @@
+// Copyright (c) 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.
+#ifndef CHROME_BROWSER_CHROMEOS_ARC_ARC_SETTINGS_BRIDGE_IMPL_H_
+#define CHROME_BROWSER_CHROMEOS_ARC_ARC_SETTINGS_BRIDGE_IMPL_H_
+
+#include <string>
+
+#include "base/gtest_prod_util.h"
+#include "base/macros.h"
+#include "base/prefs/pref_change_registrar.h"
+#include "base/values.h"
+#include "components/arc/arc_bridge_service.h"
+#include "components/arc/settings/arc_settings_bridge.h"
+
+namespace arc {
+
+namespace fontsizes {
+
+// The following values were obtained from chrome://settings and Android's
+// Display settings on Nov 2015. They are expected to remain stable.
+const float kAndroidFontScaleSmall = 0.85;
+const float kAndroidFontScaleNormal = 1;
+const float kAndroidFontScaleLarge = 1.15;
+const float kAndroidFontScaleHuge = 1.3;
+const int kChromeFontSizeNormal = 16;
+const int kChromeFontSizeLarge = 20;
+const int kChromeFontSizeVeryLarge = 24;
+
+// Android has only a single float value for system-wide font size
+// (font_scale). Chrome has three main int pixel values that affect
+// system-wide font size. We will take the largest font value of the three
+// main font values on Chrome and convert to an Android size.
+double ConvertFontSizeChromeToAndroid(int default_size,
+ int default_fixed_size,
+ int minimum_size);
+
+} // namespace fontsizes
+
+// Listens to changes for select Chrome settings (prefs) that Android cares
+// about and sends the new values to Android to keep the state in sync.
+class ArcSettingsBridgeImpl : public ArcSettingsBridge,
+ public ArcBridgeService::Observer {
+ public:
+ ArcSettingsBridgeImpl() = default;
+
+ ~ArcSettingsBridgeImpl() override;
+
+ // Starts listening to state changes of the ArcBridgeService.
+ // This must be called before the bridge service starts bootstrapping.
+ void StartObservingBridgeServiceChanges() override;
+
+ // Called when a Chrome pref we have registered an observer for has changed.
+ // Obtains the new pref value and sends it to Android.
+ void OnPrefChanged(const std::string& pref_name) const;
+
+ // ArcBridgeService::Observer
+ void OnStateChanged(ArcBridgeService::State state) override;
+
+ // ArcBridgeService::Observer
+ void OnInstanceBootPhase(InstanceBootPhase phase) override;
+
+ private:
+ // Registers to observe changes for Chrome settings we care about.
+ void StartObservingPrefChanges();
+
+ // Stops listening for Chrome settings changes.
+ void StopObservingPrefChanges();
+
+ // Retrives Chrome's state for the settings and send it to Android.
+ void SyncAllPrefs() const;
+ void SyncSpokenFeedbackEnabled() const;
+ void SyncFontSize() const;
+
+ // Registers to listen to a particular perf.
+ void AddPrefToObserve(const std::string& pref_name);
+
+ // Returns the integer value of the pref. pref_name must exist.
+ int GetIntegerPref(const std::string& pref_name) const;
+
+ // Sends a broadcast to the ArcSettings app in Android.
+ void SendSettingsBroadcast(const std::string& action,
+ const base::DictionaryValue& extras) const;
+
+ // Manages pref observation registration.
+ PrefChangeRegistrar registrar_;
+
+ DISALLOW_COPY_AND_ASSIGN(ArcSettingsBridgeImpl);
+};
+
+} // namespace arc
+
+#endif // CHROME_BROWSER_CHROMEOS_ARC_ARC_SETTINGS_BRIDGE_IMPL_H_
diff --git a/chrome/browser/chromeos/arc/arc_settings_bridge_unittest.cc b/chrome/browser/chromeos/arc/arc_settings_bridge_unittest.cc
new file mode 100644
index 0000000..864f016
--- /dev/null
+++ b/chrome/browser/chromeos/arc/arc_settings_bridge_unittest.cc
@@ -0,0 +1,53 @@
+// Copyright (c) 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.
+
+#include "chrome/browser/chromeos/arc/arc_settings_bridge_impl.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace arc {
+
+namespace fontsizes {
+
+TEST(ArcSettingsBridgeTest, FontSizeConvertChromeToAndroid) {
+ // Does not return a value smaller than Small.
+ EXPECT_DOUBLE_EQ(kAndroidFontScaleSmall,
+ ConvertFontSizeChromeToAndroid(0, 0, 0));
+
+ // Does not return a value larger than Huge
+ EXPECT_DOUBLE_EQ(kAndroidFontScaleHuge,
+ ConvertFontSizeChromeToAndroid(100, 100, 100));
+
+ // The max of any Chrome values is what determines the Android value.
+ EXPECT_DOUBLE_EQ(kAndroidFontScaleLarge,
+ ConvertFontSizeChromeToAndroid(20, 0, 0));
+ EXPECT_DOUBLE_EQ(kAndroidFontScaleLarge,
+ ConvertFontSizeChromeToAndroid(0, 20, 0));
+ EXPECT_DOUBLE_EQ(kAndroidFontScaleLarge,
+ ConvertFontSizeChromeToAndroid(0, 0, 20));
+
+ // default fixed font size is adjusted up three pixels
+ EXPECT_DOUBLE_EQ(kAndroidFontScaleLarge,
+ ConvertFontSizeChromeToAndroid(0, 17, 0));
+
+ // Small converts properly.
+ EXPECT_DOUBLE_EQ(kAndroidFontScaleSmall,
+ ConvertFontSizeChromeToAndroid(12, 0, 0));
+
+ // Normal converts properly.
+ EXPECT_DOUBLE_EQ(kAndroidFontScaleNormal,
+ ConvertFontSizeChromeToAndroid(16, 0, 0));
+
+ // Large converts properly.
+ EXPECT_DOUBLE_EQ(kAndroidFontScaleLarge,
+ ConvertFontSizeChromeToAndroid(20, 0, 0));
+
+ // Very large converts properly.
+ EXPECT_DOUBLE_EQ(kAndroidFontScaleHuge,
+ ConvertFontSizeChromeToAndroid(24, 0, 0));
+}
+
+} // namespace fontsizes
+
+} // namespace arc
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
index 3c83155..33f04e4 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -30,6 +30,7 @@
#include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h"
#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
#include "chrome/browser/chromeos/app_mode/kiosk_mode_idle_app_name_notification.h"
+#include "chrome/browser/chromeos/arc/arc_settings_bridge_impl.h"
#include "chrome/browser/chromeos/boot_times_recorder.h"
#include "chrome/browser/chromeos/dbus/chrome_console_service_provider_delegate.h"
#include "chrome/browser/chromeos/dbus/chrome_display_power_service_provider_delegate.h"
@@ -111,6 +112,7 @@
#include "chromeos/tpm/tpm_token_loader.h"
#include "components/arc/arc_bridge_service.h"
#include "components/arc/arc_service_manager.h"
+#include "components/arc/settings/arc_settings_bridge.h"
#include "components/browser_sync/common/browser_sync_switches.h"
#include "components/device_event_log/device_event_log.h"
#include "components/metrics/metrics_service.h"
@@ -389,7 +391,8 @@ void ChromeBrowserMainPartsChromeos::PreMainMessageLoopRun() {
wake_on_wifi_manager_.reset(new WakeOnWifiManager());
- arc_service_manager_.reset(new arc::ArcServiceManager());
+ arc_service_manager_.reset(new arc::ArcServiceManager(
+ make_scoped_ptr(new arc::ArcSettingsBridgeImpl())));
arc_service_manager_->arc_bridge_service()->DetectAvailability();
chromeos::ResourceReporter::GetInstance()->StartMonitoring();
diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi
index d75c5b8..41cefb0 100644
--- a/chrome/chrome_browser_chromeos.gypi
+++ b/chrome/chrome_browser_chromeos.gypi
@@ -52,6 +52,8 @@
'browser/chromeos/app_mode/kiosk_session_plugin_handler_delegate.h',
'browser/chromeos/app_mode/startup_app_launcher.cc',
'browser/chromeos/app_mode/startup_app_launcher.h',
+ 'browser/chromeos/arc/arc_settings_bridge_impl.cc',
+ 'browser/chromeos/arc/arc_settings_bridge_impl.h',
'browser/chromeos/attestation/attestation_ca_client.cc',
'browser/chromeos/attestation/attestation_ca_client.h',
'browser/chromeos/attestation/attestation_policy_observer.cc',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index e3a7546..0e99851 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -1646,6 +1646,9 @@
'chrome_unit_tests_app_list_chromeos_arc_sources': [
'browser/ui/app_list/arc/arc_app_unittest.cc',
],
+ 'chrome_unit_tests_arc_settings_bridge_sources': [
+ 'browser/chromeos/arc/arc_settings_bridge_unittest.cc',
+ ],
# Sources for Offline pages. For now only for Android.
'chrome_unit_tests_offline_pages_sources': [
'browser/android/offline_pages/offline_page_mhtml_archiver_unittest.cc',
@@ -2802,6 +2805,12 @@
'../components/components.gyp:arc_test_support',
],
}],
+ ['chromeos==1', {
+ 'sources': [ '<@(chrome_unit_tests_arc_settings_bridge_sources)' ],
+ 'dependencies': [
+ '../components/components.gyp:arc_test_support',
+ ],
+ }],
['enable_plugin_installation==0', {
'sources!': [
'browser/plugins/plugin_installer_unittest.cc',
diff --git a/components/arc.gypi b/components/arc.gypi
index 62cc463..ab98050 100644
--- a/components/arc.gypi
+++ b/components/arc.gypi
@@ -31,6 +31,8 @@
'arc/input/arc_input_bridge.h',
'arc/input/arc_input_bridge_impl.cc',
'arc/input/arc_input_bridge_impl.h',
+ 'arc/settings/arc_settings_bridge.cc',
+ 'arc/settings/arc_settings_bridge.h',
],
},
{
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn
index 4b33a45..4f96906 100644
--- a/components/arc/BUILD.gn
+++ b/components/arc/BUILD.gn
@@ -17,6 +17,8 @@ static_library("arc") {
"input/arc_input_bridge.h",
"input/arc_input_bridge_impl.cc",
"input/arc_input_bridge_impl.h",
+ "settings/arc_settings_bridge.cc",
+ "settings/arc_settings_bridge.h",
]
deps = [
diff --git a/components/arc/arc_bridge_service.h b/components/arc/arc_bridge_service.h
index 98902e6..f3cc81f 100644
--- a/components/arc/arc_bridge_service.h
+++ b/components/arc/arc_bridge_service.h
@@ -13,6 +13,7 @@
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
+#include "base/values.h"
#include "components/arc/common/arc_bridge.mojom.h"
namespace base {
@@ -205,6 +206,17 @@ class ArcBridgeService {
// When the result comes back, Observer::OnUpdateProcessList() is called.
virtual bool RequestProcessList() = 0;
+ // Send an Android broadcast message to the Android package and class
+ // specified. The 'extras' DictionaryValue will be converted to an Android
+ // Bundle accessible by the broadcast receiver.
+ //
+ // Note: Broadcasts can only be sent to whitelisted packages. Packages can be
+ // added to the whitelist in ArcBridgeService.java in the Android source.
+ virtual bool SendBroadcast(const std::string& action,
+ const std::string& package,
+ const std::string& clazz,
+ const base::DictionaryValue& extras) = 0;
+
protected:
ArcBridgeService();
diff --git a/components/arc/arc_bridge_service_impl.cc b/components/arc/arc_bridge_service_impl.cc
index d5485b4..38aed8b 100644
--- a/components/arc/arc_bridge_service_impl.cc
+++ b/components/arc/arc_bridge_service_impl.cc
@@ -8,6 +8,7 @@
#include <utility>
#include "base/command_line.h"
+#include "base/json/json_writer.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/pref_service.h"
#include "base/sequenced_task_runner.h"
@@ -120,6 +121,26 @@ bool ArcBridgeServiceImpl::RegisterInputDevice(const std::string& name,
return true;
}
+bool ArcBridgeServiceImpl::SendBroadcast(const std::string& action,
+ const std::string& package,
+ const std::string& clazz,
+ const base::DictionaryValue& extras) {
+ DCHECK(CalledOnValidThread());
+ if (action.empty() || package.empty() || clazz.empty()) {
+ LOG(ERROR) << "SendBroadcast failed: Invalid parameter";
+ return false;
+ }
+ std::string extras_json;
+ bool write_success = base::JSONWriter::Write(extras, &extras_json);
+ DCHECK(write_success);
+ if (state() != State::READY) {
+ LOG(ERROR) << "Called SendBroadcast when the service is not ready";
+ return false;
+ }
+ instance_ptr_->SendBroadcast(action, package, clazz, extras_json);
+ return true;
+}
+
bool ArcBridgeServiceImpl::SendNotificationEventToAndroid(
const std::string& key, ArcNotificationEvent event) {
DCHECK(CalledOnValidThread());
diff --git a/components/arc/arc_bridge_service_impl.h b/components/arc/arc_bridge_service_impl.h
index 8c744e1..969e0cb 100644
--- a/components/arc/arc_bridge_service_impl.h
+++ b/components/arc/arc_bridge_service_impl.h
@@ -40,6 +40,11 @@ class ArcBridgeServiceImpl : public ArcBridgeService,
const std::string& device_type,
base::ScopedFD fd) override;
+ bool SendBroadcast(const std::string& action,
+ const std::string& package,
+ const std::string& clazz,
+ const base::DictionaryValue& extras) override;
+
bool SendNotificationEventToAndroid(const std::string& key,
ArcNotificationEvent event) override;
diff --git a/components/arc/arc_service_manager.cc b/components/arc/arc_service_manager.cc
index 2fc0e00..68f01cb1 100644
--- a/components/arc/arc_service_manager.cc
+++ b/components/arc/arc_service_manager.cc
@@ -9,6 +9,7 @@
#include "components/arc/arc_bridge_bootstrap.h"
#include "components/arc/arc_bridge_service_impl.h"
#include "components/arc/input/arc_input_bridge.h"
+#include "components/arc/settings/arc_settings_bridge.h"
namespace arc {
@@ -19,12 +20,16 @@ ArcServiceManager* g_arc_service_manager = nullptr;
} // namespace
-ArcServiceManager::ArcServiceManager()
+ArcServiceManager::ArcServiceManager(
+ scoped_ptr<ArcSettingsBridge> settings_bridge)
: arc_bridge_service_(
- new ArcBridgeServiceImpl(ArcBridgeBootstrap::Create())) {
+ new ArcBridgeServiceImpl(ArcBridgeBootstrap::Create())),
+ arc_settings_bridge_(std::move(settings_bridge)) {
DCHECK(!g_arc_service_manager);
arc_input_bridge_ = ArcInputBridge::Create(arc_bridge_service_.get());
g_arc_service_manager = this;
+
+ arc_settings_bridge_->StartObservingBridgeServiceChanges();
}
ArcServiceManager::~ArcServiceManager() {
diff --git a/components/arc/arc_service_manager.h b/components/arc/arc_service_manager.h
index ed4b434..07d6273 100644
--- a/components/arc/arc_service_manager.h
+++ b/components/arc/arc_service_manager.h
@@ -13,12 +13,13 @@ namespace arc {
class ArcBridgeService;
class ArcInputBridge;
+class ArcSettingsBridge;
// Manages creation and destruction of services that communicate with the ARC
// instance via the ArcBridgeService.
class ArcServiceManager {
public:
- ArcServiceManager();
+ explicit ArcServiceManager(scoped_ptr<ArcSettingsBridge> settings_bridge);
virtual ~ArcServiceManager();
// |arc_bridge_service| can only be accessed on the thread that this
@@ -33,6 +34,7 @@ class ArcServiceManager {
base::ThreadChecker thread_checker_;
scoped_ptr<ArcBridgeService> arc_bridge_service_;
scoped_ptr<ArcInputBridge> arc_input_bridge_;
+ scoped_ptr<ArcSettingsBridge> arc_settings_bridge_;
DISALLOW_COPY_AND_ASSIGN(ArcServiceManager);
};
diff --git a/components/arc/common/arc_bridge.mojom b/components/arc/common/arc_bridge.mojom
index f555fbcc..b2e0060 100644
--- a/components/arc/common/arc_bridge.mojom
+++ b/components/arc/common/arc_bridge.mojom
@@ -263,4 +263,15 @@ interface ArcBridgeInstance {
// Requests ARC instance to return the current process list.
RequestProcessList();
+
+ // Send an Android broadcast message to the Android package and class
+ // specified. Data can be sent as extras by including a JSON map string which
+ // will be automatically converted to a bundle accessible by the receiver.
+ //
+ // Note: Broadcasts can only be sent to whitelisted packages. Packages can be
+ // added to the whitelist in ArcBridgeService.java in the Android source.
+ SendBroadcast(string action,
+ string package,
+ string cls,
+ string extras);
};
diff --git a/components/arc/settings/arc_settings_bridge.cc b/components/arc/settings/arc_settings_bridge.cc
new file mode 100644
index 0000000..649ddbe
--- /dev/null
+++ b/components/arc/settings/arc_settings_bridge.cc
@@ -0,0 +1,11 @@
+// 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.
+
+#include "components/arc/settings/arc_settings_bridge.h"
+
+namespace arc {
+
+ArcSettingsBridge::~ArcSettingsBridge() {}
+
+} // namespace arc
diff --git a/components/arc/settings/arc_settings_bridge.h b/components/arc/settings/arc_settings_bridge.h
new file mode 100644
index 0000000..ba774c1
--- /dev/null
+++ b/components/arc/settings/arc_settings_bridge.h
@@ -0,0 +1,26 @@
+// 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.
+
+#ifndef COMPONENTS_ARC_SETTINGS_ARC_SETTINGS_BRIDGE_H_
+#define COMPONENTS_ARC_SETTINGS_ARC_SETTINGS_BRIDGE_H_
+
+namespace arc {
+
+// We want ArcServiceManager to own the ArcSettingsBridge but ArcSettingsBridge
+// depends on code in chrome/ which is not accessible from components/. Since
+// ArcSettingsBridge interacts with the bridge through the global Get function,
+// session manager only needs to see a limited interface.
+//
+// Full implementation at chrome/browser/chromeos/arc/arc_settings_bridge_impl.h
+class ArcSettingsBridge {
+ public:
+ virtual ~ArcSettingsBridge() = 0;
+
+ // Starts listening to state changes of the ArcBridgeService
+ virtual void StartObservingBridgeServiceChanges() = 0;
+};
+
+} // namespace arc
+
+#endif // COMPONENTS_ARC_SETTINGS_ARC_SETTINGS_BRIDGE_H_
diff --git a/components/arc/test/fake_arc_bridge_instance.cc b/components/arc/test/fake_arc_bridge_instance.cc
index ffba237..e0c1813 100644
--- a/components/arc/test/fake_arc_bridge_instance.cc
+++ b/components/arc/test/fake_arc_bridge_instance.cc
@@ -33,6 +33,10 @@ void FakeArcBridgeInstance::LaunchApp(const mojo::String& package,
void FakeArcBridgeInstance::RequestAppIcon(const mojo::String& package,
const mojo::String& activity,
ScaleFactor scale_factor) {}
+void FakeArcBridgeInstance::SendBroadcast(const mojo::String& action,
+ const mojo::String& package,
+ const mojo::String& clazz,
+ const mojo::String& extras) {}
void FakeArcBridgeInstance::RequestProcessList() {}
diff --git a/components/arc/test/fake_arc_bridge_instance.h b/components/arc/test/fake_arc_bridge_instance.h
index 82bad56..81de1f1 100644
--- a/components/arc/test/fake_arc_bridge_instance.h
+++ b/components/arc/test/fake_arc_bridge_instance.h
@@ -34,8 +34,14 @@ class FakeArcBridgeInstance : public ArcBridgeInstance {
void RequestAppIcon(const mojo::String& package,
const mojo::String& activity,
ScaleFactor scale_factor) override;
+
void RequestProcessList() override;
+ void SendBroadcast(const mojo::String& action,
+ const mojo::String& package,
+ const mojo::String& clazz,
+ const mojo::String& extras) override;
+
private:
// Mojo endpoints.
mojo::Binding<ArcBridgeInstance> binding_;
diff --git a/components/arc/test/fake_arc_bridge_service.cc b/components/arc/test/fake_arc_bridge_service.cc
index 2c69080..a73bfb4 100644
--- a/components/arc/test/fake_arc_bridge_service.cc
+++ b/components/arc/test/fake_arc_bridge_service.cc
@@ -34,6 +34,13 @@ bool FakeArcBridgeService::RegisterInputDevice(const std::string& name,
return true;
}
+bool FakeArcBridgeService::SendBroadcast(const std::string& action,
+ const std::string& package,
+ const std::string& clazz,
+ const base::DictionaryValue& extras) {
+ return true;
+}
+
bool FakeArcBridgeService::SendNotificationEventToAndroid(
const std::string& key,
ArcNotificationEvent event) {
diff --git a/components/arc/test/fake_arc_bridge_service.h b/components/arc/test/fake_arc_bridge_service.h
index 70d862e..0d2bb07 100644
--- a/components/arc/test/fake_arc_bridge_service.h
+++ b/components/arc/test/fake_arc_bridge_service.h
@@ -71,6 +71,10 @@ class FakeArcBridgeService : public ArcBridgeService {
bool RegisterInputDevice(const std::string& name,
const std::string& device_type,
base::ScopedFD fd) override;
+ bool SendBroadcast(const std::string& action,
+ const std::string& package,
+ const std::string& clazz,
+ const base::DictionaryValue& extras) override;
bool RefreshAppList() override;
bool LaunchApp(const std::string& package,
const std::string& activity) override;