Skip to content

Commit

Permalink
Move intent_filter convert function to intent_filter_util.
Browse files Browse the repository at this point in the history
This CL is used to prepare for saving intent_filter to the AppStorage
file. Move intent_filter convert function to intent_filter_util from
preferred_apps_converter to share the convert functions for
Preferred_apps and AppStorage.

This CL is pure refactor and no function change.

BUG=1385932

Change-Id: I1f838686db38edfef0ae3d200f93b7c12bcaab06
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4957496
Reviewed-by: Dominick Ng <dominickn@chromium.org>
Commit-Queue: Nancy Wang <nancylingwang@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1212586}
  • Loading branch information
Nancy Wang authored and Chromium LUCI CQ committed Oct 20, 2023
1 parent 0f84618 commit 3038bf6
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 120 deletions.
111 changes: 111 additions & 0 deletions components/services/app_service/public/cpp/intent_filter_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "components/services/app_service/public/cpp/intent_filter_util.h"

#include "base/logging.h"
#include "base/strings/strcat.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
Expand Down Expand Up @@ -102,6 +103,11 @@ bool ConditionsHaveOverlap(const apps::ConditionPtr& condition1,

} // namespace

const char kValueKey[] = "value";
const char kMatchTypeKey[] = "match_type";
const char kConditionTypeKey[] = "condition_type";
const char kConditionValuesKey[] = "condition_values";

apps::IntentFilterPtr MakeIntentFilterForUrlScope(const GURL& url,
bool omit_port_for_testing) {
auto intent_filter = std::make_unique<apps::IntentFilter>();
Expand Down Expand Up @@ -312,4 +318,109 @@ std::set<std::string> GetSupportedLinksForAppManagement(
return supported_links;
}

base::Value::Dict ConvertConditionValueToDict(
const apps::ConditionValuePtr& condition_value) {
base::Value::Dict condition_value_dict;
condition_value_dict.Set(kValueKey, condition_value->value);
condition_value_dict.Set(kMatchTypeKey,
static_cast<int>(condition_value->match_type));
return condition_value_dict;
}

apps::ConditionValuePtr ConvertDictToConditionValue(
const base::Value::Dict& dict) {
const std::string* value_string = dict.FindString(kValueKey);
if (!value_string) {
DVLOG(0) << "Fail to parse condition value. Cannot find \"" << kValueKey
<< "\" key with string value.";
return nullptr;
}
const absl::optional<int> match_type = dict.FindInt(kMatchTypeKey);
if (!match_type) {
DVLOG(0) << "Fail to parse condition value. Cannot find \"" << kMatchTypeKey
<< "\" key with int value.";
return nullptr;
}

// We used to have a kNone=0 defined in the enum which we have merged with
// kLiteral. Some legacy storage may still have zero stored in serialized form
// as an integer which we can safely treat as kLiteral=1.
apps::PatternMatchType pattern_match_type = apps::PatternMatchType::kLiteral;
if (match_type > 0) {
pattern_match_type =
static_cast<apps::PatternMatchType>(match_type.value());
}
return std::make_unique<apps::ConditionValue>(*value_string,
pattern_match_type);
}

base::Value::Dict ConvertConditionToDict(const apps::ConditionPtr& condition) {
base::Value::Dict condition_dict;
condition_dict.Set(kConditionTypeKey,
static_cast<int>(condition->condition_type));
base::Value::List condition_values_list;
for (auto& condition_value : condition->condition_values) {
condition_values_list.Append(ConvertConditionValueToDict(condition_value));
}
condition_dict.Set(kConditionValuesKey, std::move(condition_values_list));
return condition_dict;
}

apps::ConditionPtr ConvertDictToCondition(const base::Value::Dict& dict) {
const absl::optional<int> condition_type = dict.FindInt(kConditionTypeKey);
if (!condition_type) {
DVLOG(0) << "Fail to parse condition. Cannot find \"" << kConditionTypeKey
<< "\" key with int value.";
return nullptr;
}

apps::ConditionValues condition_values;
const base::Value::List* values = dict.FindList(kConditionValuesKey);
if (!values) {
DVLOG(0) << "Fail to parse condition. Cannot find \"" << kConditionValuesKey
<< "\" key with list value.";
return nullptr;
}
for (const base::Value& condition_value : *values) {
auto parsed_condition_value =
apps_util::ConvertDictToConditionValue(condition_value.GetDict());
if (!parsed_condition_value) {
DVLOG(0) << "Fail to parse condition. Cannot parse condition values";
return nullptr;
}
condition_values.push_back(std::move(parsed_condition_value));
}

return std::make_unique<apps::Condition>(
static_cast<apps::ConditionType>(condition_type.value()),
std::move(condition_values));
}

base::Value::List ConvertIntentFilterToList(
const apps::IntentFilterPtr& intent_filter) {
base::Value::List intent_filter_list;
for (auto& condition : intent_filter->conditions) {
intent_filter_list.Append(apps_util::ConvertConditionToDict(condition));
}
return intent_filter_list;
}

apps::IntentFilterPtr ConvertValueToIntentFilter(const base::Value* value) {
if (!value || !value->is_list()) {
DVLOG(0) << "Fail to parse intent filter. Cannot find the conditions list.";
return nullptr;
}
auto intent_filter = std::make_unique<apps::IntentFilter>();
for (const base::Value& condition : value->GetList()) {
auto parsed_condition =
apps_util::ConvertDictToCondition(condition.GetDict());
if (!parsed_condition) {
DVLOG(0) << "Fail to parse intent filter. Cannot parse conditions.";
return nullptr;
}
intent_filter->conditions.push_back(std::move(parsed_condition));
}
return intent_filter;
}

} // namespace apps_util
51 changes: 51 additions & 0 deletions components/services/app_service/public/cpp/intent_filter_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,17 @@

#include <string>

#include "base/values.h"
#include "components/services/app_service/public/cpp/intent_filter.h"
#include "url/gurl.h"

namespace apps_util {

extern const char kValueKey[];
extern const char kMatchTypeKey[];
extern const char kConditionTypeKey[];
extern const char kConditionValuesKey[];

// Create intent filter for URL scope, with prefix matching only for the path.
// e.g. filter created for https://www.google.com/ will match any URL that
// started with https://www.google.com/*.
Expand Down Expand Up @@ -50,6 +56,51 @@ size_t IntentFilterUrlMatchLength(const apps::IntentFilterPtr& intent_filter,
std::set<std::string> GetSupportedLinksForAppManagement(
const apps::IntentFilterPtr& intent_filter);

// Converts `condition_value` to base::Value::Dict, e.g.:
// {
// "value": "xx",
// "match_type": 2,
// }
base::Value::Dict ConvertConditionValueToDict(
const apps::ConditionValuePtr& condition_value);

// Converts base::Value::Dict to ConditionValue.
apps::ConditionValuePtr ConvertDictToConditionValue(
const base::Value::Dict& dict);

// Converts `condition` to base::Value::Dict, e.g.:
// {
// "condition_type": 3,
// "condition_values":
// {{"value": "xx", "match_type": 2},
// {"value": "yy", "match_type": 3}},
// }
base::Value::Dict ConvertConditionToDict(const apps::ConditionPtr& condition);

// Converts base::Value::Dict to Condition.
apps::ConditionPtr ConvertDictToCondition(const base::Value::Dict& dict);

// Converts `IntentFilter` to base::Value::List, e.g.:
// {
// {
// "condition_type": 3,
// "condition_values":
// {{"value": "xx", "match_type": 2},
// {"value": "yy", "match_type": 3}},
// },
// {
// "condition_type": 2,
// "condition_values":
// {{"value": "aa", "match_type": 2},
// {"value": "bb", "match_type": 3}},
// },
// }
base::Value::List ConvertIntentFilterToList(
const apps::IntentFilterPtr& intent_filter);

// Converts base::Value to IntentFilter.
apps::IntentFilterPtr ConvertValueToIntentFilter(const base::Value* value);

} // namespace apps_util

#endif // COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_INTENT_FILTER_UTIL_H_
116 changes: 4 additions & 112 deletions components/services/app_service/public/cpp/preferred_apps_converter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,119 +18,10 @@ namespace {
constexpr int kVersionInitial = 0;
constexpr int kVersionSupportsSharing = 1;

base::Value::Dict ConvertConditionValueToDict(
const apps::ConditionValuePtr& condition_value) {
base::Value::Dict condition_value_dict;
condition_value_dict.Set(apps::kValueKey, condition_value->value);
condition_value_dict.Set(apps::kMatchTypeKey,
static_cast<int>(condition_value->match_type));
return condition_value_dict;
}

base::Value::Dict ConvertConditionToDict(const apps::ConditionPtr& condition) {
base::Value::Dict condition_dict;
condition_dict.Set(apps::kConditionTypeKey,
static_cast<int>(condition->condition_type));
base::Value::List condition_values_list;
for (auto& condition_value : condition->condition_values) {
condition_values_list.Append(ConvertConditionValueToDict(condition_value));
}
condition_dict.Set(apps::kConditionValuesKey,
std::move(condition_values_list));
return condition_dict;
}

base::Value::List ConvertIntentFilterToList(
const apps::IntentFilterPtr& intent_filter) {
base::Value::List intent_filter_list;
for (auto& condition : intent_filter->conditions) {
intent_filter_list.Append(ConvertConditionToDict(condition));
}
return intent_filter_list;
}

apps::ConditionValuePtr ParseDictToConditionValue(
const base::Value::Dict& dict) {
const std::string* value_string = dict.FindString(apps::kValueKey);
if (!value_string) {
DVLOG(0) << "Fail to parse condition value. Cannot find \""
<< apps::kValueKey << "\" key with string value.";
return nullptr;
}
const absl::optional<int> match_type = dict.FindInt(apps::kMatchTypeKey);
if (!match_type) {
DVLOG(0) << "Fail to parse condition value. Cannot find \""
<< apps::kMatchTypeKey << "\" key with int value.";
return nullptr;
}
// We used to have a kNone=0 defined in the enum which we have merged with
// kLiteral. Some legacy storage may still have zero stored in seralized form
// as an integer which we can safely treat as kLiteral=1.
apps::PatternMatchType pattern_match_type = apps::PatternMatchType::kLiteral;
if (match_type > 0) {
pattern_match_type =
static_cast<apps::PatternMatchType>(match_type.value());
}
return std::make_unique<apps::ConditionValue>(*value_string,
pattern_match_type);
}

apps::ConditionPtr ParseDictToCondition(const base::Value::Dict& dict) {
const absl::optional<int> condition_type =
dict.FindInt(apps::kConditionTypeKey);
if (!condition_type) {
DVLOG(0) << "Fail to parse condition. Cannot find \""
<< apps::kConditionTypeKey << "\" key with int value.";
return nullptr;
}

apps::ConditionValues condition_values;
const base::Value::List* values = dict.FindList(apps::kConditionValuesKey);
if (!values) {
DVLOG(0) << "Fail to parse condition. Cannot find \""
<< apps::kConditionValuesKey << "\" key with list value.";
return nullptr;
}
for (const base::Value& condition_value : *values) {
auto parsed_condition_value =
ParseDictToConditionValue(condition_value.GetDict());
if (!parsed_condition_value) {
DVLOG(0) << "Fail to parse condition. Cannot parse condition values";
return nullptr;
}
condition_values.push_back(std::move(parsed_condition_value));
}

return std::make_unique<apps::Condition>(
static_cast<apps::ConditionType>(condition_type.value()),
std::move(condition_values));
}

apps::IntentFilterPtr ParseValueToIntentFilter(const base::Value* value) {
if (!value || !value->is_list()) {
DVLOG(0) << "Fail to parse intent filter. Cannot find the conditions list.";
return nullptr;
}
auto intent_filter = std::make_unique<apps::IntentFilter>();
for (const base::Value& condition : value->GetList()) {
auto parsed_condition = ParseDictToCondition(condition.GetDict());
if (!parsed_condition) {
DVLOG(0) << "Fail to parse intent filter. Cannot parse conditions.";
return nullptr;
}
intent_filter->conditions.push_back(std::move(parsed_condition));
}
return intent_filter;
}

} // namespace

namespace apps {

const char kConditionTypeKey[] = "condition_type";
const char kConditionValuesKey[] = "condition_values";
const char kValueKey[] = "value";
const char kMatchTypeKey[] = "match_type";
const char kAppIdKey[] = "app_id";
const char kIntentFilterKey[] = "intent_filter";
const char kPreferredAppsKey[] = "preferred_apps";
Expand All @@ -143,8 +34,9 @@ base::Value ConvertPreferredAppsToValue(const PreferredApps& preferred_apps) {
base::Value::List preferred_apps_list;
for (auto& preferred_app : preferred_apps) {
base::Value::Dict preferred_app_dict;
preferred_app_dict.Set(kIntentFilterKey, ConvertIntentFilterToList(
preferred_app->intent_filter));
preferred_app_dict.Set(
kIntentFilterKey,
apps_util::ConvertIntentFilterToList(preferred_app->intent_filter));
preferred_app_dict.Set(kAppIdKey, preferred_app->app_id);
preferred_apps_list.Append(std::move(preferred_app_dict));
}
Expand Down Expand Up @@ -177,7 +69,7 @@ PreferredApps ParseValueToPreferredApps(
return PreferredApps();
}
auto parsed_intent_filter =
ParseValueToIntentFilter(entry.Find(kIntentFilterKey));
apps_util::ConvertValueToIntentFilter(entry.Find(kIntentFilterKey));
if (!parsed_intent_filter) {
DVLOG(0) << "Fail to parse condition value. Cannot parse intent filter.";
return PreferredApps();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@

namespace apps {

extern const char kConditionTypeKey[];
extern const char kConditionValuesKey[];
extern const char kValueKey[];
extern const char kMatchTypeKey[];
extern const char kAppIdKey[];
extern const char kIntentFilterKey[];
extern const char kPreferredAppsKey[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,17 @@ TEST_F(PreferredAppsConverterTest, ConvertSimpleEntry) {
(*converted_intent_filter)[i].GetDict();
auto& condition_values = condition->condition_values;
const base::Value::List* converted_condition_values =
converted_condition.FindList(apps::kConditionValuesKey);
converted_condition.FindList(apps_util::kConditionValuesKey);

EXPECT_EQ(static_cast<int>(condition->condition_type),
converted_condition.FindInt(apps::kConditionTypeKey));
converted_condition.FindInt(apps_util::kConditionTypeKey));
ASSERT_EQ(1u, converted_condition_values->size());
EXPECT_EQ(condition_values[0]->value,
*(*converted_condition_values)[0].GetDict().FindString(
apps::kValueKey));
apps_util::kValueKey));
EXPECT_EQ(static_cast<int>(condition_values[0]->match_type),
(*converted_condition_values)[0].GetDict().FindInt(
apps::kMatchTypeKey));
apps_util::kMatchTypeKey));
}

preferred_apps.Init();
Expand Down

0 comments on commit 3038bf6

Please sign in to comment.