1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/browser/api/runtime/runtime_api.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <utility> 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/lazy_instance.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/logging.h" 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/metrics/histogram.h" 13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/values.h" 14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/version.h" 15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/public/browser/browser_context.h" 167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/child_process_security_policy.h" 177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/notification_service.h" 187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/render_process_host.h" 197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/render_view_host.h" 20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/browser/api/runtime/runtime_api_delegate.h" 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/event_router.h" 2223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "extensions/browser/extension_host.h" 23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/browser/extension_prefs.h" 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_registry.h" 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h" 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/browser/extension_util.h" 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/extensions_browser_client.h" 281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "extensions/browser/lazy_background_task_queue.h" 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/notification_types.h" 30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/process_manager.h" 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/common/api/runtime.h" 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "extensions/common/error_utils.h" 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/background_info.h" 35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "extensions/common/manifest_handlers/shared_module_info.h" 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/isolated_context.h" 377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using content::BrowserContext; 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace runtime = core_api::runtime; 443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kNoBackgroundPageError[] = "You do not have a background page."; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPageLoadError[] = "Background page failed to load."; 49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const char kInstallId[] = "id"; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInstallReason[] = "reason"; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInstallReasonChromeUpdate[] = "chrome_update"; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInstallReasonUpdate[] = "update"; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInstallReasonInstall[] = "install"; 54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const char kInstallReasonSharedModuleUpdate[] = "shared_module_update"; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInstallPreviousVersion[] = "previousVersion"; 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kInvalidUrlError[] = "Invalid URL."; 57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kPlatformInfoUnavailable[] = "Platform information unavailable."; 58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kUpdatesDisabledError[] = "Autoupdate is not enabled."; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// A preference key storing the url loaded when an extension is uninstalled. 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kUninstallUrl[] = "uninstall_url"; 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// The name of the directory to be returned by getPackageDirectoryEntry. This 657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// particular value does not matter to user code, but is chosen for consistency 667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// with the equivalent Pepper API. 677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const char kPackageDirectoryPath[] = "crxfs"; 687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DispatchOnStartupEventImpl(BrowserContext* browser_context, 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& extension_id, 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool first_call, 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionHost* host) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A NULL host from the LazyBackgroundTaskQueue means the page failed to 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // load. Give up. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!host && !first_call) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Don't send onStartup events to incognito browser contexts. 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (browser_context->IsOffTheRecord()) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ExtensionsBrowserClient::Get()->IsShuttingDown() || 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !ExtensionsBrowserClient::Get()->IsValidContext(browser_context)) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionSystem* system = ExtensionSystem::Get(browser_context); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!system) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this is a persistent background page, we want to wait for it to load 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (it might not be ready, since this is startup). But only enqueue once. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If it fails to load the first time, don't bother trying again. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionRegistry::Get(browser_context)->enabled_extensions().GetByID( 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_id); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (extension && BackgroundInfo::HasPersistentBackgroundPage(extension) && 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) first_call && 97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) system->lazy_background_task_queue()->ShouldEnqueueTask(browser_context, 98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) extension)) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system->lazy_background_task_queue()->AddPendingTask( 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser_context, 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) extension_id, 102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind( 103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &DispatchOnStartupEventImpl, browser_context, extension_id, false)); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<base::ListValue> event_args(new base::ListValue()); 108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<Event> event( 109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new Event(runtime::OnStartup::kEventName, event_args.Pass())); 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) system->event_router()->DispatchEventToExtension(extension_id, event.Pass()); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SetUninstallURL(ExtensionPrefs* prefs, 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& extension_id, 115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& url_string) { 116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) prefs->UpdateExtensionPref( 117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) extension_id, kUninstallUrl, new base::StringValue(url_string)); 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string GetUninstallURL(ExtensionPrefs* prefs, 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& extension_id) { 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string url_string; 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) prefs->ReadPrefAsString(extension_id, kUninstallUrl, &url_string); 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return url_string; 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static base::LazyInstance<BrowserContextKeyedAPIFactory<RuntimeAPI> > 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) g_factory = LAZY_INSTANCE_INITIALIZER; 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BrowserContextKeyedAPIFactory<RuntimeAPI>* RuntimeAPI::GetFactoryInstance() { 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return g_factory.Pointer(); 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)RuntimeAPI::RuntimeAPI(content::BrowserContext* context) 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : browser_context_(context), 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dispatch_chrome_updated_event_(false), 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_registry_observer_(this) { 143010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) registrar_.Add(this, 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, 145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) content::Source<BrowserContext>(context)); 1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); 147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) delegate_ = ExtensionsBrowserClient::Get()->CreateRuntimeAPIDelegate( 149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser_context_); 150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Check if registered events are up-to-date. We can only do this once 152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // per browser context, since it updates internal state when called. 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) dispatch_chrome_updated_event_ = 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionsBrowserClient::Get()->DidVersionUpdate(browser_context_); 155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)RuntimeAPI::~RuntimeAPI() { 158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) delegate_->RemoveUpdateObserver(this); 159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RuntimeAPI::Observe(int type, 162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const content::NotificationSource& source, 163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const content::NotificationDetails& details) { 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, type); 165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // We're done restarting Chrome after an update. 166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) dispatch_chrome_updated_event_ = false; 167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) delegate_->AddUpdateObserver(this); 1694ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch 1704ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // RuntimeAPI is redirected in incognito, so |browser_context_| is never 1714ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // incognito. We don't observe incognito ProcessManagers but that is OK 1724ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // because we don't send onStartup events to incognito browser contexts. 1734ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch DCHECK(!browser_context_->IsOffTheRecord()); 1744ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // Some tests use partially constructed Profiles without a process manager. 175010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ExtensionSystem* extension_system = ExtensionSystem::Get(browser_context_); 1764ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch if (extension_system->process_manager()) 1774ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch extension_system->process_manager()->AddObserver(this); 178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void RuntimeAPI::OnExtensionLoaded(content::BrowserContext* browser_context, 1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const Extension* extension) { 182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!dispatch_chrome_updated_event_) 183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Dispatch the onInstalled event with reason "chrome_update". 186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::MessageLoop::current()->PostTask( 187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FROM_HERE, 188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&RuntimeEventRouter::DispatchOnInstalledEvent, 189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser_context_, 190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extension->id(), 191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Version(), 192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) true)); 193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void RuntimeAPI::OnExtensionWillBeInstalled( 1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::BrowserContext* browser_context, 1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const Extension* extension, 1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool is_update, 1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool from_ephemeral, 2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& old_name) { 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Ephemeral apps are not considered to be installed and do not receive 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the onInstalled() event. 203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (util::IsEphemeralApp(extension->id(), browser_context_)) 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 206010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Version old_version = delegate_->GetPreviousExtensionVersion(extension); 207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Dispatch the onInstalled event. 209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::MessageLoop::current()->PostTask( 210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FROM_HERE, 211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&RuntimeEventRouter::DispatchOnInstalledEvent, 212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser_context_, 213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extension->id(), 214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) old_version, 215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) false)); 216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void RuntimeAPI::OnExtensionUninstalled( 2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::BrowserContext* browser_context, 2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const Extension* extension, 2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UninstallReason reason) { 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Ephemeral apps are not considered to be installed, so the uninstall URL 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // is not invoked when they are removed. 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (util::IsEphemeralApp(extension->id(), browser_context_)) 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RuntimeEventRouter::OnExtensionUninstalled( 2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) browser_context_, extension->id(), reason); 229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2314ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdochvoid RuntimeAPI::Shutdown() { 2324ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // ExtensionSystem deletes its ProcessManager during the Shutdown() phase, so 2334ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // the observer must be removed here and not in the RuntimeAPI destructor. 2344ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch ProcessManager* process_manager = 2354ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch ExtensionSystem::Get(browser_context_)->process_manager(); 2364ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // Some tests use partially constructed Profiles without a process manager. 2374ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch if (process_manager) 2384ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch process_manager->RemoveObserver(this); 2394ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch} 2404ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch 241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void RuntimeAPI::OnAppUpdateAvailable(const Extension* extension) { 242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) RuntimeEventRouter::DispatchOnUpdateAvailableEvent( 243010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser_context_, extension->id(), extension->manifest()->value()); 244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void RuntimeAPI::OnChromeUpdateAvailable() { 247010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RuntimeEventRouter::DispatchOnBrowserUpdateAvailableEvent(browser_context_); 248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2504ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdochvoid RuntimeAPI::OnBackgroundHostStartup(const Extension* extension) { 2514ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch RuntimeEventRouter::DispatchOnStartupEvent(browser_context_, extension->id()); 2524ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch} 2534ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch 254010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void RuntimeAPI::ReloadExtension(const std::string& extension_id) { 255010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) delegate_->ReloadExtension(extension_id); 256010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 257010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 258010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool RuntimeAPI::CheckForUpdates( 259010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::string& extension_id, 260010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const RuntimeAPIDelegate::UpdateCheckCallback& callback) { 261010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return delegate_->CheckForUpdates(extension_id, callback); 262010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 263010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void RuntimeAPI::OpenURL(const GURL& update_url) { 265010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) delegate_->OpenURL(update_url); 266010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 267010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool RuntimeAPI::GetPlatformInfo(runtime::PlatformInfo* info) { 269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return delegate_->GetPlatformInfo(info); 270010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 271010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 272010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool RuntimeAPI::RestartDevice(std::string* error_message) { 273010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return delegate_->RestartDevice(error_message); 2740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 2750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RuntimeEventRouter::DispatchOnStartupEvent( 280010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::BrowserContext* context, 281010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::string& extension_id) { 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DispatchOnStartupEventImpl(context, extension_id, true, NULL); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RuntimeEventRouter::DispatchOnInstalledEvent( 287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::BrowserContext* context, 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Version& old_version, 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool chrome_updated) { 291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!ExtensionsBrowserClient::Get()->IsValidContext(context)) 292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionSystem* system = ExtensionSystem::Get(context); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!system) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<base::ListValue> event_args(new base::ListValue()); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::DictionaryValue* info = new base::DictionaryValue(); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_args->Append(info); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_version.IsValid()) { 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->SetString(kInstallReason, kInstallReasonUpdate); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->SetString(kInstallPreviousVersion, old_version.GetString()); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (chrome_updated) { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->SetString(kInstallReason, kInstallReasonChromeUpdate); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->SetString(kInstallReason, kInstallReasonInstall); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(system->event_router()); 309010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<Event> event( 310010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new Event(runtime::OnInstalled::kEventName, event_args.Pass())); 311ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch system->event_router()->DispatchEventWithLazyListener(extension_id, 312ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch event.Pass()); 313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (old_version.IsValid()) { 315f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const Extension* extension = 316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ExtensionRegistry::Get(context)->enabled_extensions().GetByID( 317f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) extension_id); 318f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (extension && SharedModuleInfo::IsSharedModule(extension)) { 319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<ExtensionSet> dependents = 320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) system->GetDependentExtensions(extension); 321f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (ExtensionSet::const_iterator i = dependents->begin(); 322f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) i != dependents->end(); 323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) i++) { 324f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<base::ListValue> sm_event_args(new base::ListValue()); 325f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::DictionaryValue* sm_info = new base::DictionaryValue(); 326f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sm_event_args->Append(sm_info); 327f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sm_info->SetString(kInstallReason, kInstallReasonSharedModuleUpdate); 328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sm_info->SetString(kInstallPreviousVersion, old_version.GetString()); 329f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sm_info->SetString(kInstallId, extension_id); 330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<Event> sm_event( 331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) new Event(runtime::OnInstalled::kEventName, sm_event_args.Pass())); 332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) system->event_router()->DispatchEventWithLazyListener((*i)->id(), 333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sm_event.Pass()); 334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RuntimeEventRouter::DispatchOnUpdateAvailableEvent( 341010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::BrowserContext* context, 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const base::DictionaryValue* manifest) { 344010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ExtensionSystem* system = ExtensionSystem::Get(context); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!system) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<base::ListValue> args(new base::ListValue); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->Append(manifest->DeepCopy()); 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(system->event_router()); 351010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<Event> event( 352010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new Event(runtime::OnUpdateAvailable::kEventName, args.Pass())); 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) system->event_router()->DispatchEventToExtension(extension_id, event.Pass()); 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RuntimeEventRouter::DispatchOnBrowserUpdateAvailableEvent( 358010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::BrowserContext* context) { 359010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ExtensionSystem* system = ExtensionSystem::Get(context); 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!system) 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<base::ListValue> args(new base::ListValue); 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(system->event_router()); 365010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<Event> event( 366010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new Event(runtime::OnBrowserUpdateAvailable::kEventName, args.Pass())); 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) system->event_router()->BroadcastEvent(event.Pass()); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// static 371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid RuntimeEventRouter::DispatchOnRestartRequiredEvent( 372010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::BrowserContext* context, 373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& app_id, 374010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) core_api::runtime::OnRestartRequired::Reason reason) { 375010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ExtensionSystem* system = ExtensionSystem::Get(context); 376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!system) 377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<Event> event( 3803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) new Event(runtime::OnRestartRequired::kEventName, 381010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) core_api::runtime::OnRestartRequired::Create(reason))); 382eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(system->event_router()); 384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch system->event_router()->DispatchEventToExtension(app_id, event.Pass()); 385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// static 38890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void RuntimeEventRouter::OnExtensionUninstalled( 389010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::BrowserContext* context, 3905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& extension_id, 3915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UninstallReason reason) { 3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!(reason == UNINSTALL_REASON_USER_INITIATED || 3935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) reason == UNINSTALL_REASON_MANAGEMENT_API)) { 3945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 3955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 397010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GURL uninstall_url( 398010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GetUninstallURL(ExtensionPrefs::Get(context), extension_id)); 39990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 40090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (uninstall_url.is_empty()) 40190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 40290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 403010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RuntimeAPI::GetFactoryInstance()->Get(context)->OpenURL(uninstall_url); 40490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 40590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 406010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ExtensionFunction::ResponseAction RuntimeGetBackgroundPageFunction::Run() { 407010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ExtensionSystem* system = ExtensionSystem::Get(browser_context()); 408010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ExtensionHost* host = 409010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) system->process_manager()->GetBackgroundHostForExtension(extension_id()); 410010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (system->lazy_background_task_queue()->ShouldEnqueueTask(browser_context(), 4115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension())) { 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) system->lazy_background_task_queue()->AddPendingTask( 413010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser_context(), 4141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) extension_id(), 4151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::Bind(&RuntimeGetBackgroundPageFunction::OnPageLoaded, this)); 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (host) { 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnPageLoaded(host); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 419010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return RespondNow(Error(kNoBackgroundPageError)); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 422010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return RespondLater(); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RuntimeGetBackgroundPageFunction::OnPageLoaded(ExtensionHost* host) { 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host) { 427010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Respond(NoArguments()); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 429010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Respond(Error(kPageLoadError)); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 433010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ExtensionFunction::ResponseAction RuntimeSetUninstallURLFunction::Run() { 43490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string url_string; 43590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &url_string)); 43690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 43790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GURL url(url_string); 43890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!url.is_valid()) { 439010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return RespondNow( 440010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Error(ErrorUtils::FormatErrorMessage(kInvalidUrlError, url_string))); 44190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetUninstallURL( 443010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ExtensionPrefs::Get(browser_context()), extension_id(), url_string); 444010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return RespondNow(NoArguments()); 44590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 44690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 447010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ExtensionFunction::ResponseAction RuntimeReloadFunction::Run() { 448010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RuntimeAPI::GetFactoryInstance()->Get(browser_context())->ReloadExtension( 4490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch extension_id()); 450010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return RespondNow(NoArguments()); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 453010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ExtensionFunction::ResponseAction RuntimeRequestUpdateCheckFunction::Run() { 454010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!RuntimeAPI::GetFactoryInstance() 455010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ->Get(browser_context()) 456010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ->CheckForUpdates( 457010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) extension_id(), 458010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&RuntimeRequestUpdateCheckFunction::CheckComplete, 459010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) this))) { 460010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return RespondNow(Error(kUpdatesDisabledError)); 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 462010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return RespondLater(); 463010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 464010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 465010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void RuntimeRequestUpdateCheckFunction::CheckComplete( 466010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const RuntimeAPIDelegate::UpdateCheckResult& result) { 467010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (result.success) { 468010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::DictionaryValue* details = new base::DictionaryValue; 469010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) details->SetString("version", result.version); 470cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Respond(TwoArguments(new base::StringValue(result.response), details)); 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 472cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // HMM(kalman): Why does !success not imply Error()? 473cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Respond(OneArgument(new base::StringValue(result.response))); 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 477010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ExtensionFunction::ResponseAction RuntimeRestartFunction::Run() { 478010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string message; 479010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool result = 480010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RuntimeAPI::GetFactoryInstance()->Get(browser_context())->RestartDevice( 481010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &message); 482010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!result) { 483010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return RespondNow(Error(message)); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 485010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return RespondNow(NoArguments()); 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 488010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ExtensionFunction::ResponseAction RuntimeGetPlatformInfoFunction::Run() { 489010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) runtime::PlatformInfo info; 490010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!RuntimeAPI::GetFactoryInstance() 491010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ->Get(browser_context()) 492010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ->GetPlatformInfo(&info)) { 493010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return RespondNow(Error(kPlatformInfoUnavailable)); 494b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 495cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return RespondNow( 496cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ArgumentList(runtime::GetPlatformInfo::Results::Create(info))); 497b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 498b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 499010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ExtensionFunction::ResponseAction 500010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)RuntimeGetPackageDirectoryEntryFunction::Run() { 50103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::IsolatedContext* isolated_context = 50203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::IsolatedContext::GetInstance(); 5037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(isolated_context); 5047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::string relative_path = kPackageDirectoryPath; 5067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::FilePath path = extension_->path(); 5077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::string filesystem_id = isolated_context->RegisterFileSystemForPath( 50803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::kFileSystemTypeNativeLocal, std::string(), path, &relative_path); 5097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int renderer_id = render_view_host_->GetProcess()->GetID(); 5117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) content::ChildProcessSecurityPolicy* policy = 5127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) content::ChildProcessSecurityPolicy::GetInstance(); 5137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) policy->GrantReadFileSystem(renderer_id, filesystem_id); 514eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::DictionaryValue* dict = new base::DictionaryValue(); 5157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) dict->SetString("fileSystemId", filesystem_id); 5167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) dict->SetString("baseName", relative_path); 517cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return RespondNow(OneArgument(dict)); 5187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 5197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 520010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} // namespace extensions 521