developer_private_api.cc revision f2477e01787aa58f445919b809d89e252beef54f
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 3// found in the LICENSE file. 4 5#include "chrome/browser/extensions/api/developer_private/developer_private_api.h" 6 7#include "apps/app_load_service.h" 8#include "apps/app_restore_service.h" 9#include "apps/saved_files_service.h" 10#include "apps/shell_window.h" 11#include "apps/shell_window_registry.h" 12#include "base/base64.h" 13#include "base/command_line.h" 14#include "base/file_util.h" 15#include "base/files/file_enumerator.h" 16#include "base/i18n/file_util_icu.h" 17#include "base/strings/string_number_conversions.h" 18#include "base/strings/utf_string_conversions.h" 19#include "base/values.h" 20#include "chrome/browser/chrome_notification_types.h" 21#include "chrome/browser/devtools/devtools_window.h" 22#include "chrome/browser/extensions/api/developer_private/developer_private_api_factory.h" 23#include "chrome/browser/extensions/api/developer_private/entry_picker.h" 24#include "chrome/browser/extensions/api/extension_action/extension_action_api.h" 25#include "chrome/browser/extensions/devtools_util.h" 26#include "chrome/browser/extensions/extension_disabled_ui.h" 27#include "chrome/browser/extensions/extension_error_reporter.h" 28#include "chrome/browser/extensions/extension_service.h" 29#include "chrome/browser/extensions/extension_system.h" 30#include "chrome/browser/extensions/extension_util.h" 31#include "chrome/browser/extensions/unpacked_installer.h" 32#include "chrome/browser/extensions/updater/extension_updater.h" 33#include "chrome/browser/platform_util.h" 34#include "chrome/browser/profiles/profile.h" 35#include "chrome/browser/sync_file_system/drive_backend_v1/drive_file_sync_service.h" 36#include "chrome/browser/sync_file_system/syncable_file_system_util.h" 37#include "chrome/browser/ui/chrome_select_file_policy.h" 38#include "chrome/browser/ui/webui/extensions/extension_icon_source.h" 39#include "chrome/common/extensions/api/developer_private.h" 40#include "chrome/common/extensions/manifest_handlers/app_launch_info.h" 41#include "chrome/common/extensions/manifest_handlers/icons_handler.h" 42#include "chrome/common/extensions/manifest_url_handler.h" 43#include "chrome/common/url_constants.h" 44#include "content/public/browser/browser_thread.h" 45#include "content/public/browser/notification_service.h" 46#include "content/public/browser/render_process_host.h" 47#include "content/public/browser/render_view_host.h" 48#include "content/public/browser/site_instance.h" 49#include "content/public/browser/storage_partition.h" 50#include "content/public/browser/web_contents.h" 51#include "extensions/browser/management_policy.h" 52#include "extensions/browser/view_type_utils.h" 53#include "extensions/common/constants.h" 54#include "extensions/common/extension_resource.h" 55#include "extensions/common/install_warning.h" 56#include "extensions/common/manifest_handlers/background_info.h" 57#include "extensions/common/manifest_handlers/incognito_info.h" 58#include "extensions/common/manifest_handlers/offline_enabled_info.h" 59#include "extensions/common/switches.h" 60#include "grit/chromium_strings.h" 61#include "grit/generated_resources.h" 62#include "grit/theme_resources.h" 63#include "net/base/net_util.h" 64#include "ui/base/l10n/l10n_util.h" 65#include "ui/base/resource/resource_bundle.h" 66#include "ui/base/webui/web_ui_util.h" 67#include "webkit/browser/fileapi/file_system_context.h" 68#include "webkit/browser/fileapi/file_system_operation.h" 69#include "webkit/browser/fileapi/file_system_operation_runner.h" 70#include "webkit/common/blob/shareable_file_reference.h" 71 72using apps::ShellWindow; 73using apps::ShellWindowRegistry; 74using content::RenderViewHost; 75 76namespace extensions { 77 78namespace developer_private = api::developer_private; 79 80namespace { 81 82const base::FilePath::CharType kUnpackedAppsFolder[] 83 = FILE_PATH_LITERAL("apps_target"); 84 85ExtensionUpdater* GetExtensionUpdater(Profile* profile) { 86 return profile->GetExtensionService()->updater(); 87} 88 89GURL GetImageURLFromData(std::string contents) { 90 std::string contents_base64; 91 if (!base::Base64Encode(contents, &contents_base64)) 92 return GURL(); 93 94 // TODO(dvh): make use of chrome::kDataScheme. Filed as crbug/297301. 95 const char kDataURLPrefix[] = "data:image;base64,"; 96 return GURL(kDataURLPrefix + contents_base64); 97} 98 99GURL GetDefaultImageURL(developer_private::ItemType type) { 100 int icon_resource_id; 101 switch (type) { 102 case developer::ITEM_TYPE_LEGACY_PACKAGED_APP: 103 case developer::ITEM_TYPE_HOSTED_APP: 104 case developer::ITEM_TYPE_PACKAGED_APP: 105 icon_resource_id = IDR_APP_DEFAULT_ICON; 106 break; 107 default: 108 icon_resource_id = IDR_EXTENSION_DEFAULT_ICON; 109 break; 110 } 111 112 return GetImageURLFromData( 113 ResourceBundle::GetSharedInstance().GetRawDataResourceForScale( 114 icon_resource_id, ui::SCALE_FACTOR_100P).as_string()); 115} 116 117// TODO(dvh): This code should be refactored and moved to 118// extensions::ImageLoader. Also a resize should be performed to avoid 119// potential huge URLs: crbug/297298. 120GURL ToDataURL(const base::FilePath& path, developer_private::ItemType type) { 121 std::string contents; 122 if (path.empty() || !base::ReadFileToString(path, &contents)) 123 return GetDefaultImageURL(type); 124 125 return GetImageURLFromData(contents); 126} 127 128bool ValidateFolderName(const base::FilePath::StringType& name) { 129 base::FilePath::StringType name_sanitized(name); 130 file_util::ReplaceIllegalCharactersInPath(&name_sanitized, '_'); 131 return name == name_sanitized; 132} 133 134const Extension* GetExtensionByPath(const ExtensionSet* extensions, 135 const base::FilePath& path) { 136 base::FilePath extension_path = base::MakeAbsoluteFilePath(path); 137 for (ExtensionSet::const_iterator iter = extensions->begin(); 138 iter != extensions->end(); ++iter) { 139 if ((*iter)->path() == extension_path) 140 return iter->get(); 141 } 142 return NULL; 143} 144 145std::string GetExtensionID(const RenderViewHost* render_view_host) { 146 if (!render_view_host->GetSiteInstance()) 147 return std::string(); 148 149 return render_view_host->GetSiteInstance()->GetSiteURL().host(); 150} 151 152} // namespace 153 154namespace AllowFileAccess = api::developer_private::AllowFileAccess; 155namespace AllowIncognito = api::developer_private::AllowIncognito; 156namespace ChoosePath = api::developer_private::ChoosePath; 157namespace Enable = api::developer_private::Enable; 158namespace GetItemsInfo = api::developer_private::GetItemsInfo; 159namespace Inspect = api::developer_private::Inspect; 160namespace PackDirectory = api::developer_private::PackDirectory; 161namespace Reload = api::developer_private::Reload; 162 163DeveloperPrivateAPI* DeveloperPrivateAPI::Get(Profile* profile) { 164 return DeveloperPrivateAPIFactory::GetForProfile(profile); 165} 166 167DeveloperPrivateAPI::DeveloperPrivateAPI(Profile* profile) : profile_(profile) { 168 RegisterNotifications(); 169} 170 171DeveloperPrivateEventRouter::DeveloperPrivateEventRouter(Profile* profile) 172: profile_(profile) { 173 int types[] = { 174 chrome::NOTIFICATION_EXTENSION_INSTALLED, 175 chrome::NOTIFICATION_EXTENSION_UNINSTALLED, 176 chrome::NOTIFICATION_EXTENSION_LOADED, 177 chrome::NOTIFICATION_EXTENSION_UNLOADED, 178 chrome::NOTIFICATION_EXTENSION_VIEW_REGISTERED, 179 chrome::NOTIFICATION_EXTENSION_VIEW_UNREGISTERED 180 }; 181 182 CHECK(registrar_.IsEmpty()); 183 for (size_t i = 0; i < arraysize(types); ++i) { 184 registrar_.Add(this, 185 types[i], 186 content::Source<Profile>(profile_)); 187 } 188} 189 190 191DeveloperPrivateEventRouter::~DeveloperPrivateEventRouter() {} 192 193void DeveloperPrivateEventRouter::Observe( 194 int type, 195 const content::NotificationSource& source, 196 const content::NotificationDetails& details) { 197 const char* event_name = NULL; 198 Profile* profile = content::Source<Profile>(source).ptr(); 199 CHECK(profile); 200 CHECK(profile_->IsSameProfile(profile)); 201 developer::EventData event_data; 202 const Extension* extension = NULL; 203 204 switch (type) { 205 case chrome::NOTIFICATION_EXTENSION_INSTALLED: 206 event_data.event_type = developer::EVENT_TYPE_INSTALLED; 207 extension = 208 content::Details<const InstalledExtensionInfo>(details)->extension; 209 break; 210 case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: 211 event_data.event_type = developer::EVENT_TYPE_UNINSTALLED; 212 extension = content::Details<const Extension>(details).ptr(); 213 break; 214 case chrome::NOTIFICATION_EXTENSION_LOADED: 215 event_data.event_type = developer::EVENT_TYPE_LOADED; 216 extension = content::Details<const Extension>(details).ptr(); 217 break; 218 case chrome::NOTIFICATION_EXTENSION_UNLOADED: 219 event_data.event_type = developer::EVENT_TYPE_UNLOADED; 220 extension = 221 content::Details<const UnloadedExtensionInfo>(details)->extension; 222 break; 223 case chrome::NOTIFICATION_EXTENSION_VIEW_UNREGISTERED: 224 event_data.event_type = developer::EVENT_TYPE_VIEW_UNREGISTERED; 225 event_data.item_id = GetExtensionID( 226 content::Details<const RenderViewHost>(details).ptr()); 227 break; 228 case chrome::NOTIFICATION_EXTENSION_VIEW_REGISTERED: 229 event_data.event_type = developer::EVENT_TYPE_VIEW_REGISTERED; 230 event_data.item_id = GetExtensionID( 231 content::Details<const RenderViewHost>(details).ptr()); 232 break; 233 default: 234 NOTREACHED(); 235 return; 236 } 237 238 if (extension) 239 event_data.item_id = extension->id(); 240 241 scoped_ptr<ListValue> args(new ListValue()); 242 args->Append(event_data.ToValue().release()); 243 244 event_name = developer_private::OnItemStateChanged::kEventName; 245 scoped_ptr<Event> event(new Event(event_name, args.Pass())); 246 ExtensionSystem::Get(profile)->event_router()->BroadcastEvent(event.Pass()); 247} 248 249void DeveloperPrivateAPI::SetLastUnpackedDirectory(const base::FilePath& path) { 250 last_unpacked_directory_ = path; 251} 252 253void DeveloperPrivateAPI::RegisterNotifications() { 254 ExtensionSystem::Get(profile_)->event_router()->RegisterObserver( 255 this, developer_private::OnItemStateChanged::kEventName); 256} 257 258DeveloperPrivateAPI::~DeveloperPrivateAPI() {} 259 260void DeveloperPrivateAPI::Shutdown() {} 261 262void DeveloperPrivateAPI::OnListenerAdded( 263 const EventListenerInfo& details) { 264 if (!developer_private_event_router_) 265 developer_private_event_router_.reset( 266 new DeveloperPrivateEventRouter(profile_)); 267} 268 269void DeveloperPrivateAPI::OnListenerRemoved( 270 const EventListenerInfo& details) { 271 if (!ExtensionSystem::Get(profile_)->event_router()->HasEventListener( 272 developer_private::OnItemStateChanged::kEventName)) 273 developer_private_event_router_.reset(NULL); 274} 275 276namespace api { 277 278bool DeveloperPrivateAutoUpdateFunction::RunImpl() { 279 ExtensionUpdater* updater = GetExtensionUpdater(GetProfile()); 280 if (updater) 281 updater->CheckNow(ExtensionUpdater::CheckParams()); 282 SetResult(new base::FundamentalValue(true)); 283 return true; 284} 285 286DeveloperPrivateAutoUpdateFunction::~DeveloperPrivateAutoUpdateFunction() {} 287 288scoped_ptr<developer::ItemInfo> 289 DeveloperPrivateGetItemsInfoFunction::CreateItemInfo( 290 const Extension& item, 291 bool item_is_enabled) { 292 scoped_ptr<developer::ItemInfo> info(new developer::ItemInfo()); 293 294 ExtensionSystem* system = ExtensionSystem::Get(GetProfile()); 295 ExtensionService* service = GetProfile()->GetExtensionService(); 296 297 info->id = item.id(); 298 info->name = item.name(); 299 info->enabled = service->IsExtensionEnabled(info->id); 300 info->offline_enabled = OfflineEnabledInfo::IsOfflineEnabled(&item); 301 info->version = item.VersionString(); 302 info->description = item.description(); 303 304 if (item.is_app()) { 305 if (item.is_legacy_packaged_app()) 306 info->type = developer::ITEM_TYPE_LEGACY_PACKAGED_APP; 307 else if (item.is_hosted_app()) 308 info->type = developer::ITEM_TYPE_HOSTED_APP; 309 else if (item.is_platform_app()) 310 info->type = developer::ITEM_TYPE_PACKAGED_APP; 311 else 312 NOTREACHED(); 313 } else if (item.is_theme()) { 314 info->type = developer::ITEM_TYPE_THEME; 315 } else if (item.is_extension()) { 316 info->type = developer::ITEM_TYPE_EXTENSION; 317 } else { 318 NOTREACHED(); 319 } 320 321 if (Manifest::IsUnpackedLocation(item.location())) { 322 info->path.reset( 323 new std::string(UTF16ToUTF8(item.path().LossyDisplayName()))); 324 for (std::vector<extensions::InstallWarning>::const_iterator it = 325 item.install_warnings().begin(); 326 it != item.install_warnings().end(); ++it) { 327 developer::InstallWarning* warning = new developer::InstallWarning(); 328 warning->message = it->message; 329 info->install_warnings.push_back(make_linked_ptr(warning)); 330 } 331 } 332 333 info->incognito_enabled = 334 extension_util::IsIncognitoEnabled(item.id(),service); 335 info->wants_file_access = item.wants_file_access(); 336 info->allow_file_access = extension_util::AllowFileAccess(&item, service); 337 info->allow_reload = Manifest::IsUnpackedLocation(item.location()); 338 info->is_unpacked = Manifest::IsUnpackedLocation(item.location()); 339 info->terminated = service->terminated_extensions()->Contains(item.id()); 340 info->allow_incognito = item.can_be_incognito_enabled(); 341 342 info->homepage_url.reset(new std::string( 343 ManifestURL::GetHomepageURL(&item).spec())); 344 if (!ManifestURL::GetOptionsPage(&item).is_empty()) { 345 info->options_url.reset( 346 new std::string(ManifestURL::GetOptionsPage(&item).spec())); 347 } 348 349 if (!ManifestURL::GetUpdateURL(&item).is_empty()) { 350 info->update_url.reset( 351 new std::string(ManifestURL::GetUpdateURL(&item).spec())); 352 } 353 354 if (item.is_app()) { 355 info->app_launch_url.reset(new std::string( 356 extensions::AppLaunchInfo::GetFullLaunchURL(&item).spec())); 357 } 358 359 info->may_disable = system->management_policy()-> 360 UserMayModifySettings(&item, NULL); 361 info->is_app = item.is_app(); 362 info->views = GetInspectablePagesForExtension(&item, item_is_enabled); 363 364 return info.Pass(); 365} 366 367void DeveloperPrivateGetItemsInfoFunction::GetIconsOnFileThread( 368 ItemInfoList item_list, 369 const std::map<std::string, ExtensionResource> idToIcon) { 370 for (ItemInfoList::iterator iter = item_list.begin(); 371 iter != item_list.end(); ++iter) { 372 developer_private::ItemInfo* info = iter->get(); 373 std::map<std::string, ExtensionResource>::const_iterator resource_ptr 374 = idToIcon.find(info->id); 375 if (resource_ptr != idToIcon.end()) { 376 info->icon_url = 377 ToDataURL(resource_ptr->second.GetFilePath(), info->type).spec(); 378 } 379 } 380 381 results_ = developer::GetItemsInfo::Results::Create(item_list); 382 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 383 base::Bind(&DeveloperPrivateGetItemsInfoFunction::SendResponse, 384 this, 385 true)); 386} 387 388void DeveloperPrivateGetItemsInfoFunction:: 389 GetInspectablePagesForExtensionProcess( 390 const Extension* extension, 391 const std::set<content::RenderViewHost*>& views, 392 ItemInspectViewList* result) { 393 bool has_generated_background_page = 394 BackgroundInfo::HasGeneratedBackgroundPage(extension); 395 for (std::set<content::RenderViewHost*>::const_iterator iter = views.begin(); 396 iter != views.end(); ++iter) { 397 content::RenderViewHost* host = *iter; 398 content::WebContents* web_contents = 399 content::WebContents::FromRenderViewHost(host); 400 ViewType host_type = GetViewType(web_contents); 401 if (VIEW_TYPE_EXTENSION_POPUP == host_type || 402 VIEW_TYPE_EXTENSION_DIALOG == host_type) 403 continue; 404 405 content::RenderProcessHost* process = host->GetProcess(); 406 bool is_background_page = 407 (web_contents->GetURL() == BackgroundInfo::GetBackgroundURL(extension)); 408 result->push_back(constructInspectView( 409 web_contents->GetURL(), 410 process->GetID(), 411 host->GetRoutingID(), 412 process->GetBrowserContext()->IsOffTheRecord(), 413 is_background_page && has_generated_background_page)); 414 } 415} 416 417void DeveloperPrivateGetItemsInfoFunction:: 418 GetShellWindowPagesForExtensionProfile( 419 const Extension* extension, 420 ItemInspectViewList* result) { 421 ShellWindowRegistry* registry = ShellWindowRegistry::Get(GetProfile()); 422 if (!registry) return; 423 424 const ShellWindowRegistry::ShellWindowList windows = 425 registry->GetShellWindowsForApp(extension->id()); 426 427 bool has_generated_background_page = 428 BackgroundInfo::HasGeneratedBackgroundPage(extension); 429 for (ShellWindowRegistry::const_iterator it = windows.begin(); 430 it != windows.end(); ++it) { 431 content::WebContents* web_contents = (*it)->web_contents(); 432 RenderViewHost* host = web_contents->GetRenderViewHost(); 433 content::RenderProcessHost* process = host->GetProcess(); 434 bool is_background_page = 435 (web_contents->GetURL() == BackgroundInfo::GetBackgroundURL(extension)); 436 result->push_back(constructInspectView( 437 web_contents->GetURL(), 438 process->GetID(), 439 host->GetRoutingID(), 440 process->GetBrowserContext()->IsOffTheRecord(), 441 is_background_page && has_generated_background_page)); 442 } 443} 444 445linked_ptr<developer::ItemInspectView> DeveloperPrivateGetItemsInfoFunction:: 446 constructInspectView( 447 const GURL& url, 448 int render_process_id, 449 int render_view_id, 450 bool incognito, 451 bool generated_background_page) { 452 linked_ptr<developer::ItemInspectView> view(new developer::ItemInspectView()); 453 454 if (url.scheme() == kExtensionScheme) { 455 // No leading slash. 456 view->path = url.path().substr(1); 457 } else { 458 // For live pages, use the full URL. 459 view->path = url.spec(); 460 } 461 462 view->render_process_id = render_process_id; 463 view->render_view_id = render_view_id; 464 view->incognito = incognito; 465 view->generated_background_page = generated_background_page; 466 return view; 467} 468 469ItemInspectViewList DeveloperPrivateGetItemsInfoFunction:: 470 GetInspectablePagesForExtension( 471 const Extension* extension, 472 bool extension_is_enabled) { 473 474 ItemInspectViewList result; 475 // Get the extension process's active views. 476 extensions::ProcessManager* process_manager = 477 ExtensionSystem::Get(GetProfile())->process_manager(); 478 GetInspectablePagesForExtensionProcess( 479 extension, 480 process_manager->GetRenderViewHostsForExtension(extension->id()), 481 &result); 482 483 // Get shell window views 484 GetShellWindowPagesForExtensionProfile(extension, &result); 485 486 // Include a link to start the lazy background page, if applicable. 487 if (BackgroundInfo::HasLazyBackgroundPage(extension) && 488 extension_is_enabled && 489 !process_manager->GetBackgroundHostForExtension(extension->id())) { 490 result.push_back(constructInspectView( 491 BackgroundInfo::GetBackgroundURL(extension), 492 -1, 493 -1, 494 false, 495 BackgroundInfo::HasGeneratedBackgroundPage(extension))); 496 } 497 498 ExtensionService* service = GetProfile()->GetExtensionService(); 499 // Repeat for the incognito process, if applicable. Don't try to get 500 // shell windows for incognito process. 501 if (service->profile()->HasOffTheRecordProfile() && 502 IncognitoInfo::IsSplitMode(extension)) { 503 process_manager = ExtensionSystem::Get( 504 service->profile()->GetOffTheRecordProfile())->process_manager(); 505 GetInspectablePagesForExtensionProcess( 506 extension, 507 process_manager->GetRenderViewHostsForExtension(extension->id()), 508 &result); 509 510 if (BackgroundInfo::HasLazyBackgroundPage(extension) && 511 extension_is_enabled && 512 !process_manager->GetBackgroundHostForExtension(extension->id())) { 513 result.push_back(constructInspectView( 514 BackgroundInfo::GetBackgroundURL(extension), 515 -1, 516 -1, 517 false, 518 BackgroundInfo::HasGeneratedBackgroundPage(extension))); 519 } 520 } 521 522 return result; 523} 524 525bool DeveloperPrivateGetItemsInfoFunction::RunImpl() { 526 scoped_ptr<developer::GetItemsInfo::Params> params( 527 developer::GetItemsInfo::Params::Create(*args_)); 528 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); 529 530 bool include_disabled = params->include_disabled; 531 bool include_terminated = params->include_terminated; 532 533 ExtensionSet items; 534 535 ExtensionService* service = GetProfile()->GetExtensionService(); 536 537 items.InsertAll(*service->extensions()); 538 539 if (include_disabled) { 540 items.InsertAll(*service->disabled_extensions()); 541 } 542 543 if (include_terminated) { 544 items.InsertAll(*service->terminated_extensions()); 545 } 546 547 std::map<std::string, ExtensionResource> id_to_icon; 548 ItemInfoList item_list; 549 550 for (ExtensionSet::const_iterator iter = items.begin(); 551 iter != items.end(); ++iter) { 552 const Extension& item = *iter->get(); 553 554 ExtensionResource item_resource = 555 IconsInfo::GetIconResource(&item, 556 extension_misc::EXTENSION_ICON_MEDIUM, 557 ExtensionIconSet::MATCH_BIGGER); 558 id_to_icon[item.id()] = item_resource; 559 560 // Don't show component extensions and invisible apps. 561 if (item.ShouldNotBeVisible()) 562 continue; 563 564 item_list.push_back(make_linked_ptr<developer::ItemInfo>( 565 CreateItemInfo( 566 item, service->IsExtensionEnabled(item.id())).release())); 567 } 568 569 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, 570 base::Bind(&DeveloperPrivateGetItemsInfoFunction::GetIconsOnFileThread, 571 this, 572 item_list, 573 id_to_icon)); 574 575 return true; 576} 577 578DeveloperPrivateGetItemsInfoFunction::~DeveloperPrivateGetItemsInfoFunction() {} 579 580bool DeveloperPrivateAllowFileAccessFunction::RunImpl() { 581 scoped_ptr<AllowFileAccess::Params> params( 582 AllowFileAccess::Params::Create(*args_)); 583 EXTENSION_FUNCTION_VALIDATE(params.get()); 584 585 EXTENSION_FUNCTION_VALIDATE(user_gesture_); 586 587 ExtensionSystem* system = ExtensionSystem::Get(GetProfile()); 588 ManagementPolicy* management_policy = system->management_policy(); 589 ExtensionService* service = GetProfile()->GetExtensionService(); 590 const Extension* extension = service->GetInstalledExtension(params->item_id); 591 bool result = true; 592 593 if (!extension) { 594 result = false; 595 } else if (!management_policy->UserMayModifySettings(extension, NULL)) { 596 LOG(ERROR) << "Attempt to change allow file access of an extension that " 597 << "non-usermanagable was made. Extension id : " 598 << extension->id(); 599 result = false; 600 } else { 601 extension_util::SetAllowFileAccess(extension, service, params->allow); 602 result = true; 603 } 604 605 return result; 606} 607 608DeveloperPrivateAllowFileAccessFunction:: 609 ~DeveloperPrivateAllowFileAccessFunction() {} 610 611bool DeveloperPrivateAllowIncognitoFunction::RunImpl() { 612 scoped_ptr<AllowIncognito::Params> params( 613 AllowIncognito::Params::Create(*args_)); 614 EXTENSION_FUNCTION_VALIDATE(params.get()); 615 616 ExtensionService* service = GetProfile()->GetExtensionService(); 617 const Extension* extension = service->GetInstalledExtension(params->item_id); 618 bool result = true; 619 620 if (!extension) 621 result = false; 622 else 623 extension_util::SetIsIncognitoEnabled( 624 extension->id(),service, params->allow); 625 626 return result; 627} 628 629DeveloperPrivateAllowIncognitoFunction:: 630 ~DeveloperPrivateAllowIncognitoFunction() {} 631 632 633bool DeveloperPrivateReloadFunction::RunImpl() { 634 scoped_ptr<Reload::Params> params(Reload::Params::Create(*args_)); 635 EXTENSION_FUNCTION_VALIDATE(params.get()); 636 637 ExtensionService* service = GetProfile()->GetExtensionService(); 638 CHECK(!params->item_id.empty()); 639 service->ReloadExtension(params->item_id); 640 return true; 641} 642 643bool DeveloperPrivateShowPermissionsDialogFunction::RunImpl() { 644 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &extension_id_)); 645 ExtensionService* service = GetProfile()->GetExtensionService(); 646 CHECK(!extension_id_.empty()); 647 ShellWindowRegistry* registry = ShellWindowRegistry::Get(GetProfile()); 648 DCHECK(registry); 649 ShellWindow* shell_window = registry->GetShellWindowForRenderViewHost( 650 render_view_host()); 651 prompt_.reset(new ExtensionInstallPrompt(shell_window->web_contents())); 652 const Extension* extension = service->GetInstalledExtension(extension_id_); 653 654 if (!extension) 655 return false; 656 657 // Released by InstallUIAbort or InstallUIProceed. 658 AddRef(); 659 std::vector<base::FilePath> retained_file_paths; 660 if (extension->HasAPIPermission(extensions::APIPermission::kFileSystem)) { 661 std::vector<apps::SavedFileEntry> retained_file_entries = 662 apps::SavedFilesService::Get(GetProfile()) 663 ->GetAllFileEntries(extension_id_); 664 for (size_t i = 0; i < retained_file_entries.size(); i++) { 665 retained_file_paths.push_back(retained_file_entries[i].path); 666 } 667 } 668 prompt_->ReviewPermissions(this, extension, retained_file_paths); 669 return true; 670} 671 672DeveloperPrivateReloadFunction::~DeveloperPrivateReloadFunction() {} 673 674// This is called when the user clicks "Revoke File Access." 675void DeveloperPrivateShowPermissionsDialogFunction::InstallUIProceed() { 676 apps::SavedFilesService::Get(GetProfile()) 677 ->ClearQueue(GetProfile()->GetExtensionService()->GetExtensionById( 678 extension_id_, true)); 679 if (apps::AppRestoreService::Get(GetProfile()) 680 ->IsAppRestorable(extension_id_)) 681 apps::AppLoadService::Get(GetProfile())->RestartApplication(extension_id_); 682 SendResponse(true); 683 Release(); 684} 685 686void DeveloperPrivateShowPermissionsDialogFunction::InstallUIAbort( 687 bool user_initiated) { 688 SendResponse(true); 689 Release(); 690} 691 692DeveloperPrivateShowPermissionsDialogFunction:: 693 DeveloperPrivateShowPermissionsDialogFunction() {} 694 695DeveloperPrivateShowPermissionsDialogFunction:: 696 ~DeveloperPrivateShowPermissionsDialogFunction() {} 697 698DeveloperPrivateEnableFunction::DeveloperPrivateEnableFunction() {} 699 700bool DeveloperPrivateEnableFunction::RunImpl() { 701 scoped_ptr<Enable::Params> params(Enable::Params::Create(*args_)); 702 EXTENSION_FUNCTION_VALIDATE(params.get()); 703 704 std::string extension_id = params->item_id; 705 706 ExtensionSystem* system = ExtensionSystem::Get(GetProfile()); 707 ManagementPolicy* policy = system->management_policy(); 708 ExtensionService* service = GetProfile()->GetExtensionService(); 709 710 const Extension* extension = service->GetInstalledExtension(extension_id); 711 if (!extension) { 712 LOG(ERROR) << "Did not find extension with id " << extension_id; 713 return false; 714 } 715 bool enable = params->enable; 716 if (!policy->UserMayModifySettings(extension, NULL) || 717 (!enable && policy->MustRemainEnabled(extension, NULL)) || 718 (enable && policy->MustRemainDisabled(extension, NULL, NULL))) { 719 LOG(ERROR) << "Attempt to change enable state denied by management policy. " 720 << "Extension id: " << extension_id.c_str(); 721 return false; 722 } 723 724 if (enable) { 725 ExtensionPrefs* prefs = service->extension_prefs(); 726 if (prefs->DidExtensionEscalatePermissions(extension_id)) { 727 ShellWindowRegistry* registry = ShellWindowRegistry::Get(GetProfile()); 728 CHECK(registry); 729 ShellWindow* shell_window = registry->GetShellWindowForRenderViewHost( 730 render_view_host()); 731 if (!shell_window) { 732 return false; 733 } 734 735 ShowExtensionDisabledDialog( 736 service, shell_window->web_contents(), extension); 737 } else if ((prefs->GetDisableReasons(extension_id) & 738 Extension::DISABLE_UNSUPPORTED_REQUIREMENT) && 739 !requirements_checker_.get()) { 740 // Recheck the requirements. 741 scoped_refptr<const Extension> extension = 742 service->GetExtensionById(extension_id, 743 true );// include_disabled 744 requirements_checker_.reset(new RequirementsChecker); 745 // Released by OnRequirementsChecked. 746 AddRef(); 747 requirements_checker_->Check( 748 extension, 749 base::Bind(&DeveloperPrivateEnableFunction::OnRequirementsChecked, 750 this, extension_id)); 751 } else { 752 service->EnableExtension(extension_id); 753 754 // Make sure any browser action contained within it is not hidden. 755 ExtensionActionAPI::SetBrowserActionVisibility( 756 prefs, extension->id(), true); 757 } 758 } else { 759 service->DisableExtension(extension_id, Extension::DISABLE_USER_ACTION); 760 } 761 return true; 762} 763 764void DeveloperPrivateEnableFunction::OnRequirementsChecked( 765 std::string extension_id, 766 std::vector<std::string> requirements_errors) { 767 if (requirements_errors.empty()) { 768 ExtensionService* service = GetProfile()->GetExtensionService(); 769 service->EnableExtension(extension_id); 770 } else { 771 ExtensionErrorReporter::GetInstance()->ReportError( 772 UTF8ToUTF16(JoinString(requirements_errors, ' ')), 773 true /* be noisy */); 774 } 775 Release(); 776} 777 778DeveloperPrivateEnableFunction::~DeveloperPrivateEnableFunction() {} 779 780bool DeveloperPrivateInspectFunction::RunImpl() { 781 scoped_ptr<developer::Inspect::Params> params( 782 developer::Inspect::Params::Create(*args_)); 783 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); 784 const developer::InspectOptions& options = params->options; 785 786 int render_process_id; 787 base::StringToInt(options.render_process_id, &render_process_id); 788 789 if (render_process_id == -1) { 790 // This is a lazy background page. Identify if it is a normal 791 // or incognito background page. 792 ExtensionService* service = GetProfile()->GetExtensionService(); 793 if (options.incognito) 794 service = ExtensionSystem::Get( 795 service->profile()->GetOffTheRecordProfile())->extension_service(); 796 const Extension* extension = service->extensions()->GetByID( 797 options.extension_id); 798 DCHECK(extension); 799 // Wakes up the background page and opens the inspect window. 800 devtools_util::InspectBackgroundPage(extension, GetProfile()); 801 return false; 802 } 803 804 int render_view_id; 805 base::StringToInt(options.render_view_id, &render_view_id); 806 content::RenderViewHost* host = content::RenderViewHost::FromID( 807 render_process_id, render_view_id); 808 809 if (!host) { 810 // This can happen if the host has gone away since the page was displayed. 811 return false; 812 } 813 814 DevToolsWindow::OpenDevToolsWindow(host); 815 return true; 816} 817 818DeveloperPrivateInspectFunction::~DeveloperPrivateInspectFunction() {} 819 820bool DeveloperPrivateLoadUnpackedFunction::RunImpl() { 821 string16 select_title = 822 l10n_util::GetStringUTF16(IDS_EXTENSION_LOAD_FROM_DIRECTORY); 823 824 // Balanced in FileSelected / FileSelectionCanceled. 825 AddRef(); 826 bool result = ShowPicker( 827 ui::SelectFileDialog::SELECT_FOLDER, 828 DeveloperPrivateAPI::Get(GetProfile())->GetLastUnpackedDirectory(), 829 select_title, 830 ui::SelectFileDialog::FileTypeInfo(), 831 0); 832 return result; 833} 834 835void DeveloperPrivateLoadUnpackedFunction::FileSelected( 836 const base::FilePath& path) { 837 ExtensionService* service = GetProfile()->GetExtensionService(); 838 UnpackedInstaller::Create(service)->Load(path); 839 DeveloperPrivateAPI::Get(GetProfile())->SetLastUnpackedDirectory(path); 840 SendResponse(true); 841 Release(); 842} 843 844void DeveloperPrivateLoadUnpackedFunction::FileSelectionCanceled() { 845 SendResponse(false); 846 Release(); 847} 848 849bool DeveloperPrivateChooseEntryFunction::ShowPicker( 850 ui::SelectFileDialog::Type picker_type, 851 const base::FilePath& last_directory, 852 const string16& select_title, 853 const ui::SelectFileDialog::FileTypeInfo& info, 854 int file_type_index) { 855 ShellWindowRegistry* registry = ShellWindowRegistry::Get(GetProfile()); 856 DCHECK(registry); 857 ShellWindow* shell_window = registry->GetShellWindowForRenderViewHost( 858 render_view_host()); 859 if (!shell_window) { 860 return false; 861 } 862 863 // The entry picker will hold a reference to this function instance, 864 // and subsequent sending of the function response) until the user has 865 // selected a file or cancelled the picker. At that point, the picker will 866 // delete itself. 867 new EntryPicker(this, shell_window->web_contents(), picker_type, 868 last_directory, select_title, info, file_type_index); 869 return true; 870} 871 872bool DeveloperPrivateChooseEntryFunction::RunImpl() { return false; } 873 874DeveloperPrivateChooseEntryFunction::~DeveloperPrivateChooseEntryFunction() {} 875 876void DeveloperPrivatePackDirectoryFunction::OnPackSuccess( 877 const base::FilePath& crx_file, 878 const base::FilePath& pem_file) { 879 developer::PackDirectoryResponse response; 880 response.message = 881 UTF16ToUTF8(PackExtensionJob::StandardSuccessMessage(crx_file, pem_file)); 882 response.status = developer::PACK_STATUS_SUCCESS; 883 results_ = developer::PackDirectory::Results::Create(response); 884 SendResponse(true); 885 Release(); 886} 887 888void DeveloperPrivatePackDirectoryFunction::OnPackFailure( 889 const std::string& error, 890 ExtensionCreator::ErrorType error_type) { 891 developer::PackDirectoryResponse response; 892 response.message = error; 893 if (error_type == ExtensionCreator::kCRXExists) { 894 response.item_path = item_path_str_; 895 response.pem_path = key_path_str_; 896 response.override_flags = ExtensionCreator::kOverwriteCRX; 897 response.status = developer::PACK_STATUS_WARNING; 898 } else { 899 response.status = developer::PACK_STATUS_ERROR; 900 } 901 results_ = developer::PackDirectory::Results::Create(response); 902 SendResponse(true); 903 Release(); 904} 905 906bool DeveloperPrivatePackDirectoryFunction::RunImpl() { 907 scoped_ptr<PackDirectory::Params> params( 908 PackDirectory::Params::Create(*args_)); 909 EXTENSION_FUNCTION_VALIDATE(params.get()); 910 911 int flags = params->flags; 912 item_path_str_ = params->path; 913 key_path_str_ = params->private_key_path; 914 915 base::FilePath root_directory = 916 base::FilePath::FromUTF8Unsafe(item_path_str_); 917 918 base::FilePath key_file = base::FilePath::FromUTF8Unsafe(key_path_str_); 919 920 developer::PackDirectoryResponse response; 921 if (root_directory.empty()) { 922 if (item_path_str_.empty()) 923 response.message = l10n_util::GetStringUTF8( 924 IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_REQUIRED); 925 else 926 response.message = l10n_util::GetStringUTF8( 927 IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_INVALID); 928 929 response.status = developer::PACK_STATUS_ERROR; 930 results_ = developer::PackDirectory::Results::Create(response); 931 SendResponse(true); 932 return true; 933 } 934 935 if (!key_path_str_.empty() && key_file.empty()) { 936 response.message = l10n_util::GetStringUTF8( 937 IDS_EXTENSION_PACK_DIALOG_ERROR_KEY_INVALID); 938 response.status = developer::PACK_STATUS_ERROR; 939 results_ = developer::PackDirectory::Results::Create(response); 940 SendResponse(true); 941 return true; 942 } 943 944 // Balanced in OnPackSuccess / OnPackFailure. 945 AddRef(); 946 947 pack_job_ = new PackExtensionJob(this, root_directory, key_file, flags); 948 pack_job_->Start(); 949 return true; 950} 951 952DeveloperPrivatePackDirectoryFunction::DeveloperPrivatePackDirectoryFunction() 953{} 954 955DeveloperPrivatePackDirectoryFunction::~DeveloperPrivatePackDirectoryFunction() 956{} 957 958DeveloperPrivateLoadUnpackedFunction::~DeveloperPrivateLoadUnpackedFunction() {} 959 960bool DeveloperPrivateExportSyncfsFolderToLocalfsFunction::RunImpl() { 961 // TODO(grv) : add unittests. 962 base::FilePath::StringType project_name; 963 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &project_name)); 964 if (!ValidateFolderName(project_name)) { 965 DVLOG(0) << "Invalid project_name : [" << project_name << "]"; 966 return false; 967 } 968 969 context_ = content::BrowserContext::GetStoragePartition( 970 GetProfile(), render_view_host()->GetSiteInstance()) 971 ->GetFileSystemContext(); 972 973 base::FilePath project_path(GetProfile()->GetPath()); 974 project_path = project_path.Append(kUnpackedAppsFolder); 975 project_path = project_path.Append(project_name); 976 977 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, 978 base::Bind(&DeveloperPrivateExportSyncfsFolderToLocalfsFunction:: 979 ClearPrexistingDirectoryContent, 980 this, 981 project_path)); 982 983 return true; 984} 985 986void DeveloperPrivateExportSyncfsFolderToLocalfsFunction:: 987 ClearPrexistingDirectoryContent(const base::FilePath& project_path) { 988 989 // Clear the project directory before copying new files. 990 base::DeleteFile(project_path, true/*recursive*/); 991 992 pendingCopyOperationsCount_ = 1; 993 994 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, 995 base::Bind(&DeveloperPrivateExportSyncfsFolderToLocalfsFunction:: 996 ReadSyncFileSystemDirectory, 997 this, project_path, project_path.BaseName())); 998} 999 1000void DeveloperPrivateExportSyncfsFolderToLocalfsFunction:: 1001 ReadSyncFileSystemDirectory(const base::FilePath& project_path, 1002 const base::FilePath& destination_path) { 1003 std::string origin_url( 1004 Extension::GetBaseURLFromExtensionId(extension_id()).spec()); 1005 fileapi::FileSystemURL url(sync_file_system::CreateSyncableFileSystemURL( 1006 GURL(origin_url), 1007 destination_path)); 1008 1009 context_->operation_runner()->ReadDirectory( 1010 url, base::Bind(&DeveloperPrivateExportSyncfsFolderToLocalfsFunction:: 1011 ReadSyncFileSystemDirectoryCb, 1012 this, project_path, destination_path)); 1013} 1014 1015void DeveloperPrivateExportSyncfsFolderToLocalfsFunction:: 1016 ReadSyncFileSystemDirectoryCb( 1017 const base::FilePath& project_path, 1018 const base::FilePath& destination_path, 1019 base::PlatformFileError status, 1020 const fileapi::FileSystemOperation::FileEntryList& file_list, 1021 bool has_more) { 1022 1023 if (status != base::PLATFORM_FILE_OK) { 1024 DLOG(ERROR) << "Error in copying files from sync filesystem."; 1025 return; 1026 } 1027 1028 // We add 1 to the pending copy operations for both files and directories. We 1029 // release the directory copy operation once all the files under the directory 1030 // are added for copying. We do that to ensure that pendingCopyOperationsCount 1031 // does not become zero before all copy operations are finished. 1032 // In case the directory happens to be executing the last copy operation it 1033 // will call SendResponse to send the response to the API. The pending copy 1034 // operations of files are released by the CopyFile function. 1035 pendingCopyOperationsCount_ += file_list.size(); 1036 1037 for (size_t i = 0; i < file_list.size(); ++i) { 1038 if (file_list[i].is_directory) { 1039 ReadSyncFileSystemDirectory(project_path.Append(file_list[i].name), 1040 destination_path.Append(file_list[i].name)); 1041 continue; 1042 } 1043 1044 std::string origin_url( 1045 Extension::GetBaseURLFromExtensionId(extension_id()).spec()); 1046 fileapi::FileSystemURL url(sync_file_system::CreateSyncableFileSystemURL( 1047 GURL(origin_url), 1048 destination_path.Append(file_list[i].name))); 1049 base::FilePath target_path = project_path; 1050 target_path = target_path.Append(file_list[i].name); 1051 1052 context_->operation_runner()->CreateSnapshotFile( 1053 url, 1054 base::Bind( 1055 &DeveloperPrivateExportSyncfsFolderToLocalfsFunction:: 1056 SnapshotFileCallback, 1057 this, 1058 target_path)); 1059 1060 } 1061 1062 // Directory copy operation released here. 1063 pendingCopyOperationsCount_--; 1064 1065 if (!pendingCopyOperationsCount_) { 1066 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 1067 base::Bind(&DeveloperPrivateExportSyncfsFolderToLocalfsFunction:: 1068 SendResponse, 1069 this, 1070 success_)); 1071 } 1072} 1073 1074void DeveloperPrivateExportSyncfsFolderToLocalfsFunction::SnapshotFileCallback( 1075 const base::FilePath& target_path, 1076 base::PlatformFileError result, 1077 const base::PlatformFileInfo& file_info, 1078 const base::FilePath& src_path, 1079 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) { 1080 if (result != base::PLATFORM_FILE_OK) { 1081 SetError("Error in copying files from sync filesystem."); 1082 success_ = false; 1083 return; 1084 } 1085 1086 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, 1087 base::Bind(&DeveloperPrivateExportSyncfsFolderToLocalfsFunction::CopyFile, 1088 this, 1089 src_path, 1090 target_path)); 1091} 1092 1093void DeveloperPrivateExportSyncfsFolderToLocalfsFunction::CopyFile( 1094 const base::FilePath& src_path, 1095 const base::FilePath& target_path) { 1096 if (!file_util::CreateDirectory(target_path.DirName())) { 1097 SetError("Error in copying files from sync filesystem."); 1098 success_ = false; 1099 } 1100 1101 if (success_) 1102 base::CopyFile(src_path, target_path); 1103 1104 CHECK(pendingCopyOperationsCount_ > 0); 1105 pendingCopyOperationsCount_--; 1106 1107 if (!pendingCopyOperationsCount_) { 1108 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 1109 base::Bind(&DeveloperPrivateExportSyncfsFolderToLocalfsFunction:: 1110 SendResponse, 1111 this, 1112 success_)); 1113 } 1114} 1115 1116DeveloperPrivateExportSyncfsFolderToLocalfsFunction:: 1117 DeveloperPrivateExportSyncfsFolderToLocalfsFunction() 1118 : pendingCopyOperationsCount_(0), success_(true) {} 1119 1120DeveloperPrivateExportSyncfsFolderToLocalfsFunction:: 1121 ~DeveloperPrivateExportSyncfsFolderToLocalfsFunction() {} 1122 1123bool DeveloperPrivateLoadProjectFunction::RunImpl() { 1124 // TODO(grv) : add unit tests. 1125 base::FilePath::StringType project_name; 1126 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &project_name)); 1127 if (!ValidateFolderName(project_name)) { 1128 DVLOG(0) << "Invalid project_name : [" << project_name << "]"; 1129 return false; 1130 } 1131 1132 base::FilePath path(GetProfile()->GetPath()); 1133 path = path.Append(kUnpackedAppsFolder); 1134 // TODO(grv) : Sanitize / check project_name. 1135 path = path.Append(project_name); 1136 ExtensionService* service = GetProfile()->GetExtensionService(); 1137 UnpackedInstaller::Create(service)->Load(path); 1138 1139 const ExtensionSet* extensions = service->extensions(); 1140 // Released by GetUnpackedExtension. 1141 AddRef(); 1142 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, 1143 base::Bind(&DeveloperPrivateLoadProjectFunction::GetUnpackedExtension, 1144 this, path, extensions)); 1145 return true; 1146} 1147 1148void DeveloperPrivateLoadProjectFunction::GetUnpackedExtension( 1149 const base::FilePath& path, 1150 const ExtensionSet* extensions) { 1151 const Extension* extension = GetExtensionByPath(extensions, path); 1152 bool success = true; 1153 if (extension) { 1154 SetResult(new base::StringValue(extension->id())); 1155 } else { 1156 SetError("unable to load the project"); 1157 success = false; 1158 } 1159 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 1160 base::Bind(&DeveloperPrivateLoadProjectFunction::SendResponse, 1161 this, 1162 success)); 1163 Release(); 1164} 1165 1166DeveloperPrivateLoadProjectFunction::DeveloperPrivateLoadProjectFunction() {} 1167 1168DeveloperPrivateLoadProjectFunction::~DeveloperPrivateLoadProjectFunction() {} 1169 1170bool DeveloperPrivateChoosePathFunction::RunImpl() { 1171 1172 scoped_ptr<developer::ChoosePath::Params> params( 1173 developer::ChoosePath::Params::Create(*args_)); 1174 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); 1175 1176 ui::SelectFileDialog::Type type = ui::SelectFileDialog::SELECT_FOLDER; 1177 ui::SelectFileDialog::FileTypeInfo info; 1178 if (params->select_type == developer::SELECT_TYPE_FILE) { 1179 type = ui::SelectFileDialog::SELECT_OPEN_FILE; 1180 } 1181 string16 select_title; 1182 1183 int file_type_index = 0; 1184 if (params->file_type == developer::FILE_TYPE_LOAD) 1185 select_title = l10n_util::GetStringUTF16(IDS_EXTENSION_LOAD_FROM_DIRECTORY); 1186 else if (params->file_type== developer::FILE_TYPE_PEM) { 1187 select_title = l10n_util::GetStringUTF16( 1188 IDS_EXTENSION_PACK_DIALOG_SELECT_KEY); 1189 info.extensions.push_back(std::vector<base::FilePath::StringType>()); 1190 info.extensions.front().push_back(FILE_PATH_LITERAL("pem")); 1191 info.extension_description_overrides.push_back( 1192 l10n_util::GetStringUTF16( 1193 IDS_EXTENSION_PACK_DIALOG_KEY_FILE_TYPE_DESCRIPTION)); 1194 info.include_all_files = true; 1195 file_type_index = 1; 1196 } else { 1197 NOTREACHED(); 1198 } 1199 1200 // Balanced by FileSelected / FileSelectionCanceled. 1201 AddRef(); 1202 bool result = ShowPicker( 1203 type, 1204 DeveloperPrivateAPI::Get(GetProfile())->GetLastUnpackedDirectory(), 1205 select_title, 1206 info, 1207 file_type_index); 1208 return result; 1209} 1210 1211void DeveloperPrivateChoosePathFunction::FileSelected( 1212 const base::FilePath& path) { 1213 SetResult(new base::StringValue(UTF16ToUTF8(path.LossyDisplayName()))); 1214 SendResponse(true); 1215 Release(); 1216} 1217 1218void DeveloperPrivateChoosePathFunction::FileSelectionCanceled() { 1219 SendResponse(false); 1220 Release(); 1221} 1222 1223DeveloperPrivateChoosePathFunction::~DeveloperPrivateChoosePathFunction() {} 1224 1225bool DeveloperPrivateGetStringsFunction::RunImpl() { 1226 base::DictionaryValue* dict = new base::DictionaryValue(); 1227 SetResult(dict); 1228 1229 webui::SetFontAndTextDirection(dict); 1230 1231 #define SET_STRING(id, idr) \ 1232 dict->SetString(id, l10n_util::GetStringUTF16(idr)) 1233 SET_STRING("extensionSettings", IDS_MANAGE_EXTENSIONS_SETTING_WINDOWS_TITLE); 1234 1235 SET_STRING("appsDevtoolSearch", IDS_APPS_DEVTOOL_SEARCH); 1236 SET_STRING("appsDevtoolApps", IDS_APPS_DEVTOOL_APPS_INSTALLED); 1237 SET_STRING("appsDevtoolExtensions", IDS_APPS_DEVTOOL_EXTENSIONS_INSTALLED); 1238 SET_STRING("appsDevtoolNoExtensions", IDS_EXTENSIONS_NONE_INSTALLED); 1239 SET_STRING("appsDevtoolUnpacked", IDS_APPS_DEVTOOL_UNPACKED_INSTALLED); 1240 SET_STRING("appsDevtoolInstalled", IDS_APPS_DEVTOOL_INSTALLED); 1241 SET_STRING("appsDevtoolNoPackedApps", IDS_APPS_DEVTOOL_NO_PACKED_APPS); 1242 SET_STRING("appsDevtoolNoUnpackedApps", IDS_APPS_DEVTOOL_NO_UNPACKED_APPS); 1243 SET_STRING("appsDevtoolNoPackedExtensions", 1244 IDS_APPS_DEVTOOL_NO_PACKED_EXTENSIONS); 1245 SET_STRING("appsDevtoolNoUnpackedExtensions", 1246 IDS_APPS_DEVTOOL_NO_UNPACKED_EXTENSIONS); 1247 SET_STRING("appsDevtoolUpdating", IDS_APPS_DEVTOOL_UPDATING); 1248 SET_STRING("extensionSettingsGetMoreExtensions", IDS_GET_MORE_EXTENSIONS); 1249 SET_STRING("extensionSettingsExtensionId", IDS_EXTENSIONS_ID); 1250 SET_STRING("extensionSettingsExtensionPath", IDS_EXTENSIONS_PATH); 1251 SET_STRING("extensionSettingsInspectViews", IDS_EXTENSIONS_INSPECT_VIEWS); 1252 SET_STRING("extensionSettingsInstallWarnings", 1253 IDS_EXTENSIONS_INSTALL_WARNINGS); 1254 SET_STRING("viewIncognito", IDS_EXTENSIONS_VIEW_INCOGNITO); 1255 SET_STRING("viewInactive", IDS_EXTENSIONS_VIEW_INACTIVE); 1256 SET_STRING("backgroundPage", IDS_EXTENSIONS_BACKGROUND_PAGE); 1257 SET_STRING("extensionSettingsEnable", IDS_EXTENSIONS_ENABLE); 1258 SET_STRING("extensionSettingsEnabled", IDS_EXTENSIONS_ENABLED); 1259 SET_STRING("extensionSettingsRemove", IDS_EXTENSIONS_REMOVE); 1260 SET_STRING("extensionSettingsEnableIncognito", 1261 IDS_EXTENSIONS_ENABLE_INCOGNITO); 1262 SET_STRING("extensionSettingsAllowFileAccess", 1263 IDS_EXTENSIONS_ALLOW_FILE_ACCESS); 1264 SET_STRING("extensionSettingsReloadTerminated", 1265 IDS_EXTENSIONS_RELOAD_TERMINATED); 1266 SET_STRING("extensionSettingsReloadUnpacked", 1267 IDS_APPS_DEV_TOOLS_RELOAD_UNPACKED); 1268 SET_STRING("extensionSettingsLaunch", IDS_EXTENSIONS_LAUNCH); 1269 SET_STRING("extensionSettingsOptions", IDS_EXTENSIONS_OPTIONS_LINK); 1270 SET_STRING("extensionSettingsPermissions", IDS_EXTENSIONS_PERMISSIONS_LINK); 1271 SET_STRING("extensionSettingsVisitWebsite", IDS_EXTENSIONS_VISIT_WEBSITE); 1272 SET_STRING("extensionSettingsVisitWebStore", IDS_EXTENSIONS_VISIT_WEBSTORE); 1273 SET_STRING("extensionSettingsPolicyControlled", 1274 IDS_EXTENSIONS_POLICY_CONTROLLED); 1275 SET_STRING("extensionSettingsManagedMode", 1276 IDS_EXTENSIONS_LOCKED_MANAGED_USER); 1277 SET_STRING("extensionSettingsShowButton", IDS_EXTENSIONS_SHOW_BUTTON); 1278 SET_STRING("appsDevtoolLoadUnpackedButton", 1279 IDS_APPS_DEVTOOL_LOAD_UNPACKED_BUTTON); 1280 SET_STRING("appsDevtoolPackButton", IDS_APPS_DEVTOOL_PACK_BUTTON); 1281 SET_STRING("extensionSettingsCommandsLink", 1282 IDS_EXTENSIONS_COMMANDS_CONFIGURE); 1283 SET_STRING("appsDevtoolUpdateButton", IDS_APPS_DEVTOOL_UPDATE_BUTTON); 1284 SET_STRING("extensionSettingsWarningsTitle", IDS_EXTENSION_WARNINGS_TITLE); 1285 SET_STRING("extensionSettingsShowDetails", IDS_EXTENSIONS_SHOW_DETAILS); 1286 SET_STRING("extensionSettingsHideDetails", IDS_EXTENSIONS_HIDE_DETAILS); 1287 SET_STRING("extensionUninstall", IDS_EXTENSIONS_UNINSTALL); 1288 SET_STRING("extensionsPermissionsHeading", 1289 IDS_EXTENSIONS_PERMISSIONS_HEADING); 1290 SET_STRING("extensionsPermissionsClose", IDS_EXTENSIONS_PERMISSIONS_CLOSE); 1291 SET_STRING("extensionDisabled", IDS_EXTENSIONS_DISABLED); 1292 SET_STRING("extensionSettingsShowLogsButton", IDS_EXTENSIONS_SHOW_LOGS); 1293 SET_STRING("extensionSettingsMoreDetailsButton", IDS_EXTENSIONS_MORE_DETAILS); 1294 SET_STRING("extensionSettingsVersion", IDS_EXTENSIONS_VERSION); 1295 SET_STRING("extensionSettingsDelete", IDS_EXTENSIONS_ADT_DELETE); 1296 SET_STRING("extensionSettingsPack", IDS_EXTENSIONS_PACK); 1297 1298// Pack Extension strings 1299 SET_STRING("packExtensionOverlay", IDS_EXTENSION_PACK_DIALOG_TITLE); 1300 SET_STRING("packExtensionHeading", IDS_EXTENSION_ADT_PACK_DIALOG_HEADING); 1301 SET_STRING("packButton", IDS_EXTENSION_ADT_PACK_BUTTON); 1302 SET_STRING("ok", IDS_OK); 1303 SET_STRING("cancel", IDS_CANCEL); 1304 SET_STRING("packExtensionRootDir", 1305 IDS_EXTENSION_PACK_DIALOG_ROOT_DIRECTORY_LABEL); 1306 SET_STRING("packExtensionPrivateKey", 1307 IDS_EXTENSION_PACK_DIALOG_PRIVATE_KEY_LABEL); 1308 SET_STRING("packExtensionBrowseButton", IDS_EXTENSION_PACK_DIALOG_BROWSE); 1309 SET_STRING("packExtensionProceedAnyway", IDS_EXTENSION_PROCEED_ANYWAY); 1310 SET_STRING("packExtensionWarningTitle", IDS_EXTENSION_PACK_WARNING_TITLE); 1311 SET_STRING("packExtensionErrorTitle", IDS_EXTENSION_PACK_ERROR_TITLE); 1312 SET_STRING("packAppOverlay", IDS_EXTENSION_PACK_APP_DIALOG_TITLE); 1313 SET_STRING("packAppHeading", IDS_EXTENSION_ADT_PACK_APP_DIALOG_HEADING); 1314 1315// Delete confirmation dialog. 1316 SET_STRING("deleteConfirmationDeleteButton", 1317 IDS_APPS_DEVTOOL_DELETE_CONFIRMATION_BUTTON); 1318 SET_STRING("deleteConfirmationTitle", 1319 IDS_APPS_DEVTOOL_DELETE_CONFIRMATION_TITLE); 1320 SET_STRING("deleteConfirmationMessageApp", 1321 IDS_APPS_DEVTOOL_DELETE_CONFIRMATION_MESSAGE_APP); 1322 SET_STRING("deleteConfirmationMessageExtension", 1323 IDS_APPS_DEVTOOL_DELETE_CONFIRMATION_MESSAGE_EXTENSION); 1324 1325// Dialog when profile is managed. 1326 SET_STRING("managedProfileDialogCloseButton", 1327 IDS_APPS_DEVTOOL_MANAGED_PROFILE_DIALOG_CLOSE_BUTTON); 1328 SET_STRING("managedProfileDialogTitle", 1329 IDS_APPS_DEVTOOL_MANAGED_PROFILE_DIALOG_TITLE); 1330 SET_STRING("managedProfileDialogDescription", 1331 IDS_APPS_DEVTOOL_MANAGED_PROFILE_DIALOG_DESCRIPTION); 1332 1333 #undef SET_STRING 1334 return true; 1335} 1336 1337DeveloperPrivateGetStringsFunction::~DeveloperPrivateGetStringsFunction() {} 1338 1339bool DeveloperPrivateIsProfileManagedFunction::RunImpl() { 1340 SetResult(new base::FundamentalValue(GetProfile()->IsManaged())); 1341 return true; 1342} 1343 1344DeveloperPrivateIsProfileManagedFunction:: 1345 ~DeveloperPrivateIsProfileManagedFunction() { 1346} 1347 1348} // namespace api 1349 1350} // namespace extensions 1351