Commit fb0c1002 authored by Maggie Cai's avatar Maggie Cai Committed by Commit Bot

[IntentHandling] Sync Preferred App Setting to ARC.

This CL adds a method to add a preferred app with specific intent filter
to ARC. Currently the existing method uses the previous queried intent
info in the ARC code base, however, with the new intent handling
implementation, the query happened in Chrome OS and ARC does not have
this information anymore, we need to send the corresponding intent
filter to ARC to be able to set the preferred app.

BUG=853604

Change-Id: I7b3bf11deb920aadd9f6421d9f05d313bbdd8850
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1882194
Commit-Queue: Maggie Cai <mxcai@chromium.org>
Reviewed-by: default avatarYusuke Sato <yusukes@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Reviewed-by: default avatarNancy Wang <nancylingwang@chromium.org>
Reviewed-by: default avatarDavid Jacobo <djacobo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#711644}
parent dc32df89
...@@ -343,11 +343,12 @@ void AppServiceProxy::AddPreferredApp(const std::string& app_id, ...@@ -343,11 +343,12 @@ void AppServiceProxy::AddPreferredApp(const std::string& app_id,
if (intent_filter) { if (intent_filter) {
preferred_apps_.AddPreferredApp(app_id, intent_filter); preferred_apps_.AddPreferredApp(app_id, intent_filter);
if (app_service_.is_connected()) { if (app_service_.is_connected()) {
cache_.ForOneApp( cache_.ForOneApp(app_id, [this, &intent_filter,
app_id, [this, &intent_filter](const apps::AppUpdate& update) { &intent](const apps::AppUpdate& update) {
app_service_->AddPreferredApp(update.AppType(), update.AppId(), app_service_->AddPreferredApp(update.AppType(), update.AppId(),
std::move(intent_filter)); std::move(intent_filter),
}); intent->Clone());
});
} }
} }
} }
......
...@@ -433,6 +433,81 @@ void ArcApps::OpenNativeSettings(const std::string& app_id) { ...@@ -433,6 +433,81 @@ void ArcApps::OpenNativeSettings(const std::string& app_id) {
display::Screen::GetScreen()->GetPrimaryDisplay().id()); display::Screen::GetScreen()->GetPrimaryDisplay().id());
} }
void ArcApps::OnPreferredAppSet(const std::string& app_id,
apps::mojom::IntentFilterPtr intent_filter,
apps::mojom::IntentPtr intent) {
auto* arc_service_manager = arc::ArcServiceManager::Get();
arc::mojom::IntentHelperInstance* instance = nullptr;
if (arc_service_manager) {
instance = ARC_GET_INSTANCE_FOR_METHOD(
arc_service_manager->arc_bridge_service()->intent_helper(),
AddPreferredApp);
}
if (!instance) {
return;
}
ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_);
if (!prefs) {
return;
}
const std::unique_ptr<ArcAppListPrefs::AppInfo> app_info =
prefs->GetApp(app_id);
if (!app_info) {
LOG(ERROR) << "Launch App failed, could not find app with id " << app_id;
return;
}
auto arc_intent = CreateArcViewIntent(std::move(intent));
std::vector<std::string> schemes;
std::vector<arc::IntentFilter::AuthorityEntry> authorities;
std::vector<arc::IntentFilter::PatternMatcher> paths;
for (auto& condition : intent_filter->conditions) {
switch (condition->condition_type) {
case apps::mojom::ConditionType::kScheme:
for (auto& condition_value : condition->condition_values) {
schemes.push_back(condition_value->value);
}
break;
case apps::mojom::ConditionType::kHost:
for (auto& condition_value : condition->condition_values) {
authorities.push_back(
arc::IntentFilter::AuthorityEntry(condition_value->value, 0));
}
break;
case apps::mojom::ConditionType::kPattern:
for (auto& condition_value : condition->condition_values) {
arc::mojom::PatternType match_type;
switch (condition_value->match_type) {
case apps::mojom::PatternMatchType::kLiteral:
match_type = arc::mojom::PatternType::PATTERN_LITERAL;
break;
case apps::mojom::PatternMatchType::kPrefix:
match_type = arc::mojom::PatternType::PATTERN_PREFIX;
break;
case apps::mojom::PatternMatchType::kGlob:
match_type = arc::mojom::PatternType::PATTERN_SIMPLE_GLOB;
break;
case apps::mojom::PatternMatchType::kNone:
NOTREACHED();
return;
}
paths.push_back(arc::IntentFilter::PatternMatcher(
condition_value->value, match_type));
}
break;
}
}
// TODO(crbug.com/853604): Add support for other action and category types.
arc::IntentFilter arc_intent_filter(app_info->package_name,
std::move(authorities), std::move(paths),
std::move(schemes));
instance->AddPreferredApp(app_info->package_name,
std::move(arc_intent_filter),
std::move(arc_intent));
}
void ArcApps::OnAppRegistered(const std::string& app_id, void ArcApps::OnAppRegistered(const std::string& app_id,
const ArcAppListPrefs::AppInfo& app_info) { const ArcAppListPrefs::AppInfo& app_info) {
ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_); ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_);
...@@ -713,8 +788,6 @@ void ArcApps::UpdateAppIntentFilters( ...@@ -713,8 +788,6 @@ void ArcApps::UpdateAppIntentFilters(
case arc::mojom::PatternType::PATTERN_SIMPLE_GLOB: case arc::mojom::PatternType::PATTERN_SIMPLE_GLOB:
match_type = apps::mojom::PatternMatchType::kGlob; match_type = apps::mojom::PatternMatchType::kGlob;
break; break;
default:
NOTREACHED();
} }
path_condition_values.push_back( path_condition_values.push_back(
apps_util::MakeConditionValue(path.pattern(), match_type)); apps_util::MakeConditionValue(path.pattern(), match_type));
......
...@@ -78,6 +78,9 @@ class ArcApps : public KeyedService, ...@@ -78,6 +78,9 @@ class ArcApps : public KeyedService,
bool clear_site_data, bool clear_site_data,
bool report_abuse) override; bool report_abuse) override;
void OpenNativeSettings(const std::string& app_id) override; void OpenNativeSettings(const std::string& app_id) override;
void OnPreferredAppSet(const std::string& app_id,
apps::mojom::IntentFilterPtr intent_filter,
apps::mojom::IntentPtr intent) override;
// ArcAppListPrefs::Observer overrides. // ArcAppListPrefs::Observer overrides.
void OnAppRegistered(const std::string& app_id, void OnAppRegistered(const std::string& app_id,
......
...@@ -182,4 +182,11 @@ void BuiltInChromeOsApps::OpenNativeSettings(const std::string& app_id) { ...@@ -182,4 +182,11 @@ void BuiltInChromeOsApps::OpenNativeSettings(const std::string& app_id) {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
} }
void BuiltInChromeOsApps::OnPreferredAppSet(
const std::string& app_id,
apps::mojom::IntentFilterPtr intent_filter,
apps::mojom::IntentPtr intent) {
NOTIMPLEMENTED();
}
} // namespace apps } // namespace apps
...@@ -57,6 +57,9 @@ class BuiltInChromeOsApps : public apps::mojom::Publisher { ...@@ -57,6 +57,9 @@ class BuiltInChromeOsApps : public apps::mojom::Publisher {
bool clear_site_data, bool clear_site_data,
bool report_abuse) override; bool report_abuse) override;
void OpenNativeSettings(const std::string& app_id) override; void OpenNativeSettings(const std::string& app_id) override;
void OnPreferredAppSet(const std::string& app_id,
apps::mojom::IntentFilterPtr intent_filter,
apps::mojom::IntentPtr intent) override;
mojo::Receiver<apps::mojom::Publisher> receiver_{this}; mojo::Receiver<apps::mojom::Publisher> receiver_{this};
......
...@@ -168,6 +168,12 @@ void CrostiniApps::OpenNativeSettings(const std::string& app_id) { ...@@ -168,6 +168,12 @@ void CrostiniApps::OpenNativeSettings(const std::string& app_id) {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
} }
void CrostiniApps::OnPreferredAppSet(const std::string& app_id,
apps::mojom::IntentFilterPtr intent_filter,
apps::mojom::IntentPtr intent) {
NOTIMPLEMENTED();
}
void CrostiniApps::OnRegistryUpdated( void CrostiniApps::OnRegistryUpdated(
crostini::CrostiniRegistryService* registry_service, crostini::CrostiniRegistryService* registry_service,
const std::vector<std::string>& updated_apps, const std::vector<std::string>& updated_apps,
......
...@@ -75,6 +75,9 @@ class CrostiniApps : public KeyedService, ...@@ -75,6 +75,9 @@ class CrostiniApps : public KeyedService,
bool clear_site_data, bool clear_site_data,
bool report_abuse) override; bool report_abuse) override;
void OpenNativeSettings(const std::string& app_id) override; void OpenNativeSettings(const std::string& app_id) override;
void OnPreferredAppSet(const std::string& app_id,
apps::mojom::IntentFilterPtr intent_filter,
apps::mojom::IntentPtr intent) override;
// CrostiniRegistryService::Observer overrides. // CrostiniRegistryService::Observer overrides.
void OnRegistryUpdated( void OnRegistryUpdated(
......
...@@ -548,6 +548,13 @@ void ExtensionApps::OpenNativeSettings(const std::string& app_id) { ...@@ -548,6 +548,13 @@ void ExtensionApps::OpenNativeSettings(const std::string& app_id) {
} }
} }
void ExtensionApps::OnPreferredAppSet(
const std::string& app_id,
apps::mojom::IntentFilterPtr intent_filter,
apps::mojom::IntentPtr intent) {
NOTIMPLEMENTED();
}
void ExtensionApps::OnContentSettingChanged( void ExtensionApps::OnContentSettingChanged(
const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern, const ContentSettingsPattern& secondary_pattern,
......
...@@ -93,6 +93,9 @@ class ExtensionApps : public apps::mojom::Publisher, ...@@ -93,6 +93,9 @@ class ExtensionApps : public apps::mojom::Publisher,
bool clear_site_data, bool clear_site_data,
bool report_abuse) override; bool report_abuse) override;
void OpenNativeSettings(const std::string& app_id) override; void OpenNativeSettings(const std::string& app_id) override;
void OnPreferredAppSet(const std::string& app_id,
apps::mojom::IntentFilterPtr intent_filter,
apps::mojom::IntentPtr intent) override;
// content_settings::Observer overrides. // content_settings::Observer overrides.
void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern, void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern,
......
...@@ -160,15 +160,21 @@ void AppServiceImpl::OpenNativeSettings(apps::mojom::AppType app_type, ...@@ -160,15 +160,21 @@ void AppServiceImpl::OpenNativeSettings(apps::mojom::AppType app_type,
iter->second->OpenNativeSettings(app_id); iter->second->OpenNativeSettings(app_id);
} }
void AppServiceImpl::AddPreferredApp( void AppServiceImpl::AddPreferredApp(apps::mojom::AppType app_type,
apps::mojom::AppType app_type, const std::string& app_id,
const std::string& app_id, apps::mojom::IntentFilterPtr intent_filter,
apps::mojom::IntentFilterPtr intent_filter) { apps::mojom::IntentPtr intent) {
preferred_apps_.AddPreferredApp(app_id, intent_filter); preferred_apps_.AddPreferredApp(app_id, intent_filter);
for (auto& subscriber : subscribers_) { for (auto& subscriber : subscribers_) {
subscriber->OnPreferredAppSet(app_id, intent_filter->Clone()); subscriber->OnPreferredAppSet(app_id, intent_filter->Clone());
} }
// TODO(crbug.com/853604): Update to the corresponding publisher.
auto iter = publishers_.find(app_type);
if (iter == publishers_.end()) {
return;
}
iter->second->OnPreferredAppSet(app_id, std::move(intent_filter),
std::move(intent));
} }
void AppServiceImpl::OnPublisherDisconnected(apps::mojom::AppType app_type) { void AppServiceImpl::OnPublisherDisconnected(apps::mojom::AppType app_type) {
......
...@@ -67,7 +67,8 @@ class AppServiceImpl : public apps::mojom::AppService { ...@@ -67,7 +67,8 @@ class AppServiceImpl : public apps::mojom::AppService {
const std::string& app_id) override; const std::string& app_id) override;
void AddPreferredApp(apps::mojom::AppType app_type, void AddPreferredApp(apps::mojom::AppType app_type,
const std::string& app_id, const std::string& app_id,
apps::mojom::IntentFilterPtr intent_filter) override; apps::mojom::IntentFilterPtr intent_filter,
apps::mojom::IntentPtr intent) override;
// Retern the preferred_apps_ for testing. // Retern the preferred_apps_ for testing.
PreferredApps& GetPreferredAppsForTesting(); PreferredApps& GetPreferredAppsForTesting();
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "base/test/task_environment.h" #include "base/test/task_environment.h"
#include "chrome/services/app_service/app_service_impl.h" #include "chrome/services/app_service/app_service_impl.h"
#include "chrome/services/app_service/public/cpp/intent_filter_util.h" #include "chrome/services/app_service/public/cpp/intent_filter_util.h"
#include "chrome/services/app_service/public/cpp/intent_util.h"
#include "chrome/services/app_service/public/cpp/preferred_apps.h" #include "chrome/services/app_service/public/cpp/preferred_apps.h"
#include "chrome/services/app_service/public/mojom/types.mojom.h" #include "chrome/services/app_service/public/mojom/types.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_receiver.h"
...@@ -86,6 +87,10 @@ class FakePublisher : public apps::mojom::Publisher { ...@@ -86,6 +87,10 @@ class FakePublisher : public apps::mojom::Publisher {
void OpenNativeSettings(const std::string& app_id) override {} void OpenNativeSettings(const std::string& app_id) override {}
void OnPreferredAppSet(const std::string& app_id,
apps::mojom::IntentFilterPtr intent_filter,
apps::mojom::IntentPtr intent) override {}
void CallOnApps(apps::mojom::Subscriber* subscriber, void CallOnApps(apps::mojom::Subscriber* subscriber,
std::vector<std::string>& app_ids) { std::vector<std::string>& app_ids) {
std::vector<apps::mojom::AppPtr> apps; std::vector<apps::mojom::AppPtr> apps;
...@@ -282,7 +287,8 @@ TEST_F(AppServiceImplTest, PreferredApps) { ...@@ -282,7 +287,8 @@ TEST_F(AppServiceImplTest, PreferredApps) {
sub1.PreferredApps().FindPreferredAppForUrl(filter_url)); sub1.PreferredApps().FindPreferredAppForUrl(filter_url));
impl.AddPreferredApp(apps::mojom::AppType::kUnknown, kAppId2, impl.AddPreferredApp(apps::mojom::AppType::kUnknown, kAppId2,
std::move(intent_filter)); std::move(intent_filter),
apps_util::CreateIntentFromUrl(filter_url));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_EQ(kAppId2, sub0.PreferredApps().FindPreferredAppForUrl(filter_url)); EXPECT_EQ(kAppId2, sub0.PreferredApps().FindPreferredAppForUrl(filter_url));
......
...@@ -75,11 +75,13 @@ interface AppService { ...@@ -75,11 +75,13 @@ interface AppService {
AppType app_type, AppType app_type,
string app_id); string app_id);
// Set app identified by |app_id| as preferred app for |intent_fitler|. // Set app identified by |app_id| as preferred app for |intent_filter|.
// |intent| is needed to set the preferred app in ARC.
AddPreferredApp( AddPreferredApp(
AppType app_type, AppType app_type,
string app_id, string app_id,
IntentFilter intent_filter); IntentFilter intent_filter,
Intent intent);
}; };
interface Publisher { interface Publisher {
...@@ -130,6 +132,15 @@ interface Publisher { ...@@ -130,6 +132,15 @@ interface Publisher {
OpenNativeSettings( OpenNativeSettings(
string app_id); string app_id);
// Indicates that the app identified by |app_id| has been set as a preferred
// app for |intent_fitler|. This method is used by the App Service to sync
// the change to publishers. |intent| is needed to set the preferred app
// in ARC.
OnPreferredAppSet(
string app_id,
IntentFilter intent_filter,
Intent intent);
}; };
interface Subscriber { interface Subscriber {
......
...@@ -260,7 +260,7 @@ interface IntentHelperHost { ...@@ -260,7 +260,7 @@ interface IntentHelperHost {
}; };
// Sends intents to ARC on behalf of Chrome. // Sends intents to ARC on behalf of Chrome.
// Next method ID: 17 // Next method ID: 18
interface IntentHelperInstance { interface IntentHelperInstance {
// Sets the given package as a preferred package. The next time an ACTION_VIEW // Sets the given package as a preferred package. The next time an ACTION_VIEW
// intent is sent with a URL that requires disambiguation, instead of opening // intent is sent with a URL that requires disambiguation, instead of opening
...@@ -268,6 +268,16 @@ interface IntentHelperInstance { ...@@ -268,6 +268,16 @@ interface IntentHelperInstance {
// When multiple packages are set as preferred, the most recent setting wins. // When multiple packages are set as preferred, the most recent setting wins.
[MinVersion=7] AddPreferredPackage@8(string package_name); [MinVersion=7] AddPreferredPackage@8(string package_name);
// Sets the given package as a preferred app for the given |intent_filter|
// and |intent_info|.
// The |package_name| is selected by the user on Chrome-side to remember the
// user preference. The |intent_info| is used to generate the components set
// and match for setting the preferred activity.
// This is used to sync the preferred app setting from Chrome OS.
[MinVersion=31] AddPreferredApp@17(string package_name,
IntentFilter intent_filter,
IntentInfo intent_info);
// DEPRECATED. Use FileSystemInstance.GetFileSize() instead. // DEPRECATED. Use FileSystemInstance.GetFileSize() instead.
[MinVersion=15] GetFileSizeDeprecated@11(string url) => (int64 size); [MinVersion=15] GetFileSizeDeprecated@11(string url) => (int64 size);
......
...@@ -55,6 +55,10 @@ FakeIntentHelperInstance::~FakeIntentHelperInstance() {} ...@@ -55,6 +55,10 @@ FakeIntentHelperInstance::~FakeIntentHelperInstance() {}
void FakeIntentHelperInstance::AddPreferredPackage( void FakeIntentHelperInstance::AddPreferredPackage(
const std::string& package_name) {} const std::string& package_name) {}
void FakeIntentHelperInstance::AddPreferredApp(const std::string& package_name,
IntentFilter intent_filter,
mojom::IntentInfoPtr intent) {}
void FakeIntentHelperInstance::GetFileSizeDeprecated( void FakeIntentHelperInstance::GetFileSizeDeprecated(
const std::string& url, const std::string& url,
GetFileSizeDeprecatedCallback callback) {} GetFileSizeDeprecatedCallback callback) {}
......
...@@ -67,6 +67,10 @@ class FakeIntentHelperInstance : public mojom::IntentHelperInstance { ...@@ -67,6 +67,10 @@ class FakeIntentHelperInstance : public mojom::IntentHelperInstance {
void AddPreferredPackage(const std::string& package_name) override; void AddPreferredPackage(const std::string& package_name) override;
void AddPreferredApp(const std::string& package_name,
IntentFilter intent_filter,
mojom::IntentInfoPtr intent) override;
void GetFileSizeDeprecated(const std::string& url, void GetFileSizeDeprecated(const std::string& url,
GetFileSizeDeprecatedCallback callback) override; GetFileSizeDeprecatedCallback callback) override;
......
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