Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(508)

Side by Side Diff: chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.cc

Issue 264743014: Move chrome.runtime to //extensions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase, renames Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.h"
6
7 #include "base/message_loop/message_loop.h"
8 #include "base/metrics/histogram.h"
9 #include "base/time/time.h"
10 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/extensions/extension_warning_service.h"
13 #include "chrome/browser/extensions/extension_warning_set.h"
14 #include "chrome/browser/extensions/updater/extension_updater.h"
15 #include "chrome/browser/omaha_query_params/omaha_query_params.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/browser_finder.h"
18 #include "chrome/browser/ui/browser_navigator.h"
19 #include "chrome/browser/ui/browser_window.h"
20 #include "content/public/browser/notification_service.h"
21 #include "extensions/browser/extension_system.h"
22
23 #if defined(OS_CHROMEOS)
24 #include "chrome/browser/chromeos/login/user_manager.h"
25 #include "chromeos/dbus/dbus_thread_manager.h"
26 #include "chromeos/dbus/power_manager_client.h"
27 #endif
28
29 using extensions::Extension;
30 using extensions::ExtensionSystem;
31 using extensions::ExtensionUpdater;
32
33 using extensions::core_api::runtime::GetPlatformInfo::Results::PlatformInfo;
34
35 namespace {
36
37 const char kUpdatesDisabledError[] = "Autoupdate is not enabled.";
38
39 const char kUpdateThrottled[] = "throttled";
40 const char kUpdateNotFound[] = "no_update";
41 const char kUpdateFound[] = "update_available";
42
43 // If an extension reloads itself within this many miliseconds of reloading
44 // itself, the reload is considered suspiciously fast.
45 const int kFastReloadTime = 10000;
46
47 // After this many suspiciously fast consecutive reloads, an extension will get
48 // disabled.
49 const int kFastReloadCount = 5;
50
51 } // namespace
52
53 ChromeRuntimeAPIDelegate::ChromeRuntimeAPIDelegate(
54 content::BrowserContext* context)
55 : browser_context_(context), registered_for_updates_(false) {
56 registrar_.Add(this,
57 chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND,
58 content::NotificationService::AllSources());
59 }
60
61 ChromeRuntimeAPIDelegate::~ChromeRuntimeAPIDelegate() {
62 }
63
64 void ChromeRuntimeAPIDelegate::AddUpdateObserver(
65 extensions::UpdateObserver* observer) {
66 registered_for_updates_ = true;
67 ExtensionSystem::Get(browser_context_)
68 ->extension_service()
69 ->AddUpdateObserver(observer);
70 }
71
72 void ChromeRuntimeAPIDelegate::RemoveUpdateObserver(
73 extensions::UpdateObserver* observer) {
74 if (registered_for_updates_) {
75 ExtensionSystem::Get(browser_context_)
76 ->extension_service()
77 ->RemoveUpdateObserver(observer);
78 }
79 }
80
81 base::Version ChromeRuntimeAPIDelegate::GetPreviousExtensionVersion(
82 const Extension* extension) {
83 // Get the previous version to check if this is an upgrade.
84 ExtensionService* service =
85 ExtensionSystem::Get(browser_context_)->extension_service();
86 const Extension* old = service->GetExtensionById(extension->id(), true);
87 if (old)
88 return *old->version();
89 return base::Version();
90 }
91
92 void ChromeRuntimeAPIDelegate::ReloadExtension(
93 const std::string& extension_id) {
94 std::pair<base::TimeTicks, int>& reload_info =
95 last_reload_time_[extension_id];
96 base::TimeTicks now = base::TimeTicks::Now();
97 if (reload_info.first.is_null() ||
98 (now - reload_info.first).InMilliseconds() > kFastReloadTime) {
99 reload_info.second = 0;
100 } else {
101 reload_info.second++;
102 }
103 if (!reload_info.first.is_null()) {
104 UMA_HISTOGRAM_LONG_TIMES("Extensions.RuntimeReloadTime",
105 now - reload_info.first);
106 }
107 UMA_HISTOGRAM_COUNTS_100("Extensions.RuntimeReloadFastCount",
108 reload_info.second);
109 reload_info.first = now;
110
111 ExtensionService* service =
112 ExtensionSystem::Get(browser_context_)->extension_service();
113 if (reload_info.second >= kFastReloadCount) {
114 // Unloading an extension clears all warnings, so first terminate the
115 // extension, and then add the warning. Since this is called from an
116 // extension function unloading the extension has to be done
117 // asynchronously. Fortunately PostTask guarentees FIFO order so just
118 // post both tasks.
119 base::MessageLoop::current()->PostTask(
120 FROM_HERE,
121 base::Bind(&ExtensionService::TerminateExtension,
122 service->AsWeakPtr(),
123 extension_id));
124 extensions::ExtensionWarningSet warnings;
125 warnings.insert(
126 extensions::ExtensionWarning::CreateReloadTooFrequentWarning(
127 extension_id));
128 base::MessageLoop::current()->PostTask(
129 FROM_HERE,
130 base::Bind(&extensions::ExtensionWarningService::NotifyWarningsOnUI,
131 browser_context_,
132 warnings));
133 } else {
134 // We can't call ReloadExtension directly, since when this method finishes
135 // it tries to decrease the reference count for the extension, which fails
136 // if the extension has already been reloaded; so instead we post a task.
137 base::MessageLoop::current()->PostTask(
138 FROM_HERE,
139 base::Bind(&ExtensionService::ReloadExtension,
140 service->AsWeakPtr(),
141 extension_id));
142 }
143 }
144
145 bool ChromeRuntimeAPIDelegate::CheckForUpdates(
146 const std::string& extension_id,
147 const UpdateCheckCallback& callback) {
148 ExtensionSystem* system = ExtensionSystem::Get(browser_context_);
149 ExtensionService* service = system->extension_service();
150 ExtensionUpdater* updater = service->updater();
151 if (!updater) {
152 return false;
153 }
154 if (!updater->CheckExtensionSoon(
155 extension_id,
156 base::Bind(&ChromeRuntimeAPIDelegate::UpdateCheckComplete,
157 base::Unretained(this),
158 extension_id))) {
159 base::MessageLoop::current()->PostTask(
160 FROM_HERE,
161 base::Bind(callback, UpdateCheckResult(true, kUpdateThrottled, "")));
162 } else {
163 UpdateCallbackList& callbacks = pending_update_checks_[extension_id];
164 callbacks.push_back(callback);
165 }
166 return true;
167 }
168
169 void ChromeRuntimeAPIDelegate::OpenURL(const GURL& uninstall_url) {
170 Profile* profile = Profile::FromBrowserContext(browser_context_);
171 Browser* browser =
172 chrome::FindLastActiveWithProfile(profile, chrome::GetActiveDesktop());
173 if (!browser)
174 browser =
175 new Browser(Browser::CreateParams(profile, chrome::GetActiveDesktop()));
176
177 chrome::NavigateParams params(
178 browser, uninstall_url, content::PAGE_TRANSITION_CLIENT_REDIRECT);
179 params.disposition = NEW_FOREGROUND_TAB;
180 params.user_gesture = false;
181 chrome::Navigate(&params);
182 }
183
184 bool ChromeRuntimeAPIDelegate::GetPlatformInfo(PlatformInfo* info) {
185 const char* os = chrome::OmahaQueryParams::GetOS();
186 if (strcmp(os, "mac") == 0) {
187 info->os = PlatformInfo::OS_MAC_;
188 } else if (strcmp(os, "win") == 0) {
189 info->os = PlatformInfo::OS_WIN_;
190 } else if (strcmp(os, "android") == 0) {
191 info->os = PlatformInfo::OS_ANDROID_;
192 } else if (strcmp(os, "cros") == 0) {
193 info->os = PlatformInfo::OS_CROS_;
194 } else if (strcmp(os, "linux") == 0) {
195 info->os = PlatformInfo::OS_LINUX_;
196 } else if (strcmp(os, "openbsd") == 0) {
197 info->os = PlatformInfo::OS_OPENBSD_;
198 } else {
199 NOTREACHED();
200 return false;
201 }
202
203 const char* arch = chrome::OmahaQueryParams::GetArch();
204 if (strcmp(arch, "arm") == 0) {
205 info->arch = PlatformInfo::ARCH_ARM;
206 } else if (strcmp(arch, "x86") == 0) {
207 info->arch = PlatformInfo::ARCH_X86_32;
208 } else if (strcmp(arch, "x64") == 0) {
209 info->arch = PlatformInfo::ARCH_X86_64;
210 } else {
211 NOTREACHED();
212 return false;
213 }
214
215 const char* nacl_arch = chrome::OmahaQueryParams::GetNaclArch();
216 if (strcmp(nacl_arch, "arm") == 0) {
217 info->nacl_arch = PlatformInfo::NACL_ARCH_ARM;
218 } else if (strcmp(nacl_arch, "x86-32") == 0) {
219 info->nacl_arch = PlatformInfo::NACL_ARCH_X86_32;
220 } else if (strcmp(nacl_arch, "x86-64") == 0) {
221 info->nacl_arch = PlatformInfo::NACL_ARCH_X86_64;
222 } else {
223 NOTREACHED();
224 return false;
225 }
226
227 return true;
228 }
229
230 bool ChromeRuntimeAPIDelegate::RestartDevice(std::string* error_message) {
231 #if defined(OS_CHROMEOS)
232 if (chromeos::UserManager::Get()->IsLoggedInAsKioskApp()) {
233 chromeos::DBusThreadManager::Get()
234 ->GetPowerManagerClient()
235 ->RequestRestart();
236 return true;
237 }
238 #endif
239 *error_message = "Function available only for ChromeOS kiosk mode.";
240 return false;
241 }
242
243 void ChromeRuntimeAPIDelegate::Observe(
244 int type,
245 const content::NotificationSource& source,
246 const content::NotificationDetails& details) {
247 DCHECK(type == chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND);
248 typedef const std::pair<std::string, Version> UpdateDetails;
249 const std::string& id = content::Details<UpdateDetails>(details)->first;
250 const Version& version = content::Details<UpdateDetails>(details)->second;
251 CallUpdateCallbacks(
252 id, UpdateCheckResult(true, kUpdateFound, version.GetString()));
253 }
254
255 void ChromeRuntimeAPIDelegate::UpdateCheckComplete(
256 const std::string& extension_id) {
257 ExtensionSystem* system = ExtensionSystem::Get(browser_context_);
258 ExtensionService* service = system->extension_service();
259 const Extension* update = service->GetPendingExtensionUpdate(extension_id);
260 if (update) {
261 CallUpdateCallbacks(
262 extension_id,
263 UpdateCheckResult(true, kUpdateFound, update->VersionString()));
264 } else {
265 CallUpdateCallbacks(extension_id,
266 UpdateCheckResult(true, kUpdateNotFound, ""));
267 }
268 }
269
270 void ChromeRuntimeAPIDelegate::CallUpdateCallbacks(
271 const std::string& extension_id,
272 const UpdateCheckResult& result) {
273 UpdateCallbackList callbacks = pending_update_checks_[extension_id];
274 pending_update_checks_.erase(extension_id);
275 for (UpdateCallbackList::const_iterator iter = callbacks.begin();
276 iter != callbacks.end();
277 ++iter) {
278 const UpdateCheckCallback& callback = *iter;
279 callback.Run(result);
280 }
281 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698