OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/webstore_standalone_installer.h" | 5 #include "chrome/browser/extensions/webstore_standalone_installer.h" |
6 | 6 |
7 #include "base/values.h" | 7 #include "base/values.h" |
8 #include "base/version.h" | 8 #include "base/version.h" |
9 #include "chrome/browser/extensions/crx_installer.h" | 9 #include "chrome/browser/extensions/crx_installer.h" |
10 #include "chrome/browser/extensions/extension_install_prompt.h" | 10 #include "chrome/browser/extensions/extension_install_prompt.h" |
11 #include "chrome/browser/extensions/extension_install_ui.h" | 11 #include "chrome/browser/extensions/extension_install_ui.h" |
12 #include "chrome/browser/extensions/extension_service.h" | 12 #include "chrome/browser/extensions/extension_service.h" |
| 13 #include "chrome/browser/extensions/install_tracker.h" |
13 #include "chrome/browser/extensions/webstore_data_fetcher.h" | 14 #include "chrome/browser/extensions/webstore_data_fetcher.h" |
14 #include "chrome/browser/profiles/profile.h" | 15 #include "chrome/browser/profiles/profile.h" |
15 #include "content/public/browser/web_contents.h" | 16 #include "content/public/browser/web_contents.h" |
16 #include "extensions/browser/extension_prefs.h" | 17 #include "extensions/browser/extension_prefs.h" |
17 #include "extensions/browser/extension_registry.h" | 18 #include "extensions/browser/extension_registry.h" |
18 #include "extensions/browser/extension_system.h" | 19 #include "extensions/browser/extension_system.h" |
19 #include "extensions/browser/extension_util.h" | 20 #include "extensions/browser/extension_util.h" |
20 #include "extensions/common/extension.h" | 21 #include "extensions/common/extension.h" |
21 #include "url/gurl.h" | 22 #include "url/gurl.h" |
22 | 23 |
23 using content::WebContents; | 24 using content::WebContents; |
24 | 25 |
25 namespace extensions { | 26 namespace extensions { |
26 | 27 |
27 const char kInvalidWebstoreItemId[] = "Invalid Chrome Web Store item ID"; | 28 const char kInvalidWebstoreItemId[] = "Invalid Chrome Web Store item ID"; |
28 const char kWebstoreRequestError[] = | 29 const char kWebstoreRequestError[] = |
29 "Could not fetch data from the Chrome Web Store"; | 30 "Could not fetch data from the Chrome Web Store"; |
30 const char kInvalidWebstoreResponseError[] = "Invalid Chrome Web Store reponse"; | 31 const char kInvalidWebstoreResponseError[] = "Invalid Chrome Web Store reponse"; |
31 const char kInvalidManifestError[] = "Invalid manifest"; | 32 const char kInvalidManifestError[] = "Invalid manifest"; |
32 const char kUserCancelledError[] = "User cancelled install"; | 33 const char kUserCancelledError[] = "User cancelled install"; |
33 const char kExtensionIsBlacklisted[] = "Extension is blacklisted"; | 34 const char kExtensionIsBlacklisted[] = "Extension is blacklisted"; |
| 35 const char kInstallInProgressError[] = "An install is already in progress"; |
| 36 const char kLaunchInProgressError[] = "A launch is already in progress"; |
34 | 37 |
35 WebstoreStandaloneInstaller::WebstoreStandaloneInstaller( | 38 WebstoreStandaloneInstaller::WebstoreStandaloneInstaller( |
36 const std::string& webstore_item_id, | 39 const std::string& webstore_item_id, |
37 Profile* profile, | 40 Profile* profile, |
38 const Callback& callback) | 41 const Callback& callback) |
39 : id_(webstore_item_id), | 42 : id_(webstore_item_id), |
40 callback_(callback), | 43 callback_(callback), |
41 profile_(profile), | 44 profile_(profile), |
42 install_source_(WebstoreInstaller::INSTALL_SOURCE_INLINE), | 45 install_source_(WebstoreInstaller::INSTALL_SOURCE_INLINE), |
43 show_user_count_(true), | 46 show_user_count_(true), |
44 average_rating_(0.0), | 47 average_rating_(0.0), |
45 rating_count_(0) { | 48 rating_count_(0) { |
46 } | 49 } |
47 | 50 |
48 void WebstoreStandaloneInstaller::BeginInstall() { | 51 void WebstoreStandaloneInstaller::BeginInstall() { |
49 // Add a ref to keep this alive for WebstoreDataFetcher. | 52 // Add a ref to keep this alive for WebstoreDataFetcher. |
50 // All code paths from here eventually lead to either CompleteInstall or | 53 // All code paths from here eventually lead to either CompleteInstall or |
51 // AbortInstall, which both release this ref. | 54 // AbortInstall, which both release this ref. |
52 AddRef(); | 55 AddRef(); |
53 | 56 |
54 if (!Extension::IdIsValid(id_)) { | 57 if (!Extension::IdIsValid(id_)) { |
55 CompleteInstall(webstore_install::INVALID_ID, kInvalidWebstoreItemId); | 58 CompleteInstall(webstore_install::INVALID_ID, kInvalidWebstoreItemId); |
56 return; | 59 return; |
57 } | 60 } |
58 | 61 |
| 62 webstore_install::Result result = webstore_install::UNKNOWN_ERROR; |
| 63 std::string error; |
| 64 if (!EnsureUniqueInstall(&result, &error)) { |
| 65 CompleteInstall(result, error); |
| 66 return; |
| 67 } |
| 68 |
59 // Use the requesting page as the referrer both since that is more correct | 69 // Use the requesting page as the referrer both since that is more correct |
60 // (it is the page that caused this request to happen) and so that we can | 70 // (it is the page that caused this request to happen) and so that we can |
61 // track top sites that trigger inline install requests. | 71 // track top sites that trigger inline install requests. |
62 webstore_data_fetcher_.reset(new WebstoreDataFetcher( | 72 webstore_data_fetcher_.reset(new WebstoreDataFetcher( |
63 this, | 73 this, |
64 profile_->GetRequestContext(), | 74 profile_->GetRequestContext(), |
65 GetRequestorURL(), | 75 GetRequestorURL(), |
66 id_)); | 76 id_)); |
67 webstore_data_fetcher_->Start(); | 77 webstore_data_fetcher_->Start(); |
68 } | 78 } |
69 | 79 |
70 // | 80 // |
71 // Private interface implementation. | 81 // Private interface implementation. |
72 // | 82 // |
73 | 83 |
74 WebstoreStandaloneInstaller::~WebstoreStandaloneInstaller() { | 84 WebstoreStandaloneInstaller::~WebstoreStandaloneInstaller() { |
75 } | 85 } |
76 | 86 |
77 void WebstoreStandaloneInstaller::AbortInstall() { | 87 void WebstoreStandaloneInstaller::AbortInstall() { |
78 callback_.Reset(); | 88 callback_.Reset(); |
79 // Abort any in-progress fetches. | 89 // Abort any in-progress fetches. |
80 if (webstore_data_fetcher_) { | 90 if (webstore_data_fetcher_) { |
81 webstore_data_fetcher_.reset(); | 91 webstore_data_fetcher_.reset(); |
82 Release(); // Matches the AddRef in BeginInstall. | 92 Release(); // Matches the AddRef in BeginInstall. |
83 } | 93 } |
84 } | 94 } |
85 | 95 |
| 96 bool WebstoreStandaloneInstaller::EnsureUniqueInstall( |
| 97 webstore_install::Result* reason, |
| 98 std::string* error) { |
| 99 InstallTracker* tracker = InstallTracker::Get(profile_); |
| 100 DCHECK(tracker); |
| 101 |
| 102 const ActiveInstallData* existing_install_data = |
| 103 tracker->GetActiveInstall(id_); |
| 104 if (existing_install_data) { |
| 105 if (existing_install_data->is_ephemeral) { |
| 106 *reason = webstore_install::LAUNCH_IN_PROGRESS; |
| 107 *error = kLaunchInProgressError; |
| 108 } else { |
| 109 *reason = webstore_install::INSTALL_IN_PROGRESS; |
| 110 *error = kInstallInProgressError; |
| 111 } |
| 112 return false; |
| 113 } |
| 114 |
| 115 ActiveInstallData install_data(id_); |
| 116 InitInstallData(&install_data); |
| 117 scoped_active_install_.reset(new ScopedActiveInstall(profile_, install_data)); |
| 118 return true; |
| 119 } |
| 120 |
86 void WebstoreStandaloneInstaller::CompleteInstall( | 121 void WebstoreStandaloneInstaller::CompleteInstall( |
87 webstore_install::Result result, | 122 webstore_install::Result result, |
88 const std::string& error) { | 123 const std::string& error) { |
89 if (!callback_.is_null()) | 124 if (!callback_.is_null()) |
90 callback_.Run(result == webstore_install::SUCCESS, error); | 125 callback_.Run(result == webstore_install::SUCCESS, error); |
91 Release(); // Matches the AddRef in BeginInstall. | 126 Release(); // Matches the AddRef in BeginInstall. |
92 } | 127 } |
93 | 128 |
94 void WebstoreStandaloneInstaller::ProceedWithInstallPrompt() { | 129 void WebstoreStandaloneInstaller::ProceedWithInstallPrompt() { |
95 install_prompt_ = CreateInstallPrompt(); | 130 install_prompt_ = CreateInstallPrompt(); |
(...skipping 18 matching lines...) Expand all Loading... |
114 manifest_.get(), | 149 manifest_.get(), |
115 Extension::REQUIRE_KEY | Extension::FROM_WEBSTORE, | 150 Extension::REQUIRE_KEY | Extension::FROM_WEBSTORE, |
116 id_, | 151 id_, |
117 localized_name_, | 152 localized_name_, |
118 localized_description_, | 153 localized_description_, |
119 &error); | 154 &error); |
120 } | 155 } |
121 return localized_extension_for_display_.get(); | 156 return localized_extension_for_display_.get(); |
122 } | 157 } |
123 | 158 |
| 159 void WebstoreStandaloneInstaller::InitInstallData( |
| 160 ActiveInstallData* install_data) const { |
| 161 // Default implementation sets no properties. |
| 162 } |
| 163 |
124 void WebstoreStandaloneInstaller::OnManifestParsed() { | 164 void WebstoreStandaloneInstaller::OnManifestParsed() { |
125 ProceedWithInstallPrompt(); | 165 ProceedWithInstallPrompt(); |
126 } | 166 } |
127 | 167 |
128 scoped_ptr<ExtensionInstallPrompt> | 168 scoped_ptr<ExtensionInstallPrompt> |
129 WebstoreStandaloneInstaller::CreateInstallUI() { | 169 WebstoreStandaloneInstaller::CreateInstallUI() { |
130 return make_scoped_ptr(new ExtensionInstallPrompt(GetWebContents())); | 170 return make_scoped_ptr(new ExtensionInstallPrompt(GetWebContents())); |
131 } | 171 } |
132 | 172 |
133 scoped_ptr<WebstoreInstaller::Approval> | 173 scoped_ptr<WebstoreInstaller::Approval> |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 void WebstoreStandaloneInstaller::OnWebStoreDataFetcherDone() { | 429 void WebstoreStandaloneInstaller::OnWebStoreDataFetcherDone() { |
390 // An instance of this class is passed in as a delegate for the | 430 // An instance of this class is passed in as a delegate for the |
391 // WebstoreInstallHelper, ExtensionInstallPrompt and WebstoreInstaller, and | 431 // WebstoreInstallHelper, ExtensionInstallPrompt and WebstoreInstaller, and |
392 // therefore needs to remain alive until they are done. Clear the webstore | 432 // therefore needs to remain alive until they are done. Clear the webstore |
393 // data fetcher to avoid calling Release in AbortInstall while any of these | 433 // data fetcher to avoid calling Release in AbortInstall while any of these |
394 // operations are in progress. | 434 // operations are in progress. |
395 webstore_data_fetcher_.reset(); | 435 webstore_data_fetcher_.reset(); |
396 } | 436 } |
397 | 437 |
398 } // namespace extensions | 438 } // namespace extensions |
OLD | NEW |