// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/extensions/api/autotest_private/autotest_private_api.h" #include #include #include "base/lazy_instance.h" #include "base/memory/ptr_util.h" #include "base/strings/string_number_conversions.h" #include "build/build_config.h" #include "chrome/browser/extensions/extension_action_manager.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/extensions/api/autotest_private.h" #include "extensions/browser/extension_function_registry.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/common/manifest_handlers/background_info.h" #include "extensions/common/manifest_handlers/options_page_info.h" #include "extensions/common/permissions/api_permission_set.h" #include "extensions/common/permissions/permission_set.h" #include "extensions/common/permissions/permissions_data.h" #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/login/lock/screen_locker.h" #include "chrome/browser/chromeos/system/input_device_settings.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/session_manager_client.h" #include "components/user_manager/user.h" #include "components/user_manager/user_manager.h" #include "ui/message_center/message_center.h" #include "ui/message_center/notification.h" #endif namespace extensions { namespace { base::ListValue* GetHostPermissions(const Extension* ext, bool effective_perm) { const PermissionsData* permissions_data = ext->permissions_data(); const URLPatternSet& pattern_set = effective_perm ? permissions_data->GetEffectiveHostPermissions() : permissions_data->active_permissions().explicit_hosts(); base::ListValue* permissions = new base::ListValue; for (URLPatternSet::const_iterator perm = pattern_set.begin(); perm != pattern_set.end(); ++perm) { permissions->AppendString(perm->GetAsString()); } return permissions; } base::ListValue* GetAPIPermissions(const Extension* ext) { base::ListValue* permissions = new base::ListValue; std::set perm_list = ext->permissions_data()->active_permissions().GetAPIsAsStrings(); for (std::set::const_iterator perm = perm_list.begin(); perm != perm_list.end(); ++perm) { permissions->AppendString(perm->c_str()); } return permissions; } bool IsTestMode(content::BrowserContext* context) { return AutotestPrivateAPI::GetFactoryInstance()->Get(context)->test_mode(); } } // namespace ExtensionFunction::ResponseAction AutotestPrivateLogoutFunction::Run() { DVLOG(1) << "AutotestPrivateLogoutFunction"; if (!IsTestMode(browser_context())) chrome::AttemptUserExit(); return RespondNow(NoArguments()); } ExtensionFunction::ResponseAction AutotestPrivateRestartFunction::Run() { DVLOG(1) << "AutotestPrivateRestartFunction"; if (!IsTestMode(browser_context())) chrome::AttemptRestart(); return RespondNow(NoArguments()); } ExtensionFunction::ResponseAction AutotestPrivateShutdownFunction::Run() { std::unique_ptr params( api::autotest_private::Shutdown::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); DVLOG(1) << "AutotestPrivateShutdownFunction " << params->force; if (!IsTestMode(browser_context())) chrome::AttemptExit(); return RespondNow(NoArguments()); } ExtensionFunction::ResponseAction AutotestPrivateLoginStatusFunction::Run() { DVLOG(1) << "AutotestPrivateLoginStatusFunction"; std::unique_ptr result(new base::DictionaryValue); #if defined(OS_CHROMEOS) const user_manager::UserManager* user_manager = user_manager::UserManager::Get(); const bool is_screen_locked = !!chromeos::ScreenLocker::default_screen_locker(); if (user_manager) { result->SetBoolean("isLoggedIn", user_manager->IsUserLoggedIn()); result->SetBoolean("isOwner", user_manager->IsCurrentUserOwner()); result->SetBoolean("isScreenLocked", is_screen_locked); if (user_manager->IsUserLoggedIn()) { result->SetBoolean("isRegularUser", user_manager->IsLoggedInAsUserWithGaiaAccount()); result->SetBoolean("isGuest", user_manager->IsLoggedInAsGuest()); result->SetBoolean("isKiosk", user_manager->IsLoggedInAsKioskApp()); const user_manager::User* user = user_manager->GetActiveUser(); result->SetString("email", user->GetAccountId().GetUserEmail()); result->SetString("displayEmail", user->display_email()); std::string user_image; switch (user->image_index()) { case user_manager::User::USER_IMAGE_EXTERNAL: user_image = "file"; break; case user_manager::User::USER_IMAGE_PROFILE: user_image = "profile"; break; default: user_image = base::IntToString(user->image_index()); break; } result->SetString("userImage", user_image); } } #endif return RespondNow(OneArgument(std::move(result))); } ExtensionFunction::ResponseAction AutotestPrivateLockScreenFunction::Run() { DVLOG(1) << "AutotestPrivateLockScreenFunction"; #if defined(OS_CHROMEOS) chromeos::DBusThreadManager::Get()->GetSessionManagerClient()-> RequestLockScreen(); #endif return RespondNow(NoArguments()); } ExtensionFunction::ResponseAction AutotestPrivateGetExtensionsInfoFunction::Run() { DVLOG(1) << "AutotestPrivateGetExtensionsInfoFunction"; ExtensionService* service = ExtensionSystem::Get(browser_context())->extension_service(); ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context()); const ExtensionSet& extensions = registry->enabled_extensions(); const ExtensionSet& disabled_extensions = registry->disabled_extensions(); ExtensionActionManager* extension_action_manager = ExtensionActionManager::Get(browser_context()); base::ListValue* extensions_values = new base::ListValue; ExtensionList all; all.insert(all.end(), extensions.begin(), extensions.end()); all.insert(all.end(), disabled_extensions.begin(), disabled_extensions.end()); for (ExtensionList::const_iterator it = all.begin(); it != all.end(); ++it) { const Extension* extension = it->get(); std::string id = extension->id(); std::unique_ptr extension_value( new base::DictionaryValue); extension_value->SetString("id", id); extension_value->SetString("version", extension->VersionString()); extension_value->SetString("name", extension->name()); extension_value->SetString("publicKey", extension->public_key()); extension_value->SetString("description", extension->description()); extension_value->SetString( "backgroundUrl", BackgroundInfo::GetBackgroundURL(extension).spec()); extension_value->SetString( "optionsUrl", OptionsPageInfo::GetOptionsPage(extension).spec()); extension_value->Set("hostPermissions", GetHostPermissions(extension, false)); extension_value->Set("effectiveHostPermissions", GetHostPermissions(extension, true)); extension_value->Set("apiPermissions", GetAPIPermissions(extension)); Manifest::Location location = extension->location(); extension_value->SetBoolean("isComponent", location == Manifest::COMPONENT); extension_value->SetBoolean("isInternal", location == Manifest::INTERNAL); extension_value->SetBoolean("isUserInstalled", location == Manifest::INTERNAL || Manifest::IsUnpackedLocation(location)); extension_value->SetBoolean("isEnabled", service->IsExtensionEnabled(id)); extension_value->SetBoolean( "allowedInIncognito", util::IsIncognitoEnabled(id, browser_context())); extension_value->SetBoolean( "hasPageAction", extension_action_manager->GetPageAction(*extension) != NULL); extensions_values->Append(std::move(extension_value)); } std::unique_ptr return_value( new base::DictionaryValue); return_value->Set("extensions", extensions_values); return RespondNow(OneArgument(std::move(return_value))); } static int AccessArray(const volatile int arr[], const volatile int *index) { return arr[*index]; } ExtensionFunction::ResponseAction AutotestPrivateSimulateAsanMemoryBugFunction::Run() { DVLOG(1) << "AutotestPrivateSimulateAsanMemoryBugFunction"; if (!IsTestMode(browser_context())) { // This array is volatile not to let compiler optimize us out. volatile int testarray[3] = {0, 0, 0}; // Cause Address Sanitizer to abort this process. volatile int index = 5; AccessArray(testarray, &index); } return RespondNow(NoArguments()); } ExtensionFunction::ResponseAction AutotestPrivateSetTouchpadSensitivityFunction::Run() { std::unique_ptr params( api::autotest_private::SetTouchpadSensitivity::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); DVLOG(1) << "AutotestPrivateSetTouchpadSensitivityFunction " << params->value; #if defined(OS_CHROMEOS) chromeos::system::InputDeviceSettings::Get()->SetTouchpadSensitivity( params->value); #endif return RespondNow(NoArguments()); } ExtensionFunction::ResponseAction AutotestPrivateSetTapToClickFunction::Run() { std::unique_ptr params( api::autotest_private::SetTapToClick::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); DVLOG(1) << "AutotestPrivateSetTapToClickFunction " << params->enabled; #if defined(OS_CHROMEOS) chromeos::system::InputDeviceSettings::Get()->SetTapToClick(params->enabled); #endif return RespondNow(NoArguments()); } ExtensionFunction::ResponseAction AutotestPrivateSetThreeFingerClickFunction::Run() { std::unique_ptr params( api::autotest_private::SetThreeFingerClick::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); DVLOG(1) << "AutotestPrivateSetThreeFingerClickFunction " << params->enabled; #if defined(OS_CHROMEOS) chromeos::system::InputDeviceSettings::Get()->SetThreeFingerClick( params->enabled); #endif return RespondNow(NoArguments()); } ExtensionFunction::ResponseAction AutotestPrivateSetTapDraggingFunction::Run() { std::unique_ptr params( api::autotest_private::SetTapDragging::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); DVLOG(1) << "AutotestPrivateSetTapDraggingFunction " << params->enabled; #if defined(OS_CHROMEOS) chromeos::system::InputDeviceSettings::Get()->SetTapDragging(params->enabled); #endif return RespondNow(NoArguments()); } ExtensionFunction::ResponseAction AutotestPrivateSetNaturalScrollFunction::Run() { std::unique_ptr params( api::autotest_private::SetNaturalScroll::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); DVLOG(1) << "AutotestPrivateSetNaturalScrollFunction " << params->enabled; #if defined(OS_CHROMEOS) chromeos::system::InputDeviceSettings::Get()->SetNaturalScroll( params->enabled); #endif return RespondNow(NoArguments()); } ExtensionFunction::ResponseAction AutotestPrivateSetMouseSensitivityFunction::Run() { std::unique_ptr params( api::autotest_private::SetMouseSensitivity::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); DVLOG(1) << "AutotestPrivateSetMouseSensitivityFunction " << params->value; #if defined(OS_CHROMEOS) chromeos::system::InputDeviceSettings::Get()->SetMouseSensitivity( params->value); #endif return RespondNow(NoArguments()); } ExtensionFunction::ResponseAction AutotestPrivateSetPrimaryButtonRightFunction::Run() { std::unique_ptr params( api::autotest_private::SetPrimaryButtonRight::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); DVLOG(1) << "AutotestPrivateSetPrimaryButtonRightFunction " << params->right; #if defined(OS_CHROMEOS) chromeos::system::InputDeviceSettings::Get()->SetPrimaryButtonRight( params->right); #endif return RespondNow(NoArguments()); } // static std::string AutotestPrivateGetVisibleNotificationsFunction::ConvertToString( message_center::NotificationType type) { #if defined(OS_CHROMEOS) switch (type) { case message_center::NOTIFICATION_TYPE_SIMPLE: return "simple"; case message_center::NOTIFICATION_TYPE_BASE_FORMAT: return "base_format"; case message_center::NOTIFICATION_TYPE_IMAGE: return "image"; case message_center::NOTIFICATION_TYPE_MULTIPLE: return "multiple"; case message_center::NOTIFICATION_TYPE_PROGRESS: return "progress"; case message_center::NOTIFICATION_TYPE_CUSTOM: return "custom"; } #endif return "unknown"; } ExtensionFunction::ResponseAction AutotestPrivateGetVisibleNotificationsFunction::Run() { DVLOG(1) << "AutotestPrivateGetVisibleNotificationsFunction"; std::unique_ptr values(new base::ListValue); #if defined(OS_CHROMEOS) for (auto* notification : message_center::MessageCenter::Get()->GetVisibleNotifications()) { auto result = base::MakeUnique(); result->SetString("id", notification->id()); result->SetString("type", ConvertToString(notification->type())); result->SetString("title", notification->title()); result->SetString("message", notification->message()); result->SetInteger("priority", notification->priority()); result->SetInteger("progress", notification->progress()); values->Append(std::move(result)); } #endif return RespondNow(OneArgument(std::move(values))); } static base::LazyInstance > g_factory = LAZY_INSTANCE_INITIALIZER; // static BrowserContextKeyedAPIFactory* AutotestPrivateAPI::GetFactoryInstance() { return g_factory.Pointer(); } template <> KeyedService* BrowserContextKeyedAPIFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { return new AutotestPrivateAPI(); } AutotestPrivateAPI::AutotestPrivateAPI() : test_mode_(false) { } AutotestPrivateAPI::~AutotestPrivateAPI() { } } // namespace extensions