Commit 8f43824d authored by benwells@chromium.org's avatar benwells@chromium.org

Allow installing paid apps from the launcher search results.

Clicking on the install button for a paid app will now open the webstore
page for the app, where the user can sign in (if not signed in already)
and see the price of the app / buy it.

BUG=319024
TEST=Check installing paid and unpaid apps from the app launcher search
results.

Review URL: https://codereview.chromium.org/448543002

Cr-Commit-Position: refs/heads/master@{#289214}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289214 0039d316-1c4b-4281-b951-d872f2087c98
parent 5ec0d4fd
...@@ -28,6 +28,7 @@ const char kKeyResults[] = "results"; ...@@ -28,6 +28,7 @@ const char kKeyResults[] = "results";
const char kKeyId[] = "id"; const char kKeyId[] = "id";
const char kKeyLocalizedName[] = "localized_name"; const char kKeyLocalizedName[] = "localized_name";
const char kKeyIconUrl[] = "icon_url"; const char kKeyIconUrl[] = "icon_url";
const char kKeyIsPaid[] = "is_paid";
const char kKeyItemType[] = "item_type"; const char kKeyItemType[] = "item_type";
const char kPlatformAppType[] = "platform_app"; const char kPlatformAppType[] = "platform_app";
...@@ -152,9 +153,11 @@ scoped_ptr<ChromeSearchResult> WebstoreProvider::CreateResult( ...@@ -152,9 +153,11 @@ scoped_ptr<ChromeSearchResult> WebstoreProvider::CreateResult(
std::string app_id; std::string app_id;
std::string localized_name; std::string localized_name;
std::string icon_url_string; std::string icon_url_string;
bool is_paid = false;
if (!dict.GetString(kKeyId, &app_id) || if (!dict.GetString(kKeyId, &app_id) ||
!dict.GetString(kKeyLocalizedName, &localized_name) || !dict.GetString(kKeyLocalizedName, &localized_name) ||
!dict.GetString(kKeyIconUrl, &icon_url_string)) { !dict.GetString(kKeyIconUrl, &icon_url_string) ||
!dict.GetBoolean(kKeyIsPaid, &is_paid)) {
return result.Pass(); return result.Pass();
} }
...@@ -166,8 +169,13 @@ scoped_ptr<ChromeSearchResult> WebstoreProvider::CreateResult( ...@@ -166,8 +169,13 @@ scoped_ptr<ChromeSearchResult> WebstoreProvider::CreateResult(
dict.GetString(kKeyItemType, &item_type_string); dict.GetString(kKeyItemType, &item_type_string);
extensions::Manifest::Type item_type = ParseItemType(item_type_string); extensions::Manifest::Type item_type = ParseItemType(item_type_string);
result.reset(new WebstoreResult( result.reset(new WebstoreResult(profile_,
profile_, app_id, localized_name, icon_url, item_type, controller_)); app_id,
localized_name,
icon_url,
is_paid,
item_type,
controller_));
return result.Pass(); return result.Pass();
} }
......
...@@ -40,7 +40,8 @@ const char kOneResult[] = "{" ...@@ -40,7 +40,8 @@ const char kOneResult[] = "{"
"{" "{"
"\"id\": \"app1_id\"," "\"id\": \"app1_id\","
"\"localized_name\": \"app1 name\"," "\"localized_name\": \"app1 name\","
"\"icon_url\": \"http://host/icon\"" "\"icon_url\": \"http://host/icon\","
"\"is_paid\": false"
"}" "}"
"]}"; "]}";
...@@ -51,18 +52,21 @@ const char kThreeResults[] = "{" ...@@ -51,18 +52,21 @@ const char kThreeResults[] = "{"
"\"id\": \"app1_id\"," "\"id\": \"app1_id\","
"\"localized_name\": \"one\"," "\"localized_name\": \"one\","
"\"icon_url\": \"http://host/icon1\"," "\"icon_url\": \"http://host/icon1\","
"\"is_paid\": true,"
"\"item_type\": \"PLATFORM_APP\"" "\"item_type\": \"PLATFORM_APP\""
"}," "},"
"{" "{"
"\"id\": \"app2_id\"," "\"id\": \"app2_id\","
"\"localized_name\": \"two\"," "\"localized_name\": \"two\","
"\"icon_url\": \"http://host/icon2\"," "\"icon_url\": \"http://host/icon2\","
"\"is_paid\": false,"
"\"item_type\": \"HOSTED_APP\"" "\"item_type\": \"HOSTED_APP\""
"}," "},"
"{" "{"
"\"id\": \"app3_id\"," "\"id\": \"app3_id\","
"\"localized_name\": \"three\"," "\"localized_name\": \"three\","
"\"icon_url\": \"http://host/icon3\"," "\"icon_url\": \"http://host/icon3\","
"\"is_paid\": false,"
"\"item_type\": \"LEGACY_PACKAGED_APP\"" "\"item_type\": \"LEGACY_PACKAGED_APP\""
"}" "}"
"]}"; "]}";
...@@ -71,20 +75,22 @@ struct ParsedSearchResult { ...@@ -71,20 +75,22 @@ struct ParsedSearchResult {
const char* id; const char* id;
const char* title; const char* title;
const char* icon_url; const char* icon_url;
bool is_paid;
Manifest::Type item_type; Manifest::Type item_type;
size_t num_actions; size_t num_actions;
}; };
ParsedSearchResult kParsedOneResult[] = { ParsedSearchResult kParsedOneResult[] = {{"app1_id", "app1 name",
{ "app1_id", "app1 name", "http://host/icon", Manifest::TYPE_UNKNOWN, 1 } "http://host/icon", false,
}; Manifest::TYPE_UNKNOWN, 1}};
ParsedSearchResult kParsedThreeResults[] = { ParsedSearchResult kParsedThreeResults[] = {
{ "app1_id", "one", "http://host/icon1", Manifest::TYPE_PLATFORM_APP, 2 }, {"app1_id", "one", "http://host/icon1", true, Manifest::TYPE_PLATFORM_APP,
{ "app2_id", "two", "http://host/icon2", Manifest::TYPE_HOSTED_APP, 2 }, 1},
{ "app3_id", "three", "http://host/icon3", {"app2_id", "two", "http://host/icon2", false, Manifest::TYPE_HOSTED_APP,
Manifest::TYPE_LEGACY_PACKAGED_APP, 1 } 2},
}; {"app3_id", "three", "http://host/icon3", false,
Manifest::TYPE_LEGACY_PACKAGED_APP, 1}};
} // namespace } // namespace
...@@ -170,6 +176,7 @@ class WebstoreProviderTest : public InProcessBrowserTest { ...@@ -170,6 +176,7 @@ class WebstoreProviderTest : public InProcessBrowserTest {
EXPECT_EQ(expected_results[i].id, webstore_result->app_id()); EXPECT_EQ(expected_results[i].id, webstore_result->app_id());
EXPECT_EQ(expected_results[i].icon_url, EXPECT_EQ(expected_results[i].icon_url,
webstore_result->icon_url().spec()); webstore_result->icon_url().spec());
EXPECT_EQ(expected_results[i].is_paid, webstore_result->is_paid());
EXPECT_EQ(expected_results[i].item_type, webstore_result->item_type()); EXPECT_EQ(expected_results[i].item_type, webstore_result->item_type());
} }
} }
......
...@@ -67,12 +67,14 @@ WebstoreResult::WebstoreResult(Profile* profile, ...@@ -67,12 +67,14 @@ WebstoreResult::WebstoreResult(Profile* profile,
const std::string& app_id, const std::string& app_id,
const std::string& localized_name, const std::string& localized_name,
const GURL& icon_url, const GURL& icon_url,
bool is_paid,
extensions::Manifest::Type item_type, extensions::Manifest::Type item_type,
AppListControllerDelegate* controller) AppListControllerDelegate* controller)
: profile_(profile), : profile_(profile),
app_id_(app_id), app_id_(app_id),
localized_name_(localized_name), localized_name_(localized_name),
icon_url_(icon_url), icon_url_(icon_url),
is_paid_(is_paid),
item_type_(item_type), item_type_(item_type),
controller_(controller), controller_(controller),
install_tracker_(NULL), install_tracker_(NULL),
...@@ -117,6 +119,13 @@ void WebstoreResult::Open(int event_flags) { ...@@ -117,6 +119,13 @@ void WebstoreResult::Open(int event_flags) {
} }
void WebstoreResult::InvokeAction(int action_index, int event_flags) { void WebstoreResult::InvokeAction(int action_index, int event_flags) {
if (is_paid_) {
// Paid apps cannot be installed directly from the launcher. Instead, open
// the webstore page for the app.
Open(event_flags);
return;
}
StartInstall(action_index == kLaunchEphemeralAppAction); StartInstall(action_index == kLaunchEphemeralAppAction);
} }
...@@ -125,6 +134,7 @@ scoped_ptr<ChromeSearchResult> WebstoreResult::Duplicate() { ...@@ -125,6 +134,7 @@ scoped_ptr<ChromeSearchResult> WebstoreResult::Duplicate() {
app_id_, app_id_,
localized_name_, localized_name_,
icon_url_, icon_url_,
is_paid_,
item_type_, item_type_,
controller_)).Pass(); controller_)).Pass();
} }
...@@ -160,9 +170,9 @@ void WebstoreResult::UpdateActions() { ...@@ -160,9 +170,9 @@ void WebstoreResult::UpdateActions() {
l10n_util::GetStringUTF16(IDS_WEBSTORE_RESULT_INSTALL), l10n_util::GetStringUTF16(IDS_WEBSTORE_RESULT_INSTALL),
l10n_util::GetStringUTF16( l10n_util::GetStringUTF16(
IDS_EXTENSION_INLINE_INSTALL_PROMPT_TITLE))); IDS_EXTENSION_INLINE_INSTALL_PROMPT_TITLE)));
if ((item_type_ == extensions::Manifest::TYPE_PLATFORM_APP ||
if (item_type_ == extensions::Manifest::TYPE_PLATFORM_APP || item_type_ == extensions::Manifest::TYPE_HOSTED_APP) &&
item_type_ == extensions::Manifest::TYPE_HOSTED_APP) { !is_paid_) {
actions.push_back(Action( actions.push_back(Action(
l10n_util::GetStringUTF16(IDS_WEBSTORE_RESULT_LAUNCH), l10n_util::GetStringUTF16(IDS_WEBSTORE_RESULT_LAUNCH),
l10n_util::GetStringUTF16(IDS_WEBSTORE_RESULT_LAUNCH_APP_TOOLTIP))); l10n_util::GetStringUTF16(IDS_WEBSTORE_RESULT_LAUNCH_APP_TOOLTIP)));
......
...@@ -34,6 +34,7 @@ class WebstoreResult : public ChromeSearchResult, ...@@ -34,6 +34,7 @@ class WebstoreResult : public ChromeSearchResult,
const std::string& app_id, const std::string& app_id,
const std::string& localized_name, const std::string& localized_name,
const GURL& icon_url, const GURL& icon_url,
bool is_paid,
extensions::Manifest::Type item_type, extensions::Manifest::Type item_type,
AppListControllerDelegate* controller); AppListControllerDelegate* controller);
virtual ~WebstoreResult(); virtual ~WebstoreResult();
...@@ -41,6 +42,7 @@ class WebstoreResult : public ChromeSearchResult, ...@@ -41,6 +42,7 @@ class WebstoreResult : public ChromeSearchResult,
const std::string& app_id() const { return app_id_; } const std::string& app_id() const { return app_id_; }
const GURL& icon_url() const { return icon_url_; } const GURL& icon_url() const { return icon_url_; }
extensions::Manifest::Type item_type() const { return item_type_; } extensions::Manifest::Type item_type() const { return item_type_; }
bool is_paid() const { return is_paid_; }
// ChromeSearchResult overides: // ChromeSearchResult overides:
virtual void Open(int event_flags) OVERRIDE; virtual void Open(int event_flags) OVERRIDE;
...@@ -83,6 +85,7 @@ class WebstoreResult : public ChromeSearchResult, ...@@ -83,6 +85,7 @@ class WebstoreResult : public ChromeSearchResult,
const std::string app_id_; const std::string app_id_;
const std::string localized_name_; const std::string localized_name_;
const GURL icon_url_; const GURL icon_url_;
const bool is_paid_;
extensions::Manifest::Type item_type_; extensions::Manifest::Type item_type_;
gfx::ImageSkia icon_; gfx::ImageSkia icon_;
......
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