Merge from Chromium at DEPS revision r213057
This commit was generated by merge_to_master.py.
Change-Id: I3e2e2506eb9b0080157e9c5f133559df3e600388
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index 8a76397..278632f 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -74,10 +74,10 @@
"+libxml", # For search engine definition parsing.
"+third_party/apple_sample_code", # Apple code ImageAndTextCell.
"+third_party/bzip2",
- "+third_party/cld",
"+third_party/expat",
"+third_party/iaccessible2",
- "+third_party/icu",
+ "+third_party/icu/source/common/unicode",
+ "+third_party/icu/source/i18n/unicode",
"+third_party/isimpledom",
"+third_party/leveldatabase",
"+third_party/libevent", # For the remote V8 debugging server
@@ -91,17 +91,13 @@
# No inclusion of WebKit from the browser, other than strictly enum/POD,
# header-only types, and some selected common code.
"-third_party/WebKit",
- "+third_party/WebKit/public/platform/WebCString.h",
"+third_party/WebKit/public/platform/WebRect.h",
"+third_party/WebKit/public/platform/WebReferrerPolicy.h",
"+third_party/WebKit/public/platform/WebScreenInfo.h",
- "+third_party/WebKit/public/platform/WebString.h",
- "+third_party/WebKit/public/platform/WebURL.h",
"+third_party/WebKit/public/web/WebAutofillClient.h",
"+third_party/WebKit/public/web/WebCache.h",
"+third_party/WebKit/public/web/WebContextMenuData.h",
"+third_party/WebKit/public/web/WebCursorInfo.h",
- "+third_party/WebKit/public/web/WebDevToolsAgent.h",
"+third_party/WebKit/public/web/WebFindOptions.h",
"+third_party/WebKit/public/web/WebInputEvent.h",
"+third_party/WebKit/public/web/WebMediaPlayerAction.h",
@@ -111,7 +107,5 @@
"+third_party/WebKit/public/web/WebTextDirection.h",
# These should be burned down. http://crbug.com/237267
- "!third_party/WebKit/public/web/WebKit.h",
- "!third_party/WebKit/public/web/WebSecurityOrigin.h",
"!third_party/WebKit/public/web/WebView.h",
]
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index cfafecc..fe000fc 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -21,6 +21,7 @@
#include "chrome/common/chrome_switches.h"
#include "components/nacl/common/nacl_switches.h"
#include "content/public/browser/user_metrics.h"
+#include "extensions/common/switches.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/google_chrome_strings.h"
@@ -439,13 +440,6 @@
#endif
},
{
- "enable-d3d11",
- IDS_FLAGS_ENABLE_D3D11_NAME,
- IDS_FLAGS_ENABLE_D3D11_DESCRIPTION,
- kOsWin,
- SINGLE_VALUE_TYPE(switches::kEnableD3D11)
- },
- {
"disable-webrtc",
IDS_FLAGS_DISABLE_WEBRTC_NAME,
IDS_FLAGS_DISABLE_WEBRTC_DESCRIPTION,
@@ -552,7 +546,7 @@
IDS_FLAGS_EXTENSIONS_ON_CHROME_URLS_NAME,
IDS_FLAGS_EXTENSIONS_ON_CHROME_URLS_DESCRIPTION,
kOsAll,
- SINGLE_VALUE_TYPE(switches::kExtensionsOnChromeURLs)
+ SINGLE_VALUE_TYPE(extensions::switches::kExtensionsOnChromeURLs)
},
{
"enable-fast-unload",
@@ -583,14 +577,6 @@
SINGLE_VALUE_TYPE(switches::kEnableAppWindowControls)
},
{
- "action-box",
- IDS_FLAGS_ACTION_BOX_NAME,
- IDS_FLAGS_ACTION_BOX_DESCRIPTION,
- kOsDesktop,
- ENABLE_DISABLE_VALUE_TYPE_AND_VALUE(switches::kActionBox, "1",
- switches::kActionBox, "0")
- },
- {
"script-badges",
IDS_FLAGS_SCRIPT_BADGES_NAME,
IDS_FLAGS_SCRIPT_BADGES_DESCRIPTION,
@@ -997,6 +983,13 @@
kOsCrOS,
SINGLE_VALUE_TYPE(chromeos::switches::kNoDiscardTabs)
},
+ {
+ "ash-enable-docked-windows",
+ IDS_FLAGS_DOCKED_WINDOWS_NAME,
+ IDS_FLAGS_DOCKED_WINDOWS_DESCRIPTION,
+ kOsCrOS,
+ SINGLE_VALUE_TYPE(ash::switches::kAshEnableDockedWindows)
+ },
#endif
{
"enable-download-resumption",
@@ -1116,6 +1109,13 @@
SINGLE_VALUE_TYPE(chromeos::switches::kFileManagerEnableSharing)
},
{
+ "file-manager-enable-folder-shortcuts",
+ IDS_FLAGS_FILE_MANAGER_ENABLE_FOLDER_SHORTCUTS,
+ IDS_FLAGS_FILE_MANAGER_ENABLE_FOLDER_SHORTCUTS_DESCRIPTION,
+ kOsCrOS,
+ SINGLE_VALUE_TYPE(chromeos::switches::kFileManagerEnableFolderShortcuts)
+ },
+ {
"disable-quickoffice-component-app",
IDS_FLAGS_DISABLE_QUICKOFFICE_COMPONENT_APP_NAME,
IDS_FLAGS_DISABLE_QUICKOFFICE_COMPONENT_APP_DESCRIPTION,
@@ -1227,7 +1227,7 @@
IDS_FLAGS_ASH_AUDIO_DEVICE_MENU_NAME,
IDS_FLAGS_ASH_AUDIO_DEVICE_MENU_DESCRIPTION,
kOsCrOS,
- SINGLE_VALUE_TYPE(ash::switches::kAshEnableAudioDeviceMenu)
+ ENABLE_DISABLE_VALUE_TYPE("", ash::switches::kAshDisableAudioDeviceMenu)
},
{
"enable-carrier-switching",
@@ -1259,12 +1259,13 @@
SINGLE_VALUE_TYPE(switches::kEnablePasswordGeneration)
},
{
- "enable-password-autofill-public-suffix-domain-matching",
- IDS_FLAGS_ENABLE_PASSWORD_AUTOFILL_PUBLIC_SUFFIX_DOMAIN_MATCHING_NAME,
- IDS_FLAGS_ENABLE_PASSWORD_AUTOFILL_PUBLIC_SUFFIX_DOMAIN_MATCHING_DESCRIPTION,
+ "password-autofill-public-suffix-domain-matching",
+ IDS_FLAGS_PASSWORD_AUTOFILL_PUBLIC_SUFFIX_DOMAIN_MATCHING_NAME,
+ IDS_FLAGS_PASSWORD_AUTOFILL_PUBLIC_SUFFIX_DOMAIN_MATCHING_DESCRIPTION,
kOsAndroid,
- SINGLE_VALUE_TYPE(
- switches::kEnablePasswordAutofillPublicSuffixDomainMatching)
+ ENABLE_DISABLE_VALUE_TYPE(
+ switches::kEnablePasswordAutofillPublicSuffixDomainMatching,
+ switches::kDisablePasswordAutofillPublicSuffixDomainMatching)
},
{
"enable-deferred-image-decoding",
diff --git a/chrome/browser/accessibility/accessibility_extension_apitest.cc b/chrome/browser/accessibility/accessibility_extension_apitest.cc
index 29e54c4..b66e2f3 100644
--- a/chrome/browser/accessibility/accessibility_extension_apitest.cc
+++ b/chrome/browser/accessibility/accessibility_extension_apitest.cc
@@ -10,6 +10,9 @@
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_switches.h"
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
// Times out on win asan, http://crbug.com/166026
#if defined(OS_WIN) && defined(ADDRESS_SANITIZER)
@@ -18,6 +21,12 @@
#define MAYBE_GetAlertsForTab GetAlertsForTab
#endif
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_GetAlertsForTab) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
content::WebContents* web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
ASSERT_TRUE(web_contents);
diff --git a/chrome/browser/android/chrome_jni_registrar.cc b/chrome/browser/android/chrome_jni_registrar.cc
index 79bbecf..cf5c8dc 100644
--- a/chrome/browser/android/chrome_jni_registrar.cc
+++ b/chrome/browser/android/chrome_jni_registrar.cc
@@ -11,6 +11,7 @@
#include "chrome/browser/android/content_view_util.h"
#include "chrome/browser/android/dev_tools_server.h"
#include "chrome/browser/android/favicon_helper.h"
+#include "chrome/browser/android/field_trial_helper.h"
#include "chrome/browser/android/intent_helper.h"
#include "chrome/browser/android/most_visited_sites.h"
#include "chrome/browser/android/provider/chrome_browser_provider.h"
@@ -66,6 +67,7 @@
{ "ContentViewUtil", RegisterContentViewUtil },
{ "DevToolsServer", RegisterDevToolsServer },
{ "FaviconHelper", FaviconHelper::RegisterFaviconHelper },
+ { "FieldTrialHelper", RegisterFieldTrialHelper },
{ "IntentHelper", RegisterIntentHelper },
{ "JavascriptAppModalDialog",
JavascriptAppModalDialogAndroid::RegisterJavascriptAppModalDialog },
diff --git a/chrome/browser/android/field_trial_helper.cc b/chrome/browser/android/field_trial_helper.cc
new file mode 100644
index 0000000..b3be6d2
--- /dev/null
+++ b/chrome/browser/android/field_trial_helper.cc
@@ -0,0 +1,33 @@
+// Copyright 2013 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/android/field_trial_helper.h"
+
+#include <jni.h>
+
+#include "base/android/jni_string.h"
+#include "base/metrics/field_trial.h"
+#include "jni/FieldTrialHelper_jni.h"
+
+using base::android::ConvertJavaStringToUTF8;
+using base::android::ConvertUTF8ToJavaString;
+
+static jstring GetFieldTrialFullName(JNIEnv* env,
+ jclass clazz,
+ jstring jtrial_name) {
+ std::string trial_name(ConvertJavaStringToUTF8(env, jtrial_name));
+ return ConvertUTF8ToJavaString(
+ env,
+ base::FieldTrialList::FindFullName(trial_name)).Release();
+}
+
+namespace chrome {
+namespace android {
+
+bool RegisterFieldTrialHelper(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+} // namespace android
+} // namespace chrome
diff --git a/chrome/browser/android/field_trial_helper.h b/chrome/browser/android/field_trial_helper.h
new file mode 100644
index 0000000..6f92ac0
--- /dev/null
+++ b/chrome/browser/android/field_trial_helper.h
@@ -0,0 +1,18 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_ANDROID_FIELD_TRIAL_HELPER_H_
+#define CHROME_BROWSER_ANDROID_FIELD_TRIAL_HELPER_H_
+
+#include <jni.h>
+
+namespace chrome {
+namespace android {
+
+bool RegisterFieldTrialHelper(JNIEnv* env);
+
+} // namespace android
+} // namespace chrome
+
+#endif // CHROME_BROWSER_ANDROID_FIELD_TRIAL_HELPER_H_
diff --git a/chrome/browser/android/most_visited_sites.cc b/chrome/browser/android/most_visited_sites.cc
index 779fb55..79ca5c8 100644
--- a/chrome/browser/android/most_visited_sites.cc
+++ b/chrome/browser/android/most_visited_sites.cc
@@ -148,6 +148,8 @@
return;
TopSites* top_sites = profile->GetTopSites();
+ if (!top_sites)
+ return;
scoped_refptr<NativeCallback> native_callback =
new NativeCallback(j_callback_obj, static_cast<int>(num_results));
@@ -181,3 +183,18 @@
url_string,
top_sites, base::Owned(j_callback_ref)));
}
+
+void BlacklistUrl(JNIEnv* env, jclass clazz, jobject j_profile, jstring j_url) {
+ Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
+
+ DCHECK(profile);
+ if (!profile)
+ return;
+
+ TopSites* top_sites = profile->GetTopSites();
+ if (!top_sites)
+ return;
+
+ std::string url_string = ConvertJavaStringToUTF8(env, j_url);
+ top_sites->AddBlacklistedURL(GURL(url_string));
+}
diff --git a/chrome/browser/app_controller_mac.h b/chrome/browser/app_controller_mac.h
index 46d8a05..4ea1356 100644
--- a/chrome/browser/app_controller_mac.h
+++ b/chrome/browser/app_controller_mac.h
@@ -81,6 +81,9 @@
scoped_ptr<PrefChangeRegistrar> profilePrefRegistrar_;
PrefChangeRegistrar localPrefRegistrar_;
+
+ // The main menu item showing the name of a currently focused packaged app.
+ base::scoped_nsobject<NSMenuItem> appMenuItem_;
}
@property(readonly, nonatomic) BOOL startupComplete;
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm
index 22e3d58..7e6222b 100644
--- a/chrome/browser/app_controller_mac.mm
+++ b/chrome/browser/app_controller_mac.mm
@@ -4,6 +4,7 @@
#import "chrome/browser/app_controller_mac.h"
+#include "apps/shell_window.h"
#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/command_line.h"
@@ -26,6 +27,7 @@
#include "chrome/browser/download/download_service_factory.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
+#include "chrome/browser/extensions/shell_window_registry.h"
#include "chrome/browser/first_run/first_run.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/printing/print_dialog_cloud.h"
@@ -69,6 +71,7 @@
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/cloud_print/cloud_print_class_mac.h"
+#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/mac/app_mode_common.h"
#include "chrome/common/pref_names.h"
@@ -193,6 +196,7 @@
- (BOOL)shouldQuitWithInProgressDownloads;
- (void)executeApplication:(id)sender;
- (void)profileWasRemoved:(const base::FilePath&)profilePath;
+- (void)showOrHideMenuItemsForPackagedApp:(NSNotification*)notification;
@end
class AppControllerProfileObserver : public ProfileInfoCacheObserver {
@@ -308,6 +312,12 @@
// Set up the command updater for when there are no windows open
[self initMenuState];
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(showOrHideMenuItemsForPackagedApp:)
+ name:NSWindowDidBecomeMainNotification
+ object:nil];
+
// Initialize the Profile menu.
[self initProfileMenu];
}
@@ -1378,6 +1388,52 @@
WorkAreaChanged());
}
+// If the window is an app window, show the menu bar for that app, otherwise
+// restore the Chrome menu bar.
+- (void)showOrHideMenuItemsForPackagedApp:(NSNotification*)notification {
+ NSMenu* mainMenu = [NSApp mainMenu];
+ apps::ShellWindow* shellWindow =
+ extensions::ShellWindowRegistry::GetShellWindowForNativeWindowAnyProfile(
+ [notification object]);
+
+ if (!shellWindow) {
+ if (!appMenuItem_)
+ return;
+
+ [mainMenu removeItem:appMenuItem_];
+ appMenuItem_.reset();
+
+ // Restore the Chrome main menu bar.
+ for (NSMenuItem* item in [mainMenu itemArray])
+ [item setHidden:NO];
+
+ return;
+ }
+
+ const extensions::Extension* app = shellWindow->extension();
+ NSString* appId = base::SysUTF8ToNSString(app->id());
+ NSString* title = base::SysUTF8ToNSString(app->name());
+
+ if (appMenuItem_) {
+ if ([[appMenuItem_ title] isEqualToString:appId])
+ return;
+
+ [mainMenu removeItem:appMenuItem_];
+ } else {
+ // Hide everything and add a menu item for the app.
+ for (NSMenuItem* item in [mainMenu itemArray])
+ [item setHidden:YES];
+ }
+
+ appMenuItem_.reset(
+ [[NSMenuItem alloc] initWithTitle:appId
+ action:nil
+ keyEquivalent:@""]);
+ base::scoped_nsobject<NSMenu> appMenu([[NSMenu alloc] initWithTitle:title]);
+ [appMenuItem_ setSubmenu:appMenu];
+ [mainMenu addItem:appMenuItem_];
+}
+
@end // @implementation AppController
//---------------------------------------------------------------------------
diff --git a/chrome/browser/app_controller_mac_browsertest.mm b/chrome/browser/app_controller_mac_browsertest.mm
index 11f2c98..567d183 100644
--- a/chrome/browser/app_controller_mac_browsertest.mm
+++ b/chrome/browser/app_controller_mac_browsertest.mm
@@ -6,10 +6,15 @@
#include "base/command_line.h"
#include "base/mac/scoped_nsobject.h"
+#include "base/strings/sys_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#import "chrome/browser/app_controller_mac.h"
+#include "chrome/browser/extensions/extension_test_message_listener.h"
+#include "chrome/browser/extensions/platform_app_browsertest_util.h"
+#include "chrome/browser/extensions/shell_window_registry.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/host_desktop.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#import "chrome/common/chrome_switches.h"
@@ -19,7 +24,8 @@
namespace {
-class AppControllerPlatformAppBrowserTest : public InProcessBrowserTest {
+class AppControllerPlatformAppBrowserTest
+ : public extensions::PlatformAppBrowserTest {
protected:
AppControllerPlatformAppBrowserTest()
: active_browser_list_(BrowserList::GetInstance(
@@ -27,6 +33,7 @@
}
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+ PlatformAppBrowserTest::SetUpCommandLine(command_line);
command_line->AppendSwitchASCII(switches::kAppId,
"1234");
}
@@ -48,6 +55,72 @@
EXPECT_EQ(1u, active_browser_list_->size());
}
+// Test that focusing an app window changes the menu bar.
+IN_PROC_BROWSER_TEST_F(AppControllerPlatformAppBrowserTest,
+ PlatformAppFocusUpdatesMenuBar) {
+ base::scoped_nsobject<AppController> app_controller(
+ [[AppController alloc] init]);
+
+ // Start two apps and wait for them to be launched.
+ ExtensionTestMessageListener listener_1("Launched", false);
+ const extensions::Extension* app_1 =
+ InstallAndLaunchPlatformApp("minimal_id");
+ ASSERT_TRUE(listener_1.WaitUntilSatisfied());
+ ExtensionTestMessageListener listener_2("Launched", false);
+ const extensions::Extension* app_2 =
+ InstallAndLaunchPlatformApp("minimal");
+ ASSERT_TRUE(listener_2.WaitUntilSatisfied());
+
+ NSMenu* main_menu = [NSApp mainMenu];
+ NSUInteger initial_menu_item_count = [[main_menu itemArray] count];
+
+ // When an app is focused, all Chrome menu items should be hidden, and a menu
+ // item for the app should be added.
+ apps::ShellWindow* app_1_shell_window =
+ extensions::ShellWindowRegistry::Get(profile())->
+ GetShellWindowsForApp(app_1->id()).front();
+ [[NSNotificationCenter defaultCenter]
+ postNotificationName:NSWindowDidBecomeMainNotification
+ object:app_1_shell_window->GetNativeWindow()];
+ NSArray* item_array = [main_menu itemArray];
+ EXPECT_EQ(initial_menu_item_count + 1, [item_array count]);
+ for (NSUInteger i = 0; i < initial_menu_item_count; ++i)
+ EXPECT_TRUE([[item_array objectAtIndex:i] isHidden]);
+ NSMenuItem* last_item = [item_array lastObject];
+ EXPECT_EQ(app_1->id(), base::SysNSStringToUTF8([last_item title]));
+ EXPECT_EQ(app_1->name(),
+ base::SysNSStringToUTF8([[last_item submenu] title]));
+ EXPECT_FALSE([last_item isHidden]);
+
+ // When another app is focused, the menu item for the app should change.
+ apps::ShellWindow* app_2_shell_window =
+ extensions::ShellWindowRegistry::Get(profile())->
+ GetShellWindowsForApp(app_2->id()).front();
+ [[NSNotificationCenter defaultCenter]
+ postNotificationName:NSWindowDidBecomeMainNotification
+ object:app_2_shell_window->GetNativeWindow()];
+ item_array = [main_menu itemArray];
+ EXPECT_EQ(initial_menu_item_count + 1, [item_array count]);
+ for (NSUInteger i = 0; i < initial_menu_item_count; ++i)
+ EXPECT_TRUE([[item_array objectAtIndex:i] isHidden]);
+ last_item = [item_array lastObject];
+ EXPECT_EQ(app_2->id(), base::SysNSStringToUTF8([last_item title]));
+ EXPECT_EQ(app_2->name(),
+ base::SysNSStringToUTF8([[last_item submenu] title]));
+ EXPECT_FALSE([last_item isHidden]);
+
+ // When Chrome is focused, the menu item for the app should be removed.
+ NSWindow* browser_native_window =
+ active_browser_list_->get(0)->window()->GetNativeWindow();
+ [[NSNotificationCenter defaultCenter]
+ postNotificationName:NSWindowDidBecomeMainNotification
+ object:browser_native_window];
+ item_array = [main_menu itemArray];
+ EXPECT_EQ(initial_menu_item_count, [item_array count]);
+ for (NSUInteger i = 0; i < initial_menu_item_count; ++i)
+ EXPECT_FALSE([[item_array objectAtIndex:i] isHidden]);
+}
+
class AppControllerWebAppBrowserTest : public InProcessBrowserTest {
protected:
AppControllerWebAppBrowserTest()
diff --git a/chrome/browser/autocomplete/autocomplete_browsertest.cc b/chrome/browser/autocomplete/autocomplete_browsertest.cc
index 8161ce37..1f43df5 100644
--- a/chrome/browser/autocomplete/autocomplete_browsertest.cc
+++ b/chrome/browser/autocomplete/autocomplete_browsertest.cc
@@ -32,6 +32,10 @@
#include "content/public/browser/notification_types.h"
#include "testing/gtest/include/gtest/gtest.h"
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
namespace {
string16 AutocompleteResultAsString(const AutocompleteResult& result) {
@@ -65,6 +69,12 @@
};
IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, Basic) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
WaitForTemplateURLServiceToLoad();
LocationBar* location_bar = GetLocationBar();
OmniboxView* location_entry = location_bar->GetLocationEntry();
@@ -109,6 +119,12 @@
#endif
IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, MAYBE_Autocomplete) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
WaitForTemplateURLServiceToLoad();
// The results depend on the history backend being loaded. Make sure it is
// loaded so that the autocomplete results are consistent.
@@ -153,9 +169,15 @@
}
IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, TabAwayRevertSelect) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
WaitForTemplateURLServiceToLoad();
// http://code.google.com/p/chromium/issues/detail?id=38385
- // Make sure that tabbing away from an empty omnibar causes a revert
+ // Make sure that tabbing away from an empty omnibox causes a revert
// and select all.
LocationBar* location_bar = GetLocationBar();
OmniboxView* location_entry = location_bar->GetLocationEntry();
@@ -174,6 +196,12 @@
}
IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, FocusSearch) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
WaitForTemplateURLServiceToLoad();
LocationBar* location_bar = GetLocationBar();
OmniboxView* location_entry = location_bar->GetLocationEntry();
diff --git a/chrome/browser/autocomplete/autocomplete_controller.cc b/chrome/browser/autocomplete/autocomplete_controller.cc
index 39937f9..77f53f8 100644
--- a/chrome/browser/autocomplete/autocomplete_controller.cc
+++ b/chrome/browser/autocomplete/autocomplete_controller.cc
@@ -151,12 +151,6 @@
bool use_hqp = !!(provider_types & AutocompleteProvider::TYPE_HISTORY_QUICK);
// TODO(mrossetti): Permanently modify the HistoryURLProvider to not search
// titles once HQP is turned on permanently.
- // History quick provider can be used on all platforms other than Android.
- // TODO(jcivelli): Enable the History Quick Provider and figure out why it
- // reports the wrong results for some pages.
-#if defined(OS_ANDROID)
- use_hqp = false;
-#endif
if (provider_types & AutocompleteProvider::TYPE_BUILTIN)
providers_.push_back(new BuiltinProvider(this, profile));
diff --git a/chrome/browser/autocomplete/autocomplete_match.cc b/chrome/browser/autocomplete/autocomplete_match.cc
index fc6774c..9c542ac 100644
--- a/chrome/browser/autocomplete/autocomplete_match.cc
+++ b/chrome/browser/autocomplete/autocomplete_match.cc
@@ -43,7 +43,6 @@
relevance(0),
typed_count(-1),
deletable(false),
- inline_autocomplete_offset(string16::npos),
transition(content::PAGE_TRANSITION_GENERATED),
is_history_what_you_typed_match(false),
type(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED),
@@ -59,7 +58,6 @@
relevance(relevance),
typed_count(-1),
deletable(deletable),
- inline_autocomplete_offset(string16::npos),
transition(content::PAGE_TRANSITION_TYPED),
is_history_what_you_typed_match(false),
type(type),
@@ -73,7 +71,7 @@
typed_count(match.typed_count),
deletable(match.deletable),
fill_into_edit(match.fill_into_edit),
- inline_autocomplete_offset(match.inline_autocomplete_offset),
+ inline_autocompletion(match.inline_autocompletion),
destination_url(match.destination_url),
stripped_destination_url(match.stripped_destination_url),
contents(match.contents),
@@ -107,7 +105,7 @@
typed_count = match.typed_count;
deletable = match.deletable;
fill_into_edit = match.fill_into_edit;
- inline_autocomplete_offset = match.inline_autocomplete_offset;
+ inline_autocompletion = match.inline_autocompletion;
destination_url = match.destination_url;
stripped_destination_url = match.stripped_destination_url;
contents = match.contents;
diff --git a/chrome/browser/autocomplete/autocomplete_match.h b/chrome/browser/autocomplete/autocomplete_match.h
index 4d4ca47..224bf99 100644
--- a/chrome/browser/autocomplete/autocomplete_match.h
+++ b/chrome/browser/autocomplete/autocomplete_match.h
@@ -246,10 +246,9 @@
// for search suggestions, this would just be the search terms.
string16 fill_into_edit;
- // The position within fill_into_edit from which we'll display the inline
- // autocomplete string. This will be string16::npos if this match should
- // not be inline autocompleted.
- size_t inline_autocomplete_offset;
+ // The inline autocompletion to display after the user's typing in the
+ // omnibox, if this match becomes the default match. It may be empty.
+ string16 inline_autocompletion;
// The URL to actually load when the autocomplete item is selected. This URL
// should be canonical so we can compare URLs with strcmp to avoid dupes.
diff --git a/chrome/browser/autocomplete/contact_provider_chromeos.cc b/chrome/browser/autocomplete/contact_provider_chromeos.cc
index 7644eae..afa14ba 100644
--- a/chrome/browser/autocomplete/contact_provider_chromeos.cc
+++ b/chrome/browser/autocomplete/contact_provider_chromeos.cc
@@ -227,7 +227,6 @@
const AutocompleteInput& input,
const ContactData& contact) {
AutocompleteMatch match(this, 0, false, AutocompleteMatchType::CONTACT);
- match.inline_autocomplete_offset = string16::npos;
match.contents = contact.full_name;
match.fill_into_edit = match.contents;
match.relevance = kBaseRelevance +
diff --git a/chrome/browser/autocomplete/extension_app_provider.cc b/chrome/browser/autocomplete/extension_app_provider.cc
index 003cdac..06f0daf 100644
--- a/chrome/browser/autocomplete/extension_app_provider.cc
+++ b/chrome/browser/autocomplete/extension_app_provider.cc
@@ -79,7 +79,6 @@
match.fill_into_edit =
app.should_match_against_launch_url ? app.launch_url : input.text();
match.destination_url = GURL(app.launch_url);
- match.inline_autocomplete_offset = string16::npos;
match.contents = AutocompleteMatch::SanitizeString(app.name);
AutocompleteMatch::ClassifyLocationInString(name_match_index,
input.text().length(), app.name.length(), ACMatchClassification::NONE,
diff --git a/chrome/browser/autocomplete/history_quick_provider.cc b/chrome/browser/autocomplete/history_quick_provider.cc
index 073aa18..fc74e13 100644
--- a/chrome/browser/autocomplete/history_quick_provider.cc
+++ b/chrome/browser/autocomplete/history_quick_provider.cc
@@ -272,17 +272,18 @@
match.contents_class =
SpansFromTermMatch(new_matches, match.contents.length(), true);
- if (!history_match.can_inline) {
- match.inline_autocomplete_offset = string16::npos;
- } else {
+ if (history_match.can_inline) {
DCHECK(!new_matches.empty());
- match.inline_autocomplete_offset = new_matches[0].offset +
+ size_t inline_autocomplete_offset = new_matches[0].offset +
new_matches[0].length;
- // The following will happen if the user has typed an URL with a scheme
- // and the last character typed is a slash because that slash is removed
- // by the FormatURLWithOffsets call above.
- if (match.inline_autocomplete_offset > match.fill_into_edit.length())
- match.inline_autocomplete_offset = match.fill_into_edit.length();
+ // |inline_autocomplete_offset| may be beyond the end of the
+ // |fill_into_edit| if the user has typed an URL with a scheme and the
+ // last character typed is a slash. That slash is removed by the
+ // FormatURLWithOffsets call above.
+ if (inline_autocomplete_offset < match.fill_into_edit.length()) {
+ match.inline_autocompletion =
+ match.fill_into_edit.substr(inline_autocomplete_offset);
+ }
}
// Format the description autocomplete presentation.
diff --git a/chrome/browser/autocomplete/history_quick_provider_unittest.cc b/chrome/browser/autocomplete/history_quick_provider_unittest.cc
index 7e28403..fe50366 100644
--- a/chrome/browser/autocomplete/history_quick_provider_unittest.cc
+++ b/chrome/browser/autocomplete/history_quick_provider_unittest.cc
@@ -295,11 +295,11 @@
<< "' but we expected '" << expected_fill_into_edit << "'.";
size_t text_pos = expected_fill_into_edit.find(text);
ASSERT_NE(string16::npos, text_pos);
- EXPECT_EQ(text_pos + text.size(),
- ac_matches_[0].inline_autocomplete_offset);
+ EXPECT_EQ(ac_matches_[0].fill_into_edit.substr(text_pos + text.size()),
+ ac_matches_[0].inline_autocompletion);
} else {
// When the top scorer is not inline-able autocomplete offset must be npos.
- EXPECT_EQ(string16::npos, ac_matches_[0].inline_autocomplete_offset);
+ EXPECT_TRUE(ac_matches_[0].inline_autocompletion.empty());
// Also, the score must be too low to be inlineable.
EXPECT_LT(ac_matches_[0].relevance,
AutocompleteResult::kLowestDefaultScore);
diff --git a/chrome/browser/autocomplete/history_url_provider.cc b/chrome/browser/autocomplete/history_url_provider.cc
index 4c51b30..48c56a1 100644
--- a/chrome/browser/autocomplete/history_url_provider.cc
+++ b/chrome/browser/autocomplete/history_url_provider.cc
@@ -349,8 +349,8 @@
match.fill_into_edit =
AutocompleteInput::FormattedStringWithEquivalentMeaning(url,
display_string);
- // NOTE: Don't set match.inline_autocomplete_offset (to allow inline
- // autocompletion) here, it's surprising and annoying.
+ // NOTE: Don't set match.inline_autocompletion to something non-empty here;
+ // it's surprising and annoying.
// Try to highlight "innermost" match location. If we fix up "w" into
// "www.w.com", we want to highlight the fifth character, not the first.
@@ -1059,10 +1059,12 @@
net::FormatUrl(info.url(), languages, format_types,
net::UnescapeRule::SPACES, NULL, NULL,
&inline_autocomplete_offset));
- if (!params->prevent_inline_autocomplete)
- match.inline_autocomplete_offset = inline_autocomplete_offset;
- DCHECK((match.inline_autocomplete_offset == string16::npos) ||
- (match.inline_autocomplete_offset <= match.fill_into_edit.length()));
+ if (!params->prevent_inline_autocomplete &&
+ (inline_autocomplete_offset != string16::npos)) {
+ DCHECK(inline_autocomplete_offset <= match.fill_into_edit.length());
+ match.inline_autocompletion =
+ match.fill_into_edit.substr(inline_autocomplete_offset);
+ }
size_t match_start = history_match.input_location;
match.contents = net::FormatUrl(info.url(), languages,
diff --git a/chrome/browser/autocomplete/history_url_provider_unittest.cc b/chrome/browser/autocomplete/history_url_provider_unittest.cc
index c35b45f..b26c9a0 100644
--- a/chrome/browser/autocomplete/history_url_provider_unittest.cc
+++ b/chrome/browser/autocomplete/history_url_provider_unittest.cc
@@ -183,8 +183,6 @@
expected_urls, num_results, &type);
}
- void RunAdjustOffsetTest(const string16 text, size_t expected_offset);
-
content::TestBrowserThreadBundle thread_bundle_;
ACMatches matches_;
scoped_ptr<TestingProfile> profile_;
@@ -286,19 +284,6 @@
EXPECT_EQ(expected_urls[i], matches_[i].destination_url.spec());
}
-void HistoryURLProviderTest::RunAdjustOffsetTest(const string16 text,
- size_t expected_offset) {
- AutocompleteInput input(text, string16::npos, string16(), GURL(), false,
- false, true, AutocompleteInput::ALL_MATCHES);
- autocomplete_->Start(input, false);
- if (!autocomplete_->done())
- base::MessageLoop::current()->Run();
-
- matches_ = autocomplete_->matches();
- ASSERT_GE(matches_.size(), 1U) << "Input text: " << text;
- EXPECT_EQ(expected_offset, matches_[0].inline_autocomplete_offset);
-}
-
TEST_F(HistoryURLProviderTest, PromoteShorterURLs) {
// Test that hosts get synthesized below popular pages.
const std::string expected_nonsynth[] = {
@@ -490,7 +475,8 @@
const std::string fixup_1[] = {"file:///C:/foo.txt"};
ASSERT_NO_FATAL_FAILURE(RunTest(input_1, string16(), false, fixup_1,
arraysize(fixup_1)));
- EXPECT_EQ(input_1.length(), matches_.front().inline_autocomplete_offset);
+ EXPECT_EQ(ASCIIToUTF16("///C:/foo.txt"),
+ matches_.front().inline_autocompletion);
// Fixing up "http:/" should result in an inline autocomplete offset of just
// after "http:/", not just after "http:".
@@ -502,7 +488,8 @@
};
ASSERT_NO_FATAL_FAILURE(RunTest(input_2, string16(), false, fixup_2,
arraysize(fixup_2)));
- EXPECT_EQ(input_2.length(), matches_.front().inline_autocomplete_offset);
+ EXPECT_EQ(ASCIIToUTF16("/bogussite.com/a"),
+ matches_.front().inline_autocompletion);
// Adding a TLD to a small number like "56" should result in "www.56.com"
// rather than "0.0.0.56.com".
@@ -522,12 +509,6 @@
arraysize(fixup_5));
}
-TEST_F(HistoryURLProviderTest, AdjustOffset) {
- RunAdjustOffsetTest(WideToUTF16(L"http://www.\uAD50\uC721"), 13);
- RunAdjustOffsetTest(ASCIIToUTF16("http://spaces.com/path%20with%20spa"), 31);
- RunAdjustOffsetTest(ASCIIToUTF16("http://ms/c++ s"), 15);
-}
-
// Make sure the results for the input 'p' don't change between the first and
// second passes.
TEST_F(HistoryURLProviderTest, EmptyVisits) {
@@ -580,7 +561,7 @@
// None of the matches should attempt to autocomplete.
matches_ = autocomplete_->matches();
for (size_t i = 0; i < matches_.size(); ++i)
- EXPECT_EQ(string16::npos, matches_[i].inline_autocomplete_offset);
+ EXPECT_TRUE(matches_[i].inline_autocompletion.empty());
}
TEST_F(HistoryURLProviderTest, TreatEmailsAsSearches) {
diff --git a/chrome/browser/autocomplete/keyword_provider.cc b/chrome/browser/autocomplete/keyword_provider.cc
index 10ae975..dd2959e 100644
--- a/chrome/browser/autocomplete/keyword_provider.cc
+++ b/chrome/browser/autocomplete/keyword_provider.cc
@@ -446,12 +446,11 @@
if (!remaining_input.empty() || !keyword_complete || supports_replacement)
match.fill_into_edit.push_back(L' ');
match.fill_into_edit.append(remaining_input);
- // If we wanted to set |result.inline_autocomplete_offset| correctly, we'd
- // need CleanUserInputKeyword() to return the amount of adjustment it's made
- // to the user's input. Because right now inexact keyword matches can't score
+ // If we wanted to set |result.inline_autocompletion| correctly, we'd need
+ // CleanUserInputKeyword() to return the amount of adjustment it's made to
+ // the user's input. Because right now inexact keyword matches can't score
// more highly than a "what you typed" match from one of the other providers,
// we just don't bother to do this, and leave inline autocompletion off.
- match.inline_autocomplete_offset = string16::npos;
// Create destination URL and popup entry content by substituting user input
// into keyword templates.
diff --git a/chrome/browser/autocomplete/search_provider.cc b/chrome/browser/autocomplete/search_provider.cc
index 6f22d09..8806491 100644
--- a/chrome/browser/autocomplete/search_provider.cc
+++ b/chrome/browser/autocomplete/search_provider.cc
@@ -326,8 +326,7 @@
match.fill_into_edit.append(match.keyword + char16(' '));
if (!input.prevent_inline_autocomplete() &&
StartsWith(query_string, input_text, false)) {
- match.inline_autocomplete_offset =
- match.fill_into_edit.length() + input_text.length();
+ match.inline_autocompletion = query_string.substr(input_text.length());
}
match.fill_into_edit.append(query_string);
@@ -1076,7 +1075,7 @@
return
matches_.front().type != AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED &&
matches_.front().type != AutocompleteMatchType::SEARCH_OTHER_ENGINE &&
- matches_.front().inline_autocomplete_offset == string16::npos &&
+ matches_.front().inline_autocompletion.empty() &&
matches_.front().fill_into_edit != input_.text();
}
@@ -1446,10 +1445,12 @@
net::FormatUrl(navigation.url(), languages, format_types,
net::UnescapeRule::SPACES, NULL, NULL,
&inline_autocomplete_offset));
- if (!input_.prevent_inline_autocomplete())
- match.inline_autocomplete_offset = inline_autocomplete_offset;
- DCHECK((match.inline_autocomplete_offset == string16::npos) ||
- (match.inline_autocomplete_offset <= match.fill_into_edit.length()));
+ if (!input_.prevent_inline_autocomplete() &&
+ (inline_autocomplete_offset != string16::npos)) {
+ DCHECK(inline_autocomplete_offset <= match.fill_into_edit.length());
+ match.inline_autocompletion =
+ match.fill_into_edit.substr(inline_autocomplete_offset);
+ }
match.contents = net::FormatUrl(navigation.url(), languages,
format_types, net::UnescapeRule::SPACES, NULL, NULL, &match_start);
diff --git a/chrome/browser/autocomplete/search_provider_unittest.cc b/chrome/browser/autocomplete/search_provider_unittest.cc
index 2551ca2..b32cadc 100644
--- a/chrome/browser/autocomplete/search_provider_unittest.cc
+++ b/chrome/browser/autocomplete/search_provider_unittest.cc
@@ -666,8 +666,8 @@
AutocompleteMatch term_match;
EXPECT_TRUE(FindMatchWithDestination(term_url, &term_match));
EXPECT_GT(term_match.relevance, wyt_match.relevance);
- EXPECT_EQ(1u, term_match.inline_autocomplete_offset);
EXPECT_EQ(ASCIIToUTF16("FOO"), term_match.fill_into_edit);
+ EXPECT_EQ(ASCIIToUTF16("OO"), term_match.inline_autocompletion);
}
// Verifies AutocompleteControllers return results (including keyword
@@ -895,108 +895,109 @@
struct {
const std::string json;
const std::string matches[4];
+ const std::string inline_autocompletion;
} cases[] = {
// Ensure that suggestrelevance scores reorder matches.
{ "[\"a\",[\"b\", \"c\"],[],[],{\"google:suggestrelevance\":[1, 2]}]",
- { "a", "c", "b", kNotApplicable } },
+ { "a", "c", "b", kNotApplicable }, std::string() },
{ "[\"a\",[\"http://b.com\", \"http://c.com\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"],"
"\"google:suggestrelevance\":[1, 2]}]",
- { "a", "c.com", "b.com", kNotApplicable } },
+ { "a", "c.com", "b.com", kNotApplicable }, std::string() },
// Without suggested relevance scores, we should only allow one
// navsuggest result to be be displayed.
{ "[\"a\",[\"http://b.com\", \"http://c.com\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"]}]",
- { "a", "b.com", kNotApplicable, kNotApplicable } },
+ { "a", "b.com", kNotApplicable, kNotApplicable }, std::string() },
// Ensure that verbatimrelevance scores reorder or suppress verbatim.
// Negative values will have no effect; the calculated value will be used.
{ "[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":9999,"
"\"google:suggestrelevance\":[9998]}]",
- { "a", "a1", kNotApplicable, kNotApplicable } },
+ { "a", "a1", kNotApplicable, kNotApplicable }, std::string() },
{ "[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":9998,"
"\"google:suggestrelevance\":[9999]}]",
- { "a1", "a", kNotApplicable, kNotApplicable } },
+ { "a1", "a", kNotApplicable, kNotApplicable }, "1" },
{ "[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":0,"
"\"google:suggestrelevance\":[9999]}]",
- { "a1", kNotApplicable, kNotApplicable, kNotApplicable } },
+ { "a1", kNotApplicable, kNotApplicable, kNotApplicable }, "1" },
{ "[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":-1,"
"\"google:suggestrelevance\":[9999]}]",
- { "a1", "a", kNotApplicable, kNotApplicable } },
+ { "a1", "a", kNotApplicable, kNotApplicable }, "1" },
{ "[\"a\",[\"http://a.com\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\"],"
"\"google:verbatimrelevance\":9999,"
"\"google:suggestrelevance\":[9998]}]",
- { "a", "a.com", kNotApplicable, kNotApplicable } },
+ { "a", "a.com", kNotApplicable, kNotApplicable }, std::string() },
{ "[\"a\",[\"http://a.com\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\"],"
"\"google:verbatimrelevance\":9998,"
"\"google:suggestrelevance\":[9999]}]",
- { "a.com", "a", kNotApplicable, kNotApplicable } },
+ { "a.com", "a", kNotApplicable, kNotApplicable }, ".com" },
{ "[\"a\",[\"http://a.com\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\"],"
"\"google:verbatimrelevance\":0,"
"\"google:suggestrelevance\":[9999]}]",
- { "a.com", kNotApplicable, kNotApplicable, kNotApplicable } },
+ { "a.com", kNotApplicable, kNotApplicable, kNotApplicable }, ".com" },
{ "[\"a\",[\"http://a.com\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\"],"
"\"google:verbatimrelevance\":-1,"
"\"google:suggestrelevance\":[9999]}]",
- { "a.com", "a", kNotApplicable, kNotApplicable } },
+ { "a.com", "a", kNotApplicable, kNotApplicable }, ".com" },
// Ensure that both types of relevance scores reorder matches together.
{ "[\"a\",[\"a1\", \"a2\"],[],[],{\"google:suggestrelevance\":[9999, 9997],"
"\"google:verbatimrelevance\":9998}]",
- { "a1", "a", "a2", kNotApplicable } },
+ { "a1", "a", "a2", kNotApplicable }, "1" },
// Ensure that only inlinable matches may be ranked as the highest result.
// Ignore all suggested relevance scores if this constraint is violated.
{ "[\"a\",[\"b\"],[],[],{\"google:suggestrelevance\":[9999]}]",
- { "a", "b", kNotApplicable, kNotApplicable } },
+ { "a", "b", kNotApplicable, kNotApplicable }, std::string() },
{ "[\"a\",[\"b\"],[],[],{\"google:suggestrelevance\":[9999],"
"\"google:verbatimrelevance\":0}]",
- { "a", "b", kNotApplicable, kNotApplicable } },
+ { "a", "b", kNotApplicable, kNotApplicable }, std::string() },
{ "[\"a\",[\"http://b.com\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\"],"
"\"google:suggestrelevance\":[9999]}]",
- { "a", "b.com", kNotApplicable, kNotApplicable } },
+ { "a", "b.com", kNotApplicable, kNotApplicable }, std::string() },
{ "[\"a\",[\"http://b.com\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\"],"
"\"google:suggestrelevance\":[9999],"
"\"google:verbatimrelevance\":0}]",
- { "a", "b.com", kNotApplicable, kNotApplicable } },
+ { "a", "b.com", kNotApplicable, kNotApplicable }, std::string() },
// Ensure that the top result is ranked as highly as calculated verbatim.
// Ignore the suggested verbatim relevance if this constraint is violated.
{ "[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":0}]",
- { "a", "a1", kNotApplicable, kNotApplicable } },
+ { "a", "a1", kNotApplicable, kNotApplicable }, std::string() },
{ "[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":1}]",
- { "a", "a1", kNotApplicable, kNotApplicable } },
+ { "a", "a1", kNotApplicable, kNotApplicable }, std::string() },
{ "[\"a\",[\"a1\"],[],[],{\"google:suggestrelevance\":[1],"
"\"google:verbatimrelevance\":0}]",
- { "a", "a1", kNotApplicable, kNotApplicable } },
+ { "a", "a1", kNotApplicable, kNotApplicable }, std::string() },
{ "[\"a\",[\"a1\", \"a2\"],[],[],{\"google:suggestrelevance\":[1, 2],"
"\"google:verbatimrelevance\":0}]",
- { "a", "a2", "a1", kNotApplicable } },
+ { "a", "a2", "a1", kNotApplicable }, std::string() },
{ "[\"a\",[\"a1\", \"a2\"],[],[],{\"google:suggestrelevance\":[1, 3],"
"\"google:verbatimrelevance\":2}]",
- { "a", "a2", "a1", kNotApplicable } },
+ { "a", "a2", "a1", kNotApplicable }, std::string() },
{ "[\"a\",[\"http://a.com\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\"],"
"\"google:suggestrelevance\":[1],"
"\"google:verbatimrelevance\":0}]",
- { "a", "a.com", kNotApplicable, kNotApplicable } },
+ { "a", "a.com", kNotApplicable, kNotApplicable }, std::string() },
{ "[\"a\",[\"http://a1.com\", \"http://a2.com\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"],"
"\"google:suggestrelevance\":[1, 2],"
"\"google:verbatimrelevance\":0}]",
- { "a", "a2.com", "a1.com", kNotApplicable } },
+ { "a", "a2.com", "a1.com", kNotApplicable }, std::string() },
// Ensure that all suggestions are considered, regardless of order.
{ "[\"a\",[\"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\"],[],[],"
"{\"google:suggestrelevance\":[1, 2, 3, 4, 5, 6, 7]}]",
- { "a", "h", "g", "f" } },
+ { "a", "h", "g", "f" }, std::string() },
{ "[\"a\",[\"http://b.com\", \"http://c.com\", \"http://d.com\","
"\"http://e.com\", \"http://f.com\", \"http://g.com\","
"\"http://h.com\"],[],[],"
@@ -1005,37 +1006,37 @@
"\"NAVIGATION\", \"NAVIGATION\","
"\"NAVIGATION\"],"
"\"google:suggestrelevance\":[1, 2, 3, 4, 5, 6, 7]}]",
- { "a", "h.com", "g.com", "f.com" } },
+ { "a", "h.com", "g.com", "f.com" }, std::string() },
// Ensure that incorrectly sized suggestion relevance lists are ignored.
{ "[\"a\",[\"a1\", \"a2\"],[],[],{\"google:suggestrelevance\":[1]}]",
- { "a", "a1", "a2", kNotApplicable } },
+ { "a", "a1", "a2", kNotApplicable }, std::string() },
{ "[\"a\",[\"a1\"],[],[],{\"google:suggestrelevance\":[9999, 1]}]",
- { "a", "a1", kNotApplicable, kNotApplicable } },
+ { "a", "a1", kNotApplicable, kNotApplicable }, std::string() },
{ "[\"a\",[\"http://a1.com\", \"http://a2.com\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"],"
"\"google:suggestrelevance\":[1]}]",
- { "a", "a1.com", kNotApplicable, kNotApplicable } },
+ { "a", "a1.com", kNotApplicable, kNotApplicable }, std::string() },
{ "[\"a\",[\"http://a1.com\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\"],"
"\"google:suggestrelevance\":[9999, 1]}]",
- { "a", "a1.com", kNotApplicable, kNotApplicable } },
+ { "a", "a1.com", kNotApplicable, kNotApplicable }, std::string() },
// Ensure that all 'verbatim' results are merged with their maximum score.
{ "[\"a\",[\"a\", \"a1\", \"a2\"],[],[],"
"{\"google:suggestrelevance\":[9998, 9997, 9999]}]",
- { "a2", "a", "a1", kNotApplicable } },
+ { "a2", "a", "a1", kNotApplicable }, "2" },
{ "[\"a\",[\"a\", \"a1\", \"a2\"],[],[],"
"{\"google:suggestrelevance\":[9998, 9997, 9999],"
"\"google:verbatimrelevance\":0}]",
- { "a2", "a", "a1", kNotApplicable } },
+ { "a2", "a", "a1", kNotApplicable }, "2" },
// Ensure that verbatim is always generated without other suggestions.
// TODO(msw): Ensure verbatimrelevance is respected (except suppression).
{ "[\"a\",[],[],[],{\"google:verbatimrelevance\":1}]",
- { "a", kNotApplicable, kNotApplicable, kNotApplicable } },
+ { "a", kNotApplicable, kNotApplicable, kNotApplicable }, std::string() },
{ "[\"a\",[],[],[],{\"google:verbatimrelevance\":0}]",
- { "a", kNotApplicable, kNotApplicable, kNotApplicable } },
+ { "a", kNotApplicable, kNotApplicable, kNotApplicable }, std::string() },
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) {
@@ -1052,8 +1053,8 @@
const ACMatches& matches = provider_->matches();
// The top match must inline and score as highly as calculated verbatim.
ASSERT_FALSE(matches.empty());
- EXPECT_NE(string16::npos, matches[0].inline_autocomplete_offset) <<
- description;
+ EXPECT_EQ(ASCIIToUTF16(cases[i].inline_autocompletion),
+ matches[0].inline_autocompletion) << description;
EXPECT_GE(matches[0].relevance, 1300) << description;
size_t j = 0;
@@ -1083,6 +1084,7 @@
const std::string contents;
const bool from_keyword;
} matches[5];
+ const std::string inline_autocompletion;
} cases[] = {
// Ensure that suggest relevance scores reorder matches and that
// the keyword verbatim (lacking a suggested verbatim score) beats
@@ -1092,7 +1094,8 @@
{ "k a", false },
{ "c", true },
{ "b", true },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
// Again, check that relevance scores reorder matches, just this
// time with navigation matches. This also checks that with
// suggested relevance scores we allow multiple navsuggest results.
@@ -1109,7 +1112,8 @@
{ "d", true },
{ "c.com", false },
{ "b.com", false },
- { "k a", false }, } },
+ { "k a", false }, },
+ std::string() },
// Without suggested relevance scores, we should only allow one
// navsuggest result to be be displayed.
@@ -1119,7 +1123,8 @@
{ "b.com", false },
{ "k a", false },
{ kNotApplicable, false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
// Ensure that verbatimrelevance scores reorder or suppress verbatim.
// Negative values will have no effect; the calculated value will be used.
@@ -1129,28 +1134,32 @@
{ "a1", true },
{ "k a", false },
{ kNotApplicable, false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
{ "[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":9998,"
"\"google:suggestrelevance\":[9999]}]",
{ { "a1", true },
{ "a", true },
{ "k a", false },
{ kNotApplicable, false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ "1" },
{ "[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":0,"
"\"google:suggestrelevance\":[9999]}]",
{ { "a1", true },
{ "k a", false },
{ kNotApplicable, false },
{ kNotApplicable, false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ "1" },
{ "[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":-1,"
"\"google:suggestrelevance\":[9999]}]",
{ { "a1", true },
{ "a", true },
{ "k a", false },
{ kNotApplicable, false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ "1" },
{ "[\"a\",[\"http://a.com\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\"],"
"\"google:verbatimrelevance\":9999,"
@@ -1159,7 +1168,8 @@
{ "a.com", false },
{ "k a", false },
{ kNotApplicable, false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
// Ensure that both types of relevance scores reorder matches together.
{ "[\"a\",[\"a1\", \"a2\"],[],[],{\"google:suggestrelevance\":[9999, 9997],"
@@ -1168,7 +1178,8 @@
{ "a", true },
{ "a2", true },
{ "k a", false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ "1" },
// Ensure that only inlinable matches may be ranked as the highest result.
// Ignore all suggested relevance scores if this constraint is violated.
@@ -1177,14 +1188,16 @@
{ "b", true },
{ "k a", false },
{ kNotApplicable, false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
{ "[\"a\",[\"b\"],[],[],{\"google:suggestrelevance\":[9999],"
"\"google:verbatimrelevance\":0}]",
{ { "a", true },
{ "b", true },
{ "k a", false },
{ kNotApplicable, false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
{ "[\"a\",[\"http://b.com\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\"],"
"\"google:suggestrelevance\":[9999]}]",
@@ -1192,7 +1205,8 @@
{ "b.com", false },
{ "k a", false },
{ kNotApplicable, false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
{ "[\"a\",[\"http://b.com\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\"],"
"\"google:suggestrelevance\":[9999],"
@@ -1201,7 +1215,8 @@
{ "b.com", false },
{ "k a", false },
{ kNotApplicable, false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
// Ensure that the top result is ranked as highly as calculated verbatim.
// Ignore the suggested verbatim relevance if this constraint is violated.
@@ -1212,13 +1227,15 @@
{ "a1", true },
{ "k a", false },
{ kNotApplicable, false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
{ "[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":1}]",
{ { "a", true },
{ "a1", true },
{ "k a", false },
{ kNotApplicable, false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
// Continuing the same category of tests, but make sure we keep the
// suggested relevance scores even as we discard the verbatim relevance
// scores.
@@ -1228,21 +1245,24 @@
{ "k a", false },
{ "a1", true },
{ kNotApplicable, false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
{ "[\"a\",[\"a1\", \"a2\"],[],[],{\"google:suggestrelevance\":[1, 2],"
"\"google:verbatimrelevance\":0}]",
{ { "a", true },
{ "k a", false },
{ "a2", true },
{ "a1", true },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
{ "[\"a\",[\"a1\", \"a2\"],[],[],{\"google:suggestrelevance\":[1, 3],"
"\"google:verbatimrelevance\":2}]",
{ { "a", true },
{ "k a", false },
{ "a2", true },
{ "a1", true },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
// Ensure that all suggestions are considered, regardless of order.
{ "[\"a\",[\"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\"],[],[],"
@@ -1251,7 +1271,8 @@
{ "k a", false },
{ "h", true },
{ "g", true },
- { "f", true } } },
+ { "f", true } },
+ std::string() },
{ "[\"a\",[\"http://b.com\", \"http://c.com\", \"http://d.com\","
"\"http://e.com\", \"http://f.com\", \"http://g.com\","
"\"http://h.com\"],[],[],"
@@ -1264,7 +1285,8 @@
{ "k a", false },
{ "h.com", false },
{ "g.com", false },
- { "f.com", false } } },
+ { "f.com", false } },
+ std::string() },
// Ensure that incorrectly sized suggestion relevance lists are ignored.
// Note that keyword suggestions by default (not in suggested relevance
@@ -1274,13 +1296,15 @@
{ "a1", true },
{ "a2", true },
{ "k a", false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
{ "[\"a\",[\"a1\"],[],[],{\"google:suggestrelevance\":[9999, 1]}]",
{ { "a", true },
{ "a1", true },
{ "k a", false },
{ kNotApplicable, false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
// In this case, ignored the suggested relevance scores means we keep
// only one navsuggest result.
{ "[\"a\",[\"http://a1.com\", \"http://a2.com\"],[],[],"
@@ -1290,7 +1314,8 @@
{ "a1.com", false },
{ "k a", false },
{ kNotApplicable, false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
{ "[\"a\",[\"http://a1.com\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\"],"
"\"google:suggestrelevance\":[9999, 1]}]",
@@ -1298,7 +1323,8 @@
{ "a1.com", false },
{ "k a", false },
{ kNotApplicable, false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
// Ensure that all 'verbatim' results are merged with their maximum score.
{ "[\"a\",[\"a\", \"a1\", \"a2\"],[],[],"
@@ -1307,7 +1333,8 @@
{ "a", true },
{ "a1", true },
{ "k a", false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ "2" },
{ "[\"a\",[\"a\", \"a1\", \"a2\"],[],[],"
"{\"google:suggestrelevance\":[9998, 9997, 9999],"
"\"google:verbatimrelevance\":0}]",
@@ -1315,7 +1342,8 @@
{ "a", true },
{ "a1", true },
{ "k a", false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ "2" },
// Ensure that verbatim is always generated without other suggestions.
// TODO(mpearson): Ensure the value of verbatimrelevance is respected
@@ -1325,13 +1353,15 @@
{ "k a", false },
{ kNotApplicable, false },
{ kNotApplicable, false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
{ "[\"a\",[],[],[],{\"google:verbatimrelevance\":0}]",
{ { "a", true },
{ "k a", false },
{ kNotApplicable, false },
{ kNotApplicable, false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
// Check that navsuggestions will be demoted below queries.
// (Navsuggestions are not allowed to appear first.) In the process,
@@ -1346,7 +1376,8 @@
{ "a2.com", false },
{ "a1.com", false },
{ "k a", false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
{ "[\"a\",[\"http://a1.com\", \"http://a2.com\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"],"
"\"google:verbatimrelevance\":9990,"
@@ -1355,7 +1386,8 @@
{ "a1.com", false },
{ "a2.com", false },
{ "k a", false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
// Check when navsuggest scores more than verbatim and there is query
// suggestion but it scores lower.
{ "[\"a\",[\"http://a1.com\", \"http://a2.com\", \"a3\"],[],[],"
@@ -1366,7 +1398,8 @@
{ "a2.com", false },
{ "a1.com", false },
{ "a3", true },
- { "k a", false } } },
+ { "k a", false } },
+ std::string() },
{ "[\"a\",[\"http://a1.com\", \"http://a2.com\", \"a3\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\", \"QUERY\"],"
"\"google:verbatimrelevance\":9990,"
@@ -1375,7 +1408,8 @@
{ "a1.com", false },
{ "a2.com", false },
{ "a3", true },
- { "k a", false } } },
+ { "k a", false } },
+ std::string() },
// Check when navsuggest scores more than a query suggestion. There is
// a verbatim but it scores lower.
{ "[\"a\",[\"http://a1.com\", \"http://a2.com\", \"a3\"],[],[],"
@@ -1386,7 +1420,8 @@
{ "a2.com", false },
{ "a1.com", false },
{ "a", true },
- { "k a", false } } },
+ { "k a", false } },
+ "3" },
{ "[\"a\",[\"http://a1.com\", \"http://a2.com\", \"a3\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\", \"QUERY\"],"
"\"google:verbatimrelevance\":9990,"
@@ -1395,7 +1430,8 @@
{ "a1.com", false },
{ "a2.com", false },
{ "a", true },
- { "k a", false } } },
+ { "k a", false } },
+ "3" },
{ "[\"a\",[\"http://a1.com\", \"http://a2.com\", \"a3\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\", \"QUERY\"],"
"\"google:verbatimrelevance\":0,"
@@ -1404,7 +1440,8 @@
{ "a2.com", false },
{ "a1.com", false },
{ "k a", false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ "3" },
{ "[\"a\",[\"http://a1.com\", \"http://a2.com\", \"a3\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\", \"QUERY\"],"
"\"google:verbatimrelevance\":0,"
@@ -1413,7 +1450,8 @@
{ "a1.com", false },
{ "a2.com", false },
{ "k a", false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ "3" },
// Check when there is neither verbatim nor a query suggestion that,
// because we can't demote navsuggestions below a query suggestion,
// we abandon suggested relevance scores entirely. One consequence is
@@ -1429,7 +1467,8 @@
{ "a2.com", false },
{ "k a", false },
{ kNotApplicable, false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
{ "[\"a\",[\"http://a1.com\", \"http://a2.com\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"],"
"\"google:verbatimrelevance\":0,"
@@ -1438,7 +1477,8 @@
{ "a1.com", false },
{ "k a", false },
{ kNotApplicable, false },
- { kNotApplicable, false } } },
+ { kNotApplicable, false } },
+ std::string() },
// More checks that everything works when it's not necessary to demote.
{ "[\"a\",[\"http://a1.com\", \"http://a2.com\", \"a3\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\", \"QUERY\"],"
@@ -1448,7 +1488,8 @@
{ "a2.com", false },
{ "a1.com", false },
{ "a", true },
- { "k a", false } } },
+ { "k a", false } },
+ "3" },
{ "[\"a\",[\"http://a1.com\", \"http://a2.com\", \"a3\"],[],[],"
"{\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\", \"QUERY\"],"
"\"google:verbatimrelevance\":9990,"
@@ -1457,7 +1498,8 @@
{ "a1.com", false },
{ "a2.com", false },
{ "a", true },
- { "k a", false } } },
+ { "k a", false } },
+ "3" },
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) {
@@ -1485,8 +1527,8 @@
const ACMatches& matches = provider_->matches();
// The top match must inline and score as highly as calculated verbatim.
ASSERT_FALSE(matches.empty());
- EXPECT_NE(string16::npos, matches[0].inline_autocomplete_offset) <<
- description;
+ EXPECT_EQ(ASCIIToUTF16(cases[i].inline_autocompletion),
+ matches[0].inline_autocompletion) << description;
EXPECT_GE(matches[0].relevance, 1300) << description;
size_t j = 0;
@@ -1757,127 +1799,139 @@
// Test the expected fill_into_edit, which may drop "http://".
// Some cases do not trim "http://" to match from the start of the scheme.
const std::string fill_into_edit;
- size_t inline_offset;
+ const std::string inline_autocompletion;
} cases[] = {
// Do not inline matches that do not contain the input; trim http as needed.
{ "x", "http://www.abc.com",
- "www.abc.com", string16::npos },
+ "www.abc.com", std::string() },
{ "https:", "http://www.abc.com",
- "www.abc.com", string16::npos },
+ "www.abc.com", std::string() },
{ "abc.com/", "http://www.abc.com",
- "www.abc.com", string16::npos },
+ "www.abc.com", std::string() },
{ "http://www.abc.com/a", "http://www.abc.com",
- "http://www.abc.com", string16::npos },
+ "http://www.abc.com", std::string() },
{ "http://www.abc.com", "https://www.abc.com",
- "https://www.abc.com", string16::npos },
+ "https://www.abc.com", std::string() },
{ "http://abc.com", "ftp://abc.com",
- "ftp://abc.com", string16::npos },
+ "ftp://abc.com", std::string() },
{ "https://www.abc.com", "http://www.abc.com",
- "www.abc.com", string16::npos },
+ "www.abc.com", std::string() },
{ "ftp://abc.com", "http://abc.com",
- "abc.com", string16::npos },
+ "abc.com", std::string() },
// Do not inline matches with invalid input prefixes; trim http as needed.
{ "ttp", "http://www.abc.com",
- "www.abc.com", string16::npos },
+ "www.abc.com", std::string() },
{ "://w", "http://www.abc.com",
- "www.abc.com", string16::npos },
+ "www.abc.com", std::string() },
{ "ww.", "http://www.abc.com",
- "www.abc.com", string16::npos },
+ "www.abc.com", std::string() },
{ ".ab", "http://www.abc.com",
- "www.abc.com", string16::npos },
+ "www.abc.com", std::string() },
{ "bc", "http://www.abc.com",
- "www.abc.com", string16::npos },
+ "www.abc.com", std::string() },
{ ".com", "http://www.abc.com",
- "www.abc.com", string16::npos },
+ "www.abc.com", std::string() },
// Do not inline matches that omit input domain labels; trim http as needed.
{ "www.a", "http://a.com",
- "a.com", string16::npos },
+ "a.com", std::string() },
{ "http://www.a", "http://a.com",
- "http://a.com", string16::npos },
+ "http://a.com", std::string() },
{ "www.a", "ftp://a.com",
- "ftp://a.com", string16::npos },
+ "ftp://a.com", std::string() },
{ "ftp://www.a", "ftp://a.com",
- "ftp://a.com", string16::npos },
+ "ftp://a.com", std::string() },
// Input matching but with nothing to inline will not yield an offset.
{ "abc.com", "http://www.abc.com",
- "www.abc.com", string16::npos },
+ "www.abc.com", std::string() },
{ "http://www.abc.com", "http://www.abc.com",
- "http://www.abc.com", string16::npos },
+ "http://www.abc.com", std::string() },
// Inline matches when the input is a leading substring of the scheme.
{ "h", "http://www.abc.com",
- "http://www.abc.com", 1 },
+ "http://www.abc.com", "ttp://www.abc.com" },
{ "http", "http://www.abc.com",
- "http://www.abc.com", 4 },
+ "http://www.abc.com", "://www.abc.com" },
// Inline matches when the input is a leading substring of the full URL.
{ "http:", "http://www.abc.com",
- "http://www.abc.com", 5 },
+ "http://www.abc.com", "//www.abc.com" },
{ "http://w", "http://www.abc.com",
- "http://www.abc.com", 8 },
+ "http://www.abc.com", "ww.abc.com" },
{ "http://www.", "http://www.abc.com",
- "http://www.abc.com", 11 },
+ "http://www.abc.com", "abc.com" },
{ "http://www.ab", "http://www.abc.com",
- "http://www.abc.com", 13 },
+ "http://www.abc.com", "c.com" },
{ "http://www.abc.com/p", "http://www.abc.com/path/file.htm?q=x#foo",
- "http://www.abc.com/path/file.htm?q=x#foo", 20 },
+ "http://www.abc.com/path/file.htm?q=x#foo",
+ "ath/file.htm?q=x#foo" },
{ "http://abc.com/p", "http://abc.com/path/file.htm?q=x#foo",
- "http://abc.com/path/file.htm?q=x#foo", 16 },
+ "http://abc.com/path/file.htm?q=x#foo",
+ "ath/file.htm?q=x#foo"},
// Inline matches with valid URLPrefixes; only trim "http://".
{ "w", "http://www.abc.com",
- "www.abc.com", 1 },
+ "www.abc.com", "ww.abc.com" },
{ "www.a", "http://www.abc.com",
- "www.abc.com", 5 },
+ "www.abc.com", "bc.com" },
{ "abc", "http://www.abc.com",
- "www.abc.com", 7 },
+ "www.abc.com", ".com" },
{ "abc.c", "http://www.abc.com",
- "www.abc.com", 9 },
+ "www.abc.com", "om" },
{ "abc.com/p", "http://www.abc.com/path/file.htm?q=x#foo",
- "www.abc.com/path/file.htm?q=x#foo", 13 },
+ "www.abc.com/path/file.htm?q=x#foo",
+ "ath/file.htm?q=x#foo" },
{ "abc.com/p", "http://abc.com/path/file.htm?q=x#foo",
- "abc.com/path/file.htm?q=x#foo", 9 },
+ "abc.com/path/file.htm?q=x#foo",
+ "ath/file.htm?q=x#foo" },
// Inline matches using the maximal URLPrefix components.
{ "h", "http://help.com",
- "help.com", 1 },
+ "help.com", "elp.com" },
{ "http", "http://http.com",
- "http.com", 4 },
+ "http.com", ".com" },
{ "h", "http://www.help.com",
- "www.help.com", 5 },
+ "www.help.com", "elp.com" },
{ "http", "http://www.http.com",
- "www.http.com", 8 },
+ "www.http.com", ".com" },
{ "w", "http://www.www.com",
- "www.www.com", 5 },
+ "www.www.com", "ww.com" },
// Test similar behavior for the ftp and https schemes.
{ "ftp://www.ab", "ftp://www.abc.com/path/file.htm?q=x#foo",
- "ftp://www.abc.com/path/file.htm?q=x#foo", 12 },
+ "ftp://www.abc.com/path/file.htm?q=x#foo",
+ "c.com/path/file.htm?q=x#foo" },
{ "www.ab", "ftp://www.abc.com/path/file.htm?q=x#foo",
- "ftp://www.abc.com/path/file.htm?q=x#foo", 12 },
+ "ftp://www.abc.com/path/file.htm?q=x#foo",
+ "c.com/path/file.htm?q=x#foo" },
{ "ab", "ftp://www.abc.com/path/file.htm?q=x#foo",
- "ftp://www.abc.com/path/file.htm?q=x#foo", 12 },
+ "ftp://www.abc.com/path/file.htm?q=x#foo",
+ "c.com/path/file.htm?q=x#foo" },
{ "ab", "ftp://abc.com/path/file.htm?q=x#foo",
- "ftp://abc.com/path/file.htm?q=x#foo", 8 },
+ "ftp://abc.com/path/file.htm?q=x#foo",
+ "c.com/path/file.htm?q=x#foo" },
{ "https://www.ab", "https://www.abc.com/path/file.htm?q=x#foo",
- "https://www.abc.com/path/file.htm?q=x#foo", 14 },
+ "https://www.abc.com/path/file.htm?q=x#foo",
+ "c.com/path/file.htm?q=x#foo" },
{ "www.ab", "https://www.abc.com/path/file.htm?q=x#foo",
- "https://www.abc.com/path/file.htm?q=x#foo", 14 },
+ "https://www.abc.com/path/file.htm?q=x#foo",
+ "c.com/path/file.htm?q=x#foo" },
{ "ab", "https://www.abc.com/path/file.htm?q=x#foo",
- "https://www.abc.com/path/file.htm?q=x#foo", 14 },
+ "https://www.abc.com/path/file.htm?q=x#foo",
+ "c.com/path/file.htm?q=x#foo" },
{ "ab", "https://abc.com/path/file.htm?q=x#foo",
- "https://abc.com/path/file.htm?q=x#foo", 10 },
+ "https://abc.com/path/file.htm?q=x#foo",
+ "c.com/path/file.htm?q=x#foo"},
// Forced query input should inline and retain the "?" prefix.
{ "?http://www.ab", "http://www.abc.com",
- "?http://www.abc.com", 14 },
+ "?http://www.abc.com", "c.com" },
{ "?www.ab", "http://www.abc.com",
- "?www.abc.com", 7 },
+ "?www.abc.com", "c.com" },
{ "?ab", "http://www.abc.com",
- "?www.abc.com", 7 },
+ "?www.abc.com", "c.com" },
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) {
@@ -1886,7 +1940,8 @@
provider_->NavigationToMatch(SearchProvider::NavigationResult(
*provider_.get(), GURL(cases[i].url), string16(), false, 0,
false)));
- EXPECT_EQ(cases[i].inline_offset, match.inline_autocomplete_offset);
+ EXPECT_EQ(ASCIIToUTF16(cases[i].inline_autocompletion),
+ match.inline_autocompletion);
EXPECT_EQ(ASCIIToUTF16(cases[i].fill_into_edit), match.fill_into_edit);
}
}
@@ -1901,14 +1956,14 @@
// Check the offset and strings when inline autocompletion is allowed.
QueryForInput(input, false, false);
AutocompleteMatch match_inline(provider_->NavigationToMatch(result));
- EXPECT_EQ(2U, match_inline.inline_autocomplete_offset);
EXPECT_EQ(url, match_inline.fill_into_edit);
+ EXPECT_EQ(url.substr(2), match_inline.inline_autocompletion);
EXPECT_EQ(url, match_inline.contents);
// Check the same offset and strings when inline autocompletion is prevented.
QueryForInput(input, true, false);
AutocompleteMatch match_prevent(provider_->NavigationToMatch(result));
- EXPECT_EQ(string16::npos, match_prevent.inline_autocomplete_offset);
+ EXPECT_TRUE(match_prevent.inline_autocompletion.empty());
EXPECT_EQ(url, match_prevent.fill_into_edit);
EXPECT_EQ(url, match_prevent.contents);
}
@@ -1920,7 +1975,7 @@
provider_->NavigationToMatch(SearchProvider::NavigationResult(
*provider_.get(), GURL("http://www.wow.com"), string16(), false, 0,
false)));
- EXPECT_EQ(5U, match.inline_autocomplete_offset);
+ EXPECT_EQ(ASCIIToUTF16("ow.com"), match.inline_autocompletion);
EXPECT_EQ(ASCIIToUTF16("www.wow.com"), match.fill_into_edit);
EXPECT_EQ(ASCIIToUTF16("www.wow.com"), match.contents);
diff --git a/chrome/browser/autocomplete/zero_suggest_provider.cc b/chrome/browser/autocomplete/zero_suggest_provider.cc
index 77c0e1f..da79e36 100644
--- a/chrome/browser/autocomplete/zero_suggest_provider.cc
+++ b/chrome/browser/autocomplete/zero_suggest_provider.cc
@@ -349,7 +349,6 @@
match.fill_into_edit +=
AutocompleteInput::FormattedStringWithEquivalentMeaning(navigation.url(),
match.contents);
- match.inline_autocomplete_offset = string16::npos;
AutocompleteMatch::ClassifyLocationInString(string16::npos, 0,
match.contents.length(), ACMatchClassification::URL,
@@ -458,7 +457,6 @@
HistoryURLProvider::SuggestExactInput(this, input,
!HasHTTPScheme(input.text())));
match.is_history_what_you_typed_match = false;
- match.inline_autocomplete_offset = string16::npos;
// The placeholder suggestion for the current URL has high relevance so
// that it is in the first suggestion slot and inline autocompleted. It
diff --git a/chrome/browser/autofill/autofill_browsertest.cc b/chrome/browser/autofill/autofill_browsertest.cc
index fd2f89f..1b37b32 100644
--- a/chrome/browser/autofill/autofill_browsertest.cc
+++ b/chrome/browser/autofill/autofill_browsertest.cc
@@ -51,6 +51,10 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/keycodes/keyboard_codes.h"
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
namespace autofill {
@@ -1177,6 +1181,12 @@
// pass the Luhn test) the credit card info should not be saved into Autofill
// preferences.
IN_PROC_BROWSER_TEST_F(AutofillTest, InvalidCreditCardNumberIsNotAggregated) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
ASSERT_TRUE(test_server()->Start());
std::string card("4408 0412 3456 7890");
ASSERT_FALSE(autofill::IsValidCreditCardNumber(ASCIIToUTF16(card)));
@@ -1192,6 +1202,12 @@
// http://www.merriampark.com/anatomycc.htm
IN_PROC_BROWSER_TEST_F(AutofillTest,
WhitespacesAndSeparatorCharsStrippedForValidCCNums) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/179830).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
ASSERT_TRUE(test_server()->Start());
SubmitCreditCard("Bob Smith", "4408 0412 3456 7893", "12", "2014");
SubmitCreditCard("Jane Doe", "4417-1234-5678-9113", "10", "2013");
@@ -1396,6 +1412,12 @@
// card infobar should not offer to save the credit card info. The credit card
// number must be a valid Luhn number.
IN_PROC_BROWSER_TEST_F(AutofillTest, CCInfoNotStoredWhenAutocompleteOff) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
ASSERT_TRUE(test_server()->Start());
FormMap data;
data["CREDIT_CARD_NAME"] = "Bob Smith";
diff --git a/chrome/browser/autofill/autofill_cc_infobar_delegate.cc b/chrome/browser/autofill/autofill_cc_infobar_delegate.cc
index ff744d4..fd6cdd4 100644
--- a/chrome/browser/autofill/autofill_cc_infobar_delegate.cc
+++ b/chrome/browser/autofill/autofill_cc_infobar_delegate.cc
@@ -29,14 +29,6 @@
infobar_service, metric_logger, save_card_callback)));
}
-// static
-scoped_ptr<ConfirmInfoBarDelegate> AutofillCCInfoBarDelegate::CreateForTesting(
- const AutofillMetrics* metric_logger,
- const base::Closure& save_card_callback) {
- return scoped_ptr<ConfirmInfoBarDelegate>(
- new AutofillCCInfoBarDelegate(NULL, metric_logger, save_card_callback));
-}
-
AutofillCCInfoBarDelegate::AutofillCCInfoBarDelegate(
InfoBarService* infobar_service,
const AutofillMetrics* metric_logger,
diff --git a/chrome/browser/autofill/autofill_cc_infobar_delegate.h b/chrome/browser/autofill/autofill_cc_infobar_delegate.h
index 4941864..6e36e2b 100644
--- a/chrome/browser/autofill/autofill_cc_infobar_delegate.h
+++ b/chrome/browser/autofill/autofill_cc_infobar_delegate.h
@@ -27,14 +27,20 @@
// card information gathered from a form submission.
class AutofillCCInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
- // Creates an AutofillCCInfoBarDelegate and adds it to |infobar_service|.
+ // Creates an autofill credit card infobar delegate and adds it to
+ // |infobar_service|.
static void Create(InfoBarService* infobar_service,
const AutofillMetrics* metric_logger,
const base::Closure& save_card_callback);
- static scoped_ptr<ConfirmInfoBarDelegate> CreateForTesting(
+#if defined(UNIT_TEST)
+ static scoped_ptr<ConfirmInfoBarDelegate> Create(
const AutofillMetrics* metric_logger,
- const base::Closure& save_card_callback);
+ const base::Closure& save_card_callback) {
+ return scoped_ptr<ConfirmInfoBarDelegate>(
+ new AutofillCCInfoBarDelegate(NULL, metric_logger, save_card_callback));
+ }
+#endif
private:
AutofillCCInfoBarDelegate(InfoBarService* infobar_service,
diff --git a/chrome/browser/autofill/form_structure_browsertest.cc b/chrome/browser/autofill/form_structure_browsertest.cc
index e6babac..0666fa2 100644
--- a/chrome/browser/autofill/form_structure_browsertest.cc
+++ b/chrome/browser/autofill/form_structure_browsertest.cc
@@ -5,10 +5,12 @@
#include <vector>
#include "base/files/file_path.h"
+#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/chrome_paths.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/autofill/content/browser/autofill_driver_impl.h"
@@ -27,6 +29,13 @@
return GURL(std::string("data:text/html;charset=utf-8,") + html);
}
+const base::FilePath& GetTestDataDir() {
+ CR_DEFINE_STATIC_LOCAL(base::FilePath, dir, ());
+ if (dir.empty())
+ PathService::Get(chrome::DIR_TEST_DATA, &dir);
+ return dir;
+}
+
} // namespace
// A data-driven test for verifying Autofill heuristics. Each input is an HTML
@@ -49,7 +58,8 @@
DISALLOW_COPY_AND_ASSIGN(FormStructureBrowserTest);
};
-FormStructureBrowserTest::FormStructureBrowserTest() {
+FormStructureBrowserTest::FormStructureBrowserTest()
+ : DataDrivenTest(GetTestDataDir()) {
}
FormStructureBrowserTest::~FormStructureBrowserTest() {
diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc
index 53fa3e0..ea10c51 100644
--- a/chrome/browser/automation/testing_automation_provider.cc
+++ b/chrome/browser/automation/testing_automation_provider.cc
@@ -139,6 +139,7 @@
#include "content/public/common/drop_data.h"
#include "content/public/common/geoposition.h"
#include "content/public/common/ssl_status.h"
+#include "content/public/common/webplugininfo.h"
#include "extensions/browser/view_type_utils.h"
#include "extensions/common/url_pattern.h"
#include "extensions/common/url_pattern_set.h"
@@ -147,7 +148,6 @@
#include "ui/base/events/event_constants.h"
#include "ui/base/keycodes/keyboard_codes.h"
#include "ui/base/ui_base_types.h"
-#include "webkit/plugins/webplugininfo.h"
#if defined(ENABLE_CONFIGURATION_POLICY)
#include "chrome/browser/policy/policy_service.h"
@@ -2125,24 +2125,25 @@
infobar_index));
return;
}
- InfoBarDelegate* infobar = infobar_service->infobar_at(infobar_index);
+ InfoBarDelegate* infobar_delegate =
+ infobar_service->infobar_at(infobar_index);
if (action == "dismiss") {
- infobar->InfoBarDismissed();
- infobar_service->RemoveInfoBar(infobar);
+ infobar_delegate->InfoBarDismissed();
+ infobar_service->RemoveInfoBar(infobar_delegate);
reply.SendSuccess(NULL);
return;
}
if ((action == "accept") || (action == "cancel")) {
- ConfirmInfoBarDelegate* delegate = infobar->AsConfirmInfoBarDelegate();
- if (!delegate) {
+ ConfirmInfoBarDelegate* confirm_infobar_delegate =
+ infobar_delegate->AsConfirmInfoBarDelegate();
+ if (!confirm_infobar_delegate) {
reply.SendError("Not a confirm infobar");
return;
}
- bool remove_infobar = (action == "accept") ?
- delegate->Accept() : delegate->Cancel();
- if (remove_infobar)
- infobar_service->RemoveInfoBar(infobar);
+ if ((action == "accept") ?
+ confirm_infobar_delegate->Accept() : confirm_infobar_delegate->Cancel())
+ infobar_service->RemoveInfoBar(infobar_delegate);
reply.SendSuccess(NULL);
return;
}
@@ -3057,11 +3058,11 @@
Browser* browser,
DictionaryValue* args,
IPC::Message* reply_message,
- const std::vector<webkit::WebPluginInfo>& plugins) {
+ const std::vector<content::WebPluginInfo>& plugins) {
PluginPrefs* plugin_prefs =
PluginPrefs::GetForProfile(browser->profile()).get();
ListValue* items = new ListValue;
- for (std::vector<webkit::WebPluginInfo>::const_iterator it =
+ for (std::vector<content::WebPluginInfo>::const_iterator it =
plugins.begin();
it != plugins.end();
++it) {
@@ -3073,7 +3074,7 @@
item->SetBoolean("enabled", plugin_prefs->IsPluginEnabled(*it));
// Add info about mime types.
ListValue* mime_types = new ListValue();
- for (std::vector<webkit::WebPluginMimeType>::const_iterator type_it =
+ for (std::vector<content::WebPluginMimeType>::const_iterator type_it =
it->mime_types.begin();
type_it != it->mime_types.end();
++type_it) {
diff --git a/chrome/browser/automation/testing_automation_provider.h b/chrome/browser/automation/testing_automation_provider.h
index df1fadb..7aad785 100644
--- a/chrome/browser/automation/testing_automation_provider.h
+++ b/chrome/browser/automation/testing_automation_provider.h
@@ -38,16 +38,13 @@
namespace content {
class RenderViewHost;
struct NativeWebKeyboardEvent;
+struct WebPluginInfo;
}
namespace gfx {
class Rect;
}
-namespace webkit {
-struct WebPluginInfo;
-}
-
// This is an automation provider containing testing calls.
class TestingAutomationProvider : public AutomationProvider,
public chrome::BrowserListObserver,
@@ -402,7 +399,7 @@
void GetPluginsInfoCallback(Browser* browser,
base::DictionaryValue* args,
IPC::Message* reply_message,
- const std::vector<webkit::WebPluginInfo>& plugins);
+ const std::vector<content::WebPluginInfo>& plugins);
// Enable a plugin.
// Uses the JSON interface for input/output.
diff --git a/chrome/browser/automation/testing_automation_provider_chromeos.cc b/chrome/browser/automation/testing_automation_provider_chromeos.cc
index a528098..6183395 100644
--- a/chrome/browser/automation/testing_automation_provider_chromeos.cc
+++ b/chrome/browser/automation/testing_automation_provider_chromeos.cc
@@ -38,6 +38,7 @@
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/cros_settings_names.h"
#include "chrome/browser/chromeos/system/timezone_settings.h"
+#include "chrome/browser/prefs/proxy_config_dictionary.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
diff --git a/chrome/browser/background/background_mode_manager.cc b/chrome/browser/background/background_mode_manager.cc
index 6bbc13b..b925aba 100644
--- a/chrome/browser/background/background_mode_manager.cc
+++ b/chrome/browser/background/background_mode_manager.cc
@@ -665,7 +665,8 @@
if (!status_tray_ || status_icon_)
return;
- status_icon_ = status_tray_->CreateStatusIcon();
+ status_icon_ =
+ status_tray_->CreateStatusIcon(StatusTray::BACKGROUND_MODE_ICON);
if (!status_icon_)
return;
diff --git a/chrome/browser/browser_commands_unittest.cc b/chrome/browser/browser_commands_unittest.cc
index 298b488..7c6ed44 100644
--- a/chrome/browser/browser_commands_unittest.cc
+++ b/chrome/browser/browser_commands_unittest.cc
@@ -167,15 +167,17 @@
EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
ASSERT_EQ(2, browser()->tab_strip_model()->count());
- // The original tab should be unchanged.
WebContents* zeroth = browser()->tab_strip_model()->GetWebContentsAt(0);
- EXPECT_EQ(url2, zeroth->GetURL());
+ WebContents* first = browser()->tab_strip_model()->GetWebContentsAt(1);
+
+ // The original tab should be unchanged.
+ EXPECT_EQ(url2, zeroth->GetLastCommittedURL());
EXPECT_TRUE(zeroth->GetController().CanGoBack());
EXPECT_FALSE(zeroth->GetController().CanGoForward());
- // The new tab should be like the first one but navigated back.
- WebContents* first = browser()->tab_strip_model()->GetWebContentsAt(1);
- EXPECT_EQ(url1, browser()->tab_strip_model()->GetWebContentsAt(1)->GetURL());
+ // The new tab should be like the first one but navigated back. Since we
+ // didn't wait for the load to complete, we can't use GetLastCommittedURL.
+ EXPECT_EQ(url1, first->GetVisibleURL());
EXPECT_FALSE(first->GetController().CanGoBack());
EXPECT_TRUE(first->GetController().CanGoForward());
@@ -190,7 +192,7 @@
chrome::GoForward(browser(), NEW_BACKGROUND_TAB);
// The previous tab should be unchanged and still in the foreground.
- EXPECT_EQ(url1, first->GetURL());
+ EXPECT_EQ(url1, first->GetLastCommittedURL());
EXPECT_FALSE(first->GetController().CanGoBack());
EXPECT_TRUE(first->GetController().CanGoForward());
EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
@@ -198,7 +200,9 @@
// There should be a new tab navigated forward.
ASSERT_EQ(3, browser()->tab_strip_model()->count());
WebContents* second = browser()->tab_strip_model()->GetWebContentsAt(2);
- EXPECT_EQ(url2, second->GetURL());
+ // Since we didn't wait for load to complete, we can't use
+ // GetLastCommittedURL.
+ EXPECT_EQ(url2, second->GetVisibleURL());
EXPECT_TRUE(second->GetController().CanGoBack());
EXPECT_FALSE(second->GetController().CanGoForward());
@@ -210,7 +214,8 @@
chrome::GoBack(browser(), NEW_FOREGROUND_TAB);
ASSERT_EQ(3, browser()->tab_strip_model()->active_index());
ASSERT_EQ(url1,
- browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
+ browser()->tab_strip_model()->GetActiveWebContents()->
+ GetVisibleURL());
// Same thing again for forward.
// TODO(brettw) bug 11055: see the comment above about why we need this.
@@ -219,6 +224,6 @@
chrome::GoForward(browser(), NEW_FOREGROUND_TAB);
ASSERT_EQ(4, browser()->tab_strip_model()->active_index());
ASSERT_EQ(url2,
- browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
+ browser()->tab_strip_model()->GetActiveWebContents()->
+ GetVisibleURL());
}
-
diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h
index 0824b1c..ca828e9 100644
--- a/chrome/browser/browser_process.h
+++ b/chrome/browser/browser_process.h
@@ -47,6 +47,7 @@
namespace chrome {
class MediaFileSystemRegistry;
+class StorageMonitor;
}
namespace chrome_variations {
@@ -217,6 +218,8 @@
virtual chrome::MediaFileSystemRegistry* media_file_system_registry() = 0;
+ virtual chrome::StorageMonitor* storage_monitor() = 0;
+
virtual bool created_local_state() const = 0;
#if defined(ENABLE_WEBRTC)
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index 9dffeab..75897f2 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -62,6 +62,7 @@
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/status_icons/status_tray.h"
+#include "chrome/browser/storage_monitor/storage_monitor.h"
#include "chrome/browser/thumbnails/render_widget_snapshot_taker.h"
#include "chrome/browser/ui/bookmarks/bookmark_prompt_controller.h"
#include "chrome/browser/ui/browser_finder.h"
@@ -106,7 +107,7 @@
#include "ui/aura/env.h"
#endif
-#if !defined(OS_ANDROID)
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
#include "chrome/browser/media_galleries/media_file_system_registry.h"
#endif
@@ -251,6 +252,15 @@
ExtensionRendererState::GetInstance()->Shutdown();
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+ media_file_system_registry_.reset();
+ // Delete |storage_monitor_| now. Otherwise the FILE thread would be gone
+ // when we try to release it in the dtor and Valgrind would report a
+ // leak on almost every single browser_test.
+ // TODO(gbillock): Make this unnecessary.
+ storage_monitor_.reset();
+#endif
+
message_center::MessageCenter::Shutdown();
#if defined(ENABLE_CONFIGURATION_POLICY)
@@ -619,9 +629,24 @@
#endif
}
+chrome::StorageMonitor* BrowserProcessImpl::storage_monitor() {
+#if defined(OS_ANDROID) || defined(OS_IOS)
+ return NULL;
+#else
+ return storage_monitor_.get();
+#endif
+}
+
+void BrowserProcessImpl::set_storage_monitor_for_test(
+ scoped_ptr<chrome::StorageMonitor> monitor) {
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+ storage_monitor_ = monitor.Pass();
+#endif
+}
+
chrome::MediaFileSystemRegistry*
BrowserProcessImpl::media_file_system_registry() {
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_IOS)
return NULL;
#else
if (!media_file_system_registry_)
@@ -910,6 +935,10 @@
}
#endif
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+ storage_monitor_.reset(chrome::StorageMonitor::Create());
+#endif
+
#if defined(OS_MACOSX)
app_shim_host_manager_.reset(new AppShimHostManager);
AppListService::InitAll(NULL);
diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h
index 66191dc..50a76d1 100644
--- a/chrome/browser/browser_process_impl.h
+++ b/chrome/browser/browser_process_impl.h
@@ -127,6 +127,8 @@
virtual CRLSetFetcher* crl_set_fetcher() OVERRIDE;
virtual PnaclComponentInstaller* pnacl_component_installer() OVERRIDE;
virtual BookmarkPromptController* bookmark_prompt_controller() OVERRIDE;
+ virtual chrome::StorageMonitor* storage_monitor() OVERRIDE;
+ void set_storage_monitor_for_test(scoped_ptr<chrome::StorageMonitor> monitor);
virtual chrome::MediaFileSystemRegistry*
media_file_system_registry() OVERRIDE;
virtual bool created_local_state() const OVERRIDE;
@@ -196,6 +198,10 @@
// Bookmark prompt controller displays the prompt for frequently visited URL.
scoped_ptr<BookmarkPromptController> bookmark_prompt_controller_;
+#endif
+
+#if !defined(OS_ANDROID) && !defined(OS_IOS)
+ scoped_ptr<chrome::StorageMonitor> storage_monitor_;
scoped_ptr<chrome::MediaFileSystemRegistry> media_file_system_registry_;
#endif
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 2234ae0..cc669ab 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -161,12 +161,6 @@
<include name="IDR_LOCAL_NTP_JS" file="resources\local_ntp\local_ntp.js" flattenhtml="true" type="BINDATA" />
<include name="IDR_LOCAL_NTP_IMAGES_2X_LOGO_PNG" file="resources\local_ntp\images\2x\ntp_google_logo.png" type="BINDATA" />
<include name="IDR_LOCAL_NTP_IMAGES_2X_WHITE_LOGO_PNG" file="resources\local_ntp\images\2x\ntp_white_google_logo.png" type="BINDATA" />
- <include name="IDR_LOCAL_OMNIBOX_POPUP_IMAGES_HISTORY_ICON_PNG" file="resources\local_omnibox_popup\images\history_icon.png" type="BINDATA" />
- <include name="IDR_LOCAL_OMNIBOX_POPUP_IMAGES_2X_HISTORY_ICON_PNG" file="resources\local_omnibox_popup\images\2x\history_icon.png" type="BINDATA" />
- <include name="IDR_LOCAL_OMNIBOX_POPUP_IMAGES_PAGE_ICON_PNG" file="resources\local_omnibox_popup\images\page_icon.png" type="BINDATA" />
- <include name="IDR_LOCAL_OMNIBOX_POPUP_IMAGES_2X_PAGE_ICON_PNG" file="resources\local_omnibox_popup\images\2x\page_icon.png" type="BINDATA" />
- <include name="IDR_LOCAL_OMNIBOX_POPUP_IMAGES_SEARCH_ICON_PNG" file="resources\local_omnibox_popup\images\search_icon.png" type="BINDATA" />
- <include name="IDR_LOCAL_OMNIBOX_POPUP_IMAGES_2X_SEARCH_ICON_PNG" file="resources\local_omnibox_popup\images\2x\search_icon.png" type="BINDATA" />
<include name="IDR_MOST_VISITED_IFRAME_CSS" file="resources\local_ntp\most_visited_iframe.css" type="BINDATA" />
<include name="IDR_MOST_VISITED_TITLE_HTML" file="resources\local_ntp\most_visited_title.html" type="BINDATA" />
<include name="IDR_MOST_VISITED_TITLE_CSS" file="resources\local_ntp\most_visited_title.css" type="BINDATA" />
@@ -288,6 +282,8 @@
<include name="IDR_CRYPTOHOME_JS" file="resources\chromeos\cryptohome.js" type="BINDATA" />
<!-- manifest file of ChromeVox accessibility extension -->
<include name="IDR_CHROMEVOX_MANIFEST" file="resources\chromeos\access_chromevox\manifest.json" type="BINDATA" />
+ <!-- manifest file of Connectivity Diagnostics app -->
+ <include name="IDR_CONNECTIVITY_DIAGNOSTICS_MANIFEST" file="resources\chromeos\connectivity_diagnostics\manifest.json" type="BINDATA" />
<!-- manifest file of built-in speech synthesis extension -->
<include name="IDR_SPEECH_SYNTHESIS_MANIFEST" file="resources\chromeos\speech_synthesis\manifest.json" type="BINDATA" />
<include name="IDR_DIAGNOSTICS_MAIN_CSS" file="resources\chromeos\diagnostics\main.css" type="BINDATA" />
@@ -358,11 +354,14 @@
<include name="IDR_SET_AS_DEFAULT_BROWSER_JS" file="resources\set_as_default_browser.js" flattenhtml="true" type="BINDATA" />
<include name="IDR_SET_AS_DEFAULT_BROWSER_HTML" file="resources\set_as_default_browser.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
</if>
+ <if expr="not is_android and not pp_ifdef('ios') and not pp_ifdef('chromeos')">
+ <include name="IDR_USER_CHOOSER_JS" file="resources\user_chooser\user_chooser.js" flattenhtml="true" type="BINDATA" />
+ <include name="IDR_USER_CHOOSER_HTML" file="resources\user_chooser\user_chooser.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
+ </if>
<include name="IDR_MANAGED_MODE_BLOCK_INTERSTITIAL_HTML" file="resources\managed_mode_block_interstitial.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_PROFILE_SIGNIN_CONFIRMATION_HTML" file="resources\profile_signin_confirmation.html" type="BINDATA" />
<include name="IDR_PROFILE_SIGNIN_CONFIRMATION_JS" file="resources\profile_signin_confirmation.js" type="BINDATA" />
<include name="IDR_PROFILE_SIGNIN_CONFIRMATION_CSS" file="resources\profile_signin_confirmation.css" type="BINDATA" />
-
<include name="IDR_RECENTLY_CLOSED_WINDOW" file="resources\ntp4\images\closed_window.png" type="BINDATA" />
<if expr="not is_android">
<include name="IDR_IDENTITY_INTERNALS_HTML" file="resources\identity_internals.html" type="BINDATA" />
diff --git a/chrome/browser/browsing_data/browsing_data_database_helper.cc b/chrome/browser/browsing_data/browsing_data_database_helper.cc
index 023dfff..5cd0fb5 100644
--- a/chrome/browser/browsing_data/browsing_data_database_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_database_helper.cc
@@ -15,8 +15,6 @@
#include "content/public/browser/storage_partition.h"
#include "net/base/completion_callback.h"
#include "net/base/net_errors.h"
-#include "third_party/WebKit/public/platform/WebCString.h"
-#include "third_party/WebKit/public/platform/WebString.h"
#include "webkit/common/database/database_identifier.h"
using content::BrowserContext;
diff --git a/chrome/browser/browsing_data/browsing_data_helper.cc b/chrome/browser/browsing_data/browsing_data_helper.cc
index 0faf856..73239b7 100644
--- a/chrome/browser/browsing_data/browsing_data_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_helper.cc
@@ -11,7 +11,6 @@
#include "chrome/common/url_constants.h"
#include "content/public/browser/child_process_security_policy.h"
#include "extensions/common/constants.h"
-#include "third_party/WebKit/public/platform/WebString.h"
#include "url/gurl.h"
// Static
@@ -34,11 +33,6 @@
}
// Static
-bool BrowsingDataHelper::IsWebScheme(const WebKit::WebString& scheme) {
- return BrowsingDataHelper::IsWebScheme(UTF16ToUTF8(scheme));
-}
-
-// Static
bool BrowsingDataHelper::HasWebScheme(const GURL& origin) {
return BrowsingDataHelper::IsWebScheme(origin.scheme());
}
@@ -49,11 +43,6 @@
}
// Static
-bool BrowsingDataHelper::IsExtensionScheme(const WebKit::WebString& scheme) {
- return BrowsingDataHelper::IsExtensionScheme(UTF16ToUTF8(scheme));
-}
-
-// Static
bool BrowsingDataHelper::HasExtensionScheme(const GURL& origin) {
return BrowsingDataHelper::IsExtensionScheme(origin.scheme());
}
diff --git a/chrome/browser/browsing_data/browsing_data_helper.h b/chrome/browser/browsing_data/browsing_data_helper.h
index 65afbcc..1afacdb 100644
--- a/chrome/browser/browsing_data/browsing_data_helper.h
+++ b/chrome/browser/browsing_data/browsing_data_helper.h
@@ -11,10 +11,6 @@
#include "base/basictypes.h"
-namespace WebKit {
-class WebString;
-}
-
class ExtensionSpecialStoragePolicy;
class GURL;
@@ -33,12 +29,10 @@
// in ChildProcessSecurityPolicy, but excluding schemes like
// `chrome-extension`.
static bool IsWebScheme(const std::string& scheme);
- static bool IsWebScheme(const WebKit::WebString& scheme);
static bool HasWebScheme(const GURL& origin);
// Returns true iff the provided scheme is an extension.
static bool IsExtensionScheme(const std::string& scheme);
- static bool IsExtensionScheme(const WebKit::WebString& scheme);
static bool HasExtensionScheme(const GURL& origin);
// Returns true if the provided origin matches the provided mask.
diff --git a/chrome/browser/browsing_data/browsing_data_helper_unittest.cc b/chrome/browser/browsing_data/browsing_data_helper_unittest.cc
index e19b81a..4901f64 100644
--- a/chrome/browser/browsing_data/browsing_data_helper_unittest.cc
+++ b/chrome/browser/browsing_data/browsing_data_helper_unittest.cc
@@ -10,7 +10,6 @@
#include "content/public/common/url_constants.h"
#include "extensions/common/constants.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/platform/WebString.h"
#include "url/gurl.h"
namespace {
@@ -39,17 +38,13 @@
bool IsWebScheme(const std::string& scheme) {
GURL test(scheme + "://example.com");
return (BrowsingDataHelper::HasWebScheme(test) &&
- BrowsingDataHelper::IsWebScheme(scheme) &&
- BrowsingDataHelper::IsWebScheme(
- WebKit::WebString::fromUTF8(scheme)));
+ BrowsingDataHelper::IsWebScheme(scheme));
}
bool IsExtensionScheme(const std::string& scheme) {
GURL test(scheme + "://example.com");
return (BrowsingDataHelper::HasExtensionScheme(test) &&
- BrowsingDataHelper::IsExtensionScheme(scheme) &&
- BrowsingDataHelper::IsExtensionScheme(
- WebKit::WebString::fromUTF8(scheme)));
+ BrowsingDataHelper::IsExtensionScheme(scheme));
}
bool Match(const GURL& origin,
diff --git a/chrome/browser/browsing_data/browsing_data_indexed_db_helper.cc b/chrome/browser/browsing_data/browsing_data_indexed_db_helper.cc
index 18840f7..1252aa4 100644
--- a/chrome/browser/browsing_data/browsing_data_indexed_db_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_indexed_db_helper.cc
@@ -224,7 +224,8 @@
for (std::set<PendingIndexedDBInfo>::const_iterator
pending_info = pending_indexed_db_info_.begin();
pending_info != pending_indexed_db_info_.end(); ++pending_info) {
- IndexedDBInfo info(pending_info->origin, 0, base::Time(), base::FilePath());
+ IndexedDBInfo info(
+ pending_info->origin, 0, base::Time(), base::FilePath(), 0);
indexed_db_info_.push_back(info);
}
diff --git a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
index 03b176a..3d659ce 100644
--- a/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
+++ b/chrome/browser/browsing_data/browsing_data_remover_unittest.cc
@@ -43,8 +43,6 @@
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/platform/WebCString.h"
-#include "third_party/WebKit/public/platform/WebString.h"
#include "webkit/browser/quota/mock_quota_manager.h"
#include "webkit/browser/quota/quota_manager.h"
#include "webkit/common/dom_storage/dom_storage_types.h"
diff --git a/chrome/browser/browsing_data/mock_browsing_data_indexed_db_helper.cc b/chrome/browser/browsing_data/mock_browsing_data_indexed_db_helper.cc
index 5d9d4d9..c933bb9 100644
--- a/chrome/browser/browsing_data/mock_browsing_data_indexed_db_helper.cc
+++ b/chrome/browser/browsing_data/mock_browsing_data_indexed_db_helper.cc
@@ -28,10 +28,10 @@
void MockBrowsingDataIndexedDBHelper::AddIndexedDBSamples() {
const GURL kOrigin1("http://idbhost1:1/");
const GURL kOrigin2("http://idbhost2:2/");
- content::IndexedDBInfo info1(kOrigin1, 1, base::Time(), base::FilePath());
+ content::IndexedDBInfo info1(kOrigin1, 1, base::Time(), base::FilePath(), 0);
response_.push_back(info1);
origins_[kOrigin1] = true;
- content::IndexedDBInfo info2(kOrigin2, 2, base::Time(), base::FilePath());
+ content::IndexedDBInfo info2(kOrigin2, 2, base::Time(), base::FilePath(), 0);
response_.push_back(info2);
origins_[kOrigin2] = true;
}
diff --git a/chrome/browser/captive_portal/captive_portal_tab_helper.h b/chrome/browser/captive_portal/captive_portal_tab_helper.h
index 88cf5ef..dec16d2 100644
--- a/chrome/browser/captive_portal/captive_portal_tab_helper.h
+++ b/chrome/browser/captive_portal/captive_portal_tab_helper.h
@@ -14,7 +14,7 @@
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
-#include "webkit/glue/resource_type.h"
+#include "webkit/common/resource_type.h"
class GURL;
class Profile;
diff --git a/chrome/browser/character_encoding.cc b/chrome/browser/character_encoding.cc
index 9a0f112..4909a7b 100644
--- a/chrome/browser/character_encoding.cc
+++ b/chrome/browser/character_encoding.cc
@@ -15,7 +15,7 @@
#include "chrome/app/chrome_command_ids.h"
#include "content/public/browser/browser_thread.h"
#include "grit/generated_resources.h"
-#include "third_party/icu/public/common/unicode/ucnv.h"
+#include "third_party/icu/source/common/unicode/ucnv.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/l10n_util_collator.h"
diff --git a/chrome/browser/chrome_browser_field_trials_mobile.cc b/chrome/browser/chrome_browser_field_trials_mobile.cc
index 7fb1896..5e17ca7 100644
--- a/chrome/browser/chrome_browser_field_trials_mobile.cc
+++ b/chrome/browser/chrome_browser_field_trials_mobile.cc
@@ -9,6 +9,7 @@
#include "base/command_line.h"
#include "base/metrics/field_trial.h"
#include "base/prefs/pref_service.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"
namespace chrome {
@@ -51,12 +52,55 @@
<< ". Selected group id: " << v;
}
+void NewTabButtonInToolbarFieldTrial(const CommandLine& parsed_command_line) {
+ // Do not enable this field trials for tablet devices.
+ if (parsed_command_line.HasSwitch(switches::kTabletUI))
+ return;
+
+ const char kPhoneNewTabToolbarButtonFieldTrialName[] =
+ "PhoneNewTabToolbarButton";
+ const base::FieldTrial::Probability kPhoneNewTabToolbarButtonDivisor = 100;
+
+ // 50/100 = 50% for Non-Stable users.
+ // 0/100 = 0% for Stable users.
+ const base::FieldTrial::Probability kPhoneNewTabToolbarButtonNonStable = 50;
+ const base::FieldTrial::Probability kPhoneNewTabToolbarButtonStable = 0;
+ const char kEnabled[] = "Enabled";
+ const char kDisabled[] = "Disabled";
+
+ // Find out if this is a stable channel.
+ const bool kIsStableChannel =
+ chrome::VersionInfo::GetChannel() == chrome::VersionInfo::CHANNEL_STABLE;
+
+ // Experiment enabled until Jan 1, 2015. By default, disabled.
+ scoped_refptr<base::FieldTrial> trial(
+ base::FieldTrialList::FactoryGetFieldTrial(
+ kPhoneNewTabToolbarButtonFieldTrialName,
+ kPhoneNewTabToolbarButtonDivisor,
+ kDisabled, 2015, 1, 1, NULL));
+
+ // We want our trial results to be persistent.
+ trial->UseOneTimeRandomization();
+ const int kEnabledGroup = trial->AppendGroup(
+ kEnabled,
+ kIsStableChannel ?
+ kPhoneNewTabToolbarButtonStable : kPhoneNewTabToolbarButtonNonStable);
+
+ const int v = trial->group();
+ VLOG(1) << "Phone NewTab toolbar button enabled group id: " << kEnabledGroup
+ << ". Selected group id: " << v;
+}
+
} // namespace
void SetupMobileFieldTrials(const CommandLine& parsed_command_line,
const base::Time& install_time,
PrefService* local_state) {
DataCompressionProxyFieldTrial();
+
+#if defined(OS_ANDROID)
+ NewTabButtonInToolbarFieldTrial(parsed_command_line);
+#endif
}
} // namespace chrome
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index bcc7b11..b8e5204 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -1019,6 +1019,8 @@
prefs::kBrowserSuppressDefaultBrowserPrompt,
master_prefs_->suppress_default_browser_prompt_for_version);
}
+
+ AppListService::Get()->HandleFirstRun();
}
if (do_first_run_tasks_ ||
diff --git a/chrome/browser/chrome_browser_main_linux.cc b/chrome/browser/chrome_browser_main_linux.cc
index dd83909..299154d 100644
--- a/chrome/browser/chrome_browser_main_linux.cc
+++ b/chrome/browser/chrome_browser_main_linux.cc
@@ -118,11 +118,6 @@
if (IsCrashReportingEnabled(local_state()))
InitCrashReporter();
-#if !defined(OS_CHROMEOS)
- const base::FilePath kDefaultMtabPath("/etc/mtab");
- storage_monitor_.reset(new chrome::StorageMonitorLinux(kDefaultMtabPath));
-#endif
-
ChromeBrowserMainPartsPosix::PreProfileInit();
}
@@ -132,14 +127,3 @@
g_browser_process->metrics_service()->RecordBreakpadRegistration(
IsCrashReporterEnabled());
}
-
-void ChromeBrowserMainPartsLinux::PostMainMessageLoopRun() {
- ChromeBrowserMainPartsPosix::PostMainMessageLoopRun();
-
-#if !defined(OS_CHROMEOS)
- // Delete it now. Otherwise the FILE thread would be gone when we try to
- // release it in the dtor and Valgrind would report a leak on almost every
- // single browser_test.
- storage_monitor_.reset();
-#endif
-}
diff --git a/chrome/browser/chrome_browser_main_linux.h b/chrome/browser/chrome_browser_main_linux.h
index 3cc5476..37f35ce 100644
--- a/chrome/browser/chrome_browser_main_linux.h
+++ b/chrome/browser/chrome_browser_main_linux.h
@@ -8,15 +8,8 @@
#define CHROME_BROWSER_CHROME_BROWSER_MAIN_LINUX_H_
#include "base/compiler_specific.h"
-#include "base/memory/scoped_ptr.h"
#include "chrome/browser/chrome_browser_main_posix.h"
-#if !defined(OS_CHROMEOS)
-namespace chrome {
-class StorageMonitorLinux;
-}
-#endif
-
class ChromeBrowserMainPartsLinux : public ChromeBrowserMainPartsPosix {
public:
explicit ChromeBrowserMainPartsLinux(
@@ -26,13 +19,8 @@
// ChromeBrowserMainParts overrides.
virtual void PreProfileInit() OVERRIDE;
virtual void PostProfileInit() OVERRIDE;
- virtual void PostMainMessageLoopRun() OVERRIDE;
private:
-#if !defined(OS_CHROMEOS)
- scoped_ptr<chrome::StorageMonitorLinux> storage_monitor_;
-#endif
-
DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainPartsLinux);
};
diff --git a/chrome/browser/chrome_browser_main_mac.h b/chrome/browser/chrome_browser_main_mac.h
index 52f6cf1..efe1bc7 100644
--- a/chrome/browser/chrome_browser_main_mac.h
+++ b/chrome/browser/chrome_browser_main_mac.h
@@ -5,13 +5,8 @@
#ifndef CHROME_BROWSER_CHROME_BROWSER_MAIN_MAC_H_
#define CHROME_BROWSER_CHROME_BROWSER_MAIN_MAC_H_
-#include "base/memory/scoped_ptr.h"
#include "chrome/browser/chrome_browser_main_posix.h"
-namespace chrome {
-class StorageMonitorMac;
-}
-
class ChromeBrowserMainPartsMac : public ChromeBrowserMainPartsPosix {
public:
explicit ChromeBrowserMainPartsMac(
@@ -21,7 +16,6 @@
// BrowserParts overrides.
virtual void PreEarlyInitialization() OVERRIDE;
virtual void PreMainMessageLoopStart() OVERRIDE;
- virtual void PreProfileInit() OVERRIDE;
virtual void PostProfileInit() OVERRIDE;
// Perform platform-specific work that needs to be done after the main event
@@ -29,8 +23,6 @@
static void DidEndMainMessageLoop();
private:
- scoped_ptr<chrome::StorageMonitorMac> storage_monitor_;
-
DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainPartsMac);
};
diff --git a/chrome/browser/chrome_browser_main_mac.mm b/chrome/browser/chrome_browser_main_mac.mm
index af5ee81..3d41c65 100644
--- a/chrome/browser/chrome_browser_main_mac.mm
+++ b/chrome/browser/chrome_browser_main_mac.mm
@@ -22,7 +22,6 @@
#include "chrome/browser/mac/keychain_reauthorize.h"
#import "chrome/browser/mac/keystone_glue.h"
#include "chrome/browser/metrics/metrics_service.h"
-#include "chrome/browser/storage_monitor/storage_monitor_mac.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "content/public/common/main_function_params.h"
@@ -265,12 +264,6 @@
setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
}
-void ChromeBrowserMainPartsMac::PreProfileInit() {
- storage_monitor_.reset(new chrome::StorageMonitorMac());
-
- ChromeBrowserMainPartsPosix::PreProfileInit();
-}
-
void ChromeBrowserMainPartsMac::PostProfileInit() {
ChromeBrowserMainPartsPosix::PostProfileInit();
g_browser_process->metrics_service()->RecordBreakpadRegistration(
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc
index 66c615a..a2e3008 100644
--- a/chrome/browser/chrome_browser_main_win.cc
+++ b/chrome/browser/chrome_browser_main_win.cc
@@ -27,7 +27,6 @@
#include "chrome/browser/profiles/profile_info_cache.h"
#include "chrome/browser/profiles/profile_shortcut_manager.h"
#include "chrome/browser/shell_integration.h"
-#include "chrome/browser/storage_monitor/storage_monitor_win.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_prepopulate_data.h"
#include "chrome/browser/search_engines/template_url_service.h"
@@ -212,7 +211,7 @@
void ChromeBrowserMainPartsWin::PostMainMessageLoopRun() {
// Log the search engine chosen on first run. Do this at shutdown, after any
// changes are made from the first run bubble link, etc.
- if (do_first_run_tasks() && !profile()->IsOffTheRecord()) {
+ if (do_first_run_tasks() && profile() && !profile()->IsOffTheRecord()) {
TemplateURLService* url_service =
TemplateURLServiceFactory::GetForProfile(profile());
const TemplateURL* default_search_engine =
@@ -230,12 +229,6 @@
ChromeBrowserMainParts::PostMainMessageLoopRun();
}
-void ChromeBrowserMainPartsWin::PreProfileInit() {
- storage_monitor_.reset(chrome::StorageMonitorWin::Create());
-
- ChromeBrowserMainParts::PreProfileInit();
-}
-
void ChromeBrowserMainPartsWin::ShowMissingLocaleMessageBox() {
ui::MessageBox(NULL, ASCIIToUTF16(chrome_browser::kMissingLocaleDataMessage),
ASCIIToUTF16(chrome_browser::kMissingLocaleDataTitle),
diff --git a/chrome/browser/chrome_browser_main_win.h b/chrome/browser/chrome_browser_main_win.h
index 6da509e..496d234 100644
--- a/chrome/browser/chrome_browser_main_win.h
+++ b/chrome/browser/chrome_browser_main_win.h
@@ -7,16 +7,10 @@
#ifndef CHROME_BROWSER_CHROME_BROWSER_MAIN_WIN_H_
#define CHROME_BROWSER_CHROME_BROWSER_MAIN_WIN_H_
-#include "base/memory/scoped_ptr.h"
#include "chrome/browser/chrome_browser_main.h"
class CommandLine;
-namespace chrome {
-class StorageMonitorWin;
-} // namespace chrome
-
-
// Handle uninstallation when given the appropriate the command-line switch.
// If |chrome_still_running| is true a modal dialog will be shown asking the
// user to close the other chrome instance.
@@ -34,7 +28,6 @@
virtual void PreMainMessageLoopStart() OVERRIDE;
virtual int PreCreateThreads() OVERRIDE;
virtual void PostMainMessageLoopRun() OVERRIDE;
- virtual void PreProfileInit() OVERRIDE;
// ChromeBrowserMainParts overrides.
virtual void ShowMissingLocaleMessageBox() OVERRIDE;
@@ -68,8 +61,6 @@
static void SetupInstallerUtilStrings();
private:
- scoped_ptr<chrome::StorageMonitorWin> storage_monitor_;
-
DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainPartsWin);
};
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index ba3f684..8aa4767 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -125,6 +125,7 @@
#include "content/public/common/content_descriptors.h"
#include "extensions/browser/view_type_utils.h"
#include "extensions/common/constants.h"
+#include "extensions/common/switches.h"
#include "grit/generated_resources.h"
#include "grit/ui_resources.h"
#include "net/base/escape.h"
@@ -687,8 +688,8 @@
ExtensionService* extension_service =
extensions::ExtensionSystem::Get(profile)->extension_service();
if (extension_service) {
- extension = extension_service->extensions()->
- GetExtensionOrAppByURL(ExtensionURLInfo(site));
+ extension =
+ extension_service->extensions()->GetExtensionOrAppByURL(site);
if (extension &&
extensions::AppIsolationInfo::HasIsolatedStorage(extension)) {
is_isolated = true;
@@ -785,8 +786,8 @@
return;
}
const GURL& url = embedder_web_contents->GetSiteInstance()->GetSiteURL();
- const Extension* extension = service->extensions()->
- GetExtensionOrAppByURL(ExtensionURLInfo(url));
+ const Extension* extension =
+ service->extensions()->GetExtensionOrAppByURL(url);
if (!extension) {
NOTREACHED();
return;
@@ -909,7 +910,7 @@
return url;
const Extension* extension = extension_service->extensions()->
- GetHostedAppByURL(ExtensionURLInfo(url));
+ GetHostedAppByURL(url);
if (!extension)
return url;
@@ -950,8 +951,8 @@
if (!extension_service)
return false;
- const Extension* extension = extension_service->extensions()->
- GetExtensionOrAppByURL(ExtensionURLInfo(effective_url));
+ const Extension* extension =
+ extension_service->extensions()->GetExtensionOrAppByURL(effective_url);
if (!extension)
return false;
@@ -1016,7 +1017,7 @@
if (!service)
return true;
const Extension* new_extension =
- service->extensions()->GetExtensionOrAppByURL(ExtensionURLInfo(url));
+ service->extensions()->GetExtensionOrAppByURL(url);
if (new_extension &&
new_extension->is_hosted_app() &&
new_extension->id() == extension_misc::kWebStoreAppId &&
@@ -1100,7 +1101,7 @@
// We have to have a valid extension with background page to proceed.
const Extension* extension =
- service->extensions()->GetExtensionOrAppByURL(ExtensionURLInfo(url));
+ service->extensions()->GetExtensionOrAppByURL(url);
if (!extension)
return false;
if (!extensions::BackgroundInfo::HasBackgroundPage(extension))
@@ -1175,9 +1176,8 @@
if (!service)
return;
- const Extension* extension =
- service->extensions()->GetExtensionOrAppByURL(ExtensionURLInfo(
- site_instance->GetSiteURL()));
+ const Extension* extension = service->extensions()->GetExtensionOrAppByURL(
+ site_instance->GetSiteURL());
if (!extension)
return;
@@ -1205,9 +1205,8 @@
if (!service)
return;
- const Extension* extension =
- service->extensions()->GetExtensionOrAppByURL(
- ExtensionURLInfo(site_instance->GetSiteURL()));
+ const Extension* extension = service->extensions()->GetExtensionOrAppByURL(
+ site_instance->GetSiteURL());
if (!extension)
return;
@@ -1257,7 +1256,7 @@
// We must swap if the URL is for an extension and we are not using an
// extension process.
const Extension* new_extension =
- service->extensions()->GetExtensionOrAppByURL(ExtensionURLInfo(new_url));
+ service->extensions()->GetExtensionOrAppByURL(new_url);
// Ignore all hosted apps except the Chrome Web Store, since they do not
// require their own BrowsingInstance (e.g., postMessage is ok).
if (new_extension &&
@@ -1279,7 +1278,7 @@
ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context);
return extensions::CrossesExtensionProcessBoundary(
io_data->GetExtensionInfoMap()->extensions(),
- ExtensionURLInfo(current_url), ExtensionURLInfo(new_url), false);
+ current_url, new_url, false);
}
bool ChromeContentBrowserClient::ShouldAssignSiteForURL(const GURL& url) {
@@ -1387,12 +1386,13 @@
autofill::switches::kDisableInteractiveAutocomplete,
autofill::switches::kEnableExperimentalFormFilling,
autofill::switches::kEnableInteractiveAutocomplete,
+ extensions::switches::kAllowLegacyExtensionManifests,
+ extensions::switches::kAllowScriptingGallery,
+ extensions::switches::kExtensionsOnChromeURLs,
switches::kAllowHTTPBackgroundPage,
- switches::kAllowLegacyExtensionManifests,
// TODO(victorhsieh): remove the following flag once we move PPAPI FileIO
// to browser.
switches::kAllowNaClFileHandleAPI,
- switches::kAllowScriptingGallery,
switches::kAppsCheckoutURL,
switches::kAppsGalleryURL,
switches::kCloudPrintServiceURL,
@@ -1411,7 +1411,6 @@
switches::kEnablePasswordGeneration,
switches::kEnablePnacl,
switches::kEnableWatchdog,
- switches::kExtensionsOnChromeURLs,
switches::kMemoryProfiling,
switches::kMessageLoopHistogrammer,
switches::kNoJsRandomness,
@@ -1433,9 +1432,9 @@
arraysize(kSwitchNames));
} else if (process_type == switches::kUtilityProcess) {
static const char* const kSwitchNames[] = {
+ extensions::switches::kExtensionsOnChromeURLs,
switches::kAllowHTTPBackgroundPage,
switches::kEnableExperimentalExtensionApis,
- switches::kExtensionsOnChromeURLs,
switches::kWhitelistedExtensionID,
};
@@ -1939,8 +1938,8 @@
// because the permission check above would have caused an early return
// already. We must use the full URL to find hosted apps, though, and not
// just the origin.
- const Extension* extension = map->extensions().GetExtensionOrAppByURL(
- ExtensionURLInfo(opener_url));
+ const Extension* extension =
+ map->extensions().GetExtensionOrAppByURL(opener_url);
if (extension && !extensions::BackgroundInfo::AllowJSAccess(extension))
*no_javascript_access = true;
}
@@ -2265,8 +2264,8 @@
if (!service)
return false;
- const Extension* extension = service->extensions()->
- GetExtensionOrAppByURL(ExtensionURLInfo(site_url));
+ const Extension* extension =
+ service->extensions()->GetExtensionOrAppByURL(site_url);
if (!extension)
return false;
diff --git a/chrome/browser/chrome_main_browsertest.cc b/chrome/browser/chrome_main_browsertest.cc
index 12ee266..d1fc436 100644
--- a/chrome/browser/chrome_main_browsertest.cc
+++ b/chrome/browser/chrome_main_browsertest.cc
@@ -22,6 +22,10 @@
#include "content/public/browser/web_contents.h"
#include "net/base/net_util.h"
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
// These tests don't apply to the Mac version; see GetCommandLineForRelaunch
// for details.
#if !defined(OS_MACOSX)
@@ -37,6 +41,12 @@
// Make sure that the second invocation creates a new window.
IN_PROC_BROWSER_TEST_F(ChromeMainTest, SecondLaunch) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
ui_test_utils::BrowserAddedObserver observer;
Relaunch(GetCommandLineForRelaunch());
observer.WaitForSingleNewBrowser();
@@ -45,6 +55,12 @@
}
IN_PROC_BROWSER_TEST_F(ChromeMainTest, ReuseBrowserInstanceWhenOpeningFile) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
base::FilePath test_file_path = ui_test_utils::GetTestFilePath(
base::FilePath(), base::FilePath().AppendASCII("empty.html"));
CommandLine new_command_line(GetCommandLineForRelaunch());
@@ -94,6 +110,12 @@
}
IN_PROC_BROWSER_TEST_F(ChromeMainTest, SecondLaunchFromIncognitoWithNormalUrl) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
// We should start with one normal window.
ASSERT_EQ(1u, chrome::GetTabbedBrowserCount(browser()->profile(),
browser()->host_desktop_type()));
diff --git a/chrome/browser/chrome_plugin_browsertest.cc b/chrome/browser/chrome_plugin_browsertest.cc
index d7b76b0..6b2bcba 100644
--- a/chrome/browser/chrome_plugin_browsertest.cc
+++ b/chrome/browser/chrome_plugin_browsertest.cc
@@ -23,11 +23,11 @@
#include "content/public/browser/plugin_service.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/process_type.h"
+#include "content/public/common/webplugininfo.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "net/base/net_util.h"
#include "webkit/plugins/plugin_constants.h"
-#include "webkit/plugins/webplugininfo.h"
using content::BrowserThread;
@@ -106,16 +106,16 @@
static void GetFlashPath(std::vector<base::FilePath>* paths) {
paths->clear();
- std::vector<webkit::WebPluginInfo> plugins = GetPlugins();
- for (std::vector<webkit::WebPluginInfo>::const_iterator it =
+ std::vector<content::WebPluginInfo> plugins = GetPlugins();
+ for (std::vector<content::WebPluginInfo>::const_iterator it =
plugins.begin(); it != plugins.end(); ++it) {
if (it->name == ASCIIToUTF16(kFlashPluginName))
paths->push_back(it->path);
}
}
- static std::vector<webkit::WebPluginInfo> GetPlugins() {
- std::vector<webkit::WebPluginInfo> plugins;
+ static std::vector<content::WebPluginInfo> GetPlugins() {
+ std::vector<content::WebPluginInfo> plugins;
scoped_refptr<content::MessageLoopRunner> runner =
new content::MessageLoopRunner;
content::PluginService::GetInstance()->GetPlugins(
@@ -170,9 +170,9 @@
}
static void GetPluginsInfoCallback(
- std::vector<webkit::WebPluginInfo>* rv,
+ std::vector<content::WebPluginInfo>* rv,
const base::Closure& quit_task,
- const std::vector<webkit::WebPluginInfo>& plugins) {
+ const std::vector<content::WebPluginInfo>& plugins) {
*rv = plugins;
quit_task.Run();
}
@@ -252,7 +252,7 @@
#endif
};
- std::vector<webkit::WebPluginInfo> plugins = GetPlugins();
+ std::vector<content::WebPluginInfo> plugins = GetPlugins();
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(expected); ++i) {
size_t j = 0;
for (; j < plugins.size(); ++j) {
diff --git a/chrome/browser/chrome_quota_permission_context.cc b/chrome/browser/chrome_quota_permission_context.cc
index a85b677..804fa24 100644
--- a/chrome/browser/chrome_quota_permission_context.cc
+++ b/chrome/browser/chrome_quota_permission_context.cc
@@ -54,7 +54,6 @@
// ConfirmInfoBarDelegate:
virtual bool ShouldExpireInternal(
const content::LoadCommittedDetails& details) const OVERRIDE;
-
virtual string16 GetMessageText() const OVERRIDE;
virtual bool Accept() OVERRIDE;
virtual bool Cancel() OVERRIDE;
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
index f31caa7..8b88552 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -84,7 +84,6 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/rlz/rlz.h"
-#include "chrome/browser/storage_monitor/storage_monitor_chromeos.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"
@@ -555,8 +554,6 @@
base::Bind(&ChromeOSVersionCallback),
&tracker_);
- storage_monitor_.reset(new StorageMonitorCros());
-
// Make sure that wallpaper boot transition and other delays in OOBE
// are disabled for tests and kiosk app launch by default.
// Individual tests may enable them if they want.
@@ -801,7 +798,6 @@
power_button_observer_.reset();
screensaver_controller_.reset();
idle_action_warning_observer_.reset();
- storage_monitor_.reset();
// Delete ContactManager while |g_browser_process| is still alive.
contact_manager_.reset();
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.h b/chrome/browser/chromeos/chrome_browser_main_chromeos.h
index f1073b0..df86349 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.h
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.h
@@ -31,7 +31,6 @@
class ScreenLockObserver;
class ScreensaverController;
class SessionManagerObserver;
-class StorageMonitorCros;
class SuspendObserver;
class SwapMetrics;
class UserActivityNotifier;
@@ -83,7 +82,6 @@
scoped_ptr<content::PowerSaveBlocker> retail_mode_power_save_blocker_;
scoped_ptr<UserActivityNotifier> user_activity_notifier_;
scoped_ptr<VideoActivityNotifier> video_activity_notifier_;
- scoped_ptr<StorageMonitorCros> storage_monitor_;
scoped_ptr<IdleActionWarningObserver> idle_action_warning_observer_;
scoped_ptr<SwapMetrics> swap_metrics_;
diff --git a/chrome/browser/chromeos/cros/cert_library.cc b/chrome/browser/chromeos/cros/cert_library.cc
index 952f14f..315c594 100644
--- a/chrome/browser/chromeos/cros/cert_library.cc
+++ b/chrome/browser/chromeos/cros/cert_library.cc
@@ -25,7 +25,7 @@
#include "grit/generated_resources.h"
#include "net/cert/cert_database.h"
#include "net/cert/nss_cert_database.h"
-#include "third_party/icu/public/i18n/unicode/coll.h" // icu::Collator
+#include "third_party/icu/source/i18n/unicode/coll.h" // icu::Collator
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/l10n_util_collator.h"
diff --git a/chrome/browser/chromeos/cros/network_library_impl_base.cc b/chrome/browser/chromeos/cros/network_library_impl_base.cc
index f5a872c..1ea9f64 100644
--- a/chrome/browser/chromeos/cros/network_library_impl_base.cc
+++ b/chrome/browser/chromeos/cros/network_library_impl_base.cc
@@ -938,7 +938,7 @@
class UserStringSubstitution : public onc::StringSubstitution {
public:
UserStringSubstitution() {}
- virtual bool GetSubstitute(std::string placeholder,
+ virtual bool GetSubstitute(const std::string& placeholder,
std::string* substitute) const OVERRIDE {
if (!UserManager::Get()->IsUserLoggedIn())
return false;
@@ -1039,20 +1039,6 @@
onc::TranslateONCObjectToShill(&onc::kNetworkConfigurationSignature,
*normalized_network);
- // Set the ProxyConfig.
- const base::DictionaryValue* proxy_settings;
- if (normalized_network->GetDictionaryWithoutPathExpansion(
- onc::network_config::kProxySettings,
- &proxy_settings)) {
- scoped_ptr<base::DictionaryValue> proxy_config =
- onc::ConvertOncProxySettingsToProxyConfig(*proxy_settings);
- std::string proxy_json;
- base::JSONWriter::Write(proxy_config.get(), &proxy_json);
- shill_dict->SetStringWithoutPathExpansion(
- flimflam::kProxyConfigProperty,
- proxy_json);
- }
-
// Set the UIData.
scoped_ptr<NetworkUIData> ui_data =
NetworkUIData::CreateFromONC(source, *normalized_network);
diff --git a/chrome/browser/chromeos/display/display_preferences.cc b/chrome/browser/chromeos/display/display_preferences.cc
index 2650909..a6a6b89 100644
--- a/chrome/browser/chromeos/display/display_preferences.cc
+++ b/chrome/browser/chromeos/display/display_preferences.cc
@@ -182,7 +182,7 @@
size_t num = display_manager->GetNumDisplays();
for (size_t i = 0; i < num; ++i) {
- int64 id = display_manager->GetDisplayAt(i)->id();
+ int64 id = display_manager->GetDisplayAt(i).id();
ash::internal::DisplayInfo info = display_manager->GetDisplayInfo(id);
scoped_ptr<base::DictionaryValue> property_value(
diff --git a/chrome/browser/chromeos/drive/drive_integration_service.cc b/chrome/browser/chromeos/drive/drive_integration_service.cc
index d4e6c53..6ae980a 100644
--- a/chrome/browser/chromeos/drive/drive_integration_service.cc
+++ b/chrome/browser/chromeos/drive/drive_integration_service.cc
@@ -15,7 +15,6 @@
#include "chrome/browser/chromeos/drive/drive_app_registry.h"
#include "chrome/browser/chromeos/drive/file_cache.h"
#include "chrome/browser/chromeos/drive/file_system.h"
-#include "chrome/browser/chromeos/drive/file_system_proxy.h"
#include "chrome/browser/chromeos/drive/file_system_util.h"
#include "chrome/browser/chromeos/drive/file_write_helper.h"
#include "chrome/browser/chromeos/drive/job_scheduler.h"
@@ -307,19 +306,15 @@
void DriveIntegrationService::AddDriveMountPoint() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DCHECK(!file_system_proxy_.get());
const base::FilePath drive_mount_point = util::GetDriveMountPointPath();
fileapi::ExternalMountPoints* mount_points =
BrowserContext::GetMountPoints(profile_);
DCHECK(mount_points);
- file_system_proxy_ = new FileSystemProxy(file_system_.get());
-
- bool success = mount_points->RegisterRemoteFileSystem(
+ bool success = mount_points->RegisterFileSystem(
drive_mount_point.BaseName().AsUTF8Unsafe(),
fileapi::kFileSystemTypeDrive,
- file_system_proxy_.get(),
drive_mount_point);
if (success) {
@@ -343,10 +338,6 @@
mount_points->RevokeFileSystem(
util::GetDriveMountPointPath().BaseName().AsUTF8Unsafe());
- if (file_system_proxy_.get()) {
- file_system_proxy_->DetachFromFileSystem();
- file_system_proxy_ = NULL;
- }
util::Log("Drive mount point is removed");
}
diff --git a/chrome/browser/chromeos/drive/drive_integration_service.h b/chrome/browser/chromeos/drive/drive_integration_service.h
index ac29cf9..56e15a9 100644
--- a/chrome/browser/chromeos/drive/drive_integration_service.h
+++ b/chrome/browser/chromeos/drive/drive_integration_service.h
@@ -29,7 +29,6 @@
class DriveAppRegistry;
class DriveServiceInterface;
class FileSystemInterface;
-class FileSystemProxy;
class FileWriteHelper;
class JobListInterface;
@@ -117,7 +116,7 @@
// Must be called on UI thread.
bool IsDriveEnabled();
- // Registers remote file system proxy for drive mount point.
+ // Registers remote file system for drive mount point.
void AddDriveMountPoint();
// Unregisters drive mount point from File API.
void RemoveDriveMountPoint();
@@ -155,7 +154,6 @@
scoped_ptr<FileSystemInterface> file_system_;
scoped_ptr<FileWriteHelper> file_write_helper_;
scoped_ptr<DownloadHandler> download_handler_;
- scoped_refptr<FileSystemProxy> file_system_proxy_;
scoped_ptr<DebugInfoCollector> debug_info_collector_;
ObserverList<DriveIntegrationServiceObserver> observers_;
diff --git a/chrome/browser/chromeos/drive/file_system_backend_delegate.cc b/chrome/browser/chromeos/drive/file_system_backend_delegate.cc
index 12598d2..b2462fc 100644
--- a/chrome/browser/chromeos/drive/file_system_backend_delegate.cc
+++ b/chrome/browser/chromeos/drive/file_system_backend_delegate.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/chromeos/drive/file_system_backend_delegate.h"
#include "base/bind.h"
+#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/chromeos/drive/async_file_util.h"
#include "chrome/browser/chromeos/drive/file_system_util.h"
@@ -15,9 +16,9 @@
#include "content/public/browser/browser_thread.h"
#include "webkit/browser/blob/file_stream_reader.h"
#include "webkit/browser/fileapi/async_file_util.h"
-#include "webkit/browser/fileapi/external_mount_points.h"
+#include "webkit/browser/fileapi/file_system_context.h"
#include "webkit/browser/fileapi/file_system_task_runners.h"
-#include "webkit/browser/fileapi/remote_file_system_proxy.h"
+#include "webkit/browser/fileapi/file_system_url.h"
using content::BrowserThread;
@@ -25,8 +26,7 @@
FileSystemBackendDelegate::FileSystemBackendDelegate(
content::BrowserContext* browser_context)
- : mount_points_(content::BrowserContext::GetMountPoints(browser_context)),
- profile_id_(Profile::FromBrowserContext(browser_context)),
+ : profile_id_(Profile::FromBrowserContext(browser_context)),
async_file_util_(new internal::AsyncFileUtil(
base::Bind(&util::GetFileSystemByProfileId, profile_id_))) {
DCHECK(profile_id_);
@@ -70,14 +70,14 @@
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DCHECK_EQ(fileapi::kFileSystemTypeDrive, url.type());
- fileapi::RemoteFileSystemProxyInterface* proxy =
- mount_points_->GetRemoteFileSystemProxy(url.filesystem_id());
- if (!proxy)
+ base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
+ if (file_path.empty())
return scoped_ptr<fileapi::FileStreamWriter>();
return scoped_ptr<fileapi::FileStreamWriter>(
new internal::WebkitFileStreamWriterImpl(
- proxy, url, offset, context->task_runners()->file_task_runner()));
+ base::Bind(&util::GetFileSystemByProfileId, profile_id_),
+ context->task_runners()->file_task_runner(),file_path, offset));
}
} // namespace drive
diff --git a/chrome/browser/chromeos/drive/file_system_backend_delegate.h b/chrome/browser/chromeos/drive/file_system_backend_delegate.h
index 55a9916..50066d3 100644
--- a/chrome/browser/chromeos/drive/file_system_backend_delegate.h
+++ b/chrome/browser/chromeos/drive/file_system_backend_delegate.h
@@ -6,7 +6,6 @@
#define CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_BACKEND_DELEGATE_H_
#include "base/basictypes.h"
-#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/chromeos/fileapi/file_system_backend_delegate.h"
@@ -16,7 +15,6 @@
namespace fileapi {
class AsyncFileUtil;
-class ExternalMountPoints;
} // namespace fileapi
namespace drive {
@@ -25,9 +23,8 @@
// for Drive file system.
class FileSystemBackendDelegate : public chromeos::FileSystemBackendDelegate {
public:
- // |browser_context| is currently used to take the ExternalMountPoints.
- explicit FileSystemBackendDelegate(
- content::BrowserContext* browser_context);
+ // |browser_context| is used to obtain |profile_id_|.
+ explicit FileSystemBackendDelegate(content::BrowserContext* browser_context);
virtual ~FileSystemBackendDelegate();
// FileSystemBackend::Delegate overrides.
@@ -44,8 +41,6 @@
fileapi::FileSystemContext* context) OVERRIDE;
private:
- scoped_refptr<fileapi::ExternalMountPoints> mount_points_;
-
// The profile for processing Drive accesses. Should not be NULL.
void* profile_id_;
scoped_ptr<fileapi::AsyncFileUtil> async_file_util_;
diff --git a/chrome/browser/chromeos/drive/file_system_interface.h b/chrome/browser/chromeos/drive/file_system_interface.h
index bf3b3be..0c2b40b 100644
--- a/chrome/browser/chromeos/drive/file_system_interface.h
+++ b/chrome/browser/chromeos/drive/file_system_interface.h
@@ -37,12 +37,14 @@
// Struct to represent a search result for SearchMetadata().
struct MetadataSearchResult {
- MetadataSearchResult(const base::FilePath& in_path,
- const ResourceEntry& in_entry,
+ MetadataSearchResult(const ResourceEntry& in_entry,
const std::string& in_highlighted_base_name)
- : path(in_path),
- entry(in_entry),
+ : entry(in_entry),
highlighted_base_name(in_highlighted_base_name) {
+ // Note: |path| is set separately from |entry| or other fields, because
+ // getting path typically takes longer time hence we want to fill it only
+ // when it is necessary. (I.e., not for temporary candidates, just for
+ // final user visible results.)
}
// The two members are used to create FileEntry object.
diff --git a/chrome/browser/chromeos/drive/file_system_proxy.cc b/chrome/browser/chromeos/drive/file_system_proxy.cc
deleted file mode 100644
index 25214f5..0000000
--- a/chrome/browser/chromeos/drive/file_system_proxy.cc
+++ /dev/null
@@ -1,445 +0,0 @@
-// 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/chromeos/drive/file_system_proxy.h"
-
-#include <string>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/platform_file.h"
-#include "base/strings/string_util.h"
-#include "base/threading/sequenced_worker_pool.h"
-#include "base/values.h"
-#include "chrome/browser/chromeos/drive/drive.pb.h"
-#include "chrome/browser/chromeos/drive/file_system_interface.h"
-#include "chrome/browser/chromeos/drive/file_system_util.h"
-#include "chrome/browser/chromeos/drive/fileapi_worker.h"
-#include "chrome/browser/chromeos/drive/webkit_file_stream_reader_impl.h"
-#include "chrome/browser/google_apis/task_util.h"
-#include "chrome/browser/google_apis/time_util.h"
-#include "content/public/browser/browser_thread.h"
-#include "webkit/browser/blob/file_stream_reader.h"
-#include "webkit/browser/fileapi/file_system_url.h"
-#include "webkit/common/blob/shareable_file_reference.h"
-#include "webkit/common/fileapi/file_system_types.h"
-#include "webkit/common/fileapi/file_system_util.h"
-
-using base::MessageLoopProxy;
-using content::BrowserThread;
-using fileapi::DirectoryEntry;
-using fileapi::FileSystemURL;
-using fileapi::FileSystemOperation;
-using webkit_blob::ShareableFileReference;
-
-namespace drive {
-
-namespace {
-
-// Runs |callback| with |error|, |file| and |peer_handle|.
-void RunOpenFileCallback(
- base::ProcessHandle peer_handle,
- const fileapi::RemoteFileSystemProxyInterface::OpenFileCallback& callback,
- base::PlatformFileError error,
- base::PlatformFile file) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- callback.Run(error, file, peer_handle);
-}
-
-// Runs |callback| with the arguments based on the given arguments.
-void RunSnapshotFileCallback(
- const fileapi::FileSystemOperation::SnapshotFileCallback& callback,
- base::PlatformFileError error,
- const base::PlatformFileInfo& file_info,
- const base::FilePath& local_path,
- webkit_blob::ScopedFile::ScopeOutPolicy scope_out_policy) {
- // ShareableFileReference is thread *unsafe* class. So it is necessary to
- // create the instance (by invoking GetOrCreate) on IO thread, though
- // most drive file system related operations run on UI thread.
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- scoped_refptr<webkit_blob::ShareableFileReference> file_reference =
- webkit_blob::ShareableFileReference::GetOrCreate(webkit_blob::ScopedFile(
- local_path,
- scope_out_policy,
- BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)
- .get()));
- callback.Run(error, file_info, local_path, file_reference);
-}
-
-} // namespace
-
-FileSystemProxy::FileSystemProxy(
- FileSystemInterface* file_system)
- : file_system_(file_system) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-}
-
-void FileSystemProxy::DetachFromFileSystem() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- file_system_ = NULL;
-}
-
-void FileSystemProxy::GetFileInfo(
- const FileSystemURL& file_url,
- const FileSystemOperation::GetMetadataCallback& callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- base::FilePath file_path;
- if (!ValidateUrl(file_url, &file_path)) {
- MessageLoopProxy::current()->PostTask(
- FROM_HERE,
- base::Bind(callback,
- base::PLATFORM_FILE_ERROR_NOT_FOUND,
- base::PlatformFileInfo()));
- return;
- }
-
- CallFileApiInternalFunctionOnUIThread(
- base::Bind(&fileapi_internal::GetFileInfo,
- file_path, google_apis::CreateRelayCallback(callback)));
-}
-
-void FileSystemProxy::Copy(
- const FileSystemURL& src_file_url,
- const FileSystemURL& dest_file_url,
- const FileSystemOperation::StatusCallback& callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- base::FilePath src_file_path, dest_file_path;
- if (!ValidateUrl(src_file_url, &src_file_path) ||
- !ValidateUrl(dest_file_url, &dest_file_path)) {
- MessageLoopProxy::current()->PostTask(
- FROM_HERE,
- base::Bind(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND));
- return;
- }
-
- CallFileApiInternalFunctionOnUIThread(
- base::Bind(&fileapi_internal::Copy,
- src_file_path, dest_file_path,
- google_apis::CreateRelayCallback(callback)));
-}
-
-void FileSystemProxy::Move(
- const FileSystemURL& src_file_url,
- const FileSystemURL& dest_file_url,
- const FileSystemOperation::StatusCallback& callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- base::FilePath src_file_path, dest_file_path;
- if (!ValidateUrl(src_file_url, &src_file_path) ||
- !ValidateUrl(dest_file_url, &dest_file_path)) {
- MessageLoopProxy::current()->PostTask(
- FROM_HERE,
- base::Bind(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND));
- return;
- }
-
- CallFileApiInternalFunctionOnUIThread(
- base::Bind(&fileapi_internal::Move,
- src_file_path, dest_file_path,
- google_apis::CreateRelayCallback(callback)));
-}
-
-void FileSystemProxy::ReadDirectory(
- const FileSystemURL& file_url,
- const FileSystemOperation::ReadDirectoryCallback& callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- base::FilePath file_path;
- if (!ValidateUrl(file_url, &file_path)) {
- base::MessageLoopProxy::current()->PostTask(
- FROM_HERE,
- base::Bind(callback,
- base::PLATFORM_FILE_ERROR_NOT_FOUND,
- std::vector<DirectoryEntry>(),
- false));
- return;
- }
-
- CallFileApiInternalFunctionOnUIThread(
- base::Bind(&fileapi_internal::ReadDirectory,
- file_path, google_apis::CreateRelayCallback(callback)));
-}
-
-void FileSystemProxy::Remove(
- const FileSystemURL& file_url,
- bool recursive,
- const FileSystemOperation::StatusCallback& callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- base::FilePath file_path;
- if (!ValidateUrl(file_url, &file_path)) {
- MessageLoopProxy::current()->PostTask(
- FROM_HERE,
- base::Bind(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND));
- return;
- }
-
- CallFileApiInternalFunctionOnUIThread(
- base::Bind(&fileapi_internal::Remove,
- file_path, recursive,
- google_apis::CreateRelayCallback(callback)));
-}
-
-void FileSystemProxy::CreateDirectory(
- const FileSystemURL& file_url,
- bool exclusive,
- bool recursive,
- const FileSystemOperation::StatusCallback& callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- base::FilePath file_path;
- if (!ValidateUrl(file_url, &file_path)) {
- MessageLoopProxy::current()->PostTask(
- FROM_HERE,
- base::Bind(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND));
- return;
- }
-
- CallFileApiInternalFunctionOnUIThread(
- base::Bind(&fileapi_internal::CreateDirectory,
- file_path, exclusive, recursive,
- google_apis::CreateRelayCallback(callback)));
-}
-
-void FileSystemProxy::CreateFile(
- const FileSystemURL& file_url,
- bool exclusive,
- const FileSystemOperation::StatusCallback& callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- base::FilePath file_path;
- if (!ValidateUrl(file_url, &file_path)) {
- MessageLoopProxy::current()->PostTask(
- FROM_HERE,
- base::Bind(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND));
- return;
- }
-
- CallFileApiInternalFunctionOnUIThread(
- base::Bind(&fileapi_internal::CreateFile,
- file_path, exclusive,
- google_apis::CreateRelayCallback(callback)));
-}
-
-void FileSystemProxy::Truncate(
- const FileSystemURL& file_url,
- int64 length,
- const FileSystemOperation::StatusCallback& callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- base::FilePath file_path;
- if (!ValidateUrl(file_url, &file_path)) {
- MessageLoopProxy::current()->PostTask(
- FROM_HERE,
- base::Bind(callback, base::PLATFORM_FILE_ERROR_NOT_FOUND));
- return;
- }
-
- CallFileApiInternalFunctionOnUIThread(
- base::Bind(&fileapi_internal::Truncate,
- file_path, length,
- google_apis::CreateRelayCallback(callback)));
-}
-
-void FileSystemProxy::OpenFile(
- const FileSystemURL& file_url,
- int file_flags,
- base::ProcessHandle peer_handle,
- const OpenFileCallback& callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- base::FilePath file_path;
- if (!ValidateUrl(file_url, &file_path)) {
- MessageLoopProxy::current()->PostTask(
- FROM_HERE,
- base::Bind(callback,
- base::PLATFORM_FILE_ERROR_NOT_FOUND,
- base::kInvalidPlatformFileValue,
- peer_handle));
- return;
- }
-
- CallFileApiInternalFunctionOnUIThread(
- base::Bind(&fileapi_internal::OpenFile,
- file_path, file_flags,
- google_apis::CreateRelayCallback(
- base::Bind(&RunOpenFileCallback, peer_handle, callback))));
-}
-
-void FileSystemProxy::NotifyCloseFile(const FileSystemURL& url) {
- base::FilePath file_path;
- if (!ValidateUrl(url, &file_path))
- return;
-
- CallFileApiInternalFunctionOnUIThread(
- base::Bind(&fileapi_internal::CloseFile, file_path));
-}
-
-void FileSystemProxy::TouchFile(
- const fileapi::FileSystemURL& url,
- const base::Time& last_access_time,
- const base::Time& last_modified_time,
- const FileSystemOperation::StatusCallback& callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- base::FilePath file_path;
- if (!ValidateUrl(url, &file_path))
- return;
-
- CallFileApiInternalFunctionOnUIThread(
- base::Bind(&fileapi_internal::TouchFile,
- file_path, last_access_time, last_modified_time,
- google_apis::CreateRelayCallback(callback)));
-}
-
-void FileSystemProxy::CreateSnapshotFile(
- const FileSystemURL& file_url,
- const FileSystemOperation::SnapshotFileCallback& callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- base::FilePath file_path;
- if (!ValidateUrl(file_url, &file_path)) {
- MessageLoopProxy::current()->PostTask(
- FROM_HERE,
- base::Bind(callback,
- base::PLATFORM_FILE_ERROR_NOT_FOUND,
- base::PlatformFileInfo(),
- base::FilePath(),
- scoped_refptr<ShareableFileReference>()));
- return;
- }
-
- CallFileApiInternalFunctionOnUIThread(
- base::Bind(&fileapi_internal::CreateSnapshotFile,
- file_path,
- google_apis::CreateRelayCallback(
- base::Bind(&RunSnapshotFileCallback, callback))));
-}
-
-void FileSystemProxy::CreateWritableSnapshotFile(
- const FileSystemURL& file_url,
- const fileapi::WritableSnapshotFile& callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- base::FilePath file_path;
- if (!ValidateUrl(file_url, &file_path)) {
- MessageLoopProxy::current()->PostTask(
- FROM_HERE,
- base::Bind(callback,
- base::PLATFORM_FILE_ERROR_NOT_FOUND,
- base::FilePath(),
- scoped_refptr<ShareableFileReference>(NULL)));
- return;
- }
-
- CallFileSystemMethodOnUIThread(
- base::Bind(&FileSystemInterface::OpenFile,
- base::Unretained(file_system_),
- file_path,
- OPEN_FILE,
- google_apis::CreateRelayCallback(
- base::Bind(
- &FileSystemProxy::OnCreateWritableSnapshotFile,
- this,
- file_path,
- callback))));
-}
-
-scoped_ptr<webkit_blob::FileStreamReader>
-FileSystemProxy::CreateFileStreamReader(
- base::SequencedTaskRunner* file_task_runner,
- const fileapi::FileSystemURL& url,
- int64 offset,
- const base::Time& expected_modification_time) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- NOTREACHED();
- return scoped_ptr<webkit_blob::FileStreamReader>();
-}
-
-FileSystemProxy::~FileSystemProxy() {
- // Should be deleted from the FileSystemBackend on UI thread.
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-}
-
-// static.
-bool FileSystemProxy::ValidateUrl(
- const FileSystemURL& url, base::FilePath* file_path) {
- *file_path = util::ExtractDrivePathFromFileSystemUrl(url);
- return !file_path->empty();
-}
-
-void FileSystemProxy::CallFileSystemMethodOnUIThread(
- const base::Closure& method_call) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(
- &FileSystemProxy::CallFileSystemMethodOnUIThreadInternal,
- this,
- method_call));
-}
-
-void FileSystemProxy::CallFileSystemMethodOnUIThreadInternal(
- const base::Closure& method_call) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- // If |file_system_| is NULL, it means the file system has already shut down.
- if (file_system_)
- method_call.Run();
-}
-
-void FileSystemProxy::CallFileApiInternalFunctionOnUIThread(
- const base::Callback<void(FileSystemInterface*)>& function) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(
- &fileapi_internal::RunFileSystemCallback,
- base::Bind(&FileSystemProxy::GetFileSystemOnUIThread, this),
- function, base::Closure()));
-}
-
-void FileSystemProxy::OnCreateWritableSnapshotFile(
- const base::FilePath& virtual_path,
- const fileapi::WritableSnapshotFile& callback,
- FileError result,
- const base::FilePath& local_path) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- scoped_refptr<ShareableFileReference> file_ref;
-
- if (result == FILE_ERROR_OK) {
- file_ref = ShareableFileReference::GetOrCreate(
- local_path,
- ShareableFileReference::DONT_DELETE_ON_FINAL_RELEASE,
- BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE).get());
- file_ref->AddFinalReleaseCallback(
- base::Bind(&FileSystemProxy::CloseWritableSnapshotFile,
- this,
- virtual_path));
- }
-
- callback.Run(FileErrorToPlatformError(result), local_path, file_ref);
-}
-
-void FileSystemProxy::CloseWritableSnapshotFile(
- const base::FilePath& virtual_path,
- const base::FilePath& local_path) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- CallFileApiInternalFunctionOnUIThread(
- base::Bind(&fileapi_internal::CloseFile, virtual_path));
-}
-
-FileSystemInterface* FileSystemProxy::GetFileSystemOnUIThread() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- return file_system_;
-}
-
-} // namespace drive
diff --git a/chrome/browser/chromeos/drive/file_system_proxy.h b/chrome/browser/chromeos/drive/file_system_proxy.h
deleted file mode 100644
index 349c5c0..0000000
--- a/chrome/browser/chromeos/drive/file_system_proxy.h
+++ /dev/null
@@ -1,148 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_PROXY_H_
-#define CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_PROXY_H_
-
-#include "chrome/browser/chromeos/drive/file_errors.h"
-#include "webkit/browser/fileapi/remote_file_system_proxy.h"
-
-namespace fileapi {
-class FileSystemURL;
-} // namespace fileapi
-
-namespace drive {
-
-class FileSystemInterface;
-class ResourceEntry;
-
-typedef std::vector<ResourceEntry> ResourceEntryVector;
-
-namespace internal {
-class FileApiWorker;
-} // namespace internal
-
-// Implementation of File API's remote file system proxy for Drive-backed
-// file system.
-class FileSystemProxy : public fileapi::RemoteFileSystemProxyInterface {
- public:
- using fileapi::RemoteFileSystemProxyInterface::OpenFileCallback;
-
- // |file_system| is the FileSystem instance owned by DriveIntegrationService.
- explicit FileSystemProxy(FileSystemInterface* file_system);
-
- // Detaches this instance from |file_system_|.
- // Method calls may result in no-op after calling this method.
- // This method must be called on UI thread.
- void DetachFromFileSystem();
-
- // fileapi::RemoteFileSystemProxyInterface overrides.
- virtual void GetFileInfo(
- const fileapi::FileSystemURL& url,
- const fileapi::FileSystemOperation::GetMetadataCallback&
- callback) OVERRIDE;
- virtual void Copy(
- const fileapi::FileSystemURL& src_url,
- const fileapi::FileSystemURL& dest_url,
- const fileapi::FileSystemOperation::StatusCallback& callback)
- OVERRIDE;
- virtual void Move(
- const fileapi::FileSystemURL& src_url,
- const fileapi::FileSystemURL& dest_url,
- const fileapi::FileSystemOperation::StatusCallback& callback)
- OVERRIDE;
- virtual void ReadDirectory(const fileapi::FileSystemURL& url,
- const fileapi::FileSystemOperation::ReadDirectoryCallback&
- callback) OVERRIDE;
- virtual void Remove(
- const fileapi::FileSystemURL& url, bool recursive,
- const fileapi::FileSystemOperation::StatusCallback& callback)
- OVERRIDE;
- virtual void CreateDirectory(
- const fileapi::FileSystemURL& file_url,
- bool exclusive,
- bool recursive,
- const fileapi::FileSystemOperation::StatusCallback& callback)
- OVERRIDE;
- virtual void CreateFile(
- const fileapi::FileSystemURL& file_url,
- bool exclusive,
- const fileapi::FileSystemOperation::StatusCallback& callback)
- OVERRIDE;
- virtual void Truncate(
- const fileapi::FileSystemURL& file_url, int64 length,
- const fileapi::FileSystemOperation::StatusCallback& callback)
- OVERRIDE;
- virtual void CreateSnapshotFile(
- const fileapi::FileSystemURL& url,
- const fileapi::FileSystemOperation::SnapshotFileCallback&
- callback) OVERRIDE;
- virtual void CreateWritableSnapshotFile(
- const fileapi::FileSystemURL& url,
- const fileapi::WritableSnapshotFile& callback) OVERRIDE;
- virtual void OpenFile(
- const fileapi::FileSystemURL& url,
- int file_flags,
- base::ProcessHandle peer_handle,
- const OpenFileCallback& callback) OVERRIDE;
- virtual void NotifyCloseFile(const fileapi::FileSystemURL& url) OVERRIDE;
- virtual void TouchFile(
- const fileapi::FileSystemURL& url,
- const base::Time& last_access_time,
- const base::Time& last_modified_time,
- const fileapi::FileSystemOperation::StatusCallback& callback)
- OVERRIDE;
- virtual scoped_ptr<webkit_blob::FileStreamReader> CreateFileStreamReader(
- base::SequencedTaskRunner* file_task_runner,
- const fileapi::FileSystemURL& url,
- int64 offset,
- const base::Time& expected_modification_time) OVERRIDE;
-
- protected:
- virtual ~FileSystemProxy();
-
- private:
- // Checks if a given |url| belongs to this file system. If it does,
- // the call will return true and fill in |file_path| with a file path of
- // a corresponding element within this file system.
- static bool ValidateUrl(const fileapi::FileSystemURL& url,
- base::FilePath* file_path);
-
- // Helper method to call methods of FileSystem. This method aborts
- // method calls in case DetachFromFileSystem() has been called.
- void CallFileSystemMethodOnUIThread(const base::Closure& method_call);
-
- // Used to implement CallFileSystemMethodOnUIThread.
- void CallFileSystemMethodOnUIThreadInternal(
- const base::Closure& method_call);
-
- // Helper method to call drive::filapi_internal functions. This method
- // aborts calls in case DetachFromFileSystem() has been called.
- void CallFileApiInternalFunctionOnUIThread(
- const base::Callback<void(FileSystemInterface*)>& function);
-
- // Helper callback for relaying reply for CreateWritableSnapshotFile() to
- // the calling thread.
- void OnCreateWritableSnapshotFile(
- const base::FilePath& virtual_path,
- const fileapi::WritableSnapshotFile& callback,
- FileError result,
- const base::FilePath& local_path);
-
- // Helper callback for closing the local cache file and committing the dirty
- // flag. This is triggered when the callback for CreateWritableSnapshotFile
- // released the refcounted reference to the file.
- void CloseWritableSnapshotFile(
- const base::FilePath& virtual_path,
- const base::FilePath& local_path);
-
- // Returns |file_system_| on UI thread.
- FileSystemInterface* GetFileSystemOnUIThread();
-
- FileSystemInterface* file_system_;
-};
-
-} // namespace drive
-
-#endif // CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_PROXY_H_
diff --git a/chrome/browser/chromeos/drive/fileapi_worker.cc b/chrome/browser/chromeos/drive/fileapi_worker.cc
index 825a19b..9f59917 100644
--- a/chrome/browser/chromeos/drive/fileapi_worker.cc
+++ b/chrome/browser/chromeos/drive/fileapi_worker.cc
@@ -132,6 +132,15 @@
callback.Run(base::PLATFORM_FILE_OK, file_info, local_path, scope_out_policy);
}
+// Runs |callback| with arguments converted from |error| and |local_path|.
+void RunCreateWritableSnapshotFileCallback(
+ const CreateWritableSnapshotFileCallback& callback,
+ FileError error,
+ const base::FilePath& local_path) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ callback.Run(FileErrorToPlatformError(error), local_path);
+}
+
// Runs |callback| with |error| and |platform_file|.
void RunOpenFileCallback(const OpenFileCallback& callback,
base::PlatformFileError* error,
@@ -296,6 +305,17 @@
base::Bind(&RunCreateSnapshotFileCallback, callback));
}
+void CreateWritableSnapshotFile(
+ const base::FilePath& file_path,
+ const CreateWritableSnapshotFileCallback& callback,
+ FileSystemInterface* file_system) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ file_system->OpenFile(
+ file_path,
+ OPEN_FILE,
+ base::Bind(&RunCreateWritableSnapshotFileCallback, callback));
+}
+
void OpenFile(const base::FilePath& file_path,
int file_flags,
const OpenFileCallback& callback,
diff --git a/chrome/browser/chromeos/drive/fileapi_worker.h b/chrome/browser/chromeos/drive/fileapi_worker.h
index c97a511..d26c65e 100644
--- a/chrome/browser/chromeos/drive/fileapi_worker.h
+++ b/chrome/browser/chromeos/drive/fileapi_worker.h
@@ -61,6 +61,10 @@
CreateSnapshotFileCallback;
typedef base::Callback<
void(base::PlatformFileError result,
+ const base::FilePath& snapshot_file_path)>
+ CreateWritableSnapshotFileCallback;
+typedef base::Callback<
+ void(base::PlatformFileError result,
base::PlatformFile platform_file)> OpenFileCallback;
// Runs |file_system_getter| to obtain the instance of FileSystemInstance,
@@ -143,6 +147,13 @@
const CreateSnapshotFileCallback& callback,
FileSystemInterface* file_system);
+// Creates a writable snapshot for the file at |file_path|.
+// After writing operation is done, CloseFile is needed to be called.
+void CreateWritableSnapshotFile(
+ const base::FilePath& file_path,
+ const CreateWritableSnapshotFileCallback& callback,
+ FileSystemInterface* file_system);
+
// Opens the file at |file_path| with options |file_flags|.
// Called from FileSystemProxy::OpenFile.
void OpenFile(const base::FilePath& file_path,
diff --git a/chrome/browser/chromeos/drive/search_metadata.cc b/chrome/browser/chromeos/drive/search_metadata.cc
index 6623d2e..b49f47f 100644
--- a/chrome/browser/chromeos/drive/search_metadata.cc
+++ b/chrome/browser/chromeos/drive/search_metadata.cc
@@ -145,14 +145,10 @@
(query && !FindAndHighlight(entry.base_name(), query, &highlighted)))
return;
- base::FilePath path = resource_metadata->GetFilePath(entry.resource_id());
- if (path.empty())
- return;
-
// Make space for |entry| when appropriate.
if (result_candidates->size() == at_most_num_matches)
result_candidates->pop();
- result_candidates->push(new MetadataSearchResult(path, entry, highlighted));
+ result_candidates->push(new MetadataSearchResult(entry, highlighted));
}
// Implements SearchMetadata().
@@ -181,8 +177,17 @@
// Prepare the result.
scoped_ptr<MetadataSearchResultVector> results(
new MetadataSearchResultVector);
- for (; !result_candidates.empty(); result_candidates.pop())
+ for (; !result_candidates.empty(); result_candidates.pop()) {
+ // The path field of entries in result_candidates are empty at this point,
+ // because we don't want to run the expensive metadata DB look up except for
+ // the final results. Hence, here we fill the part.
+ base::FilePath path = resource_metadata->GetFilePath(
+ result_candidates.top()->entry.resource_id());
+ if (path.empty())
+ continue;
results->push_back(*result_candidates.top());
+ results->back().path = path;
+ }
// Reverse the order here because |result_candidates| puts the most
// uninteresting candidate at the top.
diff --git a/chrome/browser/chromeos/drive/webkit_file_stream_writer_impl.cc b/chrome/browser/chromeos/drive/webkit_file_stream_writer_impl.cc
index 87a54fd..94e8e80 100644
--- a/chrome/browser/chromeos/drive/webkit_file_stream_writer_impl.cc
+++ b/chrome/browser/chromeos/drive/webkit_file_stream_writer_impl.cc
@@ -4,65 +4,109 @@
#include "chrome/browser/chromeos/drive/webkit_file_stream_writer_impl.h"
+#include "base/bind.h"
#include "base/callback_helpers.h"
+#include "chrome/browser/chromeos/drive/file_system_util.h"
+#include "chrome/browser/chromeos/drive/fileapi_worker.h"
+#include "chrome/browser/google_apis/task_util.h"
+#include "content/public/browser/browser_thread.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
-#include "webkit/browser/blob/local_file_stream_reader.h"
#include "webkit/browser/fileapi/local_file_stream_writer.h"
#include "webkit/browser/fileapi/remote_file_system_proxy.h"
-#include "webkit/common/blob/shareable_file_reference.h"
+
+using content::BrowserThread;
namespace drive {
namespace internal {
+namespace {
+
+// Creates a writable snapshot file of the |drive_path|.
+void CreateWritableSnapshotFile(
+ const WebkitFileStreamWriterImpl::FileSystemGetter& file_system_getter,
+ const base::FilePath& drive_path,
+ const fileapi_internal::CreateWritableSnapshotFileCallback& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(
+ &fileapi_internal::RunFileSystemCallback,
+ file_system_getter,
+ base::Bind(&fileapi_internal::CreateWritableSnapshotFile,
+ drive_path, google_apis::CreateRelayCallback(callback)),
+ google_apis::CreateRelayCallback(base::Bind(
+ callback, base::PLATFORM_FILE_ERROR_FAILED, base::FilePath()))));
+}
+
+// Closes the writable snapshot file opened by CreateWritableSnapshotFile.
+// TODO(hidehiko): Get rid of this function. crbug.com/259184.
+void CloseFile(
+ const WebkitFileStreamWriterImpl::FileSystemGetter& file_system_getter,
+ const base::FilePath& drive_path) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&fileapi_internal::RunFileSystemCallback,
+ file_system_getter,
+ base::Bind(&fileapi_internal::CloseFile, drive_path),
+ base::Closure()));
+}
+
+} // namespace
WebkitFileStreamWriterImpl::WebkitFileStreamWriterImpl(
- const scoped_refptr<fileapi::RemoteFileSystemProxyInterface>&
- remote_filesystem,
- const fileapi::FileSystemURL& url,
- int64 offset,
- base::TaskRunner* local_task_runner)
- : remote_filesystem_(remote_filesystem),
- local_task_runner_(local_task_runner),
- url_(url),
- initial_offset_(offset),
- has_pending_create_snapshot_(false),
+ const FileSystemGetter& file_system_getter,
+ base::TaskRunner* file_task_runner,
+ const base::FilePath& file_path,
+ int64 offset)
+ : file_system_getter_(file_system_getter),
+ file_task_runner_(file_task_runner),
+ file_path_(file_path),
+ offset_(offset),
weak_ptr_factory_(this) {
}
WebkitFileStreamWriterImpl::~WebkitFileStreamWriterImpl() {
+ if (local_file_writer_) {
+ // If the file is opened, close it at destructor.
+ // It is necessary to close the local file in advance.
+ local_file_writer_.reset();
+ CloseFile(file_system_getter_, file_path_);
+ }
}
int WebkitFileStreamWriterImpl::Write(net::IOBuffer* buf,
int buf_len,
const net::CompletionCallback& callback) {
- DCHECK(!has_pending_create_snapshot_);
+ DCHECK(pending_write_callback_.is_null());
DCHECK(pending_cancel_callback_.is_null());
+ DCHECK(!callback.is_null());
// If the local file is already available, just delegate to it.
if (local_file_writer_)
return local_file_writer_->Write(buf, buf_len, callback);
- // In this WebkitFileStreamWriterImpl, we only create snapshot file and don't
- // have explicit close operation. This is ok, because close is automatically
- // triggered by a refcounted |file_ref_| passed to
- // WriteAfterCreateWritableSnapshotFile, from the destructor of
- // WebkitFileStreamWriterImpl.
- has_pending_create_snapshot_ = true;
- remote_filesystem_->CreateWritableSnapshotFile(
- url_,
+ // The local file is not yet ready. Create the writable snapshot.
+ if (file_path_.empty())
+ return net::ERR_FILE_NOT_FOUND;
+
+ pending_write_callback_ = callback;
+ CreateWritableSnapshotFile(
+ file_system_getter_, file_path_,
base::Bind(
&WebkitFileStreamWriterImpl::WriteAfterCreateWritableSnapshotFile,
- weak_ptr_factory_.GetWeakPtr(),
- make_scoped_refptr(buf),
- buf_len,
- callback));
+ weak_ptr_factory_.GetWeakPtr(), make_scoped_refptr(buf), buf_len));
return net::ERR_IO_PENDING;
}
int WebkitFileStreamWriterImpl::Cancel(
const net::CompletionCallback& callback) {
- DCHECK(!callback.is_null());
DCHECK(pending_cancel_callback_.is_null());
+ DCHECK(!callback.is_null());
// If LocalFileWriter is already created, just delegate the cancel to it.
if (local_file_writer_)
@@ -70,7 +114,9 @@
// If file open operation is in-flight, wait for its completion and cancel
// further write operation in WriteAfterCreateWritableSnapshotFile.
- if (has_pending_create_snapshot_) {
+ if (!pending_write_callback_.is_null()) {
+ // Dismiss pending write callback immediately.
+ pending_write_callback_.Reset();
pending_cancel_callback_ = callback;
return net::ERR_IO_PENDING;
}
@@ -80,15 +126,15 @@
}
int WebkitFileStreamWriterImpl::Flush(const net::CompletionCallback& callback) {
- DCHECK(!callback.is_null());
DCHECK(pending_cancel_callback_.is_null());
+ DCHECK(!callback.is_null());
// If LocalFileWriter is already created, just delegate to it.
if (local_file_writer_)
return local_file_writer_->Flush(callback);
// There shouldn't be in-flight Write operation.
- DCHECK(!has_pending_create_snapshot_);
+ DCHECK(pending_write_callback_.is_null());
// Here is the case Flush() is called before any Write() invocation.
// Do nothing.
@@ -99,30 +145,36 @@
void WebkitFileStreamWriterImpl::WriteAfterCreateWritableSnapshotFile(
net::IOBuffer* buf,
int buf_len,
- const net::CompletionCallback& callback,
base::PlatformFileError open_result,
- const base::FilePath& local_path,
- const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
- has_pending_create_snapshot_ = false;
+ const base::FilePath& local_path) {
+ DCHECK(!local_file_writer_);
+
if (!pending_cancel_callback_.is_null()) {
+ DCHECK(pending_write_callback_.is_null());
// Cancel() is called during the creation of the snapshot file.
// Don't write to the file.
+ if (open_result == base::PLATFORM_FILE_OK) {
+ // Here the file is internally created. To revert the operation, close
+ // the file.
+ DCHECK(!local_path.empty());
+ CloseFile(file_system_getter_, file_path_);
+ }
+
base::ResetAndReturn(&pending_cancel_callback_).Run(net::OK);
return;
}
+ DCHECK(!pending_write_callback_.is_null());
+
+ const net::CompletionCallback callback =
+ base::ResetAndReturn(&pending_write_callback_);
if (open_result != base::PLATFORM_FILE_OK) {
callback.Run(net::PlatformFileErrorToNetError(open_result));
return;
}
- // Hold the reference to the file. Releasing the reference notifies the file
- // system about to close file.
- file_ref_ = file_ref;
-
- DCHECK(!local_file_writer_);
local_file_writer_.reset(new fileapi::LocalFileStreamWriter(
- local_task_runner_.get(), local_path, initial_offset_));
+ file_task_runner_.get(), local_path, offset_));
int result = local_file_writer_->Write(buf, buf_len, callback);
if (result != net::ERR_IO_PENDING)
callback.Run(result);
diff --git a/chrome/browser/chromeos/drive/webkit_file_stream_writer_impl.h b/chrome/browser/chromeos/drive/webkit_file_stream_writer_impl.h
index 38bfa54..1ddadba 100644
--- a/chrome/browser/chromeos/drive/webkit_file_stream_writer_impl.h
+++ b/chrome/browser/chromeos/drive/webkit_file_stream_writer_impl.h
@@ -6,43 +6,44 @@
#define CHROME_BROWSER_CHROMEOS_DRIVE_WEBKIT_FILE_STREAM_WRITER_IMPL_H_
#include "base/basictypes.h"
-#include "base/files/file_path.h"
+#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/platform_file.h"
#include "webkit/browser/fileapi/file_stream_writer.h"
-#include "webkit/browser/fileapi/file_system_context.h"
-#include "webkit/browser/fileapi/file_system_url.h"
-namespace fileapi {
-class RemoteFileSystemProxyInterface;
-}
+namespace base {
+class FilePath;
+class TaskRunner;
+} // namespace base
namespace net {
class IOBuffer;
-}
-
-namespace webkit_blob {
-class ShareableFileReference;
-}
+} // namespace net
namespace drive {
+
+class FileSystemInterface;
+
namespace internal {
// The implementation of fileapi::FileStreamWriter for the Drive File System.
class WebkitFileStreamWriterImpl : public fileapi::FileStreamWriter {
public:
- // Creates a writer for a file on |remote_filesystem| with path url |url|
- // (like "filesystem:chrome-extension://id/external/drive/...") that
- // starts writing from |offset|. When invalid parameters are set, the first
- // call to Write() method fails.
- // Uses |local_task_runner| for local file operations.
- WebkitFileStreamWriterImpl(
- const scoped_refptr<fileapi::RemoteFileSystemProxyInterface>&
- remote_filesystem,
- const fileapi::FileSystemURL& url,
- int64 offset,
- base::TaskRunner* local_task_runner);
+ // Callback to return the FileSystemInterface instance. This is an
+ // injecting point for testing.
+ // Note that the callback will be copied between threads (IO and UI), and
+ // will be called on UI thread.
+ typedef base::Callback<FileSystemInterface*()> FileSystemGetter;
+
+ // Creates a writer for a file at |file_path| on FileSystem returned by
+ // |file_system_getter| that starts writing from |offset|.
+ // When invalid parameters are set, the first call to Write() method fails.
+ // Uses |file_task_runner| for local file operations.
+ WebkitFileStreamWriterImpl(const FileSystemGetter& file_system_getter,
+ base::TaskRunner* file_task_runner,
+ const base::FilePath& file_path,
+ int64 offset);
virtual ~WebkitFileStreamWriterImpl();
// FileWriter override.
@@ -52,23 +53,20 @@
virtual int Flush(const net::CompletionCallback& callback) OVERRIDE;
private:
- // Callback function to do the continuation of the work of the first Write()
- // call, which tries to open the local copy of the file before writing.
+ // Part of Write(). Called after CreateWritableSnapshotFile is completed.
void WriteAfterCreateWritableSnapshotFile(
net::IOBuffer* buf,
int buf_len,
- const net::CompletionCallback& callback,
base::PlatformFileError open_result,
- const base::FilePath& local_path,
- const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref);
+ const base::FilePath& local_path);
- scoped_refptr<fileapi::RemoteFileSystemProxyInterface> remote_filesystem_;
- scoped_refptr<base::TaskRunner> local_task_runner_;
- const fileapi::FileSystemURL url_;
- const int64 initial_offset_;
+ FileSystemGetter file_system_getter_;
+ scoped_refptr<base::TaskRunner> file_task_runner_;
+ const base::FilePath file_path_;
+ const int64 offset_;
+
scoped_ptr<fileapi::FileStreamWriter> local_file_writer_;
- scoped_refptr<webkit_blob::ShareableFileReference> file_ref_;
- bool has_pending_create_snapshot_;
+ net::CompletionCallback pending_write_callback_;
net::CompletionCallback pending_cancel_callback_;
// Note: This should remain the last member so it'll be destroyed and
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.cc b/chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.cc
index c81be45..35f3f6a 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/file_browser_private_api.cc
@@ -2024,6 +2024,7 @@
IDS_FILE_BROWSER_ZIP_TARGET_EXISTS_ERROR);
SET_STRING("ZIP_FILESYSTEM_ERROR", IDS_FILE_BROWSER_ZIP_FILESYSTEM_ERROR);
SET_STRING("ZIP_UNEXPECTED_ERROR", IDS_FILE_BROWSER_ZIP_UNEXPECTED_ERROR);
+ SET_STRING("SHARE_ERROR", IDS_FILE_BROWSER_SHARE_ERROR);
SET_STRING("DELETED_MESSAGE_PLURAL", IDS_FILE_BROWSER_DELETED_MESSAGE_PLURAL);
SET_STRING("DELETED_MESSAGE", IDS_FILE_BROWSER_DELETED_MESSAGE);
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_manager_event_router.cc b/chrome/browser/chromeos/extensions/file_manager/file_manager_event_router.cc
index 927eaa2..487ea2d 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_manager_event_router.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/file_manager_event_router.cc
@@ -176,6 +176,30 @@
return result.Pass();
}
+// Checks for availability of the Google+ Photos app.
+bool IsGooglePhotosInstalled(Profile *profile) {
+ ExtensionService* service =
+ extensions::ExtensionSystem::Get(profile)->extension_service();
+ if (!service)
+ return false;
+
+ // Google+ Photos uses several ids for different channels. Therefore, all of
+ // them should be checked.
+ const std::string kGooglePlusPhotosIds[] = {
+ "ebpbnabdhheoknfklmpddcdijjkmklkp", // G+ Photos staging
+ "efjnaogkjbogokcnohkmnjdojkikgobo", // G+ Photos prod
+ "ejegoaikibpmikoejfephaneibodccma" // G+ Photos dev
+ };
+
+ for (size_t i = 0; i < arraysize(kGooglePlusPhotosIds); ++i) {
+ if (service->GetExtensionById(kGooglePlusPhotosIds[i],
+ false /* include_disable */) != NULL)
+ return true;
+ }
+
+ return false;
+}
+
} // namespace
// Pass dummy value to JobInfo's constructor for make it default constructible.
@@ -716,24 +740,11 @@
const base::FilePath dcim_path = mount_path.Append(
FILE_PATH_LITERAL("DCIM"));
- // TODO(mtomasz): Temporarily for M26. Remove it on M27.
- // If an external photo importer is installed, then do not show the action
- // choice dialog.
- ExtensionService* service =
- extensions::ExtensionSystem::Get(profile_)->extension_service();
- if (!service)
- return;
- const std::string kExternalPhotoImporterExtensionId =
- "efjnaogkjbogokcnohkmnjdojkikgobo";
- const bool external_photo_importer_available =
- service->GetExtensionById(kExternalPhotoImporterExtensionId,
- false /* include_disable */) != NULL;
-
// If there is no DCIM folder or an external photo importer is not available,
// then launch Files.app.
DirectoryExistsOnUIThread(
dcim_path,
- external_photo_importer_available ?
+ IsGooglePhotosInstalled(profile_) ?
base::Bind(&base::DoNothing) :
base::Bind(&file_manager_util::ViewRemovableDrive, mount_path),
base::Bind(&file_manager_util::ViewRemovableDrive, mount_path));
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_manager_util.cc b/chrome/browser/chromeos/extensions/file_manager/file_manager_util.cc
index 4ce88d2..c698bfc 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_manager_util.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/file_manager_util.cc
@@ -49,6 +49,7 @@
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/pepper_plugin_info.h"
+#include "content/public/common/webplugininfo.h"
#include "grit/generated_resources.h"
#include "net/base/escape.h"
#include "net/base/mime_util.h"
@@ -60,7 +61,6 @@
#include "webkit/browser/fileapi/file_system_operation_runner.h"
#include "webkit/browser/fileapi/file_system_url.h"
#include "webkit/common/fileapi/file_system_util.h"
-#include "webkit/plugins/webplugininfo.h"
using base::DictionaryValue;
using base::ListValue;
@@ -480,7 +480,7 @@
void CheckIfDirectoryExistsOnIOThread(
scoped_refptr<fileapi::FileSystemContext> file_system_context,
const GURL& url,
- const fileapi::FileSystemOperation::StatusCallback& callback) {
+ const fileapi::FileSystemOperationRunner::StatusCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
fileapi::FileSystemURL file_system_url = file_system_context->CrackURL(url);
@@ -492,7 +492,7 @@
void CheckIfDirectoryExists(
scoped_refptr<fileapi::FileSystemContext> file_system_context,
const GURL& url,
- const fileapi::FileSystemOperation::StatusCallback& callback) {
+ const fileapi::FileSystemOperationRunner::StatusCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
BrowserThread::PostTask(
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_apitest.cc b/chrome/browser/chromeos/extensions/wallpaper_private_apitest.cc
index 14f164f..80fbb8b 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_private_apitest.cc
+++ b/chrome/browser/chromeos/extensions/wallpaper_private_apitest.cc
@@ -5,7 +5,8 @@
#include "chrome/browser/extensions/extension_apitest.h"
#include "net/dns/mock_host_resolver.h"
-IN_PROC_BROWSER_TEST_F(ExtensionApiTest, WallpaperPicker) {
+// Flaky. See http://crbug.com/262854 .
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_WallpaperPicker) {
host_resolver()->AddRule("a.com", "127.0.0.1");
ASSERT_TRUE(StartEmbeddedTestServer());
ASSERT_TRUE(RunComponentExtensionTest("wallpaper_manager")) << message_;
diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc
index 4f21a46..fcb8919 100644
--- a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc
+++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc
@@ -23,7 +23,7 @@
#include "chromeos/ime/extension_ime_util.h"
#include "chromeos/ime/input_method_delegate.h"
#include "chromeos/ime/xkeyboard.h"
-#include "third_party/icu/public/common/unicode/uloc.h"
+#include "third_party/icu/source/common/unicode/uloc.h"
#include "ui/base/accelerators/accelerator.h"
namespace chromeos {
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc
index b2106f3..d8f2671 100644
--- a/chrome/browser/chromeos/login/chrome_restart_request.cc
+++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -139,8 +139,10 @@
ash::switches::kAshDefaultGuestWallpaperSmall,
ash::switches::kAshDefaultWallpaperLarge,
ash::switches::kAshDefaultWallpaperSmall,
+#if defined(OS_CHROMEOS)
+ ash::switches::kAshDisableAudioDeviceMenu,
ash::switches::kAshDisableNewAudioHandler,
- ash::switches::kAshEnableAudioDeviceMenu,
+#endif
ash::switches::kAshHostWindowBounds,
ash::switches::kAshTouchHud,
ash::switches::kAuraLegacyPowerButton,
@@ -149,6 +151,7 @@
// content/browser/renderer_host/render_process_host_impl.cc.
cc::switches::kBackgroundColorInsteadOfCheckerboard,
cc::switches::kCompositeToMailbox,
+ cc::switches::kDisableCompositedAntialiasing,
cc::switches::kDisableImplSidePainting,
cc::switches::kDisableThreadedAnimation,
cc::switches::kEnableImplSidePainting,
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc
index 3d64d4a..c1e14ee 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -715,6 +715,7 @@
if (UserManager::Get()->GetUserFlow(last_login_attempt_username_)->
HandleLoginFailure(failure)) {
+ login_display_->SetUIEnabled(true);
return;
}
diff --git a/chrome/browser/chromeos/login/login_display_host_impl.cc b/chrome/browser/chromeos/login/login_display_host_impl.cc
index fa60389..96d92a4 100644
--- a/chrome/browser/chromeos/login/login_display_host_impl.cc
+++ b/chrome/browser/chromeos/login/login_display_host_impl.cc
@@ -151,6 +151,9 @@
// static
LoginDisplayHost* LoginDisplayHostImpl::default_host_ = NULL;
+// static
+const int LoginDisplayHostImpl::kShowLoginWebUIid = 0x1111;
+
////////////////////////////////////////////////////////////////////////////////
// LoginDisplayHostImpl, public
@@ -439,8 +442,10 @@
}
LOG(WARNING) << "Login WebUI >> sign in";
- if (!login_window_)
+ if (!login_window_) {
+ TRACE_EVENT_ASYNC_BEGIN0("ui", "ShowLoginWebUI", kShowLoginWebUIid);
LoadURL(GURL(kLoginURL));
+ }
DVLOG(1) << "Starting sign in screen";
const chromeos::UserList& users = chromeos::UserManager::Get()->GetUsers();
diff --git a/chrome/browser/chromeos/login/login_display_host_impl.h b/chrome/browser/chromeos/login/login_display_host_impl.h
index 481001c..8d25d3f 100644
--- a/chrome/browser/chromeos/login/login_display_host_impl.h
+++ b/chrome/browser/chromeos/login/login_display_host_impl.h
@@ -84,6 +84,10 @@
const gfx::Rect& background_bounds() const { return background_bounds_; }
+ // Trace id for ShowLoginWebUI event (since there exists at most one login
+ // WebUI at a time).
+ static const int kShowLoginWebUIid;
+
protected:
// content::NotificationObserver implementation:
virtual void Observe(int type,
diff --git a/chrome/browser/chromeos/login/managed/locally_managed_user_login_flow.h b/chrome/browser/chromeos/login/managed/locally_managed_user_login_flow.h
index 688f07e..8a038f1 100644
--- a/chrome/browser/chromeos/login/managed/locally_managed_user_login_flow.h
+++ b/chrome/browser/chromeos/login/managed/locally_managed_user_login_flow.h
@@ -7,6 +7,7 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "chrome/browser/chromeos/login/user_flow.h"
diff --git a/chrome/browser/chromeos/login/wallpaper_manager.h b/chrome/browser/chromeos/login/wallpaper_manager.h
index 62e00d7..c994aba 100644
--- a/chrome/browser/chromeos/login/wallpaper_manager.h
+++ b/chrome/browser/chromeos/login/wallpaper_manager.h
@@ -21,7 +21,7 @@
#include "chromeos/dbus/power_manager_client.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
-#include "third_party/icu/public/i18n/unicode/timezone.h"
+#include "third_party/icu/source/i18n/unicode/timezone.h"
#include "ui/gfx/image/image_skia.h"
class PrefRegistrySimple;
diff --git a/chrome/browser/chromeos/login/wallpaper_manager_browsertest.cc b/chrome/browser/chromeos/login/wallpaper_manager_browsertest.cc
index ff25663..210aaa2 100644
--- a/chrome/browser/chromeos/login/wallpaper_manager_browsertest.cc
+++ b/chrome/browser/chromeos/login/wallpaper_manager_browsertest.cc
@@ -32,8 +32,8 @@
namespace {
-const int kLargeWallpaperResourceId = IDR_AURA_WALLPAPERS_5_GRADIENT5_LARGE;
-const int kSmallWallpaperResourceId = IDR_AURA_WALLPAPERS_5_GRADIENT5_SMALL;
+const int kLargeWallpaperResourceId = IDR_AURA_WALLPAPER_DEFAULT_LARGE;
+const int kSmallWallpaperResourceId = IDR_AURA_WALLPAPER_DEFAULT_SMALL;
int kLargeWallpaperWidth = 256;
int kLargeWallpaperHeight = ash::kLargeWallpaperMaxHeight;
diff --git a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
index aab384d..60aff4b 100644
--- a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
+++ b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
@@ -33,7 +33,7 @@
#include "grit/generated_resources.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/icu/public/common/unicode/locid.h"
+#include "third_party/icu/source/common/unicode/locid.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl.cc b/chrome/browser/chromeos/net/network_portal_detector_impl.cc
index f6e3c0a..5a1bbef 100644
--- a/chrome/browser/chromeos/net/network_portal_detector_impl.cc
+++ b/chrome/browser/chromeos/net/network_portal_detector_impl.cc
@@ -201,6 +201,8 @@
if (!lazy_detection_enabled())
return;
lazy_detection_enabled_ = false;
+ if (attempt_count_ == kMaxRequestAttempts && IsPortalCheckPending())
+ CancelPortalDetection();
VLOG(1) << "Lazy detection mode disabled.";
}
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl.h b/chrome/browser/chromeos/net/network_portal_detector_impl.h
index eeeef2e..b3a1371 100644
--- a/chrome/browser/chromeos/net/network_portal_detector_impl.h
+++ b/chrome/browser/chromeos/net/network_portal_detector_impl.h
@@ -138,7 +138,13 @@
// Returns current number of portal detection attempts.
// Used by unit tests.
- int attempt_count_for_testing() { return attempt_count_; }
+ int attempt_count_for_testing() const { return attempt_count_; }
+
+ // Sets current number of detection attempts.
+ // Used by unit tests.
+ void set_attempt_count_for_testing(int attempt_count) {
+ attempt_count_ = attempt_count;
+ }
// Sets minimum time between consecutive portal checks for the same
// network. Used by unit tests.
@@ -159,7 +165,7 @@
}
// Returns delay before next portal check. Used by unit tests.
- const base::TimeDelta& next_attempt_delay_for_testing() {
+ const base::TimeDelta& next_attempt_delay_for_testing() const {
return next_attempt_delay_;
}
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc b/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
index 7c30aba..2b6b410 100644
--- a/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
+++ b/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
@@ -149,6 +149,10 @@
return network_portal_detector()->attempt_count_for_testing();
}
+ void set_attempt_count(int ac) {
+ return network_portal_detector()->set_attempt_count_for_testing(ac);
+ }
+
void set_min_time_between_attempts(const base::TimeDelta& delta) {
network_portal_detector()->set_min_time_between_attempts_for_testing(delta);
}
@@ -550,6 +554,17 @@
kStubWireless1);
}
+TEST_F(NetworkPortalDetectorImplTest, DisableLazyDetectionWhilePendingRequest) {
+ ASSERT_TRUE(is_state_idle());
+ set_attempt_count(3);
+ enable_lazy_detection();
+ ASSERT_TRUE(is_state_portal_detection_pending());
+ disable_lazy_detection();
+
+ // To run CaptivePortalDetector::DetectCaptivePortal().
+ base::MessageLoop::current()->RunUntilIdle();
+}
+
TEST_F(NetworkPortalDetectorImplTest, LazyDetectionForOnlineNetwork) {
ASSERT_TRUE(is_state_idle());
set_min_time_between_attempts(base::TimeDelta());
diff --git a/chrome/browser/chromeos/net/onc_utils.cc b/chrome/browser/chromeos/net/onc_utils.cc
index 430af00..f897272 100644
--- a/chrome/browser/chromeos/net/onc_utils.cc
+++ b/chrome/browser/chromeos/net/onc_utils.cc
@@ -6,6 +6,8 @@
#include "base/logging.h"
#include "base/values.h"
+#include "chrome/browser/chromeos/login/user.h"
+#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/ui_proxy_config.h"
#include "chrome/browser/prefs/proxy_config_dictionary.h"
#include "chromeos/network/onc/onc_utils.h"
@@ -125,5 +127,53 @@
return proxy_dict.Pass();
}
+namespace {
+
+// This class defines which string placeholders of ONC are replaced by which
+// user attribute.
+class UserStringSubstitution : public chromeos::onc::StringSubstitution {
+ public:
+ explicit UserStringSubstitution(const chromeos::User* user) : user_(user) {}
+ virtual ~UserStringSubstitution() {}
+
+ virtual bool GetSubstitute(const std::string& placeholder,
+ std::string* substitute) const OVERRIDE {
+ if (placeholder == chromeos::onc::substitutes::kLoginIDField)
+ *substitute = user_->GetAccountName(false);
+ else if (placeholder == chromeos::onc::substitutes::kEmailField)
+ *substitute = user_->email();
+ else
+ return false;
+ return true;
+ }
+
+ private:
+ const chromeos::User* user_;
+
+ DISALLOW_COPY_AND_ASSIGN(UserStringSubstitution);
+};
+
+const chromeos::User* GetLoggedInUserByHash(const std::string& userhash) {
+ const chromeos::UserList& users =
+ chromeos::UserManager::Get()->GetLoggedInUsers();
+ for (chromeos::UserList::const_iterator it = users.begin(); it != users.end();
+ ++it) {
+ if ((*it)->username_hash() == userhash)
+ return *it;
+ }
+ return NULL;
+}
+
+} // namespace
+
+void ExpandStringPlaceholdersInNetworksForUser(
+ const std::string& hashed_username,
+ base::ListValue* network_configs) {
+ const chromeos::User* user = GetLoggedInUserByHash(hashed_username);
+ DCHECK(user);
+ UserStringSubstitution substitution(user);
+ chromeos::onc::ExpandStringsInNetworks(substitution, network_configs);
+}
+
} // namespace onc
} // namespace chromeos
diff --git a/chrome/browser/chromeos/net/onc_utils.h b/chrome/browser/chromeos/net/onc_utils.h
index d283e87..e855494 100644
--- a/chrome/browser/chromeos/net/onc_utils.h
+++ b/chrome/browser/chromeos/net/onc_utils.h
@@ -5,17 +5,17 @@
#ifndef CHROME_BROWSER_CHROMEOS_NET_ONC_UTILS_H_
#define CHROME_BROWSER_CHROMEOS_NET_ONC_UTILS_H_
+#include <string>
+
#include "base/memory/scoped_ptr.h"
#include "chromeos/network/onc/onc_constants.h"
namespace base {
class DictionaryValue;
+class ListValue;
}
namespace chromeos {
-
-class NetworkUIData;
-
namespace onc {
// Translates |onc_proxy_settings|, which has to be a valid ONC ProxySettings
@@ -27,6 +27,14 @@
scoped_ptr<base::DictionaryValue> ConvertOncProxySettingsToProxyConfig(
const base::DictionaryValue& onc_proxy_settings);
+// Replaces string placeholders in |network_configs|, which must be a list of
+// ONC NetworkConfigurations. Currently only user name placeholders are
+// implemented, which are replaced by attributes of the logged-in user with
+// |hashed_username|.
+void ExpandStringPlaceholdersInNetworksForUser(
+ const std::string& hashed_username,
+ base::ListValue* network_configs);
+
} // namespace onc
} // namespace chromeos
diff --git a/chrome/browser/chromeos/net/proxy_config_handler.cc b/chrome/browser/chromeos/net/proxy_config_handler.cc
index adb4c86..865d664 100644
--- a/chrome/browser/chromeos/net/proxy_config_handler.cc
+++ b/chrome/browser/chromeos/net/proxy_config_handler.cc
@@ -7,12 +7,17 @@
#include "base/bind.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
+#include "base/prefs/pref_registry_simple.h"
+#include "base/prefs/pref_service.h"
#include "base/values.h"
+#include "chrome/browser/chromeos/net/onc_utils.h"
#include "chrome/browser/prefs/proxy_config_dictionary.h"
#include "chrome/common/pref_names.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/shill_service_client.h"
#include "chromeos/network/network_handler_callbacks.h"
+#include "chromeos/network/network_profile.h"
+#include "chromeos/network/network_profile_handler.h"
#include "chromeos/network/network_state.h"
#include "chromeos/network/network_state_handler.h"
#include "components/user_prefs/pref_registry_syncable.h"
@@ -21,10 +26,124 @@
namespace chromeos {
+namespace {
+
+const base::DictionaryValue* GetNetworkConfigByGUID(
+ const base::ListValue& network_configs,
+ const std::string& guid) {
+ for (base::ListValue::const_iterator it = network_configs.begin();
+ it != network_configs.end();
+ ++it) {
+ const base::DictionaryValue* network = NULL;
+ (*it)->GetAsDictionary(&network);
+ std::string current_guid;
+ network->GetStringWithoutPathExpansion(onc::network_config::kGUID,
+ ¤t_guid);
+ if (current_guid == guid)
+ return network;
+ }
+ return NULL;
+}
+
+scoped_ptr<ProxyConfigDictionary> GetProxyPolicy(
+ const PrefService* pref_service,
+ const char* pref_name,
+ const NetworkState& network,
+ bool* network_is_managed) {
+ *network_is_managed = false;
+
+ if (!pref_service || network.guid().empty())
+ return scoped_ptr<ProxyConfigDictionary>();
+
+ if (!pref_service->IsManagedPreference(pref_name)) {
+ // No policy set.
+ return scoped_ptr<ProxyConfigDictionary>();
+ }
+
+ const base::ListValue* onc_policy = pref_service->GetList(pref_name);
+ if (!onc_policy) {
+ LOG(ERROR) << "Pref " << pref_name << " is managed, but no value is set.";
+ return scoped_ptr<ProxyConfigDictionary>();
+ }
+
+ const base::DictionaryValue* network_policy =
+ GetNetworkConfigByGUID(*onc_policy, network.guid());
+ if (!network_policy) {
+ // This network isn't managed by this policy.
+ return scoped_ptr<ProxyConfigDictionary>();
+ }
+
+ const base::DictionaryValue* proxy_policy = NULL;
+ network_policy->GetDictionaryWithoutPathExpansion(
+ onc::network_config::kProxySettings, &proxy_policy);
+ if (!proxy_policy) {
+ // This policy doesn't set a proxy for this network. Nonetheless, this
+ // disallows changes by the user.
+ *network_is_managed = true;
+ return scoped_ptr<ProxyConfigDictionary>();
+ }
+
+ scoped_ptr<base::DictionaryValue> proxy_dict =
+ onc::ConvertOncProxySettingsToProxyConfig(*proxy_policy);
+ *network_is_managed = true;
+ return make_scoped_ptr(new ProxyConfigDictionary(proxy_dict.get()));
+}
+
+} // namespace
+
namespace proxy_config {
scoped_ptr<ProxyConfigDictionary> GetProxyConfigForNetwork(
- const NetworkState& network) {
+ const PrefService* profile_prefs,
+ const PrefService* local_state_prefs,
+ const NetworkState& network,
+ onc::ONCSource* onc_source) {
+ VLOG(2) << "GetProxyConfigForNetwork network: " << network.path()
+ << " , guid: " << network.guid();
+ *onc_source = onc::ONC_SOURCE_NONE;
+ bool network_is_managed = false;
+
+ scoped_ptr<ProxyConfigDictionary> proxy_config =
+ GetProxyPolicy(profile_prefs,
+ prefs::kOpenNetworkConfiguration,
+ network,
+ &network_is_managed);
+ if (network_is_managed) {
+ VLOG(1) << "Network " << network.path() << " is managed by user policy.";
+ *onc_source = onc::ONC_SOURCE_USER_POLICY;
+ return proxy_config.Pass();
+ }
+ proxy_config = GetProxyPolicy(local_state_prefs,
+ prefs::kDeviceOpenNetworkConfiguration,
+ network,
+ &network_is_managed);
+ if (network_is_managed) {
+ VLOG(1) << "Network " << network.path() << " is managed by device policy.";
+ *onc_source = onc::ONC_SOURCE_DEVICE_POLICY;
+ return proxy_config.Pass();
+ }
+
+ if (network.profile_path().empty())
+ return scoped_ptr<ProxyConfigDictionary>();
+
+ const NetworkProfile* profile = NetworkHandler::Get()
+ ->network_profile_handler()->GetProfileForPath(network.profile_path());
+ if (!profile) {
+ LOG(WARNING) << "Unknown profile_path '" << network.profile_path() << "'.";
+ return scoped_ptr<ProxyConfigDictionary>();
+ }
+ if (!profile_prefs && profile->type() == NetworkProfile::TYPE_USER) {
+ // This case occurs, for example, if called from the proxy config tracker
+ // created for the system request context and the signin screen. Both don't
+ // use profile prefs and shouldn't depend on the user's not shared proxy
+ // settings.
+ VLOG(1)
+ << "Don't use unshared settings for system context or signin screen.";
+ return scoped_ptr<ProxyConfigDictionary>();
+ }
+
+ // No policy set for this network, read instead the user's (shared or
+ // unshared) configuration.
const base::DictionaryValue& value = network.proxy_config();
if (value.empty())
return scoped_ptr<ProxyConfigDictionary>();
@@ -46,7 +165,8 @@
base::Bind(&base::DoNothing),
base::Bind(&network_handler::ShillErrorCallbackFunction,
"SetProxyConfig.ClearProperty Failed",
- network.path(), network_handler::ErrorCallback()));
+ network.path(),
+ network_handler::ErrorCallback()));
} else {
std::string proxy_config_str;
base::JSONWriter::Write(&proxy_config.GetDictionary(), &proxy_config_str);
@@ -57,21 +177,28 @@
base::Bind(&base::DoNothing),
base::Bind(&network_handler::ShillErrorCallbackFunction,
"SetProxyConfig.SetProperty Failed",
- network.path(), network_handler::ErrorCallback()));
+ network.path(),
+ network_handler::ErrorCallback()));
}
if (NetworkHandler::IsInitialized()) {
- NetworkHandler::Get()->network_state_handler()->
- RequestUpdateForNetwork(network.path());
+ NetworkHandler::Get()->network_state_handler()
+ ->RequestUpdateForNetwork(network.path());
}
}
-void RegisterProfilePrefs(
- user_prefs::PrefRegistrySyncable* registry) {
+void RegisterPrefs(PrefRegistrySimple* registry) {
+ registry->RegisterListPref(prefs::kDeviceOpenNetworkConfiguration);
+}
+
+void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterBooleanPref(
prefs::kUseSharedProxies,
false,
user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+
+ registry->RegisterListPref(prefs::kOpenNetworkConfiguration,
+ user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
}
} // namespace proxy_config
diff --git a/chrome/browser/chromeos/net/proxy_config_handler.h b/chrome/browser/chromeos/net/proxy_config_handler.h
index b8455dc..40635d3 100644
--- a/chrome/browser/chromeos/net/proxy_config_handler.h
+++ b/chrome/browser/chromeos/net/proxy_config_handler.h
@@ -6,7 +6,10 @@
#define CHROME_BROWSER_CHROMEOS_NET_PROXY_CONFIG_HANDLER_H_
#include "base/memory/scoped_ptr.h"
+#include "chromeos/network/onc/onc_constants.h"
+class PrefRegistrySimple;
+class PrefService;
class ProxyConfigDictionary;
namespace user_prefs {
@@ -19,12 +22,21 @@
namespace proxy_config {
+// Get the proxy configuration including per-network policies for network
+// |network|. If |profile_prefs| is NULL, then only shared settings (and device
+// policy) are respected. This is e.g. the case for the signin screen and the
+// system request context.
scoped_ptr<ProxyConfigDictionary> GetProxyConfigForNetwork(
- const NetworkState& network);
+ const PrefService* profile_prefs,
+ const PrefService* local_state_prefs,
+ const NetworkState& network,
+ onc::ONCSource* onc_source);
void SetProxyConfigForNetwork(const ProxyConfigDictionary& proxy_config,
const NetworkState& network);
+void RegisterPrefs(PrefRegistrySimple* registry);
+
void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
} // namespace proxy_config
diff --git a/chrome/browser/chromeos/offline/offline_load_page.cc b/chrome/browser/chromeos/offline/offline_load_page.cc
index d752d1d..2a12636 100644
--- a/chrome/browser/chromeos/offline/offline_load_page.cc
+++ b/chrome/browser/chromeos/offline/offline_load_page.cc
@@ -113,8 +113,7 @@
extensions::ExtensionSystem::Get(profile)->extension_service();
// Extension service does not exist in test.
if (extensions_service)
- extension = extensions_service->extensions()->GetHostedAppByURL(
- ExtensionURLInfo(url_));
+ extension = extensions_service->extensions()->GetHostedAppByURL(url_);
if (extension)
GetAppOfflineStrings(extension, &strings);
diff --git a/chrome/browser/chromeos/options/network_config_view.cc b/chrome/browser/chromeos/options/network_config_view.cc
index ad5e37f..8de2ba7 100644
--- a/chrome/browser/chromeos/options/network_config_view.cc
+++ b/chrome/browser/chromeos/options/network_config_view.cc
@@ -286,6 +286,14 @@
: gfx::Size();
}
+// static
+const base::DictionaryValue* NetworkConfigView::FindPolicyForActiveUser(
+ const Network* network,
+ onc::ONCSource* onc_source) {
+ *onc_source = network->ui_data().onc_source();
+ return NetworkLibrary::Get()->FindOncForNetwork(network->unique_id());
+}
+
void ControlledSettingIndicatorView::Layout() {
image_view_->SetBounds(0, 0, width(), height());
}
diff --git a/chrome/browser/chromeos/options/network_config_view.h b/chrome/browser/chromeos/options/network_config_view.h
index 8e5954f..0a8290b 100644
--- a/chrome/browser/chromeos/options/network_config_view.h
+++ b/chrome/browser/chromeos/options/network_config_view.h
@@ -74,6 +74,10 @@
delegate_ = delegate;
}
+ static const base::DictionaryValue* FindPolicyForActiveUser(
+ const Network* network,
+ onc::ONCSource* onc_source);
+
protected:
// views::View overrides:
virtual void Layout() OVERRIDE;
diff --git a/chrome/browser/chromeos/options/vpn_config_view.cc b/chrome/browser/chromeos/options/vpn_config_view.cc
index 943e781..d8e019b 100644
--- a/chrome/browser/chromeos/options/vpn_config_view.cc
+++ b/chrome/browser/chromeos/options/vpn_config_view.cc
@@ -900,13 +900,14 @@
Network* network,
const std::string& dict_key,
const std::string& key) {
- NetworkLibrary* network_library = NetworkLibrary::Get();
+ onc::ONCSource onc_source = onc::ONC_SOURCE_NONE;
const base::DictionaryValue* onc =
- network_library->FindOncForNetwork(network->unique_id());
- VLOG_IF(1, !onc) << "No ONC found for VPN network " << network->unique_id();
+ NetworkConfigView::FindPolicyForActiveUser(network, &onc_source);
+ VLOG_IF(1, !onc) << "No ONC found for VPN network " << network->unique_id();
property_ui_data->ParseOncProperty(
- network->ui_data().onc_source(), onc,
+ onc_source,
+ onc,
base::StringPrintf("%s.%s.%s",
onc::network_config::kVPN,
dict_key.c_str(),
diff --git a/chrome/browser/chromeos/options/wifi_config_view.cc b/chrome/browser/chromeos/options/wifi_config_view.cc
index b2338e7..211f728 100644
--- a/chrome/browser/chromeos/options/wifi_config_view.cc
+++ b/chrome/browser/chromeos/options/wifi_config_view.cc
@@ -1246,10 +1246,13 @@
NetworkPropertyUIData* property_ui_data,
Network* network,
const std::string& key) {
- NetworkLibrary* network_library = NetworkLibrary::Get();
+ onc::ONCSource onc_source = onc::ONC_SOURCE_NONE;
+ const base::DictionaryValue* onc =
+ NetworkConfigView::FindPolicyForActiveUser(network, &onc_source);
+
property_ui_data->ParseOncProperty(
- network->ui_data().onc_source(),
- network_library->FindOncForNetwork(network->unique_id()),
+ onc_source,
+ onc,
base::StringPrintf("%s.%s", onc::network_config::kWiFi, key.c_str()));
}
diff --git a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc
index 81844f2..3fb1382 100644
--- a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc
+++ b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc
@@ -35,14 +35,18 @@
NetworkConfigurationPolicyHandler*
NetworkConfigurationPolicyHandler::CreateForUserPolicy() {
return new NetworkConfigurationPolicyHandler(
- key::kOpenNetworkConfiguration, onc::ONC_SOURCE_USER_POLICY);
+ key::kOpenNetworkConfiguration,
+ onc::ONC_SOURCE_USER_POLICY,
+ prefs::kOpenNetworkConfiguration);
}
// static
NetworkConfigurationPolicyHandler*
NetworkConfigurationPolicyHandler::CreateForDevicePolicy() {
return new NetworkConfigurationPolicyHandler(
- key::kDeviceOpenNetworkConfiguration, onc::ONC_SOURCE_DEVICE_POLICY);
+ key::kDeviceOpenNetworkConfiguration,
+ onc::ONC_SOURCE_DEVICE_POLICY,
+ prefs::kDeviceOpenNetworkConfiguration);
}
NetworkConfigurationPolicyHandler::~NetworkConfigurationPolicyHandler() {}
@@ -76,12 +80,10 @@
onc::Validator::Result validation_result;
root_dict = validator.ValidateAndRepairObject(
&onc::kToplevelConfigurationSignature, *root_dict, &validation_result);
- if (validation_result == onc::Validator::VALID_WITH_WARNINGS) {
- errors->AddError(policy_name(),
- IDS_POLICY_NETWORK_CONFIG_IMPORT_PARTIAL);
- } else if (validation_result == onc::Validator::INVALID) {
+ if (validation_result == onc::Validator::VALID_WITH_WARNINGS)
+ errors->AddError(policy_name(), IDS_POLICY_NETWORK_CONFIG_IMPORT_PARTIAL);
+ else if (validation_result == onc::Validator::INVALID)
errors->AddError(policy_name(), IDS_POLICY_NETWORK_CONFIG_IMPORT_FAILED);
- }
// In any case, don't reject the policy as some networks or certificates
// could still be applied.
@@ -93,8 +95,19 @@
void NetworkConfigurationPolicyHandler::ApplyPolicySettings(
const PolicyMap& policies,
PrefValueMap* prefs) {
- // Network policy is read directly from the provider and injected into
- // NetworkLibrary, so no need to convert the policy settings into prefs.
+ const base::Value* value = policies.GetValue(policy_name());
+ if (!value)
+ return;
+
+ std::string onc_blob;
+ value->GetAsString(&onc_blob);
+
+ scoped_ptr<base::ListValue> network_configs(new base::ListValue);
+ base::ListValue certificates;
+ chromeos::onc::ParseAndValidateOncForImport(
+ onc_blob, onc_source_, "", network_configs.get(), &certificates);
+
+ prefs->SetValue(pref_path_, network_configs.release());
}
void NetworkConfigurationPolicyHandler::PrepareForDisplaying(
@@ -112,9 +125,11 @@
NetworkConfigurationPolicyHandler::NetworkConfigurationPolicyHandler(
const char* policy_name,
- chromeos::onc::ONCSource onc_source)
+ chromeos::onc::ONCSource onc_source,
+ const char* pref_path)
: TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_STRING),
- onc_source_(onc_source) {
+ onc_source_(onc_source),
+ pref_path_(pref_path) {
}
// static
diff --git a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.h b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.h
index 9533d1d..8e0db73 100644
--- a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.h
+++ b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.h
@@ -36,7 +36,8 @@
private:
explicit NetworkConfigurationPolicyHandler(
const char* policy_name,
- chromeos::onc::ONCSource onc_source);
+ chromeos::onc::ONCSource onc_source,
+ const char* pref_path);
// Takes network policy in Value representation and produces an output Value
// that contains a pretty-printed and sanitized version. In particular, we
@@ -48,6 +49,9 @@
// distinguishes between user and device policy.
const chromeos::onc::ONCSource onc_source_;
+ // The name of the pref to apply the policy to.
+ const char* pref_path_;
+
DISALLOW_COPY_AND_ASSIGN(NetworkConfigurationPolicyHandler);
};
diff --git a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
index 3d25797..c5c9a48 100644
--- a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
+++ b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
@@ -35,6 +35,7 @@
#include "chrome/browser/prefs/session_startup_pref.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/host_desktop.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_switches.h"
@@ -332,9 +333,10 @@
base::Bind(IsSessionStarted)).Wait();
// Check that the startup pages specified in policy were opened.
- EXPECT_EQ(1U, chrome::GetTotalBrowserCount());
- Browser* browser =
- chrome::FindLastActiveWithHostDesktopType(chrome::HOST_DESKTOP_TYPE_ASH);
+ BrowserList* browser_list =
+ BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
+ EXPECT_EQ(1U, browser_list->size());
+ Browser* browser = browser_list->get(0);
ASSERT_TRUE(browser);
TabStripModel* tabs = browser->tab_strip_model();
diff --git a/chrome/browser/chromeos/policy/network_configuration_updater_impl.cc b/chrome/browser/chromeos/policy/network_configuration_updater_impl.cc
index fae76ac..262e776 100644
--- a/chrome/browser/chromeos/policy/network_configuration_updater_impl.cc
+++ b/chrome/browser/chromeos/policy/network_configuration_updater_impl.cc
@@ -10,6 +10,7 @@
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/values.h"
+#include "chrome/browser/chromeos/net/onc_utils.h"
#include "chrome/browser/policy/policy_map.h"
#include "chromeos/network/certificate_handler.h"
#include "chromeos/network/managed_network_configuration_handler.h"
@@ -20,43 +21,96 @@
namespace policy {
NetworkConfigurationUpdaterImpl::NetworkConfigurationUpdaterImpl(
- PolicyService* policy_service,
+ PolicyService* device_policy_service,
scoped_ptr<chromeos::CertificateHandler> certificate_handler)
- : policy_change_registrar_(
- policy_service, PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())),
- policy_service_(policy_service),
+ : device_policy_change_registrar_(device_policy_service,
+ PolicyNamespace(POLICY_DOMAIN_CHROME,
+ std::string())),
+ user_policy_service_(NULL),
+ device_policy_service_(device_policy_service),
certificate_handler_(certificate_handler.Pass()) {
- policy_change_registrar_.Observe(
+ device_policy_change_registrar_.Observe(
key::kDeviceOpenNetworkConfiguration,
base::Bind(&NetworkConfigurationUpdaterImpl::OnPolicyChanged,
base::Unretained(this),
chromeos::onc::ONC_SOURCE_DEVICE_POLICY));
- policy_change_registrar_.Observe(
- key::kOpenNetworkConfiguration,
- base::Bind(&NetworkConfigurationUpdaterImpl::OnPolicyChanged,
- base::Unretained(this),
- chromeos::onc::ONC_SOURCE_USER_POLICY));
- // Apply the current device policies immediately.
- ApplyNetworkConfiguration(chromeos::onc::ONC_SOURCE_DEVICE_POLICY);
+ if (device_policy_service_->IsInitializationComplete(POLICY_DOMAIN_CHROME)) {
+ // Apply the current device policies immediately.
+ VLOG(1) << "Device policy service is already initialized.";
+ ApplyNetworkConfiguration(chromeos::onc::ONC_SOURCE_DEVICE_POLICY);
+ } else {
+ device_policy_service_->AddObserver(POLICY_DOMAIN_CHROME, this);
+ }
}
NetworkConfigurationUpdaterImpl::~NetworkConfigurationUpdaterImpl() {
+ DCHECK(!user_policy_service_);
+ DCHECK(!user_policy_change_registrar_);
+ device_policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, this);
}
void NetworkConfigurationUpdaterImpl::SetUserPolicyService(
bool allow_trusted_certs_from_policy,
const std::string& hashed_username,
PolicyService* user_policy_service) {
- // TODO(pneubeck): observe user_policy_service for the actual initialization.
- VLOG(1) << "User policy initialized.";
+ VLOG(1) << "Got user policy service.";
+ user_policy_service_ = user_policy_service;
hashed_username_ = hashed_username;
if (allow_trusted_certs_from_policy)
SetAllowTrustedCertsFromPolicy();
- ApplyNetworkConfiguration(chromeos::onc::ONC_SOURCE_USER_POLICY);
+
+ user_policy_change_registrar_.reset(new PolicyChangeRegistrar(
+ user_policy_service_,
+ PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())));
+ user_policy_change_registrar_->Observe(
+ key::kOpenNetworkConfiguration,
+ base::Bind(&NetworkConfigurationUpdaterImpl::OnPolicyChanged,
+ base::Unretained(this),
+ chromeos::onc::ONC_SOURCE_USER_POLICY));
+
+ if (user_policy_service_->IsInitializationComplete(POLICY_DOMAIN_CHROME)) {
+ VLOG(1) << "User policy service is already initialized.";
+ ApplyNetworkConfiguration(chromeos::onc::ONC_SOURCE_USER_POLICY);
+ } else {
+ user_policy_service_->AddObserver(POLICY_DOMAIN_CHROME, this);
+ }
}
void NetworkConfigurationUpdaterImpl::UnsetUserPolicyService() {
+ if (!user_policy_service_)
+ return;
+
+ user_policy_change_registrar_.reset();
+ user_policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, this);
+ user_policy_service_ = NULL;
+}
+
+void NetworkConfigurationUpdaterImpl::OnPolicyUpdated(
+ const PolicyNamespace& ns,
+ const PolicyMap& previous,
+ const PolicyMap& current) {
+ // Ignore this call. Policy changes are already observed by the registrar.
+}
+
+void NetworkConfigurationUpdaterImpl::OnPolicyServiceInitialized(
+ PolicyDomain domain) {
+ if (domain != POLICY_DOMAIN_CHROME)
+ return;
+
+ // We don't know which policy service called this function, thus check
+ // both. Multiple removes are handled gracefully.
+ if (device_policy_service_->IsInitializationComplete(POLICY_DOMAIN_CHROME)) {
+ VLOG(1) << "Device policy service initialized.";
+ device_policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, this);
+ ApplyNetworkConfiguration(chromeos::onc::ONC_SOURCE_DEVICE_POLICY);
+ }
+ if (user_policy_service_ &&
+ user_policy_service_->IsInitializationComplete(POLICY_DOMAIN_CHROME)) {
+ VLOG(1) << "User policy service initialized.";
+ user_policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, this);
+ ApplyNetworkConfiguration(chromeos::onc::ONC_SOURCE_USER_POLICY);
+ }
}
void NetworkConfigurationUpdaterImpl::OnPolicyChanged(
@@ -74,12 +128,16 @@
<< chromeos::onc::GetSourceAsString(onc_source);
std::string policy_key;
- if (onc_source == chromeos::onc::ONC_SOURCE_USER_POLICY)
+ PolicyService* policy_service;
+ if (onc_source == chromeos::onc::ONC_SOURCE_USER_POLICY) {
policy_key = key::kOpenNetworkConfiguration;
- else
+ policy_service = user_policy_service_;
+ } else {
policy_key = key::kDeviceOpenNetworkConfiguration;
+ policy_service = device_policy_service_;
+ }
- const PolicyMap& policies = policy_service_->GetPolicies(
+ const PolicyMap& policies = policy_service->GetPolicies(
PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
const base::Value* policy_value = policies.GetValue(policy_key);
@@ -97,21 +155,17 @@
chromeos::onc::ParseAndValidateOncForImport(
onc_blob, onc_source, "", &network_configs, &certificates);
- chromeos::CertificateHandler::CertsByGUID imported_server_and_ca_certs;
scoped_ptr<net::CertificateList> web_trust_certs(new net::CertificateList);
certificate_handler_->ImportCertificates(
- certificates, onc_source, web_trust_certs.get(),
- &imported_server_and_ca_certs);
+ certificates, onc_source, web_trust_certs.get());
- if (!chromeos::onc::ResolveServerCertRefsInNetworks(
- imported_server_and_ca_certs, &network_configs)) {
- LOG(ERROR) << "Some certificate references in the ONC policy for source "
- << chromeos::onc::GetSourceAsString(onc_source)
- << " could not be resolved.";
+ std::string userhash;
+ if (onc_source == chromeos::onc::ONC_SOURCE_USER_POLICY) {
+ userhash = hashed_username_;
+ chromeos::onc::ExpandStringPlaceholdersInNetworksForUser(hashed_username_,
+ &network_configs);
}
- std::string userhash = onc_source == chromeos::onc::ONC_SOURCE_USER_POLICY ?
- hashed_username_ : std::string();
chromeos::NetworkHandler::Get()->managed_network_configuration_handler()->
SetPolicy(onc_source, userhash, network_configs);
diff --git a/chrome/browser/chromeos/policy/network_configuration_updater_impl.h b/chrome/browser/chromeos/policy/network_configuration_updater_impl.h
index 955aaa4..f9d7f10 100644
--- a/chrome/browser/chromeos/policy/network_configuration_updater_impl.h
+++ b/chrome/browser/chromeos/policy/network_configuration_updater_impl.h
@@ -15,7 +15,6 @@
namespace chromeos {
class CertificateHandler;
-class ManagedNetworkConfigurationHandler;
}
namespace policy {
@@ -25,10 +24,11 @@
// This implementation pushes policies to the
// ManagedNetworkConfigurationHandler. User policies are only pushed after
// OnUserPolicyInitialized() was called.
-class NetworkConfigurationUpdaterImpl : public NetworkConfigurationUpdater {
+class NetworkConfigurationUpdaterImpl : public NetworkConfigurationUpdater,
+ public PolicyService::Observer {
public:
NetworkConfigurationUpdaterImpl(
- PolicyService* policy_service,
+ PolicyService* device_policy_service,
scoped_ptr<chromeos::CertificateHandler> certificate_handler);
virtual ~NetworkConfigurationUpdaterImpl();
@@ -40,27 +40,38 @@
virtual void UnsetUserPolicyService() OVERRIDE;
- private:
- // Callback that's called by |policy_service_| if the respective ONC policy
- // changed.
- void OnPolicyChanged(chromeos::onc::ONCSource onc_source,
- const base::Value* previous,
- const base::Value* current);
+ // PolicyService::Observer overrides for both device and user policies.
+ virtual void OnPolicyUpdated(const PolicyNamespace& ns,
+ const PolicyMap& previous,
+ const PolicyMap& current) OVERRIDE;
+ virtual void OnPolicyServiceInitialized(PolicyDomain domain) OVERRIDE;
- void ApplyNetworkConfiguration(chromeos::onc::ONCSource onc_source);
+ private:
+ // Called if the ONC policy from |onc_source| changed.
+ void OnPolicyChanged(chromeos::onc::ONCSource onc_source,
+ const base::Value* previous,
+ const base::Value* current);
- // Wraps the policy service we read network configuration from.
- PolicyChangeRegistrar policy_change_registrar_;
+ void ApplyNetworkConfiguration(chromeos::onc::ONCSource onc_source);
- // The policy service storing the ONC policies.
- PolicyService* policy_service_;
+ // Used to register for notifications from the |user_policy_service_|.
+ scoped_ptr<PolicyChangeRegistrar> user_policy_change_registrar_;
- // User hash of the user that the user policy applies to.
- std::string hashed_username_;
+ // Used to register for notifications from the |device_policy_service_|.
+ PolicyChangeRegistrar device_policy_change_registrar_;
- scoped_ptr<chromeos::CertificateHandler> certificate_handler_;
+ // Used to retrieve user policies.
+ PolicyService* user_policy_service_;
- DISALLOW_COPY_AND_ASSIGN(NetworkConfigurationUpdaterImpl);
+ // Used to retrieve device policies.
+ PolicyService* device_policy_service_;
+
+ // User hash of the user that the user policy applies to.
+ std::string hashed_username_;
+
+ scoped_ptr<chromeos::CertificateHandler> certificate_handler_;
+
+ DISALLOW_COPY_AND_ASSIGN(NetworkConfigurationUpdaterImpl);
};
} // namespace policy
diff --git a/chrome/browser/chromeos/policy/network_configuration_updater_impl_cros.cc b/chrome/browser/chromeos/policy/network_configuration_updater_impl_cros.cc
index 654382e..95de6fb 100644
--- a/chrome/browser/chromeos/policy/network_configuration_updater_impl_cros.cc
+++ b/chrome/browser/chromeos/policy/network_configuration_updater_impl_cros.cc
@@ -165,18 +165,9 @@
chromeos::onc::ParseAndValidateOncForImport(
onc_blob, onc_source, "", &network_configs, &certificates);
- chromeos::CertificateHandler::CertsByGUID imported_server_and_ca_certs;
scoped_ptr<net::CertificateList> web_trust_certs(new net::CertificateList);
certificate_handler_->ImportCertificates(
- certificates, onc_source, web_trust_certs.get(),
- &imported_server_and_ca_certs);
-
- if (!chromeos::onc::ResolveServerCertRefsInNetworks(
- imported_server_and_ca_certs, &network_configs)) {
- LOG(ERROR) << "Some certificate references in the ONC policy for source "
- << chromeos::onc::GetSourceAsString(onc_source)
- << " could not be resolved.";
- }
+ certificates, onc_source, web_trust_certs.get());
network_library_->LoadOncNetworks(network_configs, onc_source);
diff --git a/chrome/browser/chromeos/policy/network_configuration_updater_impl_cros_unittest.cc b/chrome/browser/chromeos/policy/network_configuration_updater_impl_cros_unittest.cc
index 292dcd7..1bd6eb9 100644
--- a/chrome/browser/chromeos/policy/network_configuration_updater_impl_cros_unittest.cc
+++ b/chrome/browser/chromeos/policy/network_configuration_updater_impl_cros_unittest.cc
@@ -25,7 +25,6 @@
#include "net/cert/cert_trust_anchor_provider.h"
#include "net/cert/x509_certificate.h"
#include "net/test/cert_test_util.h"
-#include "net/test/test_certificate_data.h"
#include "policy/policy_constants.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -183,7 +182,7 @@
EXPECT_CALL(network_library_, LoadOncNetworks(_, _));
StrictMock<chromeos::MockCertificateHandler>* certificate_handler =
new StrictMock<chromeos::MockCertificateHandler>();
- EXPECT_CALL(*certificate_handler, ImportCertificates(_, _, _, _));
+ EXPECT_CALL(*certificate_handler, ImportCertificates(_, _, _));
NetworkConfigurationUpdaterImplCros updater(
policy_service_.get(),
@@ -201,16 +200,10 @@
onc::ONC_SOURCE_USER_POLICY));
EXPECT_CALL(*certificate_handler,
ImportCertificates(_, chromeos::onc::ONC_SOURCE_DEVICE_POLICY,
- _, _));
- scoped_refptr<net::X509Certificate> google_cert(
- net::X509Certificate::CreateFromBytes(
- reinterpret_cast<const char*>(google_der), sizeof(google_der)));
- chromeos::CertificateHandler::CertsByGUID imported_certs;
- imported_certs["test-ca"] = google_cert;
+ _));
EXPECT_CALL(*certificate_handler,
ImportCertificates(_, chromeos::onc::ONC_SOURCE_USER_POLICY,
- _, _))
- .WillOnce(SetImportedCerts(imported_certs));
+ _));
EXPECT_CALL(network_library_, RemoveNetworkProfileObserver(_));
@@ -254,7 +247,7 @@
StrictMock<chromeos::MockCertificateHandler>* certificate_handler =
new StrictMock<chromeos::MockCertificateHandler>();
EXPECT_CALL(*certificate_handler, ImportCertificates(
- IsEqualTo(device_certs), onc::ONC_SOURCE_DEVICE_POLICY, _, _));
+ IsEqualTo(device_certs), onc::ONC_SOURCE_DEVICE_POLICY, _));
NetworkConfigurationUpdaterImplCros updater(
policy_service_.get(),
@@ -268,12 +261,12 @@
EXPECT_CALL(network_library_, LoadOncNetworks(
IsEqualTo(device_networks), onc::ONC_SOURCE_DEVICE_POLICY));
EXPECT_CALL(*certificate_handler, ImportCertificates(
- IsEqualTo(device_certs), onc::ONC_SOURCE_DEVICE_POLICY, _, _));
+ IsEqualTo(device_certs), onc::ONC_SOURCE_DEVICE_POLICY, _));
EXPECT_CALL(network_library_, LoadOncNetworks(
IsEqualTo(user_networks), onc::ONC_SOURCE_USER_POLICY));
EXPECT_CALL(*certificate_handler, ImportCertificates(
- IsEqualTo(user_certs), onc::ONC_SOURCE_USER_POLICY, _, _));
+ IsEqualTo(user_certs), onc::ONC_SOURCE_USER_POLICY, _));
EXPECT_CALL(network_library_, RemoveNetworkProfileObserver(_));
@@ -298,7 +291,7 @@
EXPECT_CALL(network_library_, LoadOncNetworks(_, _)).Times(AnyNumber());
StrictMock<chromeos::MockCertificateHandler>* certificate_handler =
new StrictMock<chromeos::MockCertificateHandler>();
- EXPECT_CALL(*certificate_handler, ImportCertificates(_, _, _, _))
+ EXPECT_CALL(*certificate_handler, ImportCertificates(_, _, _))
.WillRepeatedly(SetCertificateList(empty_cert_list));
NetworkConfigurationUpdaterImplCros updater(
policy_service_.get(),
@@ -321,11 +314,11 @@
// Certificates with the "Web" trust flag set should be forwarded to the
// trust provider.
EXPECT_CALL(network_library_, LoadOncNetworks(_, _));
- EXPECT_CALL(*certificate_handler, ImportCertificates(_, _, _, _))
+ EXPECT_CALL(*certificate_handler, ImportCertificates(_, _, _))
.WillRepeatedly(SetCertificateList(empty_cert_list));
onc::ONCSource current_source = NameToONCSource(GetParam());
EXPECT_CALL(network_library_, LoadOncNetworks(_, current_source));
- EXPECT_CALL(*certificate_handler, ImportCertificates(_, current_source, _, _))
+ EXPECT_CALL(*certificate_handler, ImportCertificates(_, current_source, _))
.WillRepeatedly(SetCertificateList(cert_list));
// Trigger a new policy load, and spin the IO message loop to pass the
// certificates to the |trust_provider| on the IO thread.
@@ -355,7 +348,7 @@
.Times(AnyNumber());
StrictMock<chromeos::MockCertificateHandler>* certificate_handler =
new StrictMock<chromeos::MockCertificateHandler>();
- EXPECT_CALL(*certificate_handler, ImportCertificates(_, _, _, _))
+ EXPECT_CALL(*certificate_handler, ImportCertificates(_, _, _))
.Times(AnyNumber());
NetworkConfigurationUpdaterImplCros updater(
policy_service_.get(),
@@ -369,7 +362,7 @@
EXPECT_CALL(network_library_, LoadOncNetworks(
IsEqualTo(fake_network_configs_.get()), NameToONCSource(GetParam())));
EXPECT_CALL(*certificate_handler, ImportCertificates(
- IsEqualTo(fake_certificates_.get()), NameToONCSource(GetParam()), _, _));
+ IsEqualTo(fake_certificates_.get()), NameToONCSource(GetParam()), _));
// In the current implementation, we always apply both policies.
EXPECT_CALL(network_library_, LoadOncNetworks(
@@ -378,7 +371,7 @@
EXPECT_CALL(*certificate_handler, ImportCertificates(
IsEqualTo(empty_certificates_.get()),
Ne(NameToONCSource(GetParam())),
- _, _));
+ _));
PolicyMap policy;
policy.Set(GetParam(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
@@ -395,7 +388,7 @@
EXPECT_CALL(*certificate_handler, ImportCertificates(
IsEqualTo(empty_certificates_.get()),
onc::ONC_SOURCE_DEVICE_POLICY,
- _, _));
+ _));
EXPECT_CALL(network_library_, LoadOncNetworks(
IsEqualTo(empty_network_configs_.get()),
@@ -403,7 +396,7 @@
EXPECT_CALL(*certificate_handler, ImportCertificates(
IsEqualTo(empty_certificates_.get()),
onc::ONC_SOURCE_USER_POLICY,
- _, _));
+ _));
EXPECT_CALL(network_library_, RemoveNetworkProfileObserver(_));
diff --git a/chrome/browser/chromeos/power/power_prefs.cc b/chrome/browser/chromeos/power/power_prefs.cc
index 60fc213..c2081bb 100644
--- a/chrome/browser/chromeos/power/power_prefs.cc
+++ b/chrome/browser/chromeos/power/power_prefs.cc
@@ -10,6 +10,7 @@
#include "base/logging.h"
#include "base/prefs/pref_change_registrar.h"
#include "base/prefs/pref_service.h"
+#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/profiles/profile.h"
@@ -74,10 +75,13 @@
const content::NotificationSource& source,
const content::NotificationDetails& details) {
switch (type) {
- case chrome::NOTIFICATION_LOGIN_WEBUI_VISIBLE:
+ case chrome::NOTIFICATION_LOGIN_WEBUI_VISIBLE: {
// Update |profile_| when entering the login screen.
- SetProfile(ProfileHelper::GetSigninProfile());
+ ProfileManager* profile_manager = g_browser_process->profile_manager();
+ if (!profile_manager || !profile_manager->IsLoggedIn())
+ SetProfile(ProfileHelper::GetSigninProfile());
break;
+ }
case chrome::NOTIFICATION_SESSION_STARTED:
// Update |profile_| when entering a session.
SetProfile(ProfileManager::GetDefaultProfile());
diff --git a/chrome/browser/chromeos/power/power_prefs_unittest.cc b/chrome/browser/chromeos/power/power_prefs_unittest.cc
index 27deca2..e5cd2d3 100644
--- a/chrome/browser/chromeos/power/power_prefs_unittest.cc
+++ b/chrome/browser/chromeos/power/power_prefs_unittest.cc
@@ -235,6 +235,18 @@
EXPECT_EQ(GetExpectedAllowScreenWakeLocksForProfile(user_profile),
GetCurrentAllowScreenWakeLocks());
+ // Simulate the login screen coming up as part of screen locking.
+ power_prefs_->Observe(chrome::NOTIFICATION_LOGIN_WEBUI_VISIBLE,
+ content::Source<PowerPrefsTest>(this),
+ content::NotificationService::NoDetails());
+
+ // Verify that power policy didn't revert to login screen settings.
+ EXPECT_EQ(user_profile, GetProfile());
+ EXPECT_EQ(GetExpectedPowerPolicyForProfile(user_profile),
+ GetCurrentPowerPolicy());
+ EXPECT_EQ(GetExpectedAllowScreenWakeLocksForProfile(user_profile),
+ GetCurrentAllowScreenWakeLocks());
+
// Inform power_prefs_ that the session has ended and the user profile has
// been destroyed.
power_prefs_->Observe(chrome::NOTIFICATION_PROFILE_DESTROYED,
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc
index 5248353..3925818 100644
--- a/chrome/browser/chromeos/preferences.cc
+++ b/chrome/browser/chromeos/preferences.cc
@@ -33,7 +33,7 @@
#include "chromeos/ime/input_method_manager.h"
#include "chromeos/ime/xkeyboard.h"
#include "components/user_prefs/pref_registry_syncable.h"
-#include "third_party/icu/public/i18n/unicode/timezone.h"
+#include "third_party/icu/source/i18n/unicode/timezone.h"
#include "ui/base/events/event_constants.h"
#include "ui/base/events/event_utils.h"
#include "url/gurl.h"
diff --git a/chrome/browser/chromeos/proxy_config_service_impl.cc b/chrome/browser/chromeos/proxy_config_service_impl.cc
index 95f4f19..7c618f8 100644
--- a/chrome/browser/chromeos/proxy_config_service_impl.cc
+++ b/chrome/browser/chromeos/proxy_config_service_impl.cc
@@ -5,6 +5,8 @@
#include "chrome/browser/chromeos/proxy_config_service_impl.h"
#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/callback.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/prefs/pref_service.h"
@@ -27,12 +29,17 @@
namespace {
-// Writes the proxy config of |network| to |proxy_config|. Returns false if no
+// Writes the proxy config of |network| to |proxy_config|. Set |onc_source| to
+// the source of this configuration. Returns false if no
// proxy was configured for this network.
-bool GetProxyConfig(const NetworkState& network,
- net::ProxyConfig* proxy_config) {
+bool GetProxyConfig(const PrefService* profile_prefs,
+ const PrefService* local_state_prefs,
+ const NetworkState& network,
+ net::ProxyConfig* proxy_config,
+ onc::ONCSource* onc_source) {
scoped_ptr<ProxyConfigDictionary> proxy_dict =
- proxy_config::GetProxyConfigForNetwork(network);
+ proxy_config::GetProxyConfigForNetwork(
+ profile_prefs, local_state_prefs, network, onc_source);
if (!proxy_dict)
return false;
return PrefProxyConfigTrackerImpl::PrefConfigToNetConfig(*proxy_dict,
@@ -47,16 +54,21 @@
: local_state_prefs),
active_config_state_(ProxyPrefs::CONFIG_UNSET),
profile_prefs_(profile_prefs),
+ local_state_prefs_(local_state_prefs),
pointer_factory_(this) {
- // Register for notifications of UseSharedProxies user preference.
+ const base::Closure proxy_change_callback = base::Bind(
+ &ProxyConfigServiceImpl::OnProxyPrefChanged, base::Unretained(this));
+
if (profile_prefs) {
- DCHECK(profile_prefs->FindPreference(prefs::kUseSharedProxies));
- use_shared_proxies_.Init(
- prefs::kUseSharedProxies,
- profile_prefs,
- base::Bind(&ProxyConfigServiceImpl::OnUseSharedProxiesChanged,
- base::Unretained(this)));
+ profile_pref_registrar_.Init(profile_prefs);
+ profile_pref_registrar_.Add(prefs::kOpenNetworkConfiguration,
+ proxy_change_callback);
+ profile_pref_registrar_.Add(prefs::kUseSharedProxies,
+ proxy_change_callback);
}
+ local_state_pref_registrar_.Init(local_state_prefs);
+ local_state_pref_registrar_.Add(prefs::kDeviceOpenNetworkConfiguration,
+ proxy_change_callback);
// Register for changes to the default network.
NetworkStateHandler* state_handler =
@@ -81,8 +93,7 @@
DetermineEffectiveConfigFromDefaultNetwork();
}
-void ProxyConfigServiceImpl::OnUseSharedProxiesChanged() {
- VLOG(1) << "use-shared-proxies pref changed.";
+void ProxyConfigServiceImpl::OnProxyPrefChanged() {
DetermineEffectiveConfigFromDefaultNetwork();
}
@@ -116,9 +127,11 @@
return false;
}
- const NetworkProfile* profile =
- NetworkHandler::Get()->network_profile_handler()->
- GetProfileForPath(network_profile_path);
+ if (network_profile_path.empty())
+ return true;
+
+ const NetworkProfile* profile = NetworkHandler::Get()
+ ->network_profile_handler()->GetProfileForPath(network_profile_path);
if (!profile) {
LOG(WARNING) << "Unknown profile_path '" << network_profile_path
<< "'. Ignoring proxy.";
@@ -133,7 +146,7 @@
g_browser_process->browser_policy_connector();
const User* logged_in_user = UserManager::Get()->GetLoggedInUser();
if (connector->GetUserAffiliation(logged_in_user->email()) ==
- policy::USER_AFFILIATION_MANAGED) {
+ policy::USER_AFFILIATION_MANAGED) {
VLOG(1) << "Respecting proxy for network, as logged-in user belongs to "
<< "the domain the device is enrolled to.";
return false;
@@ -160,16 +173,19 @@
net::ProxyConfigService::CONFIG_UNSET;
bool ignore_proxy = true;
if (network) {
- ignore_proxy = IgnoreProxy(
- profile_prefs_, network->profile_path(), network->onc_source());
+ onc::ONCSource onc_source = onc::ONC_SOURCE_NONE;
+ const bool network_proxy_configured = chromeos::GetProxyConfig(
+ prefs(), local_state_prefs_, *network, &network_config, &onc_source);
+ ignore_proxy =
+ IgnoreProxy(profile_prefs_, network->profile_path(), onc_source);
+
// If network is shared but use-shared-proxies is off, use direct mode.
if (ignore_proxy) {
- VLOG(1) << "Shared network && !use-shared-proxies, use direct";
+ network_config = net::ProxyConfig();
network_availability = net::ProxyConfigService::CONFIG_VALID;
- } else if (chromeos::GetProxyConfig(*network, &network_config)) {
+ } else if (network_proxy_configured) {
// Network is private or shared with user using shared proxies.
- VLOG(1) << this << ": using network proxy: "
- << network->proxy_config();
+ VLOG(1) << this << ": using proxy of network " << network->path();
network_availability = net::ProxyConfigService::CONFIG_VALID;
}
}
@@ -186,8 +202,8 @@
bool update_now = update_pending();
if (!update_now) { // Otherwise, only update now if there're changes.
update_now = active_config_state_ != effective_config_state ||
- (active_config_state_ != ProxyPrefs::CONFIG_UNSET &&
- !active_config_.Equals(effective_config));
+ (active_config_state_ != ProxyPrefs::CONFIG_UNSET &&
+ !active_config_.Equals(effective_config));
}
if (update_now) { // Activate and store new effective config.
active_config_state_ = effective_config_state;
@@ -201,13 +217,13 @@
effective_config_state = ProxyPrefs::CONFIG_OTHER_PRECEDE;
// If config is manual, add rule to bypass local host.
if (effective_config.proxy_rules().type !=
- net::ProxyConfig::ProxyRules::TYPE_NO_RULES)
+ net::ProxyConfig::ProxyRules::TYPE_NO_RULES) {
effective_config.proxy_rules().bypass_rules.AddRuleToBypassLocal();
+ }
PrefProxyConfigTrackerImpl::OnProxyConfigChanged(effective_config_state,
effective_config);
if (VLOG_IS_ON(1) && !update_pending()) { // Update was successful.
- scoped_ptr<base::DictionaryValue> config_dict(
- effective_config.ToValue());
+ scoped_ptr<base::DictionaryValue> config_dict(effective_config.ToValue());
VLOG(1) << this << ": Proxy changed: "
<< ProxyPrefs::ConfigStateToDebugString(active_config_state_)
<< ", " << *config_dict;
diff --git a/chrome/browser/chromeos/proxy_config_service_impl.h b/chrome/browser/chromeos/proxy_config_service_impl.h
index de8f493..1037a05 100644
--- a/chrome/browser/chromeos/proxy_config_service_impl.h
+++ b/chrome/browser/chromeos/proxy_config_service_impl.h
@@ -9,17 +9,11 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
-#include "base/prefs/pref_member.h"
+#include "base/prefs/pref_change_registrar.h"
#include "chrome/browser/net/pref_proxy_config_tracker_impl.h"
#include "chromeos/network/network_state_handler_observer.h"
#include "chromeos/network/onc/onc_constants.h"
-class PrefRegistrySimple;
-
-namespace user_prefs {
-class PrefRegistrySyncable;
-}
-
namespace chromeos {
class NetworkState;
@@ -70,8 +64,8 @@
onc::ONCSource onc_source);
private:
- // Called when the kUseSharedProxies preference changes.
- void OnUseSharedProxiesChanged();
+ // Called when any proxy preference changes.
+ void OnProxyPrefChanged();
// Determines effective proxy config based on prefs from config tracker, the
// current default network and if user is using shared proxies. The effective
@@ -86,13 +80,20 @@
// Active proxy configuration, which could be from prefs or network.
net::ProxyConfig active_config_;
- // Track changes in UseSharedProxies user preference.
- BooleanPrefMember use_shared_proxies_;
+ // Track changes in profile preferences: UseSharedProxies and
+ // OpenNetworkConfiguration.
+ PrefChangeRegistrar profile_pref_registrar_;
+
+ // Track changes in local state preferences: DeviceOpenNetworkConfiguration.
+ PrefChangeRegistrar local_state_pref_registrar_;
// Not owned. NULL if tracking only local state prefs (e.g. in the system
// request context or sign-in screen).
PrefService* profile_prefs_;
+ // Not owned.
+ PrefService* local_state_prefs_;
+
base::WeakPtrFactory<ProxyConfigServiceImpl> pointer_factory_;
DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceImpl);
diff --git a/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc b/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc
index a0dea43..f66a0b5 100644
--- a/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc
+++ b/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc
@@ -221,14 +221,16 @@
SetUpNetwork();
PrefProxyConfigTrackerImpl::RegisterPrefs(pref_service_.registry());
- proxy_config_service_.reset(new ChromeProxyConfigService(NULL));
+
// Create a ProxyConfigServiceImpl like for the system request context.
config_service_impl_.reset(
new ProxyConfigServiceImpl(NULL, // no profile prefs
&pref_service_));
- config_service_impl_->SetChromeProxyConfigService(
- proxy_config_service_.get());
- // SetChromeProxyConfigService triggers update of initial prefs proxy
+ proxy_config_service_ =
+ config_service_impl_->CreateTrackingProxyConfigService(
+ scoped_ptr<net::ProxyConfigService>());
+
+ // CreateTrackingProxyConfigService triggers update of initial prefs proxy
// config by tracker to chrome proxy config service, so flush all pending
// tasks so that tests start fresh.
loop_.RunUntilIdle();
@@ -319,7 +321,7 @@
}
base::MessageLoop loop_;
- scoped_ptr<ChromeProxyConfigService> proxy_config_service_;
+ scoped_ptr<net::ProxyConfigService> proxy_config_service_;
scoped_ptr<ProxyConfigServiceImpl> config_service_impl_;
TestingPrefServiceSimple pref_service_;
diff --git a/chrome/browser/chromeos/proxy_cros_settings_parser.cc b/chrome/browser/chromeos/proxy_cros_settings_parser.cc
index a6195d9..2ccb83d 100644
--- a/chrome/browser/chromeos/proxy_cros_settings_parser.cc
+++ b/chrome/browser/chromeos/proxy_cros_settings_parser.cc
@@ -366,7 +366,8 @@
data = new base::StringValue("");
dict->Set("value", data);
if (path == kProxyType) {
- dict->SetString("controlledBy", controlled_by);
+ if (!controlled_by.empty())
+ dict->SetString("controlledBy", controlled_by);
dict->SetBoolean("disabled", !config.user_modifiable);
} else {
dict->SetBoolean("disabled", false);
diff --git a/chrome/browser/chromeos/settings/device_oauth2_token_service.cc b/chrome/browser/chromeos/settings/device_oauth2_token_service.cc
index 361d49e..58d823d 100644
--- a/chrome/browser/chromeos/settings/device_oauth2_token_service.cc
+++ b/chrome/browser/chromeos/settings/device_oauth2_token_service.cc
@@ -195,10 +195,10 @@
DeviceOAuth2TokenService::DeviceOAuth2TokenService(
net::URLRequestContextGetter* getter,
PrefService* local_state)
- : OAuth2TokenService(getter),
- refresh_token_is_valid_(false),
+ : refresh_token_is_valid_(false),
max_refresh_token_validation_retries_(3),
pending_validators_(new std::set<ValidatingConsumer*>()),
+ url_request_context_getter_(getter),
local_state_(local_state) {
}
@@ -206,6 +206,11 @@
STLDeleteElements(pending_validators_.get());
}
+net::URLRequestContextGetter* DeviceOAuth2TokenService::GetRequestContext() {
+ return url_request_context_getter_.get();
+}
+
+
// TODO(davidroche): if the caller deletes the returned Request while
// the fetches are in-flight, the OAuth2TokenService class won't call
// back into the ValidatingConsumer and we'll end up with stale values
diff --git a/chrome/browser/chromeos/settings/device_oauth2_token_service.h b/chrome/browser/chromeos/settings/device_oauth2_token_service.h
index 9ace020..c509216 100644
--- a/chrome/browser/chromeos/settings/device_oauth2_token_service.h
+++ b/chrome/browser/chromeos/settings/device_oauth2_token_service.h
@@ -66,6 +66,9 @@
PrefService* local_state);
virtual ~DeviceOAuth2TokenService();
+ // Implementation of OAuth2TokenService.
+ virtual net::URLRequestContextGetter* GetRequestContext() OVERRIDE;
+
void OnValidationComplete(ValidatingConsumer* validator, bool token_is_valid);
bool refresh_token_is_valid_;
@@ -73,6 +76,8 @@
scoped_ptr<std::set<ValidatingConsumer*> > pending_validators_;
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
+
// Cache the decrypted refresh token, so we only decrypt once.
std::string refresh_token_;
PrefService* local_state_;
diff --git a/chrome/browser/chromeos/settings/system_settings_provider.h b/chrome/browser/chromeos/settings/system_settings_provider.h
index ef7c174..0b993b1 100644
--- a/chrome/browser/chromeos/settings/system_settings_provider.h
+++ b/chrome/browser/chromeos/settings/system_settings_provider.h
@@ -11,7 +11,7 @@
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/chromeos/settings/cros_settings_provider.h"
#include "chrome/browser/chromeos/system/timezone_settings.h"
-#include "third_party/icu/public/i18n/unicode/timezone.h"
+#include "third_party/icu/source/i18n/unicode/timezone.h"
namespace base {
class StringValue;
diff --git a/chrome/browser/chromeos/system/ash_system_tray_delegate.cc b/chrome/browser/chromeos/system/ash_system_tray_delegate.cc
index 4d6b796..8c2fdb4 100644
--- a/chrome/browser/chromeos/system/ash_system_tray_delegate.cc
+++ b/chrome/browser/chromeos/system/ash_system_tray_delegate.cc
@@ -542,14 +542,14 @@
if (!active_contents)
return true;
- GURL active_url = active_contents->GetActiveURL();
+ GURL visible_url = active_contents->GetLastCommittedURL();
std::string display_settings_url =
std::string(chrome::kChromeUISettingsURL) + kDisplaySettingsSubPageName;
std::string display_overscan_url =
std::string(chrome::kChromeUISettingsURL) +
kDisplayOverscanSettingsSubPageName;
- return (active_url.spec() != display_settings_url) &&
- (active_url.spec() != display_overscan_url);
+ return (visible_url.spec() != display_settings_url) &&
+ (visible_url.spec() != display_overscan_url);
}
virtual void ShowDriveSettings() OVERRIDE {
diff --git a/chrome/browser/chromeos/system/input_device_settings.cc b/chrome/browser/chromeos/system/input_device_settings.cc
index 91471f0..09c17ae 100644
--- a/chrome/browser/chromeos/system/input_device_settings.cc
+++ b/chrome/browser/chromeos/system/input_device_settings.cc
@@ -64,8 +64,14 @@
}
va_end(vl);
- content::BrowserThread::GetBlockingPool()->PostTask(FROM_HERE,
- base::Bind(&ExecuteScriptOnFileThread, argv));
+ // Control scripts can take long enough to cause SIGART during shutdown
+ // (http://crbug.com/261426). Run the blocking pool task with
+ // CONTINUE_ON_SHUTDOWN so it won't be joined when Chrome shuts down.
+ base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
+ scoped_refptr<base::TaskRunner> runner =
+ pool->GetTaskRunnerWithShutdownBehavior(
+ base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
+ runner->PostTask(FROM_HERE, base::Bind(&ExecuteScriptOnFileThread, argv));
}
void SetPointerSensitivity(const char* script, int value) {
diff --git a/chrome/browser/chromeos/system/timezone_settings.cc b/chrome/browser/chromeos/system/timezone_settings.cc
index 6ebffc9..eab34e9 100644
--- a/chrome/browser/chromeos/system/timezone_settings.cc
+++ b/chrome/browser/chromeos/system/timezone_settings.cc
@@ -21,7 +21,7 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
-#include "third_party/icu/public/i18n/unicode/timezone.h"
+#include "third_party/icu/source/i18n/unicode/timezone.h"
using content::BrowserThread;
diff --git a/chrome/browser/chromeos/system/timezone_settings.h b/chrome/browser/chromeos/system/timezone_settings.h
index 6e9cc6c..ca62bf9 100644
--- a/chrome/browser/chromeos/system/timezone_settings.h
+++ b/chrome/browser/chromeos/system/timezone_settings.h
@@ -8,7 +8,7 @@
#include <vector>
#include "base/strings/string16.h"
-#include "third_party/icu/public/i18n/unicode/timezone.h"
+#include "third_party/icu/source/i18n/unicode/timezone.h"
namespace chromeos {
namespace system {
diff --git a/chrome/browser/chromeos/ui_proxy_config_service.cc b/chrome/browser/chromeos/ui_proxy_config_service.cc
index a7925a9..d607c0e 100644
--- a/chrome/browser/chromeos/ui_proxy_config_service.cc
+++ b/chrome/browser/chromeos/ui_proxy_config_service.cc
@@ -35,51 +35,57 @@
return "";
}
-// Writes the proxy config of |network| to |proxy_config|. Returns false if no
-// proxy was configured for this network.
-bool GetProxyConfig(const NetworkState& network,
- net::ProxyConfig* proxy_config) {
+// Writes the proxy config of |network| to |proxy_config|. Sets |onc_source| to
+// the source of this configuration. Returns false if no proxy was configured
+// for this network.
+bool GetProxyConfig(const PrefService* profile_prefs,
+ const PrefService* local_state_prefs,
+ const NetworkState& network,
+ net::ProxyConfig* proxy_config,
+ onc::ONCSource* onc_source) {
scoped_ptr<ProxyConfigDictionary> proxy_dict =
- proxy_config::GetProxyConfigForNetwork(network);
+ proxy_config::GetProxyConfigForNetwork(
+ profile_prefs, local_state_prefs, network, onc_source);
if (!proxy_dict)
return false;
return PrefProxyConfigTrackerImpl::PrefConfigToNetConfig(*proxy_dict,
proxy_config);
}
-// Returns true if proxy settings of |network| are editable.
-bool IsNetworkProxySettingsEditable(const NetworkState& network) {
- onc::ONCSource source = network.onc_source();
- return source != onc::ONC_SOURCE_DEVICE_POLICY &&
- source != onc::ONC_SOURCE_USER_POLICY;
+// Returns true if proxy settings from |onc_source| are editable.
+bool IsNetworkProxySettingsEditable(const onc::ONCSource onc_source) {
+ return onc_source != onc::ONC_SOURCE_DEVICE_POLICY &&
+ onc_source != onc::ONC_SOURCE_USER_POLICY;
}
} // namespace
UIProxyConfigService::UIProxyConfigService()
- : signin_screen_(false),
- pref_service_(NULL) {
+ : profile_prefs_(NULL), local_state_prefs_(NULL) {
}
UIProxyConfigService::~UIProxyConfigService() {
}
-void UIProxyConfigService::SetPrefs(bool signin_screen,
- PrefService* pref_service) {
- signin_screen_ = signin_screen;
- pref_service_ = pref_service;
+void UIProxyConfigService::SetPrefs(PrefService* profile_prefs,
+ PrefService* local_state_prefs) {
+ profile_prefs_ = profile_prefs;
+ local_state_prefs_ = local_state_prefs;
}
void UIProxyConfigService::SetCurrentNetwork(
const std::string& current_network) {
- const NetworkState* network = NULL;
- if (!current_network.empty()) {
- network = NetworkHandler::Get()->network_state_handler()->GetNetworkState(
- current_network);
- LOG_IF(ERROR, !network)
- << "Can't find requested network " << current_network;
- }
current_ui_network_ = current_network;
+}
+
+void UIProxyConfigService::UpdateFromPrefs() {
+ const NetworkState* network = NULL;
+ if (!current_ui_network_.empty()) {
+ network = NetworkHandler::Get()->network_state_handler()
+ ->GetNetworkState(current_ui_network_);
+ LOG_IF(ERROR, !network) << "Can't find requested network "
+ << current_ui_network_;
+ }
if (!network) {
current_ui_network_.clear();
current_ui_config_ = UIProxyConfig();
@@ -87,9 +93,8 @@
}
DetermineEffectiveConfig(*network);
- VLOG(1) << "Current ui network: "
- << network->name()
- << ", " << ModeToString(current_ui_config_.mode) << ", "
+ VLOG(1) << "Current ui network: " << network->name() << ", "
+ << ModeToString(current_ui_config_.mode) << ", "
<< ProxyPrefs::ConfigStateToDebugString(current_ui_config_.state)
<< ", modifiable:" << current_ui_config_.user_modifiable;
}
@@ -125,20 +130,30 @@
void UIProxyConfigService::DetermineEffectiveConfig(
const NetworkState& network) {
- DCHECK(pref_service_);
+ DCHECK(local_state_prefs_);
+
+ // The pref service to read proxy settings that apply to all networks.
+ // Settings from the profile overrule local state.
+ PrefService* top_pref_service =
+ profile_prefs_ ? profile_prefs_ : local_state_prefs_;
// Get prefs proxy config if available.
net::ProxyConfig pref_config;
ProxyPrefs::ConfigState pref_state = ProxyConfigServiceImpl::ReadPrefConfig(
- pref_service_, &pref_config);
+ top_pref_service, &pref_config);
// Get network proxy config if available.
net::ProxyConfig network_config;
net::ProxyConfigService::ConfigAvailability network_availability =
net::ProxyConfigService::CONFIG_UNSET;
- if (chromeos::GetProxyConfig(network, &network_config)) {
+ onc::ONCSource onc_source = onc::ONC_SOURCE_NONE;
+ if (chromeos::GetProxyConfig(profile_prefs_,
+ local_state_prefs_,
+ network,
+ &network_config,
+ &onc_source)) {
// Network is private or shared with user using shared proxies.
- VLOG(1) << this << ": using network proxy: " << network.proxy_config();
+ VLOG(1) << this << ": using proxy of network: " << network.path();
network_availability = net::ProxyConfigService::CONFIG_VALID;
}
@@ -155,16 +170,12 @@
current_ui_config_.state = effective_config_state;
if (ProxyConfigServiceImpl::PrefPrecedes(effective_config_state)) {
current_ui_config_.user_modifiable = false;
- } else if (!IsNetworkProxySettingsEditable(network)) {
- // TODO(xiyuan): Figure out the right way to set config state for managed
- // network.
+ } else if (!IsNetworkProxySettingsEditable(onc_source)) {
current_ui_config_.state = ProxyPrefs::CONFIG_POLICY;
current_ui_config_.user_modifiable = false;
} else {
current_ui_config_.user_modifiable = !ProxyConfigServiceImpl::IgnoreProxy(
- signin_screen_ ? NULL : pref_service_,
- network.profile_path(),
- network.onc_source());
+ profile_prefs_, network.profile_path(), onc_source);
}
}
diff --git a/chrome/browser/chromeos/ui_proxy_config_service.h b/chrome/browser/chromeos/ui_proxy_config_service.h
index f9d0de3..c6e28bb 100644
--- a/chrome/browser/chromeos/ui_proxy_config_service.h
+++ b/chrome/browser/chromeos/ui_proxy_config_service.h
@@ -28,19 +28,19 @@
UIProxyConfigService();
~UIProxyConfigService();
- // |signin_screen| indicates whether this object is used for the
- // signin screen, in which case proxies of (shared) networks are
- // unconditionally respected. After signin, proxy settings of shared networks
- // may be ignored, e.g. depending on the kUseSharedProxies flag. After this
- // call, proxy settings are read from
- // |prefs|.
- void SetPrefs(bool signin_screen, PrefService* prefs);
+ // After this call, proxy settings are read from |profile_prefs| and
+ // |local_state_prefs|. In case of usage for the sign-in screen,
+ // |profile_prefs| must be NULL because sign-in screen should depend only on
+ // shared settings.
+ void SetPrefs(PrefService* profile_prefs, PrefService* local_state_prefs);
// Called by UI to set the network with service path |current_network| to be
// displayed or edited. Subsequent Set*/Get* methods will use this
// network, until this method is called again.
void SetCurrentNetwork(const std::string& current_network);
+ void UpdateFromPrefs();
+
// Called from UI to retrieve the stored proxy configuration, which is either
// the last proxy config of the current network or the one last set by
// SetProxyConfig.
@@ -65,7 +65,12 @@
UIProxyConfig current_ui_config_;
bool signin_screen_;
- PrefService* pref_service_;
+
+ // Not owned.
+ PrefService* profile_prefs_;
+
+ // Not owned.
+ PrefService* local_state_prefs_;
DISALLOW_COPY_AND_ASSIGN(UIProxyConfigService);
};
diff --git a/chrome/browser/component_updater/component_updater_configurator.cc b/chrome/browser/component_updater/component_updater_configurator.cc
index d211e5e..f85c7db 100644
--- a/chrome/browser/component_updater/component_updater_configurator.cc
+++ b/chrome/browser/component_updater/component_updater_configurator.cc
@@ -10,7 +10,6 @@
#include "base/command_line.h"
#include "base/compiler_specific.h"
-#include "base/metrics/histogram.h"
#include "base/strings/string_util.h"
#include "base/win/windows_version.h"
#include "build/build_config.h"
@@ -38,6 +37,10 @@
const char kSwitchRequestParam[] = "test-request";
// Disables differential updates.
const char kSwitchDisableDeltaUpdates[] = "disable-delta-updates";
+// Disables pings. Pings are the requests sent to the update server that report
+// the success or the failure of component install or update attempts.
+extern const char kSwitchDisablePings[] = "disable-pings";
+
// Sets the URL for updates.
const char kSwitchUrlSource[] = "url-source";
@@ -46,6 +49,9 @@
const char kDefaultUrlSource[] =
"http://clients2.google.com/service/update2/crx";
+// The url to send the pings to.
+const char kPingUrl[] = "http://tools.google.com/service/update2";
+
// Returns true if and only if |test| is contained in |vec|.
bool HasSwitchValue(const std::vector<std::string>& vec, const char* test) {
if (vec.empty())
@@ -89,11 +95,11 @@
virtual int MinimumReCheckWait() OVERRIDE;
virtual int OnDemandDelay() OVERRIDE;
virtual GURL UpdateUrl() OVERRIDE;
+ virtual GURL PingUrl() OVERRIDE;
virtual const char* ExtraRequestParams() OVERRIDE;
virtual size_t UrlSizeLimit() OVERRIDE;
virtual net::URLRequestContextGetter* RequestContext() OVERRIDE;
virtual bool InProcess() OVERRIDE;
- virtual void OnEvent(Events event, int val) OVERRIDE;
virtual ComponentPatcher* CreateComponentPatcher() OVERRIDE;
virtual bool DeltasEnabled() const OVERRIDE;
@@ -103,6 +109,7 @@
std::string url_source_;
bool fast_update_;
bool out_of_process_;
+ bool pings_enabled_;
bool deltas_enabled_;
};
@@ -113,6 +120,7 @@
chrome::OmahaQueryParams::CHROME)),
fast_update_(false),
out_of_process_(false),
+ pings_enabled_(false),
deltas_enabled_(false) {
// Parse comma-delimited debug flags.
std::vector<std::string> switch_values;
@@ -120,6 +128,7 @@
",", &switch_values);
fast_update_ = HasSwitchValue(switch_values, kSwitchFastUpdate);
out_of_process_ = HasSwitchValue(switch_values, kSwitchOutOfProcess);
+ pings_enabled_ = !HasSwitchValue(switch_values, kSwitchDisablePings);
#if defined(OS_WIN)
deltas_enabled_ = !HasSwitchValue(switch_values, kSwitchDisableDeltaUpdates);
#else
@@ -166,6 +175,10 @@
return GURL(url_source_);
}
+GURL ChromeConfigurator::PingUrl() {
+ return pings_enabled_ ? GURL(kPingUrl) : GURL();
+}
+
const char* ChromeConfigurator::ExtraRequestParams() {
return extra_info_.c_str();
}
@@ -182,32 +195,6 @@
return !out_of_process_;
}
-void ChromeConfigurator::OnEvent(Events event, int val) {
- switch (event) {
- case kManifestCheck:
- UMA_HISTOGRAM_ENUMERATION("ComponentUpdater.ManifestCheck", val, 100);
- break;
- case kComponentUpdated:
- UMA_HISTOGRAM_ENUMERATION("ComponentUpdater.ComponentUpdated", val, 100);
- break;
- case kManifestError:
- UMA_HISTOGRAM_COUNTS_100("ComponentUpdater.ManifestError", val);
- break;
- case kNetworkError:
- UMA_HISTOGRAM_ENUMERATION("ComponentUpdater.NetworkError", val, 100);
- break;
- case kUnpackError:
- UMA_HISTOGRAM_ENUMERATION("ComponentUpdater.UnpackError", val, 100);
- break;
- case kInstallerError:
- UMA_HISTOGRAM_ENUMERATION("ComponentUpdater.InstallError", val, 100);
- break;
- default:
- NOTREACHED();
- break;
- }
-}
-
ComponentPatcher* ChromeConfigurator::CreateComponentPatcher() {
#if defined(OS_WIN)
return new ComponentPatcherWin();
diff --git a/chrome/browser/component_updater/component_updater_ping_manager.cc b/chrome/browser/component_updater/component_updater_ping_manager.cc
new file mode 100644
index 0000000..e052bc3
--- /dev/null
+++ b/chrome/browser/component_updater/component_updater_ping_manager.cc
@@ -0,0 +1,170 @@
+// Copyright 2013 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/component_updater/component_updater_ping_manager.h"
+#include "base/guid.h"
+#include "base/logging.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "base/sys_info.h"
+#include "base/win/windows_version.h"
+#include "chrome/browser/component_updater/crx_update_item.h"
+#include "chrome/common/chrome_version_info.h"
+#include "chrome/common/omaha_query_params/omaha_query_params.h"
+#include "net/base/load_flags.h"
+#include "net/base/net_errors.h"
+#include "net/url_request/url_fetcher.h"
+#include "net/url_request/url_fetcher_delegate.h"
+#include "net/url_request/url_request_status.h"
+
+namespace {
+
+// Returns true if the |update_item| contains a valid differential update url.
+bool HasDiffUpdate(const CrxUpdateItem* update_item) {
+ return update_item->diff_crx_url.is_valid();
+}
+
+} // namespace
+
+namespace component_updater {
+
+// Sends a fire and forget ping. The instances of this class have no
+// ownership and they self-delete upon completion.
+class PingSender : public net::URLFetcherDelegate {
+ public:
+ PingSender();
+
+ void SendPing(const GURL& ping_url,
+ net::URLRequestContextGetter* url_request_context_getter,
+ const CrxUpdateItem* item);
+ private:
+ virtual ~PingSender();
+
+ // Overrides for URLFetcherDelegate.
+ virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
+
+ static std::string BuildPing(const CrxUpdateItem* item);
+ static std::string BuildPingEventElement(const CrxUpdateItem* item);
+
+ scoped_ptr<net::URLFetcher> url_fetcher_;
+
+ DISALLOW_COPY_AND_ASSIGN(PingSender);
+};
+
+PingSender::PingSender() {}
+
+PingSender::~PingSender() {}
+
+void PingSender::OnURLFetchComplete(const net::URLFetcher* source) {
+ delete this;
+}
+
+void PingSender::SendPing(
+ const GURL& ping_url,
+ net::URLRequestContextGetter* url_request_context_getter,
+ const CrxUpdateItem* item) {
+ DCHECK(item);
+
+ if (!ping_url.is_valid())
+ return;
+
+ url_fetcher_.reset(net::URLFetcher::Create(0,
+ ping_url,
+ net::URLFetcher::POST,
+ this));
+
+ url_fetcher_->SetUploadData("application/xml", BuildPing(item));
+ url_fetcher_->SetRequestContext(url_request_context_getter);
+ url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
+ net::LOAD_DO_NOT_SAVE_COOKIES |
+ net::LOAD_DISABLE_CACHE);
+ url_fetcher_->SetAutomaticallyRetryOn5xx(false);
+ url_fetcher_->Start();
+}
+
+// Builds a ping message for the specified update item.
+std::string PingSender::BuildPing(const CrxUpdateItem* item) {
+ const std::string prod_id(chrome::OmahaQueryParams::GetProdIdString(
+ chrome::OmahaQueryParams::CHROME));
+
+ const char response_format[] =
+ "<o:gupdate xmlns:o=\"http://www.google.com/update2/request\" "
+ "protocol=\"2.0\" version=\"%s-%s\" requestid=\"{%s}\"> "
+ "<o:os platform=\"%s\" version=\"%s\"/> "
+ "<o:app appid=\"%s\" version=\"%s\">"
+ "%s"
+ "</o:app></o:gupdate>";
+ const std::string response(
+ base::StringPrintf(response_format,
+ prod_id.c_str(),
+ chrome::VersionInfo().Version().c_str(),
+ base::GenerateGUID().c_str(),
+ chrome::VersionInfo().OSType().c_str(),
+ base::SysInfo().OperatingSystemVersion().c_str(),
+ item->id.c_str(),
+ item->component.version.GetString().c_str(),
+ BuildPingEventElement(item).c_str()));
+ return response;
+}
+
+// Returns a string representing one ping event xml element for an update item.
+std::string PingSender::BuildPingEventElement(const CrxUpdateItem* item) {
+ DCHECK(item->status == CrxUpdateItem::kNoUpdate ||
+ item->status == CrxUpdateItem::kUpdated);
+
+ using base::StringAppendF;
+
+ std::string ping_event("<o:event eventtype=\"3\"");
+ const int event_result = item->status == CrxUpdateItem::kUpdated;
+ StringAppendF(&ping_event, " eventresult=\"%d\"", event_result);
+ StringAppendF(&ping_event, " previousversion=\"%s\"",
+ item->previous_version.GetString().c_str());
+ StringAppendF(&ping_event, " nextversion=\"%s\"",
+ item->next_version.GetString().c_str());
+ if (item->error_category)
+ StringAppendF(&ping_event, " errorcat=\"%d\"", item->error_category);
+ if (item->error_code)
+ StringAppendF(&ping_event, " errorcode=\"%d\"", item->error_code);
+ if (item->extra_code1)
+ StringAppendF(&ping_event, " extracode1=\"%d\"", item->extra_code1);
+ if (HasDiffUpdate(item))
+ StringAppendF(&ping_event, " diffresult=\"%d\"", !item->diff_update_failed);
+ if (item->diff_error_category)
+ StringAppendF(&ping_event,
+ " differrorcat=\"%d\"",
+ item->diff_error_category);
+ if (item->diff_error_code)
+ StringAppendF(&ping_event, " differrorcode=\"%d\"", item->diff_error_code);
+ if (item->diff_extra_code1) {
+ StringAppendF(&ping_event,
+ " diffextracode1=\"%d\"",
+ item->diff_extra_code1);
+ }
+ if (!item->previous_fp.empty())
+ StringAppendF(&ping_event, " previousfp=\"%s\"", item->previous_fp.c_str());
+ if (!item->next_fp.empty())
+ StringAppendF(&ping_event, " nextfp=\"%s\"", item->next_fp.c_str());
+ StringAppendF(&ping_event, "/>");
+ return ping_event;
+}
+
+PingManager::PingManager(
+ const GURL& ping_url,
+ net::URLRequestContextGetter* url_request_context_getter)
+ : ping_url_(ping_url),
+ url_request_context_getter_(url_request_context_getter) {
+}
+
+PingManager::~PingManager() {
+}
+
+// Sends a fire and forget ping when the updates are complete. The ping
+// sender object self-deletes after sending the ping.
+void PingManager::OnUpdateComplete(const CrxUpdateItem* item) {
+ component_updater::PingSender* ping_sender(new PingSender);
+ ping_sender->SendPing(ping_url_, url_request_context_getter_, item);
+}
+
+} // namespace component_updater
+
diff --git a/chrome/browser/component_updater/component_updater_ping_manager.h b/chrome/browser/component_updater/component_updater_ping_manager.h
new file mode 100644
index 0000000..1620245
--- /dev/null
+++ b/chrome/browser/component_updater/component_updater_ping_manager.h
@@ -0,0 +1,41 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_COMPONENT_UPDATER_COMPONENT_UPDATER_PING_MANAGER_H_
+#define CHROME_BROWSER_COMPONENT_UPDATER_COMPONENT_UPDATER_PING_MANAGER_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "url/gurl.h"
+
+namespace net {
+class URLRequestContextGetter;
+} // namespace net
+
+struct CrxUpdateItem;
+
+namespace component_updater {
+
+// Provides an event sink for completion events from ComponentUpdateService
+// and sends fire-and-forget pings when handling these events.
+class PingManager {
+ public:
+ PingManager(const GURL& ping_url,
+ net::URLRequestContextGetter* url_request_context_getter);
+ ~PingManager();
+
+ void OnUpdateComplete(const CrxUpdateItem* item);
+ private:
+ const GURL ping_url_;
+
+ // This member is not owned by this class.
+ net::URLRequestContextGetter* url_request_context_getter_;
+
+ DISALLOW_COPY_AND_ASSIGN(PingManager);
+};
+
+} // namespace component_updater
+
+#endif // CHROME_BROWSER_COMPONENT_UPDATER_COMPONENT_UPDATER_PING_MANAGER_H_
+
diff --git a/chrome/browser/component_updater/component_updater_service.cc b/chrome/browser/component_updater/component_updater_service.cc
index 8b4b88b..cd1ee8ef4 100644
--- a/chrome/browser/component_updater/component_updater_service.cc
+++ b/chrome/browser/component_updater/component_updater_service.cc
@@ -25,6 +25,8 @@
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/component_updater/component_patcher.h"
#include "chrome/browser/component_updater/component_unpacker.h"
+#include "chrome/browser/component_updater/component_updater_ping_manager.h"
+#include "chrome/browser/component_updater/crx_update_item.h"
#include "chrome/common/chrome_utility_messages.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/extensions/extension.h"
@@ -107,14 +109,6 @@
return id;
}
-// Returns given a crx id it returns a small number, less than 100, that has a
-// decent chance of being unique among the registered components. It also has
-// the nice property that can be trivially computed by hand.
-static int CrxIdtoUMAId(const std::string& id) {
- CHECK_GT(id.size(), 2U);
- return id[0] + id[1] + id[2] - ('a' * 3);
-}
-
// Helper to do version check for components.
bool IsVersionNewer(const Version& current, const std::string& proposed) {
Version proposed_ver(proposed);
@@ -172,98 +166,29 @@
(fetcher.GetResponseCode() == 200);
}
-// This is the one and only per-item state structure. Designed to be hosted
-// in a std::vector or a std::list. The two main members are |component|
-// which is supplied by the the component updater client and |status| which
-// is modified as the item is processed by the update pipeline. The expected
-// transition graph is:
-//
-// kNew
-// |
-// V
-// +----------------------> kChecking -<---------+-----<-------+
-// | | | |
-// | error V no | |
-// kNoUpdate <---------------- [update?] ->---- kUpToDate kUpdated
-// ^ | ^
-// | yes | |
-// | diff=false V |
-// | +-----------> kCanUpdate |
-// | | | |
-// | | V no |
-// | | [differential update?]->----+ |
-// | | | | |
-// | | yes | | |
-// | | error V | |
-// | +---------<- kDownloadingDiff | |
-// | | | | |
-// | | | | |
-// | | error V | |
-// | +---------<- kUpdatingDiff ->--------|-----------+ success
-// | | |
-// | error V |
-// +----------------------------------------- kDownloading |
-// | | |
-// | error V |
-// +------------------------------------------ kUpdating ->----+ success
-//
-struct CrxUpdateItem {
- enum Status {
- kNew,
- kChecking,
- kCanUpdate,
- kDownloadingDiff,
- kDownloading,
- kUpdatingDiff,
- kUpdating,
- kUpdated,
- kUpToDate,
- kNoUpdate,
- kLastStatus
- };
+// Returns the error code which occured during the fetch.The function returns 0
+// if the fetch was successful. If errors happen, the function could return a
+// network error, an http response code, or the status of the fetch, if the
+// fetch is pending or canceled.
+int GetFetchError(const net::URLFetcher& fetcher) {
+ if (FetchSuccess(fetcher))
+ return 0;
- Status status;
- std::string id;
- CrxComponent component;
+ const net::URLRequestStatus::Status status(fetcher.GetStatus().status());
+ if (status == net::URLRequestStatus::FAILED)
+ return fetcher.GetStatus().error();
- base::Time last_check;
+ if (status == net::URLRequestStatus::IO_PENDING ||
+ status == net::URLRequestStatus::CANCELED)
+ return status;
- // These members are initialized with their corresponding values from the
- // update server response.
- GURL crx_url;
- GURL diff_crx_url;
- int size;
- int diff_size;
+ const int response_code(fetcher.GetResponseCode());
+ if (status == net::URLRequestStatus::SUCCESS && response_code != 200)
+ return response_code;
- // The from/to version and fingerprint values.
- Version previous_version;
- Version next_version;
- std::string previous_fp;
- std::string next_fp;
-
- // True if the differential update failed for any reason.
- bool diff_update_failed;
-
- CrxUpdateItem()
- : status(kNew),
- size(0),
- diff_size(0),
- diff_update_failed(false) {
+ return -1;
}
- // Function object used to find a specific component.
- class FindById {
- public:
- explicit FindById(const std::string& id) : id_(id) {}
-
- bool operator() (CrxUpdateItem* item) const {
- return (item->id == id_);
- }
- private:
- const std::string& id_;
- };
-};
-
// Returns true if a differential update is available for the update item.
bool IsDiffUpdateAvailable(const CrxUpdateItem* update_item) {
return update_item->diff_crx_url.is_valid();
@@ -278,7 +203,21 @@
config.DeltasEnabled();
}
-} // namespace.
+} // namespace
+
+CrxUpdateItem::CrxUpdateItem()
+ : status(kNew),
+ diff_update_failed(false),
+ error_category(0),
+ error_code(0),
+ extra_code1(0),
+ diff_error_category(0),
+ diff_error_code(0),
+ diff_extra_code1(0) {
+}
+
+CrxUpdateItem::~CrxUpdateItem() {
+}
CrxComponent::CrxComponent()
: installer(NULL) {
@@ -370,9 +309,15 @@
CRXContext* context);
private:
+ enum ErrorCategory {
+ kErrorNone = 0,
+ kNetworkError,
+ kUnpackError,
+ kInstallError,
+ };
+
// See ManifestParserBridge.
- void OnParseUpdateManifestSucceeded(
- const UpdateManifest::Results& results);
+ void OnParseUpdateManifestSucceeded(const UpdateManifest::Results& results);
// See ManifestParserBridge.
void OnParseUpdateManifestFailed(const std::string& error_message);
@@ -402,6 +347,8 @@
scoped_ptr<net::URLFetcher> url_fetcher_;
+ scoped_ptr<component_updater::PingManager> ping_manager_;
+
// A collection of every work item.
typedef std::vector<CrxUpdateItem*> UpdateItems;
UpdateItems work_items_;
@@ -424,11 +371,14 @@
CrxUpdateService::CrxUpdateService(ComponentUpdateService::Configurator* config)
: config_(config),
component_patcher_(config->CreateComponentPatcher()),
+ ping_manager_(new component_updater::PingManager(
+ config->PingUrl(),
+ config->RequestContext())),
chrome_version_(chrome::VersionInfo().Version()),
prod_id_(chrome::OmahaQueryParams::GetProdIdString(
chrome::OmahaQueryParams::CHROME)),
running_(false) {
-}
+ }
CrxUpdateService::~CrxUpdateService() {
// Because we are a singleton, at this point only the UI thread should be
@@ -436,7 +386,7 @@
// flight in other threads.
Stop();
STLDeleteElements(&work_items_);
-}
+ }
ComponentUpdateService::Status CrxUpdateService::Start() {
// Note that RegisterComponent will call Start() when the first
@@ -586,6 +536,12 @@
item->previous_fp = item->component.fingerprint;
item->next_fp.clear();
item->diff_update_failed = false;
+ item->error_category = 0;
+ item->error_code = 0;
+ item->extra_code1 = 0;
+ item->diff_error_category = 0;
+ item->diff_error_code = 0;
+ item->diff_extra_code1 = 0;
return true;
}
@@ -801,8 +757,6 @@
if (crx->status != CrxUpdateItem::kChecking)
continue; // Not updating this component now.
- config_->OnEvent(Configurator::kManifestCheck, CrxIdtoUMAId(crx->id));
-
if (it->version.empty()) {
// No version means no update available.
crx->status = CrxUpdateItem::kNoUpdate;
@@ -823,9 +777,7 @@
// All test passed. Queue an upgrade for this component and fire the
// notifications.
crx->crx_url = it->crx_url;
- crx->size = it->size;
crx->diff_crx_url = it->diff_crx_url;
- crx->diff_size = it->diff_size;
crx->status = CrxUpdateItem::kCanUpdate;
crx->next_version = Version(it->version);
crx->next_fp = it->package_fingerprint;
@@ -850,7 +802,6 @@
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
size_t count = ChangeItemStatus(CrxUpdateItem::kChecking,
CrxUpdateItem::kNoUpdate);
- config_->OnEvent(Configurator::kManifestError, static_cast<int>(count));
DCHECK_GT(count, 0ul);
ScheduleNextRun(false);
}
@@ -869,19 +820,28 @@
if (source->FileErrorOccurred(&error_code) || !FetchSuccess(*source)) {
if (crx->status == CrxUpdateItem::kDownloadingDiff) {
+ crx->diff_error_category = kNetworkError;
+ crx->diff_error_code = GetFetchError(*source);
crx->diff_update_failed = true;
size_t count = ChangeItemStatus(CrxUpdateItem::kDownloadingDiff,
CrxUpdateItem::kCanUpdate);
DCHECK_EQ(count, 1ul);
+ url_fetcher_.reset();
+
ScheduleNextRun(true);
return;
}
+ crx->error_category = kNetworkError;
+ crx->error_code = GetFetchError(*source);
size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading,
CrxUpdateItem::kNoUpdate);
DCHECK_EQ(count, 1ul);
- config_->OnEvent(Configurator::kNetworkError, CrxIdtoUMAId(context->id));
url_fetcher_.reset();
+ // At this point, since both the differential and the full downloads failed,
+ // the update for this component has finished with an error.
+ ping_manager_->OnUpdateComplete(crx);
+
ScheduleNextRun(false);
} else {
base::FilePath temp_crx_path;
@@ -942,15 +902,32 @@
}
// Installation has been completed. Adjust the component status and
-// schedule the next check.
+// schedule the next check. Schedule a short delay before trying the full
+// update when the differential update failed.
void CrxUpdateService::DoneInstalling(const std::string& component_id,
ComponentUnpacker::Error error,
int extra_code) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ ErrorCategory error_category = kErrorNone;
+ switch (error) {
+ case ComponentUnpacker::kNone:
+ break;
+ case ComponentUnpacker::kInstallerError:
+ error_category = kInstallError;
+ break;
+ default:
+ error_category = kUnpackError;
+ break;
+ }
+
+ const bool is_success = error == ComponentUnpacker::kNone;
+
CrxUpdateItem* item = FindUpdateItemById(component_id);
- if (item->status == CrxUpdateItem::kUpdatingDiff) {
- if (error != ComponentUnpacker::kNone) {
+ if (item->status == CrxUpdateItem::kUpdatingDiff && !is_success) {
+ item->diff_error_category = error_category;
+ item->diff_error_code = error;
+ item->diff_extra_code1 = extra_code;
item->diff_update_failed = true;
size_t count = ChangeItemStatus(CrxUpdateItem::kUpdatingDiff,
CrxUpdateItem::kCanUpdate);
@@ -958,29 +935,20 @@
ScheduleNextRun(true);
return;
}
- }
- item->status = (error == ComponentUnpacker::kNone) ? CrxUpdateItem::kUpdated :
- CrxUpdateItem::kNoUpdate;
- if (item->status == CrxUpdateItem::kUpdated) {
+ if (is_success) {
+ item->status = CrxUpdateItem::kUpdated;
item->component.version = item->next_version;
item->component.fingerprint = item->next_fp;
+ } else {
+ item->status = CrxUpdateItem::kNoUpdate;
+ item->error_category = error_category;
+ item->error_code = error;
+ item->extra_code1 = extra_code;
}
- Configurator::Events event;
- switch (error) {
- case ComponentUnpacker::kNone:
- event = Configurator::kComponentUpdated;
- break;
- case ComponentUnpacker::kInstallerError:
- event = Configurator::kInstallerError;
- break;
- default:
- event = Configurator::kUnpackError;
- break;
- }
+ ping_manager_->OnUpdateComplete(item);
- config_->OnEvent(event, CrxIdtoUMAId(component_id));
ScheduleNextRun(false);
}
diff --git a/chrome/browser/component_updater/component_updater_service.h b/chrome/browser/component_updater/component_updater_service.h
index de1748b..7125ff4 100644
--- a/chrome/browser/component_updater/component_updater_service.h
+++ b/chrome/browser/component_updater/component_updater_service.h
@@ -11,15 +11,15 @@
#include "base/version.h"
#include "url/gurl.h"
-namespace net {
-class URLRequestContextGetter;
-}
-
namespace base {
class DictionaryValue;
class FilePath;
}
+namespace net {
+class URLRequestContextGetter;
+}
+
class ComponentPatcher;
// Component specific installers must derive from this class and implement
@@ -91,15 +91,6 @@
// Controls the component updater behavior.
class Configurator {
public:
- enum Events {
- kManifestCheck,
- kComponentUpdated,
- kManifestError,
- kNetworkError,
- kUnpackError,
- kInstallerError
- };
-
virtual ~Configurator() {}
// Delay in seconds from calling Start() to the first update check.
virtual int InitialDelay() = 0;
@@ -114,6 +105,9 @@
virtual int OnDemandDelay() = 0;
// The url that is going to be used update checks over Omaha protocol.
virtual GURL UpdateUrl() = 0;
+ // The url where the completion pings are sent. Invalid if and only if
+ // pings are disabled.
+ virtual GURL PingUrl() = 0;
// Parameters added to each url request. It can be null if none are needed.
virtual const char* ExtraRequestParams() = 0;
// How big each update request can be. Don't go above 2000.
@@ -122,10 +116,6 @@
virtual net::URLRequestContextGetter* RequestContext() = 0;
// True means that all ops are performed in this process.
virtual bool InProcess() = 0;
- // The component updater will call this function when an interesting event
- // happens. It should be used mostly as a place to add application specific
- // logging or telemetry. |extra| is |event| dependent.
- virtual void OnEvent(Events event, int extra) = 0;
// Creates a new ComponentPatcher in a platform-specific way. This is useful
// for dependency injection.
virtual ComponentPatcher* CreateComponentPatcher() = 0;
diff --git a/chrome/browser/component_updater/crx_update_item.h b/chrome/browser/component_updater/crx_update_item.h
new file mode 100644
index 0000000..9378401
--- /dev/null
+++ b/chrome/browser/component_updater/crx_update_item.h
@@ -0,0 +1,114 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_COMPONENT_UPDATER_CRX_UPDATE_ITEM_H_
+#define CHROME_BROWSER_COMPONENT_UPDATER_CRX_UPDATE_ITEM_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/time/time.h"
+#include "base/version.h"
+#include "chrome/browser/component_updater/component_updater_service.h"
+
+// This is the one and only per-item state structure. Designed to be hosted
+// in a std::vector or a std::list. The two main members are |component|
+// which is supplied by the the component updater client and |status| which
+// is modified as the item is processed by the update pipeline. The expected
+// transition graph is:
+//
+// kNew
+// |
+// V
+// +----------------------> kChecking -<---------+-----<-------+
+// | | | |
+// | error V no | |
+// kNoUpdate <---------------- [update?] ->---- kUpToDate kUpdated
+// ^ | ^
+// | yes | |
+// | diff=false V |
+// | +-----------> kCanUpdate |
+// | | | |
+// | | V no |
+// | | [differential update?]->----+ |
+// | | | | |
+// | | yes | | |
+// | | error V | |
+// | +---------<- kDownloadingDiff | |
+// | | | | |
+// | | | | |
+// | | error V | |
+// | +---------<- kUpdatingDiff ->--------|-----------+ success
+// | | |
+// | error V |
+// +----------------------------------------- kDownloading |
+// | | |
+// | error V |
+// +------------------------------------------ kUpdating ->----+ success
+//
+struct CrxUpdateItem {
+ enum Status {
+ kNew,
+ kChecking,
+ kCanUpdate,
+ kDownloadingDiff,
+ kDownloading,
+ kUpdatingDiff,
+ kUpdating,
+ kUpdated,
+ kUpToDate,
+ kNoUpdate,
+ kLastStatus
+ };
+
+ Status status;
+ std::string id;
+ CrxComponent component;
+
+ base::Time last_check;
+
+ // The url the full and differential update CRXs are downloaded from.
+ GURL crx_url;
+ GURL diff_crx_url;
+
+ // The from/to version and fingerprint values.
+ Version previous_version;
+ Version next_version;
+ std::string previous_fp;
+ std::string next_fp;
+
+ // True if the differential update failed for any reason.
+ bool diff_update_failed;
+
+ // The error information for full and differential updates.
+ // The |error_category| contains a hint about which module in the component
+ // updater generated the error. The |error_code| constains the error and
+ // the |extra_code1| usually contains a system error, but it can contain
+ // any extended information that is relevant to either the category or the
+ // error itself.
+ int error_category;
+ int error_code;
+ int extra_code1;
+ int diff_error_category;
+ int diff_error_code;
+ int diff_extra_code1;
+
+ CrxUpdateItem();
+ ~CrxUpdateItem();
+
+ // Function object used to find a specific component.
+ class FindById {
+ public:
+ explicit FindById(const std::string& id) : id_(id) {}
+
+ bool operator() (CrxUpdateItem* item) const {
+ return (item->id == id_);
+ }
+ private:
+ const std::string& id_;
+ };
+};
+
+#endif // CHROME_BROWSER_COMPONENT_UPDATER_CRX_UPDATE_ITEM_H_
diff --git a/chrome/browser/component_updater/pepper_flash_component_installer.cc b/chrome/browser/component_updater/pepper_flash_component_installer.cc
index 0b1e359..0897fe6 100644
--- a/chrome/browser/component_updater/pepper_flash_component_installer.cc
+++ b/chrome/browser/component_updater/pepper_flash_component_installer.cc
@@ -155,22 +155,22 @@
plugin_info->version = flash_version.GetString();
- webkit::WebPluginMimeType swf_mime_type(kFlashPluginSwfMimeType,
- kFlashPluginSwfExtension,
- kFlashPluginName);
+ content::WebPluginMimeType swf_mime_type(kFlashPluginSwfMimeType,
+ kFlashPluginSwfExtension,
+ kFlashPluginName);
plugin_info->mime_types.push_back(swf_mime_type);
- webkit::WebPluginMimeType spl_mime_type(kFlashPluginSplMimeType,
- kFlashPluginSplExtension,
- kFlashPluginName);
+ content::WebPluginMimeType spl_mime_type(kFlashPluginSplMimeType,
+ kFlashPluginSplExtension,
+ kFlashPluginName);
plugin_info->mime_types.push_back(spl_mime_type);
return true;
}
-bool IsPepperFlash(const webkit::WebPluginInfo& plugin) {
+bool IsPepperFlash(const content::WebPluginInfo& plugin) {
// We try to recognize Pepper Flash by the following criteria:
// * It is a Pepper plug-in.
// * It has the special Flash permissions.
- return webkit::IsPepperPlugin(plugin) &&
+ return plugin.is_pepper_plugin() &&
(plugin.pepper_permissions & ppapi::PERMISSION_FLASH);
}
@@ -181,9 +181,9 @@
if (!MakePepperFlashPluginInfo(path, version, true, &plugin_info))
return;
- std::vector<webkit::WebPluginInfo> plugins;
+ std::vector<content::WebPluginInfo> plugins;
PluginService::GetInstance()->GetInternalPlugins(&plugins);
- for (std::vector<webkit::WebPluginInfo>::const_iterator it = plugins.begin();
+ for (std::vector<content::WebPluginInfo>::const_iterator it = plugins.begin();
it != plugins.end(); ++it) {
if (!IsPepperFlash(*it))
continue;
diff --git a/chrome/browser/component_updater/test/component_patcher_unittest.cc b/chrome/browser/component_updater/test/component_patcher_unittest.cc
index f121fc0..67256f9 100644
--- a/chrome/browser/component_updater/test/component_patcher_unittest.cc
+++ b/chrome/browser/component_updater/test/component_patcher_unittest.cc
@@ -77,11 +77,11 @@
int error = 0;
scoped_ptr<DeltaUpdateOp> op(new DeltaUpdateOpCreate());
ComponentUnpacker::Error result = op->Run(command_args.get(),
- input_dir_.path(),
- unpack_dir_.path(),
- patcher_.get(),
- NULL,
- &error);
+ input_dir_.path(),
+ unpack_dir_.path(),
+ patcher_.get(),
+ NULL,
+ &error);
EXPECT_EQ(ComponentUnpacker::kNone, result);
EXPECT_EQ(0, error);
@@ -105,11 +105,74 @@
int error = 0;
scoped_ptr<DeltaUpdateOp> op(new DeltaUpdateOpCopy());
ComponentUnpacker::Error result = op->Run(command_args.get(),
- input_dir_.path(),
- unpack_dir_.path(),
- patcher_.get(),
- installer_.get(),
- &error);
+ input_dir_.path(),
+ unpack_dir_.path(),
+ patcher_.get(),
+ installer_.get(),
+ &error);
+ EXPECT_EQ(ComponentUnpacker::kNone, result);
+ EXPECT_EQ(0, error);
+ EXPECT_TRUE(base::ContentsEqual(
+ unpack_dir_.path().Append(FILE_PATH_LITERAL("output.bin")),
+ test_file("binary_output.bin")));
+}
+
+// Verify that a 'courgette' delta update operation works correctly.
+TEST_F(ComponentPatcherOperationTest, CheckCourgetteOperation) {
+ EXPECT_TRUE(base::CopyFile(
+ test_file("binary_input.bin"),
+ installed_dir_.path().Append(FILE_PATH_LITERAL("binary_input.bin"))));
+ EXPECT_TRUE(base::CopyFile(
+ test_file("binary_courgette_patch.bin"),
+ input_dir_.path().Append(
+ FILE_PATH_LITERAL("binary_courgette_patch.bin"))));
+
+ scoped_ptr<base::DictionaryValue> command_args(new base::DictionaryValue());
+ command_args->SetString("output", "output.bin");
+ command_args->SetString("sha256", binary_output_hash);
+ command_args->SetString("op", "courgette");
+ command_args->SetString("input", "binary_input.bin");
+ command_args->SetString("patch", "binary_courgette_patch.bin");
+
+ int error = 0;
+ scoped_ptr<DeltaUpdateOp> op(new DeltaUpdateOpPatchCourgette());
+ ComponentUnpacker::Error result = op->Run(command_args.get(),
+ input_dir_.path(),
+ unpack_dir_.path(),
+ patcher_.get(),
+ installer_.get(),
+ &error);
+ EXPECT_EQ(ComponentUnpacker::kNone, result);
+ EXPECT_EQ(0, error);
+ EXPECT_TRUE(base::ContentsEqual(
+ unpack_dir_.path().Append(FILE_PATH_LITERAL("output.bin")),
+ test_file("binary_output.bin")));
+}
+
+// Verify that a 'bsdiff' delta update operation works correctly.
+TEST_F(ComponentPatcherOperationTest, CheckBsdiffOperation) {
+ EXPECT_TRUE(base::CopyFile(
+ test_file("binary_input.bin"),
+ installed_dir_.path().Append(FILE_PATH_LITERAL("binary_input.bin"))));
+ EXPECT_TRUE(base::CopyFile(
+ test_file("binary_bsdiff_patch.bin"),
+ input_dir_.path().Append(FILE_PATH_LITERAL("binary_bsdiff_patch.bin"))));
+
+ scoped_ptr<base::DictionaryValue> command_args(new base::DictionaryValue());
+ command_args->SetString("output", "output.bin");
+ command_args->SetString("sha256", binary_output_hash);
+ command_args->SetString("op", "courgette");
+ command_args->SetString("input", "binary_input.bin");
+ command_args->SetString("patch", "binary_bsdiff_patch.bin");
+
+ int error = 0;
+ scoped_ptr<DeltaUpdateOp> op(new DeltaUpdateOpPatchBsdiff());
+ ComponentUnpacker::Error result = op->Run(command_args.get(),
+ input_dir_.path(),
+ unpack_dir_.path(),
+ patcher_.get(),
+ installer_.get(),
+ &error);
EXPECT_EQ(ComponentUnpacker::kNone, result);
EXPECT_EQ(0, error);
EXPECT_TRUE(base::ContentsEqual(
diff --git a/chrome/browser/component_updater/test/component_patcher_unittest_win.cc b/chrome/browser/component_updater/test/component_patcher_unittest_win.cc
deleted file mode 100644
index afec59d..0000000
--- a/chrome/browser/component_updater/test/component_patcher_unittest_win.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2013 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 "base/compiler_specific.h"
-#include "base/file_util.h"
-#include "base/files/file_path.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/path_service.h"
-#include "base/values.h"
-#include "chrome/browser/component_updater/component_patcher.h"
-#include "chrome/browser/component_updater/component_patcher_operation.h"
-#include "chrome/browser/component_updater/component_updater_service.h"
-#include "chrome/browser/component_updater/test/component_patcher_mock.h"
-#include "chrome/browser/component_updater/test/component_patcher_unittest.h"
-#include "chrome/browser/component_updater/test/test_installer.h"
-#include "chrome/common/chrome_paths.h"
-#include "courgette/courgette.h"
-#include "courgette/third_party/bsdiff.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-// Verify that a 'courgette' delta update operation works correctly.
-TEST_F(ComponentPatcherOperationTest, CheckCourgetteOperation) {
- EXPECT_TRUE(base::CopyFile(
- test_file("binary_input.bin"),
- installed_dir_.path().Append(FILE_PATH_LITERAL("binary_input.bin"))));
- EXPECT_TRUE(base::CopyFile(
- test_file("binary_courgette_patch.bin"),
- input_dir_.path().Append(
- FILE_PATH_LITERAL("binary_courgette_patch.bin"))));
-
- scoped_ptr<base::DictionaryValue> command_args(new base::DictionaryValue());
- command_args->SetString("output", "output.bin");
- command_args->SetString("sha256", binary_output_hash);
- command_args->SetString("op", "courgette");
- command_args->SetString("input", "binary_input.bin");
- command_args->SetString("patch", "binary_courgette_patch.bin");
-
- int error = 0;
- scoped_ptr<DeltaUpdateOp> op(new DeltaUpdateOpPatchCourgette());
- ComponentUnpacker::Error result = op->Run(command_args.get(),
- input_dir_.path(),
- unpack_dir_.path(),
- patcher_.get(),
- installer_.get(),
- &error);
- EXPECT_EQ(ComponentUnpacker::kNone, result);
- EXPECT_EQ(0, error);
- EXPECT_TRUE(base::ContentsEqual(
- unpack_dir_.path().Append(FILE_PATH_LITERAL("output.bin")),
- test_file("binary_output.bin")));
-}
-
-// Verify that a 'bsdiff' delta update operation works correctly.
-TEST_F(ComponentPatcherOperationTest, CheckBsdiffOperation) {
- EXPECT_TRUE(base::CopyFile(
- test_file("binary_input.bin"),
- installed_dir_.path().Append(FILE_PATH_LITERAL("binary_input.bin"))));
- EXPECT_TRUE(base::CopyFile(
- test_file("binary_bsdiff_patch.bin"),
- input_dir_.path().Append(FILE_PATH_LITERAL("binary_bsdiff_patch.bin"))));
-
- scoped_ptr<base::DictionaryValue> command_args(new base::DictionaryValue());
- command_args->SetString("output", "output.bin");
- command_args->SetString("sha256", binary_output_hash);
- command_args->SetString("op", "courgette");
- command_args->SetString("input", "binary_input.bin");
- command_args->SetString("patch", "binary_bsdiff_patch.bin");
-
- int error = 0;
- scoped_ptr<DeltaUpdateOp> op(new DeltaUpdateOpPatchBsdiff());
- ComponentUnpacker::Error result = op->Run(command_args.get(),
- input_dir_.path(),
- unpack_dir_.path(),
- patcher_.get(),
- installer_.get(),
- &error);
- EXPECT_EQ(ComponentUnpacker::kNone, result);
- EXPECT_EQ(0, error);
- EXPECT_TRUE(base::ContentsEqual(
- unpack_dir_.path().Append(FILE_PATH_LITERAL("output.bin")),
- test_file("binary_output.bin")));
-}
diff --git a/chrome/browser/component_updater/test/component_updater_service_unittest.cc b/chrome/browser/component_updater/test/component_updater_service_unittest.cc
index edc1512..7a66d55 100644
--- a/chrome/browser/component_updater/test/component_updater_service_unittest.cc
+++ b/chrome/browser/component_updater/test/component_updater_service_unittest.cc
@@ -2,43 +2,35 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <list>
-#include <utility>
-#include "base/compiler_specific.h"
+#include "chrome/browser/component_updater/test/component_updater_service_unittest.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/memory/scoped_vector.h"
-#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/component_updater/component_updater_service.h"
-#include "chrome/browser/component_updater/test/component_patcher_mock.h"
-#include "chrome/browser/component_updater/test/component_updater_service_unittest.h"
#include "chrome/browser/component_updater/test/test_installer.h"
#include "chrome/common/chrome_paths.h"
-#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_service.h"
-#include "content/public/test/test_browser_thread.h"
-#include "content/public/test/test_notification_tracker.h"
#include "content/test/net/url_request_prepackaged_interceptor.h"
#include "libxml/globals.h"
#include "net/base/upload_bytes_element_reader.h"
#include "net/url_request/url_fetcher.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_filter.h"
-#include "net/url_request/url_request_simple_job.h"
-#include "net/url_request/url_request_test_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
using content::BrowserThread;
using content::TestNotificationTracker;
TestConfigurator::TestConfigurator()
- : times_(1), recheck_time_(0), ondemand_time_(0), cus_(NULL) {
+ : times_(1),
+ recheck_time_(0),
+ ondemand_time_(0),
+ cus_(NULL),
+ context_(new net::TestURLRequestContextGetter(
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO))) {
}
TestConfigurator::~TestConfigurator() {
@@ -86,20 +78,21 @@
return GURL("http://localhost/upd");
}
+GURL TestConfigurator::PingUrl() {
+ return GURL("http://localhost2/ping");
+}
+
const char* TestConfigurator::ExtraRequestParams() { return "extra=foo"; }
size_t TestConfigurator::UrlSizeLimit() { return 256; }
net::URLRequestContextGetter* TestConfigurator::RequestContext() {
- return new net::TestURLRequestContextGetter(
- BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
+ return context_.get();
}
// Don't use the utility process to decode files.
bool TestConfigurator::InProcess() { return true; }
-void TestConfigurator::OnEvent(Events event, int extra) { }
-
ComponentPatcher* TestConfigurator::CreateComponentPatcher() {
return new MockComponentPatcher();
}
@@ -128,11 +121,16 @@
cus_ = cus;
}
-ComponentUpdaterTest::ComponentUpdaterTest() : test_config_(NULL) {
+ComponentUpdaterTest::ComponentUpdaterTest()
+ : test_config_(NULL),
+ ui_thread_(BrowserThread::UI, &message_loop_),
+ file_thread_(BrowserThread::FILE),
+ io_thread_(BrowserThread::IO) {
// The component updater instance under test.
test_config_ = new TestConfigurator;
component_updater_.reset(ComponentUpdateServiceFactory(test_config_));
test_config_->SetComponentUpdateService(component_updater_.get());
+
// The test directory is chrome/test/data/components.
PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_);
test_data_dir_ = test_data_dir_.AppendASCII("components");
@@ -150,6 +148,9 @@
notifications[ix], content::NotificationService::AllSources());
}
net::URLFetcher::SetEnableInterceptionForTests(true);
+
+ io_thread_.StartIOThread();
+ file_thread_.Start();
}
ComponentUpdaterTest::~ComponentUpdaterTest() {
@@ -197,6 +198,48 @@
return component_updater_->RegisterComponent(*com);
}
+PingChecker::PingChecker(const std::map<std::string, std::string>& attributes)
+ : num_hits_(0), num_misses_(0), attributes_(attributes) {
+}
+
+PingChecker::~PingChecker() {}
+
+void PingChecker::Trial(net::URLRequest* request) {
+ if (Test(request))
+ ++num_hits_;
+ else
+ ++num_misses_;
+}
+
+bool PingChecker::Test(net::URLRequest* request) {
+ if (request->has_upload()) {
+ const net::UploadDataStream* stream = request->get_upload();
+ const net::UploadBytesElementReader* reader =
+ stream->element_readers()[0]->AsBytesReader();
+ int size = reader->length();
+ scoped_refptr <net::IOBuffer> buffer = new net::IOBuffer(size);
+ std::string data(reader->bytes());
+ // For now, we assume that there is only one ping per POST.
+ std::string::size_type start = data.find("<o:event");
+ if (start != std::string::npos) {
+ std::string::size_type end = data.find(">", start);
+ if (end != std::string::npos) {
+ std::string ping = data.substr(start, end - start);
+ std::map<std::string, std::string>::const_iterator iter;
+ for (iter = attributes_.begin(); iter != attributes_.end(); ++iter) {
+ // does the ping contain the specified attribute/value?
+ if (ping.find(std::string(" ") + (iter->first) +
+ std::string("=") + (iter->second)) == string::npos) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
// Verify that our test fixture work and the component updater can
// be created and destroyed with no side effects.
TEST_F(ComponentUpdaterTest, VerifyFixture) {
@@ -208,11 +251,8 @@
// start-shutdown situation. Failure of this test will be a crash. Also
// if there is no work to do, there are no notifications generated.
TEST_F(ComponentUpdaterTest, StartStop) {
- base::MessageLoop message_loop;
- content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
-
component_updater()->Start();
- message_loop.RunUntilIdle();
+ message_loop_.RunUntilIdle();
component_updater()->Stop();
EXPECT_EQ(0ul, notification_tracker().size());
@@ -222,14 +262,6 @@
// the COMPONENT_UPDATER_STARTED and COMPONENT_UPDATER_SLEEPING notifications
// are generated.
TEST_F(ComponentUpdaterTest, CheckCrxSleep) {
- base::MessageLoop message_loop;
- content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
- content::TestBrowserThread file_thread(BrowserThread::FILE);
- content::TestBrowserThread io_thread(BrowserThread::IO);
-
- io_thread.StartIOThread();
- file_thread.Start();
-
content::URLLocalHostRequestPrepackagedInterceptor interceptor;
TestInstaller installer;
@@ -255,7 +287,7 @@
TestNotificationTracker::Event ev1 = notification_tracker().at(0);
EXPECT_EQ(chrome::NOTIFICATION_COMPONENT_UPDATER_STARTED, ev1.type);
- message_loop.Run();
+ message_loop_.Run();
ASSERT_EQ(3ul, notification_tracker().size());
TestNotificationTracker::Event ev2 = notification_tracker().at(1);
@@ -279,7 +311,7 @@
test_configurator()->SetLoopCount(2);
component_updater()->Start();
- message_loop.Run();
+ message_loop_.Run();
ASSERT_EQ(3ul, notification_tracker().size());
ev1 = notification_tracker().at(0);
@@ -300,19 +332,19 @@
// the notifications above NOTIFICATION_COMPONENT_UPDATE_FOUND and
// NOTIFICATION_COMPONENT_UPDATE_READY should have been fired. We do two loops
// so the second time around there should be nothing left to do.
-// We also check that only 3 network requests are issued:
+// We also check that only 3 non-ping network requests are issued:
// 1- manifest check
// 2- download crx
// 3- second manifest check.
TEST_F(ComponentUpdaterTest, InstallCrx) {
- base::MessageLoop message_loop;
- content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
- content::TestBrowserThread file_thread(BrowserThread::FILE);
- content::TestBrowserThread io_thread(BrowserThread::IO);
-
- io_thread.StartIOThread();
- file_thread.Start();
-
+ std::map<std::string, std::string> map;
+ map.insert(std::pair<std::string, std::string>("eventtype", "\"3\""));
+ map.insert(std::pair<std::string, std::string>("eventresult", "\"1\""));
+ map.insert(std::pair<std::string, std::string>("previousversion",
+ "\"0.9\""));
+ map.insert(std::pair<std::string, std::string>("nextversion", "\"1.0\""));
+ PingChecker ping_checker(map);
+ URLRequestPostInterceptor post_interceptor(&ping_checker);
content::URLLocalHostRequestPrepackagedInterceptor interceptor;
TestInstaller installer1;
@@ -342,7 +374,7 @@
test_configurator()->SetLoopCount(2);
component_updater()->Start();
- message_loop.Run();
+ message_loop_.Run();
EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error());
EXPECT_EQ(1, static_cast<TestInstaller*>(com1.installer)->install_count());
@@ -350,6 +382,8 @@
EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count());
EXPECT_EQ(3, interceptor.GetHitCount());
+ EXPECT_EQ(1, ping_checker.NumHits());
+ EXPECT_EQ(0, ping_checker.NumMisses());
ASSERT_EQ(5ul, notification_tracker().size());
@@ -372,14 +406,9 @@
// particular there should not be an install because the minimum product
// version is much higher than of chrome.
TEST_F(ComponentUpdaterTest, ProdVersionCheck) {
- base::MessageLoop message_loop;
- content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
- content::TestBrowserThread file_thread(BrowserThread::FILE);
- content::TestBrowserThread io_thread(BrowserThread::IO);
-
- io_thread.StartIOThread();
- file_thread.Start();
-
+ std::map<std::string, std::string> map;
+ PingChecker ping_checker(map);
+ URLRequestPostInterceptor post_interceptor(&ping_checker);
content::URLLocalHostRequestPrepackagedInterceptor interceptor;
TestInstaller installer;
@@ -397,8 +426,10 @@
test_configurator()->SetLoopCount(1);
component_updater()->Start();
- message_loop.Run();
+ message_loop_.Run();
+ EXPECT_EQ(0, ping_checker.NumHits());
+ EXPECT_EQ(0, ping_checker.NumMisses());
EXPECT_EQ(1, interceptor.GetHitCount());
EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->install_count());
@@ -413,14 +444,14 @@
// - We ping.
// - This triggers a second loop, which has a reply that triggers an install.
TEST_F(ComponentUpdaterTest, CheckForUpdateSoon) {
- base::MessageLoop message_loop;
- content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
- content::TestBrowserThread file_thread(BrowserThread::FILE);
- content::TestBrowserThread io_thread(BrowserThread::IO);
-
- io_thread.StartIOThread();
- file_thread.Start();
-
+ std::map<std::string, std::string> map;
+ map.insert(std::pair<std::string, std::string>("eventtype", "\"3\""));
+ map.insert(std::pair<std::string, std::string>("eventresult", "\"1\""));
+ map.insert(std::pair<std::string, std::string>("previousversion",
+ "\"0.9\""));
+ map.insert(std::pair<std::string, std::string>("nextversion", "\"1.0\""));
+ PingChecker ping_checker(map);
+ URLRequestPostInterceptor post_interceptor(&ping_checker);
content::URLLocalHostRequestPrepackagedInterceptor interceptor;
TestInstaller installer1;
@@ -451,7 +482,7 @@
test_configurator()->SetLoopCount(2);
test_configurator()->AddComponentToCheck(&com2, 1);
component_updater()->Start();
- message_loop.Run();
+ message_loop_.Run();
EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error());
EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->install_count());
@@ -501,7 +532,7 @@
EXPECT_EQ(ComponentUpdateService::kOk,
component_updater()->CheckForUpdateSoon(com2));
- message_loop.Run();
+ message_loop_.Run();
ASSERT_EQ(2ul, notification_tracker().size());
ev0 = notification_tracker().at(0);
@@ -519,8 +550,10 @@
EXPECT_EQ(ComponentUpdateService::kOk,
component_updater()->CheckForUpdateSoon(com2));
- message_loop.Run();
+ message_loop_.Run();
+ EXPECT_EQ(1, ping_checker.NumHits());
+ EXPECT_EQ(0, ping_checker.NumMisses());
ASSERT_EQ(2ul, notification_tracker().size());
ev0 = notification_tracker().at(0);
EXPECT_EQ(chrome::NOTIFICATION_COMPONENT_UPDATER_STARTED, ev0.type);
@@ -532,14 +565,14 @@
// Verify that a previously registered component can get re-registered
// with a different version.
TEST_F(ComponentUpdaterTest, CheckReRegistration) {
- base::MessageLoop message_loop;
- content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
- content::TestBrowserThread file_thread(BrowserThread::FILE);
- content::TestBrowserThread io_thread(BrowserThread::IO);
-
- io_thread.StartIOThread();
- file_thread.Start();
-
+ std::map<std::string, std::string> map;
+ map.insert(std::pair<std::string, std::string>("eventtype", "\"3\""));
+ map.insert(std::pair<std::string, std::string>("eventresult", "\"1\""));
+ map.insert(std::pair<std::string, std::string>("previousversion",
+ "\"0.9\""));
+ map.insert(std::pair<std::string, std::string>("nextversion", "\"1.0\""));
+ PingChecker ping_checker(map);
+ URLRequestPostInterceptor post_interceptor(&ping_checker);
content::URLLocalHostRequestPrepackagedInterceptor interceptor;
TestInstaller installer1;
@@ -572,13 +605,15 @@
test_configurator()->SetLoopCount(2);
component_updater()->Start();
- message_loop.Run();
+ message_loop_.Run();
EXPECT_EQ(0, static_cast<TestInstaller*>(com1.installer)->error());
EXPECT_EQ(1, static_cast<TestInstaller*>(com1.installer)->install_count());
EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->error());
EXPECT_EQ(0, static_cast<TestInstaller*>(com2.installer)->install_count());
+ EXPECT_EQ(1, ping_checker.NumHits());
+ EXPECT_EQ(0, ping_checker.NumMisses());
EXPECT_EQ(3, interceptor.GetHitCount());
ASSERT_EQ(5ul, notification_tracker().size());
@@ -622,7 +657,7 @@
// Loop once just to notice the check happening with the re-register version.
test_configurator()->SetLoopCount(1);
component_updater()->Start();
- message_loop.Run();
+ message_loop_.Run();
ASSERT_EQ(2ul, notification_tracker().size());
@@ -643,24 +678,91 @@
component_updater()->Stop();
}
+// Verify that we can download and install a component and a differential
+// update to that component. We do three loops; the final loop should do
+// nothing.
+// We also check that exactly 5 non-ping network requests are issued:
+// 1- update check (response: v1 available)
+// 2- download crx (v1)
+// 3- update check (response: v2 available)
+// 4- download differential crx (v1 to v2)
+// 5- update check (response: no further update available)
+// There should be two pings, one for each update. The second will bear a
+// diffresult=1, while the first will not.
+TEST_F(ComponentUpdaterTest, DifferentialUpdate) {
+ std::map<std::string, std::string> map;
+ map.insert(std::pair<std::string, std::string>("eventtype", "\"3\""));
+ map.insert(std::pair<std::string, std::string>("eventresult", "\"1\""));
+ map.insert(std::pair<std::string, std::string>("diffresult", "\"1\""));
+ PingChecker ping_checker(map);
+ URLRequestPostInterceptor post_interceptor(&ping_checker);
+ content::URLLocalHostRequestPrepackagedInterceptor interceptor;
+
+ VersionedTestInstaller installer;
+ CrxComponent com;
+ RegisterComponent(&com, kTestComponent_ihfo, Version("0.0"), &installer);
+
+ const GURL expected_update_url_0(
+ "http://localhost/upd?extra=foo"
+ "&x=id%3Dihfokbkgjpifnbbojhneepfflplebdkc%26v%3D0.0%26fp%3D%26uc");
+ const GURL expected_update_url_1(
+ "http://localhost/upd?extra=foo"
+ "&x=id%3Dihfokbkgjpifnbbojhneepfflplebdkc%26v%3D1.0%26fp%3D1%26uc");
+ const GURL expected_update_url_2(
+ "http://localhost/upd?extra=foo"
+ "&x=id%3Dihfokbkgjpifnbbojhneepfflplebdkc%26v%3D2.0%26fp%3Df22%26uc");
+ const GURL expected_crx_url_1(
+ "http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx");
+ const GURL expected_crx_url_1_diff_2(
+ "http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx");
+
+ interceptor.SetResponse(expected_update_url_0,
+ test_file("updatecheck_diff_reply_1.xml"));
+ interceptor.SetResponse(expected_update_url_1,
+ test_file("updatecheck_diff_reply_2.xml"));
+ interceptor.SetResponse(expected_update_url_2,
+ test_file("updatecheck_diff_reply_3.xml"));
+ interceptor.SetResponse(expected_crx_url_1,
+ test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"));
+ interceptor.SetResponse(
+ expected_crx_url_1_diff_2,
+ test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"));
+
+ test_configurator()->SetLoopCount(3);
+
+ component_updater()->Start();
+ message_loop_.Run();
+
+ EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
+ EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count());
+
+ // One ping has the diffresult=1, the other does not.
+ EXPECT_EQ(1, ping_checker.NumHits());
+ EXPECT_EQ(1, ping_checker.NumMisses());
+
+ EXPECT_EQ(5, interceptor.GetHitCount());
+
+ component_updater()->Stop();
+}
+
// Verify that component installation falls back to downloading and installing
// a full update if the differential update fails (in this case, because the
// installer does not know about the existing files). We do two loops; the final
// loop should do nothing.
-// We also check that exactly 4 network requests are issued:
+// We also check that exactly 4 non-ping network requests are issued:
// 1- update check (loop 1)
// 2- download differential crx
// 3- download full crx
// 4- update check (loop 2 - no update available)
+// There should be one ping for the first attempted update.
TEST_F(ComponentUpdaterTest, DifferentialUpdateFails) {
- base::MessageLoop message_loop;
- content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
- content::TestBrowserThread file_thread(BrowserThread::FILE);
- content::TestBrowserThread io_thread(BrowserThread::IO);
-
- io_thread.StartIOThread();
- file_thread.Start();
-
+ std::map<std::string, std::string> map;
+ map.insert(std::pair<std::string, std::string>("eventtype", "\"3\""));
+ map.insert(std::pair<std::string, std::string>("eventresult", "\"1\""));
+ map.insert(std::pair<std::string, std::string>("diffresult", "\"0\""));
+ map.insert(std::pair<std::string, std::string>("differrorcode", "\"16\""));
+ PingChecker ping_checker(map);
+ URLRequestPostInterceptor post_interceptor(&ping_checker);
content::URLLocalHostRequestPrepackagedInterceptor interceptor;
TestInstaller installer;
@@ -695,29 +797,92 @@
test_configurator()->SetLoopCount(2);
component_updater()->Start();
- message_loop.Run();
+ message_loop_.Run();
// A failed differential update does not count as a failed install.
EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
EXPECT_EQ(1, static_cast<TestInstaller*>(com.installer)->install_count());
+ EXPECT_EQ(1, ping_checker.NumHits());
+ EXPECT_EQ(0, ping_checker.NumMisses());
EXPECT_EQ(4, interceptor.GetHitCount());
component_updater()->Stop();
}
+// Verify that a failed installation causes an install failure ping.
+TEST_F(ComponentUpdaterTest, CheckFailedInstallPing) {
+ std::map<std::string, std::string> map;
+ map.insert(std::pair<std::string, std::string>("eventtype", "\"3\""));
+ map.insert(std::pair<std::string, std::string>("eventresult", "\"0\""));
+ map.insert(std::pair<std::string, std::string>("errorcode", "\"9\""));
+ map.insert(std::pair<std::string, std::string>("previousversion",
+ "\"0.9\""));
+ map.insert(std::pair<std::string, std::string>("nextversion", "\"1.0\""));
+ PingChecker ping_checker(map);
+ URLRequestPostInterceptor post_interceptor(&ping_checker);
+ content::URLLocalHostRequestPrepackagedInterceptor interceptor;
+
+ // This test installer reports installation failure.
+ class : public TestInstaller {
+ virtual bool Install(const base::DictionaryValue& manifest,
+ const base::FilePath& unpack_path) OVERRIDE {
+ ++install_count_;
+ base::DeleteFile(unpack_path, true);
+ return false;
+ }
+ } installer;
+
+ CrxComponent com;
+ RegisterComponent(&com, kTestComponent_jebg, Version("0.9"), &installer);
+
+ // Start with 0.9, and attempt update to 1.0
+ const GURL expected_update_url_1(
+ "http://localhost/upd?extra=foo"
+ "&x=id%3Djebgalgnebhfojomionfpkfelancnnkf%26v%3D0.9%26fp%3D%26uc");
+
+ interceptor.SetResponse(expected_update_url_1,
+ test_file("updatecheck_reply_1.xml"));
+ interceptor.SetResponse(GURL(expected_crx_url),
+ test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
+
+ // Loop twice to issue two checks: (1) with original 0.9 version
+ // and (2), which should retry with 0.9.
+ test_configurator()->SetLoopCount(2);
+ component_updater()->Start();
+ message_loop_.Run();
+
+ // Loop once more, but expect no ping because a noupdate response is issued.
+ // This is necessary to clear out the fire-and-forget ping from the previous
+ // iteration.
+ interceptor.SetResponse(expected_update_url_1,
+ test_file("updatecheck_reply_noupdate.xml"));
+ test_configurator()->SetLoopCount(1);
+ component_updater()->Start();
+ message_loop_.Run();
+
+ EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
+ EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count());
+
+ EXPECT_EQ(2, ping_checker.NumHits());
+ EXPECT_EQ(0, ping_checker.NumMisses());
+ EXPECT_EQ(5, interceptor.GetHitCount());
+
+ component_updater()->Stop();
+}
+
// Verify that we successfully propagate a patcher error.
// ihfokbkgjpifnbbojhneepfflplebdkc_1to2_bad.crx contains an incorrect
// patching instruction that should fail.
TEST_F(ComponentUpdaterTest, DifferentialUpdateFailErrorcode) {
- base::MessageLoop message_loop;
- content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
- content::TestBrowserThread file_thread(BrowserThread::FILE);
- content::TestBrowserThread io_thread(BrowserThread::IO);
-
- io_thread.StartIOThread();
- file_thread.Start();
-
+ std::map<std::string, std::string> map;
+ map.insert(std::pair<std::string, std::string>("eventtype", "\"3\""));
+ map.insert(std::pair<std::string, std::string>("eventresult", "\"1\""));
+ map.insert(std::pair<std::string, std::string>("diffresult", "\"0\""));
+ map.insert(std::pair<std::string, std::string>("differrorcode", "\"14\""));
+ map.insert(std::pair<std::string, std::string>("diffextracode1", "\"305\""));
+ PingChecker ping_checker(map);
+ URLRequestPostInterceptor post_interceptor(&ping_checker);
content::URLLocalHostRequestPrepackagedInterceptor interceptor;
VersionedTestInstaller installer;
@@ -757,11 +922,13 @@
test_configurator()->SetLoopCount(3);
component_updater()->Start();
- message_loop.Run();
+ message_loop_.Run();
EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count());
+ EXPECT_EQ(1, ping_checker.NumHits());
+ EXPECT_EQ(1, ping_checker.NumMisses());
EXPECT_EQ(6, interceptor.GetHitCount());
component_updater()->Stop();
diff --git a/chrome/browser/component_updater/test/component_updater_service_unittest.h b/chrome/browser/component_updater/test/component_updater_service_unittest.h
index ba98102..ca3a7b8 100644
--- a/chrome/browser/component_updater/test/component_updater_service_unittest.h
+++ b/chrome/browser/component_updater/test/component_updater_service_unittest.h
@@ -6,18 +6,23 @@
#define CHROME_BROWSER_COMPONENT_UPDATER_TEST_COMPONENT_UPDATER_SERVICE_UNITTEST_H_
#include <list>
+#include <map>
+#include <string>
#include <utility>
-
+#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/files/file_path.h"
+#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
#include "chrome/browser/component_updater/component_updater_service.h"
#include "chrome/browser/component_updater/test/component_patcher_mock.h"
+#include "chrome/browser/component_updater/test/url_request_post_interceptor.h"
+#include "content/public/test/test_browser_thread.h"
#include "content/public/test/test_notification_tracker.h"
+#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
-using content::TestNotificationTracker;
-
-class GURL;
class TestInstaller;
// component 1 has extension id "jebgalgnebhfojomionfpkfelancnnkf", and
@@ -59,6 +64,8 @@
virtual GURL UpdateUrl() OVERRIDE;
+ virtual GURL PingUrl() OVERRIDE;
+
virtual const char* ExtraRequestParams() OVERRIDE;
virtual size_t UrlSizeLimit() OVERRIDE;
@@ -68,8 +75,6 @@
// Don't use the utility process to decode files.
virtual bool InProcess() OVERRIDE;
- virtual void OnEvent(Events event, int extra) OVERRIDE;
-
virtual ComponentPatcher* CreateComponentPatcher() OVERRIDE;
virtual bool DeltasEnabled() const OVERRIDE;
@@ -91,6 +96,7 @@
std::list<CheckAtLoopCount> components_to_check_;
ComponentUpdateService* cus_;
+ scoped_refptr<net::TestURLRequestContextGetter> context_;
};
class ComponentUpdaterTest : public testing::Test {
@@ -112,7 +118,7 @@
// Makes the full path to a component updater test file.
const base::FilePath test_file(const char* file);
- TestNotificationTracker& notification_tracker();
+ content::TestNotificationTracker& notification_tracker();
TestConfigurator* test_configurator();
@@ -120,15 +126,42 @@
TestComponents component,
const Version& version,
TestInstaller* installer);
+ protected:
+ base::MessageLoop message_loop_;
private:
- scoped_ptr<ComponentUpdateService> component_updater_;
- base::FilePath test_data_dir_;
- TestNotificationTracker notification_tracker_;
TestConfigurator* test_config_;
+ base::FilePath test_data_dir_;
+ content::TestNotificationTracker notification_tracker_;
+ content::TestBrowserThread ui_thread_;
+ content::TestBrowserThread file_thread_;
+ content::TestBrowserThread io_thread_;
+ scoped_ptr<ComponentUpdateService> component_updater_;
};
const char expected_crx_url[] =
"http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx";
+class PingChecker : public RequestCounter {
+ public:
+ explicit PingChecker(const std::map<std::string, std::string>& attributes);
+
+ virtual ~PingChecker();
+
+ virtual void Trial(net::URLRequest* request) OVERRIDE;
+
+ int NumHits() const {
+ return num_hits_;
+ }
+ int NumMisses() const {
+ return num_misses_;
+ }
+
+ private:
+ int num_hits_;
+ int num_misses_;
+ const std::map<std::string, std::string> attributes_;
+ virtual bool Test(net::URLRequest* request);
+};
+
#endif // CHROME_BROWSER_COMPONENT_UPDATER_TEST_COMPONENT_UPDATER_SERVICE_UNITTEST_H_
diff --git a/chrome/browser/component_updater/test/component_updater_service_unittest_win.cc b/chrome/browser/component_updater/test/component_updater_service_unittest_win.cc
deleted file mode 100644
index 8a51010..0000000
--- a/chrome/browser/component_updater/test/component_updater_service_unittest_win.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2013 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 <list>
-#include <utility>
-#include "base/compiler_specific.h"
-#include "base/file_util.h"
-#include "base/files/file_path.h"
-#include "base/memory/scoped_vector.h"
-#include "base/message_loop/message_loop.h"
-#include "base/path_service.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "base/values.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/component_updater/component_updater_service.h"
-#include "chrome/browser/component_updater/test/component_patcher_mock.h"
-#include "chrome/browser/component_updater/test/component_updater_service_unittest.h"
-#include "chrome/browser/component_updater/test/test_installer.h"
-#include "chrome/common/chrome_paths.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/test/test_browser_thread.h"
-#include "content/public/test/test_notification_tracker.h"
-#include "content/test/net/url_request_prepackaged_interceptor.h"
-#include "libxml/globals.h"
-#include "net/base/upload_bytes_element_reader.h"
-#include "net/url_request/url_fetcher.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_filter.h"
-#include "net/url_request/url_request_simple_job.h"
-#include "net/url_request/url_request_test_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-using content::BrowserThread;
-using content::TestNotificationTracker;
-
-// Verify that we can download and install a component and a differential
-// update to that component. We do three loops; the final loop should do
-// nothing.
-// We also check that exactly 5 network requests are issued:
-// 1- update check (response: v1 available)
-// 2- download crx (v1)
-// 3- update check (response: v2 available)
-// 4- download differential crx (v1 to v2)
-// 5- update check (response: no further update available)
-TEST_F(ComponentUpdaterTest, DifferentialUpdate) {
- base::MessageLoop message_loop;
- content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
- content::TestBrowserThread file_thread(BrowserThread::FILE);
- content::TestBrowserThread io_thread(BrowserThread::IO);
-
- io_thread.StartIOThread();
- file_thread.Start();
-
- content::URLLocalHostRequestPrepackagedInterceptor interceptor;
-
- VersionedTestInstaller installer;
- CrxComponent com;
- RegisterComponent(&com, kTestComponent_ihfo, Version("0.0"), &installer);
-
- const GURL expected_update_url_0(
- "http://localhost/upd?extra=foo"
- "&x=id%3Dihfokbkgjpifnbbojhneepfflplebdkc%26v%3D0.0%26fp%3D%26uc");
- const GURL expected_update_url_1(
- "http://localhost/upd?extra=foo"
- "&x=id%3Dihfokbkgjpifnbbojhneepfflplebdkc%26v%3D1.0%26fp%3D1%26uc");
- const GURL expected_update_url_2(
- "http://localhost/upd?extra=foo"
- "&x=id%3Dihfokbkgjpifnbbojhneepfflplebdkc%26v%3D2.0%26fp%3Df22%26uc");
- const GURL expected_crx_url_1(
- "http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx");
- const GURL expected_crx_url_1_diff_2(
- "http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx");
-
- interceptor.SetResponse(expected_update_url_0,
- test_file("updatecheck_diff_reply_1.xml"));
- interceptor.SetResponse(expected_update_url_1,
- test_file("updatecheck_diff_reply_2.xml"));
- interceptor.SetResponse(expected_update_url_2,
- test_file("updatecheck_diff_reply_3.xml"));
- interceptor.SetResponse(expected_crx_url_1,
- test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"));
- interceptor.SetResponse(
- expected_crx_url_1_diff_2,
- test_file("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"));
-
- test_configurator()->SetLoopCount(3);
-
- component_updater()->Start();
- message_loop.Run();
-
- EXPECT_EQ(0, static_cast<TestInstaller*>(com.installer)->error());
- EXPECT_EQ(2, static_cast<TestInstaller*>(com.installer)->install_count());
-
- EXPECT_EQ(5, interceptor.GetHitCount());
-
- component_updater()->Stop();
-}
diff --git a/chrome/browser/component_updater/test/url_request_post_interceptor.cc b/chrome/browser/component_updater/test/url_request_post_interceptor.cc
new file mode 100644
index 0000000..885c9c6
--- /dev/null
+++ b/chrome/browser/component_updater/test/url_request_post_interceptor.cc
@@ -0,0 +1,68 @@
+// Copyright 2013 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/component_updater/test/url_request_post_interceptor.h"
+
+#include "content/public/test/test_browser_thread.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_filter.h"
+#include "net/url_request/url_request_test_util.h"
+
+using content::BrowserThread;
+
+URLRequestPostInterceptor::URLRequestPostInterceptor(
+ RequestCounter* counter) : delegate_(new Delegate(counter)) {
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&Delegate::Register,
+ base::Unretained(delegate_)));
+}
+
+URLRequestPostInterceptor::~URLRequestPostInterceptor() {
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&Delegate::Unregister,
+ base::Unretained(delegate_)));
+}
+
+URLRequestPostInterceptor::Delegate::Delegate(
+ RequestCounter* counter) : counter_(counter) {
+}
+
+void URLRequestPostInterceptor::Delegate::Register() {
+ net::URLRequestFilter::GetInstance()->AddHostnameProtocolHandler(
+ "http", "localhost2",
+ scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(this));
+}
+
+void URLRequestPostInterceptor::Delegate::Unregister() {
+ net::URLRequestFilter::GetInstance()->
+ RemoveHostnameHandler("http", "localhost2");
+}
+
+net::URLRequestJob* URLRequestPostInterceptor::Delegate::MaybeCreateJob(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const {
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ if (request->has_upload()) {
+ counter_->Trial(request);
+ return new URLRequestPingMockJob(request, network_delegate);
+ }
+ return NULL;
+}
+
+URLRequestPingMockJob::URLRequestPingMockJob(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate)
+ : net::URLRequestSimpleJob(request, network_delegate) {
+}
+
+int URLRequestPingMockJob::GetData(
+ std::string* mime_type,
+ std::string* charset,
+ std::string* data,
+ const net::CompletionCallback& callback) const {
+ mime_type->assign("text/plain");
+ charset->assign("US-ASCII");
+ data->assign(""); // There is no reason to have a response body.
+ return net::OK;
+}
diff --git a/chrome/browser/component_updater/test/url_request_post_interceptor.h b/chrome/browser/component_updater/test/url_request_post_interceptor.h
new file mode 100644
index 0000000..3d0af2b
--- /dev/null
+++ b/chrome/browser/component_updater/test/url_request_post_interceptor.h
@@ -0,0 +1,72 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_COMPONENT_UPDATER_TEST_URL_REQUEST_POST_INTERCEPTOR_H_
+#define CHROME_BROWSER_COMPONENT_UPDATER_TEST_URL_REQUEST_POST_INTERCEPTOR_H_
+
+#include "base/basictypes.h"
+#include "net/url_request/url_request_job_factory.h"
+#include "net/url_request/url_request_simple_job.h"
+
+namespace net {
+class NetworkDelegate;
+class URLRequest;
+}
+
+class RequestCounter {
+ public:
+ virtual void Trial(net::URLRequest* request) = 0;
+};
+
+class URLRequestPostInterceptor {
+ public:
+ explicit URLRequestPostInterceptor(RequestCounter* counter);
+ virtual ~URLRequestPostInterceptor();
+
+ private:
+ class Delegate;
+
+ // After creation, |delegate_| lives on the IO thread, and a task to delete it
+ // is posted from ~URLRequestPostInterceptor().
+ Delegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(URLRequestPostInterceptor);
+};
+
+class URLRequestPostInterceptor::Delegate
+ : public net::URLRequestJobFactory::ProtocolHandler {
+ public:
+ explicit Delegate(RequestCounter* counter);
+ virtual ~Delegate() {}
+
+ void Register();
+
+ void Unregister();
+
+ private:
+ RequestCounter* counter_;
+
+ virtual net::URLRequestJob* MaybeCreateJob(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const OVERRIDE;
+};
+
+class URLRequestPingMockJob : public net::URLRequestSimpleJob {
+ public:
+ URLRequestPingMockJob(net::URLRequest* request,
+ net::NetworkDelegate* network_delegate);
+
+ protected:
+ virtual int GetData(std::string* mime_type,
+ std::string* charset,
+ std::string* data,
+ const net::CompletionCallback& callback) const OVERRIDE;
+
+ private:
+ virtual ~URLRequestPingMockJob() {}
+
+ DISALLOW_COPY_AND_ASSIGN(URLRequestPingMockJob);
+};
+
+#endif // CHROME_BROWSER_COMPONENT_UPDATER_TEST_URL_REQUEST_POST_INTERCEPTOR_H_
diff --git a/chrome/browser/component_updater/widevine_cdm_component_installer.cc b/chrome/browser/component_updater/widevine_cdm_component_installer.cc
index 400b94f..cdb9f24 100644
--- a/chrome/browser/component_updater/widevine_cdm_component_installer.cc
+++ b/chrome/browser/component_updater/widevine_cdm_component_installer.cc
@@ -134,7 +134,7 @@
plugin_info->name = kWidevineCdmDisplayName;
plugin_info->description = kWidevineCdmDescription;
plugin_info->version = version.GetString();
- webkit::WebPluginMimeType widevine_cdm_mime_type(
+ content::WebPluginMimeType widevine_cdm_mime_type(
kWidevineCdmPluginMimeType,
kWidevineCdmPluginExtension,
kWidevineCdmPluginMimeTypeDescription);
diff --git a/chrome/browser/content_settings/content_settings_browsertest.cc b/chrome/browser/content_settings/content_settings_browsertest.cc
index bee7ee8..f13eea9 100644
--- a/chrome/browser/content_settings/content_settings_browsertest.cc
+++ b/chrome/browser/content_settings/content_settings_browsertest.cc
@@ -37,6 +37,10 @@
#include "base/mac/scoped_nsautorelease_pool.h"
#endif
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
using content::BrowserThread;
using content::URLRequestMockHTTPJob;
@@ -562,6 +566,12 @@
// Tests Pepper plugins that use JavaScript instead of Plug-ins settings.
IN_PROC_BROWSER_TEST_F(PepperContentSettingsTest, PluginSpecialCases) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
HostContentSettingsMap* content_settings =
browser()->profile()->GetHostContentSettingsMap();
diff --git a/chrome/browser/geolocation/geolocation_settings_state.cc b/chrome/browser/content_settings/content_settings_usages_state.cc
similarity index 80%
rename from chrome/browser/geolocation/geolocation_settings_state.cc
rename to chrome/browser/content_settings/content_settings_usages_state.cc
index 21cbb77..4e82b6f 100644
--- a/chrome/browser/geolocation/geolocation_settings_state.cc
+++ b/chrome/browser/content_settings/content_settings_usages_state.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright 2013 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/geolocation/geolocation_settings_state.h"
+#include "chrome/browser/content_settings/content_settings_usages_state.h"
#include <string>
@@ -16,20 +16,22 @@
#include "content/public/browser/navigation_entry.h"
#include "net/base/net_util.h"
-GeolocationSettingsState::GeolocationSettingsState(Profile* profile)
- : profile_(profile) {
+ContentSettingsUsagesState::ContentSettingsUsagesState(Profile* profile,
+ ContentSettingsType type)
+ : profile_(profile),
+ type_(type) {
}
-GeolocationSettingsState::~GeolocationSettingsState() {
+ContentSettingsUsagesState::~ContentSettingsUsagesState() {
}
-void GeolocationSettingsState::OnGeolocationPermissionSet(
+void ContentSettingsUsagesState::OnPermissionSet(
const GURL& requesting_origin, bool allowed) {
state_map_[requesting_origin] =
allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
}
-void GeolocationSettingsState::DidNavigate(
+void ContentSettingsUsagesState::DidNavigate(
const content::LoadCommittedDetails& details) {
if (details.entry)
embedder_url_ = details.entry->GetURL();
@@ -47,18 +49,18 @@
state_map_.clear();
}
-void GeolocationSettingsState::ClearStateMap() {
+void ContentSettingsUsagesState::ClearStateMap() {
state_map_.clear();
}
-void GeolocationSettingsState::GetDetailedInfo(
+void ContentSettingsUsagesState::GetDetailedInfo(
FormattedHostsPerState* formatted_hosts_per_state,
unsigned int* tab_state_flags) const {
DCHECK(tab_state_flags);
DCHECK(embedder_url_.is_valid());
ContentSetting default_setting =
profile_->GetHostContentSettingsMap()->GetDefaultContentSetting(
- CONTENT_SETTINGS_TYPE_GEOLOCATION, NULL);
+ type_, NULL);
std::set<std::string> formatted_hosts;
std::set<std::string> repeated_formatted_hosts;
@@ -87,10 +89,7 @@
const ContentSetting saved_setting =
profile_->GetHostContentSettingsMap()->GetContentSetting(
- i->first,
- embedder_url_,
- CONTENT_SETTINGS_TYPE_GEOLOCATION,
- std::string());
+ i->first, embedder_url_, type_, std::string());
if (saved_setting != default_setting)
*tab_state_flags |= TABSTATE_HAS_EXCEPTION;
if (saved_setting != i->second)
@@ -100,7 +99,7 @@
}
}
-std::string GeolocationSettingsState::GURLToFormattedHost(
+std::string ContentSettingsUsagesState::GURLToFormattedHost(
const GURL& url) const {
string16 display_host;
net::AppendFormattedHost(url,
diff --git a/chrome/browser/geolocation/geolocation_settings_state.h b/chrome/browser/content_settings/content_settings_usages_state.h
similarity index 65%
rename from chrome/browser/geolocation/geolocation_settings_state.h
rename to chrome/browser/content_settings/content_settings_usages_state.h
index c5f9948..e137620 100644
--- a/chrome/browser/geolocation/geolocation_settings_state.h
+++ b/chrome/browser/content_settings/content_settings_usages_state.h
@@ -1,14 +1,15 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright 2013 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.
-#ifndef CHROME_BROWSER_GEOLOCATION_GEOLOCATION_SETTINGS_STATE_H_
-#define CHROME_BROWSER_GEOLOCATION_GEOLOCATION_SETTINGS_STATE_H_
+#ifndef CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_USAGES_STATE_H_
+#define CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_USAGES_STATE_H_
#include <map>
#include <set>
#include "chrome/common/content_settings.h"
+#include "chrome/common/content_settings_types.h"
#include "url/gurl.h"
class Profile;
@@ -17,12 +18,13 @@
struct LoadCommittedDetails;
}
-// This class manages the geolocation state per tab, and provides information
-// and presentation data about the geolocation usage.
-class GeolocationSettingsState {
+// This class manages a content setting state per tab for a given
+// |ContentSettingsType|, and provides information and presentation data about
+// the content setting usage.
+class ContentSettingsUsagesState {
public:
- explicit GeolocationSettingsState(Profile* profile);
- virtual ~GeolocationSettingsState();
+ ContentSettingsUsagesState(Profile* profile, ContentSettingsType type);
+ virtual ~ContentSettingsUsagesState();
typedef std::map<GURL, ContentSetting> StateMap;
const StateMap& state_map() const {
@@ -30,7 +32,7 @@
}
// Sets the state for |requesting_origin|.
- void OnGeolocationPermissionSet(const GURL& requesting_origin, bool allowed);
+ void OnPermissionSet(const GURL& requesting_origin, bool allowed);
// Delegated by WebContents to indicate a navigation has happened and we
// may need to clear our settings.
@@ -62,10 +64,11 @@
std::string GURLToFormattedHost(const GURL& url) const;
Profile* profile_;
+ ContentSettingsType type_;
StateMap state_map_;
GURL embedder_url_;
- DISALLOW_COPY_AND_ASSIGN(GeolocationSettingsState);
+ DISALLOW_COPY_AND_ASSIGN(ContentSettingsUsagesState);
};
-#endif // CHROME_BROWSER_GEOLOCATION_GEOLOCATION_SETTINGS_STATE_H_
+#endif // CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_USAGES_STATE_H_
diff --git a/chrome/browser/content_settings/content_settings_usages_state_unittest.cc b/chrome/browser/content_settings/content_settings_usages_state_unittest.cc
new file mode 100644
index 0000000..ef89d25
--- /dev/null
+++ b/chrome/browser/content_settings/content_settings_usages_state_unittest.cc
@@ -0,0 +1,219 @@
+// Copyright 2013 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/content_settings/content_settings_usages_state.h"
+
+#include <string>
+
+#include "base/message_loop/message_loop.h"
+#include "chrome/browser/content_settings/host_content_settings_map.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/browser/navigation_details.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/test/test_browser_thread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using content::BrowserThread;
+using content::NavigationEntry;
+
+namespace {
+
+// ContentSettingsUsagesState class should work for any ContentSettingsType.
+// Here, following tests use |kTypeForTesting| as representation.
+// TODO(toyoshim): Add at least one test to verify the class works with other
+// types. http://crbug.com/263292 .
+ContentSettingsType kTypeForTesting = CONTENT_SETTINGS_TYPE_GEOLOCATION;
+
+class ContentSettingsUsagesStateTests : public testing::Test {
+ public:
+ ContentSettingsUsagesStateTests()
+ : ui_thread_(BrowserThread::UI, &message_loop_) {
+ }
+
+ protected:
+ base::MessageLoop message_loop_;
+ content::TestBrowserThread ui_thread_;
+};
+
+TEST_F(ContentSettingsUsagesStateTests, ClearOnNewOrigin) {
+ TestingProfile profile;
+ ContentSettingsUsagesState state(&profile, kTypeForTesting);
+ GURL url_0("http://www.example.com");
+
+ scoped_ptr<NavigationEntry> entry(NavigationEntry::Create());
+ entry->SetURL(url_0);
+ content::LoadCommittedDetails load_committed_details;
+ load_committed_details.entry = entry.get();
+ state.DidNavigate(load_committed_details);
+
+ profile.GetHostContentSettingsMap()->SetContentSetting(
+ ContentSettingsPattern::FromURLNoWildcard(url_0),
+ ContentSettingsPattern::FromURLNoWildcard(url_0),
+ kTypeForTesting,
+ std::string(),
+ CONTENT_SETTING_ALLOW);
+ state.OnPermissionSet(url_0, true);
+
+ GURL url_1("http://www.example1.com");
+ profile.GetHostContentSettingsMap()->SetContentSetting(
+ ContentSettingsPattern::FromURLNoWildcard(url_1),
+ ContentSettingsPattern::FromURLNoWildcard(url_0),
+ kTypeForTesting,
+ std::string(),
+ CONTENT_SETTING_BLOCK);
+ state.OnPermissionSet(url_1, false);
+
+ ContentSettingsUsagesState::StateMap state_map =
+ state.state_map();
+ EXPECT_EQ(2U, state_map.size());
+
+ ContentSettingsUsagesState::FormattedHostsPerState formatted_host_per_state;
+ unsigned int tab_state_flags = 0;
+ state.GetDetailedInfo(&formatted_host_per_state, &tab_state_flags);
+ EXPECT_TRUE(tab_state_flags &
+ ContentSettingsUsagesState::TABSTATE_HAS_ANY_ALLOWED)
+ << tab_state_flags;
+ EXPECT_TRUE(tab_state_flags &
+ ContentSettingsUsagesState::TABSTATE_HAS_EXCEPTION)
+ << tab_state_flags;
+ EXPECT_FALSE(tab_state_flags &
+ ContentSettingsUsagesState::TABSTATE_HAS_CHANGED)
+ << tab_state_flags;
+ EXPECT_TRUE(tab_state_flags &
+ ContentSettingsUsagesState::TABSTATE_HAS_ANY_ICON)
+ << tab_state_flags;
+ EXPECT_EQ(1U, formatted_host_per_state[CONTENT_SETTING_ALLOW].size());
+ EXPECT_EQ(1U,
+ formatted_host_per_state[CONTENT_SETTING_ALLOW].count(
+ url_0.host()));
+
+ EXPECT_EQ(1U, formatted_host_per_state[CONTENT_SETTING_BLOCK].size());
+ EXPECT_EQ(1U,
+ formatted_host_per_state[CONTENT_SETTING_BLOCK].count(
+ url_1.host()));
+
+ state.OnPermissionSet(url_0, false);
+
+ formatted_host_per_state.clear();
+ tab_state_flags = 0;
+ state.GetDetailedInfo(&formatted_host_per_state, &tab_state_flags);
+ EXPECT_FALSE(tab_state_flags &
+ ContentSettingsUsagesState::TABSTATE_HAS_ANY_ALLOWED)
+ << tab_state_flags;
+ EXPECT_TRUE(tab_state_flags &
+ ContentSettingsUsagesState::TABSTATE_HAS_EXCEPTION)
+ << tab_state_flags;
+ EXPECT_TRUE(tab_state_flags &
+ ContentSettingsUsagesState::TABSTATE_HAS_CHANGED)
+ << tab_state_flags;
+ EXPECT_TRUE(tab_state_flags &
+ ContentSettingsUsagesState::TABSTATE_HAS_ANY_ICON)
+ << tab_state_flags;
+ EXPECT_EQ(0U, formatted_host_per_state[CONTENT_SETTING_ALLOW].size());
+ EXPECT_EQ(2U, formatted_host_per_state[CONTENT_SETTING_BLOCK].size());
+ EXPECT_EQ(1U,
+ formatted_host_per_state[CONTENT_SETTING_BLOCK].count(
+ url_0.host()));
+ EXPECT_EQ(1U,
+ formatted_host_per_state[CONTENT_SETTING_BLOCK].count(
+ url_1.host()));
+
+ state.OnPermissionSet(url_0, true);
+
+ load_committed_details.previous_url = url_0;
+ state.DidNavigate(load_committed_details);
+
+ ContentSettingsUsagesState::StateMap new_state_map =
+ state.state_map();
+ EXPECT_EQ(state_map.size(), new_state_map.size());
+
+ GURL different_url("http://foo.com");
+ entry->SetURL(different_url);
+ state.DidNavigate(load_committed_details);
+
+ EXPECT_TRUE(state.state_map().empty());
+
+ formatted_host_per_state.clear();
+ tab_state_flags = 0;
+ state.GetDetailedInfo(&formatted_host_per_state, &tab_state_flags);
+ EXPECT_TRUE(formatted_host_per_state.empty());
+ EXPECT_EQ(0U, tab_state_flags);
+}
+
+TEST_F(ContentSettingsUsagesStateTests, ShowPortOnSameHost) {
+ TestingProfile profile;
+ ContentSettingsUsagesState state(&profile, kTypeForTesting);
+ GURL url_0("http://www.example.com");
+
+ scoped_ptr<NavigationEntry> entry(NavigationEntry::Create());
+ entry->SetURL(url_0);
+ content::LoadCommittedDetails load_committed_details;
+ load_committed_details.entry = entry.get();
+ state.DidNavigate(load_committed_details);
+
+ profile.GetHostContentSettingsMap()->SetContentSetting(
+ ContentSettingsPattern::FromURLNoWildcard(url_0),
+ ContentSettingsPattern::FromURLNoWildcard(url_0),
+ kTypeForTesting,
+ std::string(),
+ CONTENT_SETTING_ALLOW);
+ state.OnPermissionSet(url_0, true);
+
+ GURL url_1("https://www.example.com");
+ profile.GetHostContentSettingsMap()->SetContentSetting(
+ ContentSettingsPattern::FromURLNoWildcard(url_1),
+ ContentSettingsPattern::FromURLNoWildcard(url_0),
+ kTypeForTesting,
+ std::string(),
+ CONTENT_SETTING_ALLOW);
+ state.OnPermissionSet(url_1, true);
+
+ GURL url_2("http://www.example1.com");
+ profile.GetHostContentSettingsMap()->SetContentSetting(
+ ContentSettingsPattern::FromURLNoWildcard(url_2),
+ ContentSettingsPattern::FromURLNoWildcard(url_0),
+ kTypeForTesting,
+ std::string(),
+ CONTENT_SETTING_ALLOW);
+ state.OnPermissionSet(url_2, true);
+
+ ContentSettingsUsagesState::StateMap state_map =
+ state.state_map();
+ EXPECT_EQ(3U, state_map.size());
+
+ ContentSettingsUsagesState::FormattedHostsPerState formatted_host_per_state;
+ unsigned int tab_state_flags = 0;
+ state.GetDetailedInfo(&formatted_host_per_state, &tab_state_flags);
+
+ EXPECT_EQ(3U, formatted_host_per_state[CONTENT_SETTING_ALLOW].size());
+ EXPECT_EQ(1U,
+ formatted_host_per_state[CONTENT_SETTING_ALLOW].count(
+ url_0.spec()));
+ EXPECT_EQ(1U,
+ formatted_host_per_state[CONTENT_SETTING_ALLOW].count(
+ url_1.spec()));
+ EXPECT_EQ(1U,
+ formatted_host_per_state[CONTENT_SETTING_ALLOW].count(
+ url_2.host()));
+
+ state.OnPermissionSet(url_1, false);
+ formatted_host_per_state.clear();
+ tab_state_flags = 0;
+ state.GetDetailedInfo(&formatted_host_per_state, &tab_state_flags);
+
+ EXPECT_EQ(2U, formatted_host_per_state[CONTENT_SETTING_ALLOW].size());
+ EXPECT_EQ(1U,
+ formatted_host_per_state[CONTENT_SETTING_ALLOW].count(
+ url_0.spec()));
+ EXPECT_EQ(1U,
+ formatted_host_per_state[CONTENT_SETTING_ALLOW].count(
+ url_2.host()));
+ EXPECT_EQ(1U, formatted_host_per_state[CONTENT_SETTING_BLOCK].size());
+ EXPECT_EQ(1U,
+ formatted_host_per_state[CONTENT_SETTING_BLOCK].count(
+ url_1.spec()));
+}
+
+
+} // namespace
diff --git a/chrome/browser/content_settings/tab_specific_content_settings.cc b/chrome/browser/content_settings/tab_specific_content_settings.cc
index 1ddd3e9..7b6d95b 100644
--- a/chrome/browser/content_settings/tab_specific_content_settings.cc
+++ b/chrome/browser/content_settings/tab_specific_content_settings.cc
@@ -79,7 +79,7 @@
profile_(Profile::FromBrowserContext(tab->GetBrowserContext())),
allowed_local_shared_objects_(profile_),
blocked_local_shared_objects_(profile_),
- geolocation_settings_state_(profile_),
+ geolocation_usages_state_(profile_, CONTENT_SETTINGS_TYPE_GEOLOCATION),
pending_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()),
previous_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()),
pending_protocol_handler_setting_(CONTENT_SETTING_DEFAULT),
@@ -450,8 +450,7 @@
void TabSpecificContentSettings::OnGeolocationPermissionSet(
const GURL& requesting_origin,
bool allowed) {
- geolocation_settings_state_.OnGeolocationPermissionSet(requesting_origin,
- allowed);
+ geolocation_usages_state_.OnPermissionSet(requesting_origin, allowed);
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
content::Source<WebContents>(web_contents()),
@@ -547,11 +546,11 @@
void TabSpecificContentSettings::GeolocationDidNavigate(
const content::LoadCommittedDetails& details) {
- geolocation_settings_state_.DidNavigate(details);
+ geolocation_usages_state_.DidNavigate(details);
}
void TabSpecificContentSettings::ClearGeolocationContentSettings() {
- geolocation_settings_state_.ClearStateMap();
+ geolocation_usages_state_.ClearStateMap();
}
void TabSpecificContentSettings::SetPepperBrokerAllowed(bool allowed) {
diff --git a/chrome/browser/content_settings/tab_specific_content_settings.h b/chrome/browser/content_settings/tab_specific_content_settings.h
index ad1fa63..1cd3147 100644
--- a/chrome/browser/content_settings/tab_specific_content_settings.h
+++ b/chrome/browser/content_settings/tab_specific_content_settings.h
@@ -12,8 +12,8 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
+#include "chrome/browser/content_settings/content_settings_usages_state.h"
#include "chrome/browser/content_settings/local_shared_objects_container.h"
-#include "chrome/browser/geolocation/geolocation_settings_state.h"
#include "chrome/common/content_settings.h"
#include "chrome/common/content_settings_types.h"
#include "chrome/common/custom_handlers/protocol_handler.h"
@@ -188,10 +188,10 @@
const std::set<std::string>& BlockedResourcesForType(
ContentSettingsType content_type) const;
- // Returns the GeolocationSettingsState that controls the
+ // Returns the ContentSettingsUsagesState that controls the
// geolocation API usage on this page.
- const GeolocationSettingsState& geolocation_settings_state() const {
- return geolocation_settings_state_;
+ const ContentSettingsUsagesState& geolocation_usages_state() const {
+ return geolocation_usages_state_;
}
// Call to indicate that there is a protocol handler pending user approval.
@@ -353,7 +353,7 @@
LocalSharedObjectsContainer blocked_local_shared_objects_;
// Manages information about Geolocation API usage in this page.
- GeolocationSettingsState geolocation_settings_state_;
+ ContentSettingsUsagesState geolocation_usages_state_;
// The pending protocol handler, if any. This can be set if
// registerProtocolHandler was invoked without user gesture.
diff --git a/chrome/browser/crash_upload_list.cc b/chrome/browser/crash_upload_list.cc
index 911fec4..12a069c 100644
--- a/chrome/browser/crash_upload_list.cc
+++ b/chrome/browser/crash_upload_list.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/crash_upload_list.h"
#include "base/files/file_path.h"
+#include "base/message_loop/message_loop_proxy.h"
#include "base/path_service.h"
#include "chrome/common/chrome_paths.h"
#if defined(OS_WIN)
@@ -29,6 +30,8 @@
CrashUploadList::CrashUploadList(Delegate* delegate,
const base::FilePath& upload_log_path)
- : UploadList(delegate, upload_log_path) {}
+ : base::UploadList(delegate,
+ upload_log_path,
+ base::MessageLoopProxy::current()) {}
CrashUploadList::~CrashUploadList() {}
diff --git a/chrome/browser/crash_upload_list.h b/chrome/browser/crash_upload_list.h
index f0b201c..b7ff6cf 100644
--- a/chrome/browser/crash_upload_list.h
+++ b/chrome/browser/crash_upload_list.h
@@ -5,10 +5,10 @@
#ifndef CHROME_BROWSER_CRASH_UPLOAD_LIST_H_
#define CHROME_BROWSER_CRASH_UPLOAD_LIST_H_
-#include "chrome/browser/upload_list.h"
+#include "base/upload_list.h"
// An upload list manager for crash reports from breakpad.
-class CrashUploadList : public UploadList {
+class CrashUploadList : public base::UploadList {
public:
// Static factory method that creates the platform-specific implementation
// of the crash upload list with the given callback delegate.
diff --git a/chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h b/chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h
index 3e73c14..90b7eae 100644
--- a/chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h
+++ b/chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h
@@ -16,9 +16,10 @@
// card information gathered from a form submission.
class RegisterProtocolHandlerInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
- // Creates a new RPH delegate. Searches |infobar_service| for an existing
- // delegate for the same |handler|; replaces it with the new delegate if
- // found, otherwise adds the new infobar to |infobar_service|.
+ // Creates a new register protocol handler infobar delegate. Searches
+ // |infobar_service| for an existing delegate for the same |handler|; replaces
+ // it with the new delegate if found, otherwise adds the new infobar to
+ // |infobar_service|.
static void Create(InfoBarService* infobar_service,
ProtocolHandlerRegistry* registry,
const ProtocolHandler& handler);
diff --git a/chrome/browser/devtools/adb/android_usb_device.cc b/chrome/browser/devtools/adb/android_usb_device.cc
index 82a8b8c..0f662d5 100644
--- a/chrome/browser/devtools/adb/android_usb_device.cc
+++ b/chrome/browser/devtools/adb/android_usb_device.cc
@@ -153,6 +153,20 @@
zero_mask, devices));
}
+static void InterfacesListed(
+ crypto::RSAPrivateKey* rsa_key,
+ scoped_refptr<UsbDevice> usb_device,
+ scoped_refptr<UsbConfigDescriptor> config,
+ AndroidUsbDevices* devices,
+ bool success) {
+ if (!success)
+ return;
+ for (size_t j = 0; j < config->GetNumInterfaces(); ++j) {
+ ClaimInterface(rsa_key, usb_device, config->GetInterface(j),
+ devices);
+ }
+}
+
static uint32 Checksum(const std::string& data) {
unsigned char* x = (unsigned char*)data.data();
int count = data.length();
@@ -209,7 +223,7 @@
// static
void AndroidUsbDevice::Enumerate(Profile* profile,
crypto::RSAPrivateKey* rsa_key,
- AndroidUsbDevices* devices) {
+ const AndroidUsbDevicesCallback& callback) {
UsbService* service =
UsbServiceFactory::GetInstance()->GetForProfile(profile);
UsbDevices usb_devices;
@@ -237,21 +251,18 @@
}
// Add new devices.
- AndroidUsbDevices new_devices;
for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end();
++it) {
- UsbDevice* usb_device = *it;
- if (claimed_devices.find(usb_device) != claimed_devices.end())
+ scoped_refptr<UsbDevice> usb_device = *it;
+ if (claimed_devices.find(usb_device.get()) != claimed_devices.end())
continue;
scoped_refptr<UsbConfigDescriptor> config = new UsbConfigDescriptor();
- usb_device->ListInterfaces(config.get(), base::Bind(&BoolNoop));
- for (size_t j = 0; j < config->GetNumInterfaces(); ++j) {
- ClaimInterface(rsa_key, usb_device, config->GetInterface(j),
- &g_devices.Get());
- }
+ usb_device->ListInterfaces(config.get(),
+ base::Bind(&InterfacesListed, rsa_key,
+ usb_device, config,
+ &g_devices.Get()));
}
-
- *devices = g_devices.Get();
+ callback.Run(g_devices.Get());
}
AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key,
@@ -331,12 +342,16 @@
if (append_zero)
body_buffer->data()[body_length - 1] = 0;
outgoing_queue_.push(std::make_pair(body_buffer, body_length));
+ if (zero_mask_ && (body_length & zero_mask_) == 0) {
+ // Send a zero length packet.
+ outgoing_queue_.push(std::make_pair(body_buffer, 0));
+ }
}
ProcessOutgoing();
}
void AndroidUsbDevice::ProcessOutgoing() {
- if (outgoing_queue_.empty())
+ if (outgoing_queue_.empty() || terminated_)
return;
BulkMessage message = outgoing_queue_.front();
@@ -358,6 +373,8 @@
}
void AndroidUsbDevice::ReadHeader(bool initial) {
+ if (terminated_)
+ return;
if (!initial && HasOneRef())
return; // Stop polling.
scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kHeaderSize);
diff --git a/chrome/browser/devtools/adb/android_usb_device.h b/chrome/browser/devtools/adb/android_usb_device.h
index 67f50ff..6a8292d 100644
--- a/chrome/browser/devtools/adb/android_usb_device.h
+++ b/chrome/browser/devtools/adb/android_usb_device.h
@@ -62,12 +62,14 @@
class AndroidUsbDevice;
typedef std::vector<scoped_refptr<AndroidUsbDevice> > AndroidUsbDevices;
+typedef base::Callback<void(const AndroidUsbDevices&)>
+ AndroidUsbDevicesCallback;
class AndroidUsbDevice : public base::RefCountedThreadSafe<AndroidUsbDevice> {
public:
static void Enumerate(Profile* profile,
crypto::RSAPrivateKey* rsa_key,
- AndroidUsbDevices* devices);
+ const AndroidUsbDevicesCallback& callback);
AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key,
scoped_refptr<UsbDevice> device,
diff --git a/chrome/browser/devtools/adb/android_usb_socket.cc b/chrome/browser/devtools/adb/android_usb_socket.cc
index 63d1787..c9b87b4 100644
--- a/chrome/browser/devtools/adb/android_usb_socket.cc
+++ b/chrome/browser/devtools/adb/android_usb_socket.cc
@@ -159,7 +159,7 @@
void AndroidUsbSocket::Disconnect() {
is_connected_ = false;
- device_->Send(AdbMessage::kCommandCLSE, local_id_, 0, "");
+ device_->Send(AdbMessage::kCommandCLSE, local_id_, remote_id_, "");
RespondToReaders(true);
}
diff --git a/chrome/browser/devtools/devtools_adb_bridge.cc b/chrome/browser/devtools/devtools_adb_bridge.cc
index 1a21127..a4cf6b7 100644
--- a/chrome/browser/devtools/devtools_adb_bridge.cc
+++ b/chrome/browser/devtools/devtools_adb_bridge.cc
@@ -23,7 +23,6 @@
#include "base/threading/thread.h"
#include "base/values.h"
#include "chrome/browser/devtools/adb/android_rsa.h"
-#include "chrome/browser/devtools/adb/android_usb_device.h"
#include "chrome/browser/devtools/adb_client_socket.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/devtools/tethering_adb_filter.h"
@@ -629,8 +628,9 @@
void DisconnectOnHandlerThread(bool closed_by_device) {
if (!socket_)
return;
- socket_->Disconnect();
- socket_.reset();
+ // Wipe out socket_ first since Disconnect can re-enter this method.
+ scoped_ptr<net::StreamSocket> socket(socket_.release());
+ socket->Disconnect();
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(&AdbWebSocket::OnSocketClosed, this, closed_by_device));
}
@@ -864,22 +864,16 @@
void DevToolsAdbBridge::EnumerateDevices(
const AndroidDevicesCallback& callback) {
- AdbClientSocket::AdbQuery(
- kAdbPort, kHostDevicesCommand,
- base::Bind(&DevToolsAdbBridge::ReceivedDevices, this, callback));
-}
+ DCHECK_EQ(base::MessageLoop::current(), adb_thread_->message_loop());
-void DevToolsAdbBridge::Query(
- const std::string query,
- const Callback& callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (!has_message_loop_) {
- callback.Run(net::ERR_FAILED, "Could not start ADB thread");
- return;
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kRemoteDebuggingRawUSB)) {
+ AndroidUsbDevice::Enumerate(
+ profile_, rsa_key_.get(),
+ base::Bind(&DevToolsAdbBridge::ReceivedUsbDevices, this, callback));
+ } else {
+ ReceivedUsbDevices(callback, AndroidUsbDevices());
}
- scoped_refptr<AdbQueryCommand> command(new AdbQueryCommand(query, callback));
- adb_thread_->message_loop()->PostTask(FROM_HERE,
- base::Bind(&AdbQueryCommand::Run, command));
}
void DevToolsAdbBridge::Attach(const std::string& serial,
@@ -899,12 +893,14 @@
}
void DevToolsAdbBridge::AddListener(Listener* listener) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (listeners_.empty())
RequestPages();
listeners_.push_back(listener);
}
void DevToolsAdbBridge::RemoveListener(Listener* listener) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
Listeners::iterator it =
std::find(listeners_.begin(), listeners_.end(), listener);
DCHECK(it != listeners_.end());
@@ -912,28 +908,36 @@
}
DevToolsAdbBridge::~DevToolsAdbBridge() {
- DCHECK(listeners_.empty());
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(listeners_.empty());
}
-void DevToolsAdbBridge::ReceivedDevices(const AndroidDevicesCallback& callback,
- int result,
- const std::string& response) {
+void DevToolsAdbBridge::ReceivedUsbDevices(
+ const AndroidDevicesCallback& callback,
+ const AndroidUsbDevices& usb_devices) {
AndroidDevices devices;
+
#if defined(DEBUG_DEVTOOLS)
devices.push_back(new AdbDeviceImpl("")); // For desktop remote debugging.
#endif // defined(DEBUG_DEVTOOLS)
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kRemoteDebuggingRawUSB)) {
- AndroidUsbDevices usb_devices;
- AndroidUsbDevice::Enumerate(profile_, rsa_key_.get(), &usb_devices);
- for (AndroidUsbDevices::iterator it = usb_devices.begin();
- it != usb_devices.end(); ++it) {
- devices.push_back(new UsbDeviceImpl(*it));
- }
+ for (AndroidUsbDevices::const_iterator it = usb_devices.begin();
+ it != usb_devices.end(); ++it) {
+ devices.push_back(new UsbDeviceImpl(*it));
}
+ AdbClientSocket::AdbQuery(
+ kAdbPort, kHostDevicesCommand,
+ base::Bind(&DevToolsAdbBridge::ReceivedAdbDevices, this, callback,
+ devices));
+
+}
+
+void DevToolsAdbBridge::ReceivedAdbDevices(
+ const AndroidDevicesCallback& callback,
+ AndroidDevices devices,
+ int result,
+ const std::string& response) {
if (result != net::OK) {
callback.Run(devices);
return;
diff --git a/chrome/browser/devtools/devtools_adb_bridge.h b/chrome/browser/devtools/devtools_adb_bridge.h
index a114e94..f091365 100644
--- a/chrome/browser/devtools/devtools_adb_bridge.h
+++ b/chrome/browser/devtools/devtools_adb_bridge.h
@@ -11,6 +11,7 @@
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/devtools/adb/android_usb_device.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service_factory.h"
#include "net/socket/tcp_client_socket.h"
@@ -162,7 +163,7 @@
explicit DevToolsAdbBridge(Profile* profile);
void EnumerateDevices(const AndroidDevicesCallback& callback);
- void Query(const std::string query, const Callback& callback);
+
void Attach(const std::string& serial,
const std::string& socket,
const std::string& debug_url,
@@ -184,8 +185,6 @@
friend class AdbWebSocket;
friend class AgentHostDelegate;
- virtual ~DevToolsAdbBridge();
-
class RefCountedAdbThread : public base::RefCounted<RefCountedAdbThread> {
public:
static scoped_refptr<RefCountedAdbThread> GetInstance();
@@ -201,9 +200,13 @@
base::Thread* thread_;
};
- void ReceivedDevices(const AndroidDevicesCallback& callback,
- int result,
- const std::string& response);
+ virtual ~DevToolsAdbBridge();
+ void ReceivedUsbDevices(const AndroidDevicesCallback& callback,
+ const AndroidUsbDevices& usb_devices);
+ void ReceivedAdbDevices(const AndroidDevicesCallback& callback,
+ AndroidDevices devices,
+ int result,
+ const std::string& response);
void RequestPages();
void ReceivedPages(int result, RemotePages* pages);
diff --git a/chrome/browser/devtools/devtools_file_helper.cc b/chrome/browser/devtools/devtools_file_helper.cc
index cb596d6..5d971f0 100644
--- a/chrome/browser/devtools/devtools_file_helper.cc
+++ b/chrome/browser/devtools/devtools_file_helper.cc
@@ -299,9 +299,18 @@
const AddFileSystemCallback& callback,
const ShowInfoBarCallback& show_info_bar_callback,
const base::FilePath& path) {
+ std::string file_system_path = path.AsUTF8Unsafe();
+
+ const DictionaryValue* file_systems_paths_value =
+ profile_->GetPrefs()->GetDictionary(prefs::kDevToolsFileSystemPaths);
+ if (file_systems_paths_value->HasKey(file_system_path)) {
+ callback.Run(FileSystem());
+ return;
+ }
+
string16 message = l10n_util::GetStringFUTF16(
IDS_DEV_TOOLS_CONFIRM_ADD_FILE_SYSTEM_MESSAGE,
- UTF8ToUTF16(path.AsUTF8Unsafe() + "/"));
+ UTF8ToUTF16(file_system_path + "/"));
show_info_bar_callback.Run(
message,
Bind(&DevToolsFileHelper::AddUserConfirmedFileSystem,
diff --git a/chrome/browser/devtools/devtools_sanity_browsertest.cc b/chrome/browser/devtools/devtools_sanity_browsertest.cc
index 3abe937..4905f6e 100644
--- a/chrome/browser/devtools/devtools_sanity_browsertest.cc
+++ b/chrome/browser/devtools/devtools_sanity_browsertest.cc
@@ -47,6 +47,10 @@
#include "net/socket/tcp_listen_socket.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
using content::BrowserThread;
using content::DevToolsManager;
using content::DevToolsAgentHost;
@@ -474,12 +478,6 @@
RunTest("testContentScriptIsPresent", kPageWithContentScript);
}
-// Tests that renderer process native memory is feasible.
-IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
- DISABLED_TestRendererProcessNativeMemorySize) {
- RunTest("testRendererProcessNativeMemorySize", std::string());
-}
-
// Tests that scripts are not duplicated after Scripts Panel switch.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
TestNoScriptDuplicatesOnPanelSwitch) {
@@ -597,6 +595,12 @@
#endif
// Flakily fails with 25s timeout: http://crbug.com/89845
IN_PROC_BROWSER_TEST_F(WorkerDevToolsSanityTest, MAYBE_InspectSharedWorker) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
RunTest("testSharedWorker", kSharedWorkerTestPage);
}
@@ -658,6 +662,12 @@
};
IN_PROC_BROWSER_TEST_F(RemoteDebuggingTest, RemoteDebugger) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
ASSERT_TRUE(RunExtensionTest("target_list")) << message_;
}
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc
index 6125d22..b07cba9 100644
--- a/chrome/browser/download/download_browsertest.cc
+++ b/chrome/browser/download/download_browsertest.cc
@@ -65,7 +65,6 @@
#include "content/public/browser/download_save_info.h"
#include "content/public/browser/download_url_parameters.h"
#include "content/public/browser/notification_source.h"
-#include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/web_contents.h"
@@ -83,7 +82,10 @@
#include "net/test/spawned_test_server/spawned_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
-#include "webkit/plugins/npapi/mock_plugin_list.h"
+
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
using content::BrowserContext;
using content::BrowserThread;
@@ -473,6 +475,10 @@
file_activity_observer_.reset();
}
+ virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+ command_line->AppendSwitch(switches::kDisablePluginsDiscovery);
+ }
+
// Returning false indicates a failure of the setup, and should be asserted
// in the caller.
virtual bool InitialSetup() {
@@ -1850,12 +1856,6 @@
base::FilePath file(FILE_PATH_LITERAL("downloads/dangerous/dangerous.swf"));
GURL download_url(URLRequestMockHTTPJob::GetMockUrl(file));
- // Null out plugins so that flash plugin won't interfere with testing.
-#if defined(ENABLE_PLUGINS)
- webkit::npapi::MockPluginList plugin_list;
- content::PluginService::GetInstance()->SetPluginListForTesting(&plugin_list);
-#endif
-
// Download the url and wait until the object has been stored.
scoped_ptr<content::DownloadTestObserver> download_observer(
new content::DownloadTestObserverTerminal(
@@ -2776,6 +2776,12 @@
// Verify the multiple downloads infobar.
IN_PROC_BROWSER_TEST_F(DownloadTest, TestMultipleDownloadsInfobar) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
ASSERT_TRUE(test_server()->Start());
// Create a downloads observer.
diff --git a/chrome/browser/download/download_crx_util.cc b/chrome/browser/download/download_crx_util.cc
index 1f71a88..06e8b18 100644
--- a/chrome/browser/download/download_crx_util.cc
+++ b/chrome/browser/download/download_crx_util.cc
@@ -16,9 +16,9 @@
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/host_desktop.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/extensions/user_script.h"
#include "content/public/browser/download_item.h"
#include "content/public/browser/notification_service.h"
+#include "extensions/common/user_script.h"
using content::BrowserThread;
using content::DownloadItem;
diff --git a/chrome/browser/download/download_danger_prompt.cc b/chrome/browser/download/download_danger_prompt.cc
index bdd75cc..d75c6cc 100644
--- a/chrome/browser/download/download_danger_prompt.cc
+++ b/chrome/browser/download/download_danger_prompt.cc
@@ -22,7 +22,6 @@
public TabModalConfirmDialogDelegate {
public:
DownloadDangerPromptImpl(content::DownloadItem* item,
- content::WebContents* web_contents,
bool show_context,
const base::Closure& accepted,
const base::Closure& canceled);
@@ -63,12 +62,10 @@
DownloadDangerPromptImpl::DownloadDangerPromptImpl(
content::DownloadItem* download,
- content::WebContents* web_contents,
bool show_context,
const base::Closure& accepted,
const base::Closure& canceled)
- : TabModalConfirmDialogDelegate(web_contents),
- download_(download),
+ : download_(download),
show_context_(show_context),
accepted_(accepted),
canceled_(canceled) {
@@ -175,7 +172,7 @@
const base::Closure& accepted,
const base::Closure& canceled) {
DownloadDangerPromptImpl* prompt = new DownloadDangerPromptImpl(
- item, web_contents, show_context, accepted, canceled);
+ item, show_context, accepted, canceled);
// |prompt| will be deleted when the dialog is done.
TabModalConfirmDialog::Create(prompt, web_contents);
return prompt;
diff --git a/chrome/browser/download/download_item_model.cc b/chrome/browser/download/download_item_model.cc
index ec11fc0..f8dc3db 100644
--- a/chrome/browser/download/download_item_model.cc
+++ b/chrome/browser/download/download_item_model.cc
@@ -402,28 +402,39 @@
}
bool DownloadItemModel::ShouldRemoveFromShelfWhenComplete() const {
- // If the download was already opened automatically, it should be removed.
- if (download_->GetAutoOpened())
- return true;
+ switch (download_->GetState()) {
+ case DownloadItem::IN_PROGRESS:
+ // If the download is dangerous or malicious, we should display a warning
+ // on the shelf until the user accepts the download.
+ if (IsDangerous())
+ return false;
- // If the download is interrupted or cancelled, it should not be removed.
- DownloadItem::DownloadState state = download_->GetState();
- if (state == DownloadItem::INTERRUPTED || state == DownloadItem::CANCELLED)
- return false;
+ // If the download is an extension, temporary, or will be opened
+ // automatically, then it should be removed from the shelf on completion.
+ // TODO(asanka): The logic for deciding opening behavior should be in a
+ // central location. http://crbug.com/167702
+ return (download_crx_util::IsExtensionDownload(*download_) ||
+ download_->IsTemporary() ||
+ download_->GetOpenWhenComplete() ||
+ download_->ShouldOpenFileBasedOnExtension());
- // If the download is dangerous or malicious, we should display a warning on
- // the shelf until the user accepts the download.
- if (IsDangerous())
- return false;
+ case DownloadItem::COMPLETE:
+ // If the download completed, then rely on GetAutoOpened() to check for
+ // opening behavior. This should accurately reflect whether the download
+ // was successfully opened. Extensions, for example, may fail to open.
+ return download_->GetAutoOpened() || download_->IsTemporary();
- // If the download is an extension, temporary, or will be opened
- // automatically, then it should be removed from the shelf on completion.
- // TODO(asanka): The logic for deciding opening behavior should be in a
- // central location. http://crbug.com/167702
- return (download_crx_util::IsExtensionDownload(*download_) ||
- download_->IsTemporary() ||
- download_->GetOpenWhenComplete() ||
- download_->ShouldOpenFileBasedOnExtension());
+ case DownloadItem::CANCELLED:
+ case DownloadItem::INTERRUPTED:
+ // Interrupted or cancelled downloads should remain on the shelf.
+ return false;
+
+ case DownloadItem::MAX_DOWNLOAD_STATE:
+ NOTREACHED();
+ }
+
+ NOTREACHED();
+ return false;
}
bool DownloadItemModel::ShouldShowDownloadStartedAnimation() const {
diff --git a/chrome/browser/download/download_item_model_unittest.cc b/chrome/browser/download/download_item_model_unittest.cc
index 807a32a..4dbf072 100644
--- a/chrome/browser/download/download_item_model_unittest.cc
+++ b/chrome/browser/download/download_item_model_unittest.cc
@@ -12,6 +12,7 @@
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "chrome/common/extensions/extension.h"
#include "content/public/test/mock_download_item.h"
#include "grit/generated_resources.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -358,30 +359,35 @@
TEST_F(DownloadItemModelTest, ShouldRemoveFromShelfWhenComplete) {
const struct TestCase {
DownloadItem::DownloadState state;
- bool is_dangerous;
- bool is_auto_open; // Either an extension install, temporary, open when
- // complete or open based on extension.
+ bool is_dangerous; // Expectation for IsDangerous().
+ bool is_auto_open; // Expectation for GetOpenWhenComplete().
+ bool auto_opened; // Whether the download was successfully
+ // auto-opened. Expecation for GetAutoOpened().
bool expected_result;
} kTestCases[] = {
- // All the valid combinations of state, is_dangerous and is_auto_open.
+ // All the valid combinations of state, is_dangerous, is_auto_open and
+ // auto_opened.
//
// .--- Is dangerous.
// | .--- Auto open or temporary.
- // | | .--- Expected result.
- { DownloadItem::IN_PROGRESS, false, false, false },
- { DownloadItem::IN_PROGRESS, false, true , true },
- { DownloadItem::IN_PROGRESS, true , false, false },
- { DownloadItem::IN_PROGRESS, true , true , false },
- { DownloadItem::COMPLETE, false, false, false },
- { DownloadItem::COMPLETE, false, true , true },
- { DownloadItem::CANCELLED, false, false, false },
- { DownloadItem::CANCELLED, false, true , false },
- { DownloadItem::CANCELLED, true , false, false },
- { DownloadItem::CANCELLED, true , true , false },
- { DownloadItem::INTERRUPTED, false, false, false },
- { DownloadItem::INTERRUPTED, false, true , false },
- { DownloadItem::INTERRUPTED, true , false, false },
- { DownloadItem::INTERRUPTED, true , true , false }
+ // | | .--- Auto opened.
+ // | | | .--- Expected result.
+ { DownloadItem::IN_PROGRESS, false, false, false, false},
+ { DownloadItem::IN_PROGRESS, false, true , false, true },
+ { DownloadItem::IN_PROGRESS, true , false, false, false},
+ { DownloadItem::IN_PROGRESS, true , true , false, false},
+ { DownloadItem::COMPLETE, false, false, false, false},
+ { DownloadItem::COMPLETE, false, true , false, false},
+ { DownloadItem::COMPLETE, false, false, true , true },
+ { DownloadItem::COMPLETE, false, true , true , true },
+ { DownloadItem::CANCELLED, false, false, false, false},
+ { DownloadItem::CANCELLED, false, true , false, false},
+ { DownloadItem::CANCELLED, true , false, false, false},
+ { DownloadItem::CANCELLED, true , true , false, false},
+ { DownloadItem::INTERRUPTED, false, false, false, false},
+ { DownloadItem::INTERRUPTED, false, true , false, false},
+ { DownloadItem::INTERRUPTED, true , false, false, false},
+ { DownloadItem::INTERRUPTED, true , true , false, false}
};
SetupDownloadItemDefaults();
@@ -394,6 +400,8 @@
.WillRepeatedly(Return(test_case.state));
EXPECT_CALL(item(), IsDangerous())
.WillRepeatedly(Return(test_case.is_dangerous));
+ EXPECT_CALL(item(), GetAutoOpened())
+ .WillRepeatedly(Return(test_case.auto_opened));
EXPECT_EQ(test_case.expected_result,
model().ShouldRemoveFromShelfWhenComplete())
diff --git a/chrome/browser/download/download_request_infobar_delegate.h b/chrome/browser/download/download_request_infobar_delegate.h
index 815e3ca..410f91f 100644
--- a/chrome/browser/download/download_request_infobar_delegate.h
+++ b/chrome/browser/download/download_request_infobar_delegate.h
@@ -23,15 +23,13 @@
base::WeakPtr<DownloadRequestLimiter::TabDownloadState> host)>
FakeCreateCallback;
+ virtual ~DownloadRequestInfoBarDelegate();
+
// Creates a download request delegate and adds it to |infobar_service|.
static void Create(
InfoBarService* infobar_service,
base::WeakPtr<DownloadRequestLimiter::TabDownloadState> host);
- static void SetCallbackForTesting(FakeCreateCallback* callback);
-
- virtual ~DownloadRequestInfoBarDelegate();
-
#if defined(UNIT_TEST)
static scoped_ptr<DownloadRequestInfoBarDelegate> Create(
base::WeakPtr<DownloadRequestLimiter::TabDownloadState> host) {
@@ -40,6 +38,8 @@
}
#endif
+ static void SetCallbackForTesting(FakeCreateCallback* callback);
+
private:
static FakeCreateCallback* callback_;
diff --git a/chrome/browser/download/download_shelf_unittest.cc b/chrome/browser/download/download_shelf_unittest.cc
index 2280173..3a16773 100644
--- a/chrome/browser/download/download_shelf_unittest.cc
+++ b/chrome/browser/download/download_shelf_unittest.cc
@@ -151,6 +151,8 @@
EXPECT_CALL(*download_item(), GetState())
.WillRepeatedly(Return(DownloadItem::COMPLETE));
+ EXPECT_CALL(*download_item(), GetAutoOpened())
+ .WillRepeatedly(Return(true));
base::RunLoop run_loop;
run_loop.RunUntilIdle();
diff --git a/chrome/browser/download/download_util.h b/chrome/browser/download/download_util.h
index e5e9a60..7900868 100644
--- a/chrome/browser/download/download_util.h
+++ b/chrome/browser/download/download_util.h
@@ -183,6 +183,9 @@
// The download was initiated by the plugin installer.
INITIATED_BY_PLUGIN_INSTALLER,
+ // The download was initiated by the PDF plugin..
+ INITIATED_BY_PDF_SAVE,
+
CHROME_DOWNLOAD_SOURCE_LAST_ENTRY,
};
diff --git a/chrome/browser/extensions/active_tab_permission_granter.cc b/chrome/browser/extensions/active_tab_permission_granter.cc
index 97440e2..312a6c3 100644
--- a/chrome/browser/extensions/active_tab_permission_granter.cc
+++ b/chrome/browser/extensions/active_tab_permission_granter.cc
@@ -13,13 +13,13 @@
#include "chrome/common/extensions/extension_messages.h"
#include "chrome/common/extensions/permissions/permission_set.h"
#include "chrome/common/extensions/permissions/permissions_data.h"
-#include "chrome/common/extensions/user_script.h"
-#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_details.h"
+#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
+#include "extensions/common/user_script.h"
using content::RenderProcessHost;
using content::WebContentsObserver;
diff --git a/chrome/browser/extensions/activity_log/activity_actions.cc b/chrome/browser/extensions/activity_log/activity_actions.cc
index 2e87663..93e9b68 100644
--- a/chrome/browser/extensions/activity_log/activity_actions.cc
+++ b/chrome/browser/extensions/activity_log/activity_actions.cc
@@ -3,18 +3,30 @@
// found in the LICENSE file.
#include <string>
+#include "base/json/json_string_value_serializer.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/extensions/activity_log/activity_actions.h"
+namespace {
+
+std::string Serialize(const base::Value* value) {
+ std::string value_as_text;
+ if (!value) {
+ value_as_text = "null";
+ } else {
+ JSONStringValueSerializer serializer(&value_as_text);
+ serializer.SerializeAndOmitBinaryValues(*value);
+ }
+ return value_as_text;
+}
+
+} // namespace
+
namespace extensions {
using api::activity_log_private::ExtensionActivity;
-const char* Action::kTableBasicFields =
- "extension_id LONGVARCHAR NOT NULL, "
- "time INTEGER NOT NULL";
-
Action::Action(const std::string& extension_id,
const base::Time& time,
ExtensionActivity::ActivityType activity_type)
@@ -22,40 +34,83 @@
time_(time),
activity_type_(activity_type) {}
-// static
-bool Action::InitializeTableInternal(sql::Connection* db,
- const char* table_name,
- const char* content_fields[],
- const char* field_types[],
- const int num_content_fields) {
- if (!db->DoesTableExist(table_name)) {
- std::string table_creator = base::StringPrintf(
- "CREATE TABLE %s (%s", table_name, kTableBasicFields);
- for (int i = 0; i < num_content_fields; i++) {
- table_creator += base::StringPrintf(", %s %s",
- content_fields[i],
- field_types[i]);
- }
- table_creator += ")";
- if (!db->Execute(table_creator.c_str()))
- return false;
- } else {
- // In case we ever want to add new fields, this initializes them to be
- // empty strings.
- for (int i = 0; i < num_content_fields; i++) {
- if (!db->DoesColumnExist(table_name, content_fields[i])) {
- std::string table_updater = base::StringPrintf(
- "ALTER TABLE %s ADD COLUMN %s %s; ",
- table_name,
- content_fields[i],
- field_types[i]);
- if (!db->Execute(table_updater.c_str()))
- return false;
- }
- }
- }
+WatchdogAction::WatchdogAction(const std::string& extension_id,
+ const base::Time& time,
+ const ActionType action_type,
+ const std::string& api_name,
+ scoped_ptr<ListValue> args,
+ const GURL& page_url,
+ const GURL& arg_url,
+ scoped_ptr<DictionaryValue> other)
+ : Action(extension_id, time, ExtensionActivity::ACTIVITY_TYPE_CHROME),
+ action_type_(action_type),
+ api_name_(api_name),
+ args_(args.Pass()),
+ page_url_(page_url),
+ arg_url_(arg_url),
+ other_(other.Pass()) {}
+
+WatchdogAction::~WatchdogAction() {}
+
+bool WatchdogAction::Record(sql::Connection* db) {
+ // This methods isn't used and will go away entirely soon once database
+ // writing moves to the policy objects.
+ NOTREACHED();
return true;
}
-} // namespace extensions
+scoped_ptr<api::activity_log_private::ExtensionActivity>
+WatchdogAction::ConvertToExtensionActivity() {
+ scoped_ptr<api::activity_log_private::ExtensionActivity> result;
+ return result.Pass();
+}
+std::string WatchdogAction::PrintForDebug() {
+ std::string result = "ID=" + extension_id() + " CATEGORY=";
+ switch (action_type_) {
+ case ACTION_API_CALL:
+ result += "api_call";
+ break;
+ case ACTION_API_EVENT:
+ result += "api_event_callback";
+ break;
+ case ACTION_WEB_REQUEST:
+ result += "webrequest";
+ break;
+ case ACTION_CONTENT_SCRIPT:
+ result += "content_script";
+ break;
+ case ACTION_API_BLOCKED:
+ result += "api_blocked";
+ break;
+ case ACTION_DOM_EVENT:
+ result += "dom_event";
+ break;
+ case ACTION_DOM_XHR:
+ result += "dom_xhr";
+ break;
+ case ACTION_DOM_ACCESS:
+ result += "dom_access";
+ break;
+ default:
+ result += base::StringPrintf("type%d", static_cast<int>(action_type_));
+ }
+
+ result += " API=" + api_name_;
+ if (args_.get()) {
+ result += " ARGS=" + Serialize(args_.get());
+ }
+ if (page_url_.is_valid()) {
+ result += " PAGE_URL=" + page_url_.spec();
+ }
+ if (arg_url_.is_valid()) {
+ result += " ARG_URL=" + arg_url_.spec();
+ }
+ if (other_.get()) {
+ result += " OTHER=" + Serialize(other_.get());
+ }
+
+ return result;
+}
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/activity_log/activity_actions.h b/chrome/browser/extensions/activity_log/activity_actions.h
index 2a5d636..22a242b 100644
--- a/chrome/browser/extensions/activity_log/activity_actions.h
+++ b/chrome/browser/extensions/activity_log/activity_actions.h
@@ -13,6 +13,7 @@
#include "sql/connection.h"
#include "sql/statement.h"
#include "sql/transaction.h"
+#include "url/gurl.h"
namespace extensions {
@@ -20,10 +21,18 @@
// the activity log.
class Action : public base::RefCountedThreadSafe<Action> {
public:
- static const char* kTableBasicFields;
-
- // Initialize the table for a given action type.
- static bool InitializeTableInternal(sql::Connection* db);
+ // Types of log entries that can be stored. The numeric values are stored in
+ // the database, so keep them stable. Append values only.
+ enum ActionType {
+ ACTION_API_CALL = 0,
+ ACTION_API_EVENT = 1,
+ ACTION_API_BLOCKED = 2,
+ ACTION_CONTENT_SCRIPT = 3,
+ ACTION_DOM_ACCESS = 4,
+ ACTION_DOM_EVENT = 5,
+ ACTION_DOM_XHR = 6,
+ ACTION_WEB_REQUEST = 7,
+ };
// Record the action in the database.
virtual bool Record(sql::Connection* db) = 0;
@@ -46,17 +55,6 @@
api::activity_log_private::ExtensionActivity::ActivityType type);
virtual ~Action() {}
- // Initialize the table for a given action type.
- // The content_fields array should list the names of all of the columns in
- // the database. The field_types should specify the types of the corresponding
- // columns (e.g., INTEGER or LONGVARCHAR). There should be the same number of
- // field_types as content_fields, since the two arrays should correspond.
- static bool InitializeTableInternal(sql::Connection* db,
- const char* table_name,
- const char* content_fields[],
- const char* field_types[],
- const int num_content_fields);
-
private:
friend class base::RefCountedThreadSafe<Action>;
@@ -67,6 +65,38 @@
DISALLOW_COPY_AND_ASSIGN(Action);
};
+// TODO(mvrable): This is a temporary class used to represent Actions which
+// have been loaded from the SQLite database. Soon the entire Action hierarchy
+// will be flattened out as the type-specific classes are eliminated, at which
+// time some of the logic here will be moved.
+class WatchdogAction : public Action {
+ public:
+ WatchdogAction(const std::string& extension_id,
+ const base::Time& time,
+ const ActionType action_type,
+ const std::string& api_name, // full method name
+ scoped_ptr<ListValue> args, // the argument list
+ const GURL& page_url, // page the action occurred on
+ const GURL& arg_url, // URL extracted from the argument list
+ scoped_ptr<DictionaryValue> other); // any extra logging info
+
+ virtual bool Record(sql::Connection* db) OVERRIDE;
+ virtual scoped_ptr<api::activity_log_private::ExtensionActivity>
+ ConvertToExtensionActivity() OVERRIDE;
+ virtual std::string PrintForDebug() OVERRIDE;
+
+ protected:
+ virtual ~WatchdogAction();
+
+ private:
+ ActionType action_type_;
+ std::string api_name_;
+ scoped_ptr<ListValue> args_;
+ GURL page_url_;
+ GURL arg_url_;
+ scoped_ptr<DictionaryValue> other_;
+};
+
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_ACTIONS_H_
diff --git a/chrome/browser/extensions/activity_log/activity_database.cc b/chrome/browser/extensions/activity_log/activity_database.cc
index 9770937..1a644b8 100644
--- a/chrome/browser/extensions/activity_log/activity_database.cc
+++ b/chrome/browser/extensions/activity_log/activity_database.cc
@@ -4,6 +4,7 @@
#include <string>
#include "base/command_line.h"
+#include "base/json/json_reader.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
@@ -12,6 +13,7 @@
#include "base/time/clock.h"
#include "base/time/time.h"
#include "chrome/browser/extensions/activity_log/activity_database.h"
+#include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
#include "chrome/common/chrome_switches.h"
#include "sql/error_delegate_util.h"
#include "sql/transaction.h"
@@ -160,44 +162,45 @@
early_bound = early_time.ToInternalValue();
late_bound = late_time.ToInternalValue();
}
- // Get the DOMActions.
- std::string dom_str = base::StringPrintf("SELECT * FROM %s "
- "WHERE extension_id=? AND "
- "time>? AND time<=?",
- DOMAction::kTableName);
- sql::Statement dom_statement(db_.GetCachedStatement(SQL_FROM_HERE,
- dom_str.c_str()));
- dom_statement.BindString(0, extension_id);
- dom_statement.BindInt64(1, early_bound);
- dom_statement.BindInt64(2, late_bound);
- while (dom_statement.is_valid() && dom_statement.Step()) {
- actions->push_back(new DOMAction(dom_statement));
- }
- // Get the APIActions.
- std::string api_str = base::StringPrintf("SELECT * FROM %s "
- "WHERE extension_id=? AND "
- "time>? AND time<=?",
- APIAction::kTableName);
- sql::Statement api_statement(db_.GetCachedStatement(SQL_FROM_HERE,
- api_str.c_str()));
- api_statement.BindString(0, extension_id);
- api_statement.BindInt64(1, early_bound);
- api_statement.BindInt64(2, late_bound);
- while (api_statement.is_valid() && api_statement.Step()) {
- actions->push_back(new APIAction(api_statement));
- }
- // Get the BlockedActions.
- std::string blocked_str = base::StringPrintf("SELECT * FROM %s "
- "WHERE extension_id=? AND "
- "time>? AND time<=?",
- BlockedAction::kTableName);
- sql::Statement blocked_statement(db_.GetCachedStatement(SQL_FROM_HERE,
- blocked_str.c_str()));
- blocked_statement.BindString(0, extension_id);
- blocked_statement.BindInt64(1, early_bound);
- blocked_statement.BindInt64(2, late_bound);
- while (blocked_statement.is_valid() && blocked_statement.Step()) {
- actions->push_back(new BlockedAction(blocked_statement));
+ std::string query_str = base::StringPrintf(
+ "SELECT time, action_type, api_name, args, page_url, arg_url, other "
+ "FROM %s WHERE extension_id=? AND time>? AND time<=?",
+ FullStreamUIPolicy::kTableName);
+ sql::Statement query(db_.GetCachedStatement(SQL_FROM_HERE,
+ query_str.c_str()));
+ query.BindString(0, extension_id);
+ query.BindInt64(1, early_bound);
+ query.BindInt64(2, late_bound);
+ while (query.is_valid() && query.Step()) {
+ scoped_ptr<Value> raw_value(base::JSONReader::Read(query.ColumnString(3)));
+ scoped_ptr<ListValue> args;
+ if (raw_value && raw_value->IsType(Value::TYPE_LIST)) {
+ args.reset(static_cast<ListValue*>(raw_value.release()));
+ } else {
+ args.reset(new ListValue());
+ }
+
+ GURL page_url(query.ColumnString(4));
+ GURL arg_url(query.ColumnString(5));
+
+ raw_value.reset(base::JSONReader::Read(query.ColumnString(6)));
+ scoped_ptr<DictionaryValue> other;
+ if (raw_value && raw_value->IsType(Value::TYPE_DICTIONARY)) {
+ other.reset(static_cast<DictionaryValue*>(raw_value.release()));
+ } else {
+ other.reset(new DictionaryValue());
+ }
+
+ scoped_refptr<WatchdogAction> action =
+ new WatchdogAction(extension_id,
+ base::Time::FromInternalValue(query.ColumnInt64(0)),
+ static_cast<Action::ActionType>(query.ColumnInt(1)),
+ query.ColumnString(2),
+ args.Pass(),
+ page_url,
+ arg_url,
+ other.Pass());
+ actions->push_back(action);
}
// Sort by time (from newest to oldest).
std::sort(actions->begin(), actions->end(), SortActionsByTime);
@@ -260,4 +263,40 @@
&ActivityDatabase::RecordBatchedActionsWhileTesting);
}
+// static
+bool ActivityDatabase::InitializeTable(sql::Connection* db,
+ const char* table_name,
+ const char* content_fields[],
+ const char* field_types[],
+ const int num_content_fields) {
+ if (!db->DoesTableExist(table_name)) {
+ std::string table_creator =
+ base::StringPrintf("CREATE TABLE %s (", table_name);
+ for (int i = 0; i < num_content_fields; i++) {
+ table_creator += base::StringPrintf("%s%s %s",
+ i == 0 ? "" : ", ",
+ content_fields[i],
+ field_types[i]);
+ }
+ table_creator += ")";
+ if (!db->Execute(table_creator.c_str()))
+ return false;
+ } else {
+ // In case we ever want to add new fields, this initializes them to be
+ // empty strings.
+ for (int i = 0; i < num_content_fields; i++) {
+ if (!db->DoesColumnExist(table_name, content_fields[i])) {
+ std::string table_updater = base::StringPrintf(
+ "ALTER TABLE %s ADD COLUMN %s %s; ",
+ table_name,
+ content_fields[i],
+ field_types[i]);
+ if (!db->Execute(table_updater.c_str()))
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
} // namespace extensions
diff --git a/chrome/browser/extensions/activity_log/activity_database.h b/chrome/browser/extensions/activity_log/activity_database.h
index e646840..6c3c554 100644
--- a/chrome/browser/extensions/activity_log/activity_database.h
+++ b/chrome/browser/extensions/activity_log/activity_database.h
@@ -97,18 +97,9 @@
// update the database schema if needed.
void Init(const base::FilePath& db_name);
- // The ActivityLog should call this to kill the ActivityDatabase.
+ // An ActivityLogPolicy should call this to kill the ActivityDatabase.
void Close();
- // Record a DOMAction in the database.
- void RecordDOMAction(scoped_refptr<DOMAction> action);
-
- // Record an APIAction in the database.
- void RecordAPIAction(scoped_refptr<APIAction> action);
-
- // Record a BlockedAction in the database.
- void RecordBlockedAction(scoped_refptr<BlockedAction> action);
-
// Record an Action in the database.
void RecordAction(scoped_refptr<Action> action);
@@ -125,19 +116,27 @@
bool is_db_valid() const { return valid_db_; }
+ // A helper method for initializing or upgrading a database table. The
+ // content_fields array should list the names of all of the columns in the
+ // database. The field_types should specify the types of the corresponding
+ // columns (e.g., INTEGER or LONGVARCHAR). There should be the same number of
+ // field_types as content_fields, since the two arrays should correspond.
+ static bool InitializeTable(sql::Connection* db,
+ const char* table_name,
+ const char* content_fields[],
+ const char* field_types[],
+ const int num_content_fields);
+
private:
// This should never be invoked by another class. Use Close() to order a
// suicide.
virtual ~ActivityDatabase();
- // Used by the Init() method as a convenience for handling a failied
- // database initialization attempt. Prints an error and puts us in the soft
- // failure state.
+ // Used by the Init() method as a convenience for handling a failed database
+ // initialization attempt. Prints an error and puts us in the soft failure
+ // state.
void LogInitFailure();
- sql::InitStatus InitializeTable(const char* table_name,
- const char* table_structure);
-
// When we're in batched mode (which is on by default), we write to the db
// every X minutes instead of on every API call. This prevents the annoyance
// of writing to disk multiple times a second.
diff --git a/chrome/browser/extensions/activity_log/activity_database_unittest.cc b/chrome/browser/extensions/activity_log/activity_database_unittest.cc
index 3fd040bf..1add2ff 100644
--- a/chrome/browser/extensions/activity_log/activity_database_unittest.cc
+++ b/chrome/browser/extensions/activity_log/activity_database_unittest.cc
@@ -14,6 +14,7 @@
#include "chrome/browser/extensions/activity_log/api_actions.h"
#include "chrome/browser/extensions/activity_log/blocked_actions.h"
#include "chrome/browser/extensions/activity_log/dom_actions.h"
+#include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/test_extension_system.h"
#include "chrome/common/chrome_constants.h"
@@ -47,10 +48,12 @@
protected:
virtual bool OnDatabaseInit(sql::Connection* db) OVERRIDE {
- if (!DOMAction::InitializeTable(db)) return false;
- if (!APIAction::InitializeTable(db)) return false;
- if (!BlockedAction::InitializeTable(db)) return false;
- return true;
+ return ActivityDatabase::InitializeTable(
+ db,
+ FullStreamUIPolicy::kTableName,
+ FullStreamUIPolicy::kTableContentFields,
+ FullStreamUIPolicy::kTableFieldTypes,
+ FullStreamUIPolicy::kTableFieldCount);
}
// Called by ActivityDatabase just before the ActivityDatabase object is
@@ -112,9 +115,7 @@
sql::Connection db;
ASSERT_TRUE(db.Open(db_file));
- ASSERT_TRUE(db.DoesTableExist(DOMAction::kTableName));
- ASSERT_TRUE(db.DoesTableExist(APIAction::kTableName));
- ASSERT_TRUE(db.DoesTableExist(BlockedAction::kTableName));
+ ASSERT_TRUE(db.DoesTableExist(FullStreamUIPolicy::kTableName));
db.Close();
}
@@ -128,12 +129,15 @@
ActivityDatabase* activity_db = OpenDatabase(db_file);
activity_db->SetBatchModeForTesting(false);
+ base::ListValue args_list;
+ args_list.AppendString("woof");
scoped_refptr<APIAction> action = new APIAction(
"punky",
base::Time::Now(),
APIAction::CALL,
"brewster",
"woof",
+ args_list,
"extra");
activity_db->RecordAction(action);
activity_db->Close();
@@ -141,15 +145,15 @@
sql::Connection db;
ASSERT_TRUE(db.Open(db_file));
- ASSERT_TRUE(db.DoesTableExist(APIAction::kTableName));
+ ASSERT_TRUE(db.DoesTableExist(FullStreamUIPolicy::kTableName));
std::string sql_str = "SELECT * FROM " +
- std::string(APIAction::kTableName);
+ std::string(FullStreamUIPolicy::kTableName);
sql::Statement statement(db.GetUniqueStatement(sql_str.c_str()));
ASSERT_TRUE(statement.Step());
ASSERT_EQ("punky", statement.ColumnString(0));
- ASSERT_EQ(0, statement.ColumnInt(2));
+ ASSERT_EQ(static_cast<int>(Action::ACTION_API_CALL), statement.ColumnInt(2));
ASSERT_EQ("brewster", statement.ColumnString(3));
- ASSERT_EQ("woof", statement.ColumnString(4));
+ ASSERT_EQ("[\"woof\"]", statement.ColumnString(4));
}
// Check that DOM actions are recorded in the db.
@@ -177,22 +181,26 @@
sql::Connection db;
ASSERT_TRUE(db.Open(db_file));
- ASSERT_TRUE(db.DoesTableExist(APIAction::kTableName));
+ ASSERT_TRUE(db.DoesTableExist(FullStreamUIPolicy::kTableName));
std::string sql_str = "SELECT * FROM " +
- std::string(DOMAction::kTableName);
+ std::string(FullStreamUIPolicy::kTableName);
sql::Statement statement(db.GetUniqueStatement(sql_str.c_str()));
ASSERT_TRUE(statement.Step());
ASSERT_EQ("punky", statement.ColumnString(0));
- ASSERT_EQ(DomActionType::MODIFIED, statement.ColumnInt(2));
- ASSERT_EQ("http://www.google.com", statement.ColumnString(3));
+ ASSERT_EQ(static_cast<int>(Action::ACTION_DOM_ACCESS),
+ statement.ColumnInt(2));
+ // TODO(mvrable): This test doesn't work properly, due to crbug.com/260784
+ // This will be fixed when URL sanitization is moved into the activity log
+ // policies in some upcoming code refactoring.
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableExtensionActivityLogTesting))
- ASSERT_EQ("/foo?bar", statement.ColumnString(4));
+ ASSERT_EQ("http://www.google.com/foo?bar", statement.ColumnString(5));
else
- ASSERT_EQ("/foo", statement.ColumnString(4));
- ASSERT_EQ("lets", statement.ColumnString(6));
- ASSERT_EQ("vamoose", statement.ColumnString(7));
- ASSERT_EQ("extra", statement.ColumnString(8));
+ ASSERT_EQ("http://www.google.com/foo", statement.ColumnString(5));
+ ASSERT_EQ("lets", statement.ColumnString(3));
+ ASSERT_EQ("[\"vamoose\"]", statement.ColumnString(4));
+ ASSERT_EQ("{\"dom_verb\":6,\"extra\":\"extra\",\"page_title\":\"\"}",
+ statement.ColumnString(7));
}
// Check that blocked actions are recorded in the db.
@@ -217,16 +225,17 @@
sql::Connection db;
ASSERT_TRUE(db.Open(db_file));
- ASSERT_TRUE(db.DoesTableExist(BlockedAction::kTableName));
+ ASSERT_TRUE(db.DoesTableExist(FullStreamUIPolicy::kTableName));
std::string sql_str = "SELECT * FROM " +
- std::string(BlockedAction::kTableName);
+ std::string(FullStreamUIPolicy::kTableName);
sql::Statement statement(db.GetUniqueStatement(sql_str.c_str()));
ASSERT_TRUE(statement.Step());
ASSERT_EQ("punky", statement.ColumnString(0));
- ASSERT_EQ("do.evilThings", statement.ColumnString(2));
- ASSERT_EQ("1, 2", statement.ColumnString(3));
- ASSERT_EQ(1, statement.ColumnInt(4));
- ASSERT_EQ("extra", statement.ColumnString(5));
+ ASSERT_EQ(static_cast<int>(Action::ACTION_API_BLOCKED),
+ statement.ColumnInt(2));
+ ASSERT_EQ("do.evilThings", statement.ColumnString(3));
+ ASSERT_EQ("1, 2", statement.ColumnString(4));
+ ASSERT_EQ("{\"reason\":1}", statement.ColumnString(7));
}
// Check that we can read back recent actions in the db.
@@ -245,12 +254,15 @@
// Record some actions
ActivityDatabase* activity_db = OpenDatabase(db_file);
+ base::ListValue args_list;
+ args_list.AppendString("woof");
scoped_refptr<APIAction> api_action = new APIAction(
"punky",
mock_clock.Now() - base::TimeDelta::FromMinutes(40),
APIAction::CALL,
"brewster",
"woof",
+ args_list,
"extra");
scoped_refptr<DOMAction> dom_action = new DOMAction(
"punky",
@@ -275,9 +287,12 @@
activity_db->RecordAction(extra_dom_action);
// Read them back
- std::string api_print = "ID: punky, CATEGORY: call, "
- "API: brewster, ARGS: woof";
- std::string dom_print = "DOM API CALL: lets, ARGS: vamoose, VERB: modified";
+ std::string api_print =
+ "ID=punky CATEGORY=api_call API=brewster ARGS=[\"woof\"] OTHER={}";
+ std::string dom_print =
+ "ID=punky CATEGORY=dom_access API=lets ARGS=[\"vamoose\"] "
+ "PAGE_URL=http://www.google.com/ "
+ "OTHER={\"dom_verb\":6,\"extra\":\"extra\",\"page_title\":\"\"}";
scoped_ptr<std::vector<scoped_refptr<Action> > > actions =
activity_db->GetActions("punky", 0);
ASSERT_EQ(2, static_cast<int>(actions->size()));
@@ -303,6 +318,8 @@
// Record some actions
ActivityDatabase* activity_db = OpenDatabase(db_file);
+ base::ListValue args_list;
+ args_list.AppendString("woof");
scoped_refptr<APIAction> api_action = new APIAction(
"punky",
mock_clock.Now() - base::TimeDelta::FromDays(3)
@@ -310,6 +327,7 @@
APIAction::CALL,
"brewster",
"woof",
+ args_list,
"extra");
scoped_refptr<DOMAction> dom_action = new DOMAction(
"punky",
@@ -344,9 +362,12 @@
activity_db->RecordAction(tooold_dom_action);
// Read them back
- std::string api_print = "ID: punky, CATEGORY: call, "
- "API: brewster, ARGS: woof";
- std::string dom_print = "DOM API CALL: lets, ARGS: vamoose, VERB: modified";
+ std::string api_print =
+ "ID=punky CATEGORY=api_call API=brewster ARGS=[\"woof\"] OTHER={}";
+ std::string dom_print =
+ "ID=punky CATEGORY=dom_access API=lets ARGS=[\"vamoose\"] "
+ "PAGE_URL=http://www.google.com/ "
+ "OTHER={\"dom_verb\":6,\"extra\":\"extra\",\"page_title\":\"\"}";
scoped_ptr<std::vector<scoped_refptr<Action> > > actions =
activity_db->GetActions("punky", 3);
ASSERT_EQ(2, static_cast<int>(actions->size()));
@@ -373,12 +394,15 @@
ActivityDatabase* activity_db = OpenDatabase(db_file);
activity_db->SetBatchModeForTesting(false);
activity_db->SetClockForTesting(&mock_clock);
+ base::ListValue args_list;
+ args_list.AppendString("woof");
scoped_refptr<APIAction> api_action = new APIAction(
"punky",
mock_clock.Now() - base::TimeDelta::FromMinutes(40),
APIAction::CALL,
"brewster",
"woof",
+ args_list,
"extra");
activity_db->RecordAction(api_action);
@@ -405,12 +429,15 @@
ActivityDatabase* activity_db = OpenDatabase(db_file);
activity_db->SetBatchModeForTesting(true);
activity_db->SetClockForTesting(&mock_clock);
+ base::ListValue args_list;
+ args_list.AppendString("woof");
scoped_refptr<APIAction> api_action = new APIAction(
"punky",
mock_clock.Now() - base::TimeDelta::FromMinutes(40),
APIAction::CALL,
"brewster",
"woof",
+ args_list,
"extra");
activity_db->RecordAction(api_action);
@@ -439,12 +466,15 @@
ActivityDatabase* activity_db =
new ActivityDatabase(new ActivityDatabaseTestPolicy());
+ base::ListValue args_list;
+ args_list.AppendString("woof");
scoped_refptr<APIAction> action = new APIAction(
"punky",
base::Time::Now(),
APIAction::CALL,
"brewster",
"woooof",
+ args_list,
"extra");
activity_db->RecordAction(action);
activity_db->Close();
diff --git a/chrome/browser/extensions/activity_log/activity_log.cc b/chrome/browser/extensions/activity_log/activity_log.cc
index 7eac24f..4233e12 100644
--- a/chrome/browser/extensions/activity_log/activity_log.cc
+++ b/chrome/browser/extensions/activity_log/activity_log.cc
@@ -289,6 +289,7 @@
type,
api_call,
MakeArgList(args),
+ *args,
extra);
observers_->Notify(&Observer::OnExtensionActivity, action);
diff --git a/chrome/browser/extensions/activity_log/activity_log.h b/chrome/browser/extensions/activity_log/activity_log.h
index 2a4e491..19813c2 100644
--- a/chrome/browser/extensions/activity_log/activity_log.h
+++ b/chrome/browser/extensions/activity_log/activity_log.h
@@ -17,6 +17,7 @@
#include "chrome/browser/extensions/activity_log/activity_actions.h"
#include "chrome/browser/extensions/activity_log/activity_database.h"
#include "chrome/browser/extensions/activity_log/activity_log_policy.h"
+#include "chrome/browser/extensions/activity_log/api_actions.h"
#include "chrome/browser/extensions/install_observer.h"
#include "chrome/browser/extensions/install_tracker.h"
#include "chrome/browser/extensions/tab_helper.h"
diff --git a/chrome/browser/extensions/activity_log/activity_log_browsertest.cc b/chrome/browser/extensions/activity_log/activity_log_browsertest.cc
index 6bb158f..db573c1 100644
--- a/chrome/browser/extensions/activity_log/activity_log_browsertest.cc
+++ b/chrome/browser/extensions/activity_log/activity_log_browsertest.cc
@@ -34,7 +34,9 @@
switches::kPrerenderModeSwitchValueEnabled);
}
- static void Prerender_Arguments(int port,
+ static void Prerender_Arguments(
+ const std::string& extension_id,
+ int port,
scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
// This is to exit RunLoop (base::MessageLoop::current()->Run()) below
base::MessageLoop::current()->PostTask(
@@ -44,9 +46,11 @@
scoped_refptr<Action> last = i->front();
std::string args = base::StringPrintf(
- "Injected scripts (\"/google_cs.js \") "
- "onto http://www.google.com.bo:%d/test.html (prerender)",
- port);
+ "ID=%s CATEGORY=content_script API= ARGS=[\"\\\"/google_cs.js \\\"\"] "
+ "PAGE_URL=http://www.google.com.bo:%d/test.html "
+ "OTHER={\"dom_verb\":3,\"extra\":\"(prerender)\",\"page_title\":\"www."
+ "google.com.bo:%d/test.html\"}",
+ extension_id.c_str(), port, port);
// TODO: Replace PrintForDebug with field testing
// when this feature will be available
ASSERT_EQ(args, last->PrintForDebug());
@@ -91,14 +95,14 @@
scoped_ptr<prerender::PrerenderHandle> prerender_handle(
prerender_manager->AddPrerenderFromLocalPredictor(
url,
- web_contents->GetController().GetSessionStorageNamespace(),
+ web_contents->GetController().GetDefaultSessionStorageNamespace(),
kSize));
page_observer.Wait();
activity_log->GetActions(
ext->id(), 0, base::Bind(
- ActivityLogPrerenderTest::Prerender_Arguments, port));
+ ActivityLogPrerenderTest::Prerender_Arguments, ext->id(), port));
// Allow invocation of Prerender_Arguments
base::MessageLoop::current()->Run();
diff --git a/chrome/browser/extensions/activity_log/activity_log_unittest.cc b/chrome/browser/extensions/activity_log/activity_log_unittest.cc
index e9f2c3e..4a7958e 100644
--- a/chrome/browser/extensions/activity_log/activity_log_unittest.cc
+++ b/chrome/browser/extensions/activity_log/activity_log_unittest.cc
@@ -84,11 +84,15 @@
scoped_refptr<Action> last = i->front();
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableExtensionActivityLogTesting))
- args = "Injected scripts () onto "
- "http://www.google.com/foo?bar extra";
+ args =
+ "ID=abc CATEGORY=content_script API=document.write ARGS=[\"\"] "
+ "PAGE_URL=http://www.google.com/foo?bar "
+ "OTHER={\"dom_verb\":3,\"extra\":\"extra\",\"page_title\":\"\"}";
else
- args = "Injected scripts () onto "
- "http://www.google.com/foo extra";
+ args =
+ "ID=abc CATEGORY=content_script API=document.write ARGS=[\"\"] "
+ "PAGE_URL=http://www.google.com/foo "
+ "OTHER={\"dom_verb\":3,\"extra\":\"extra\",\"page_title\":\"\"}";
ASSERT_EQ(args, last->PrintForDebug());
}
@@ -96,8 +100,8 @@
scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
scoped_refptr<Action> last = i->front();
std::string id(kExtensionId);
- std::string noargs = "ID: " + id + ", CATEGORY: "
- "call, API: tabs.testMethod, ARGS: ";
+ std::string noargs =
+ "ID=" + id + " CATEGORY=api_call API=tabs.testMethod ARGS=[] OTHER={}";
ASSERT_EQ(noargs, last->PrintForDebug());
}
@@ -105,8 +109,9 @@
scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
scoped_refptr<Action> last = i->front();
std::string id(kExtensionId);
- std::string args = "ID: " + id + ", CATEGORY: "
- "call, API: extension.connect, ARGS: \"hello\", \"world\"";
+ std::string args = "ID=" + id +
+ " CATEGORY=api_call API=extension.connect "
+ "ARGS=[\"hello\",\"world\"] OTHER={}";
ASSERT_EQ(args, last->PrintForDebug());
}
@@ -122,8 +127,10 @@
scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
ASSERT_EQ(1U, i->size());
scoped_refptr<Action> last = i->front();
- std::string args = "Injected scripts (\"script \") "
- "onto http://www.google.com/ (prerender)";
+ std::string args =
+ "ID=odlameecjipmbmbejkplpemijjgpljce CATEGORY=content_script API= "
+ "ARGS=[\"\\\"script \\\"\"] PAGE_URL=http://www.google.com/ "
+ "OTHER={\"dom_verb\":3,\"extra\":\"(prerender)\",\"page_title\":\"\"}";
ASSERT_EQ(args, last->PrintForDebug());
}
@@ -242,7 +249,7 @@
scoped_ptr<prerender::PrerenderHandle> prerender_handle(
prerender_manager->AddPrerenderFromLocalPredictor(
url,
- web_contents()->GetController().GetSessionStorageNamespace(),
+ web_contents()->GetController().GetDefaultSessionStorageNamespace(),
kSize));
const std::vector<content::WebContents*> contentses =
@@ -264,3 +271,4 @@
}
} // namespace extensions
+
diff --git a/chrome/browser/extensions/activity_log/api_actions.cc b/chrome/browser/extensions/activity_log/api_actions.cc
index 39ec099..bb50674 100644
--- a/chrome/browser/extensions/activity_log/api_actions.cc
+++ b/chrome/browser/extensions/activity_log/api_actions.cc
@@ -2,12 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/json/json_string_value_serializer.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/extensions/activity_log/api_actions.h"
#include "chrome/browser/extensions/activity_log/api_name_constants.h"
+#include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/ui/browser.h"
#include "content/public/browser/browser_thread.h"
@@ -100,6 +102,13 @@
std::map<std::string, std::string> nums_to_names_; // <number label, name>
};
+std::string Serialize(const base::Value& value) {
+ std::string value_as_text;
+ JSONStringValueSerializer serializer(&value_as_text);
+ serializer.SerializeAndOmitBinaryValues(value);
+ return value_as_text;
+}
+
} // namespace
namespace extensions {
@@ -109,12 +118,6 @@
using api::activity_log_private::ChromeActivityDetail;
using api::activity_log_private::BlockedChromeActivityDetail;
-const char* APIAction::kTableName = "activitylog_apis";
-const char* APIAction::kTableContentFields[] =
- {"api_type", "api_call", "args", "extra"};
-const char* APIAction::kTableFieldTypes[] =
- {"INTEGER", "LONGVARCHAR", "LONGVARCHAR", "LONGVARCHAR"};
-
// We should log the arguments to these API calls, even if argument logging is
// disabled by default.
const char* APIAction::kAlwaysLog[] =
@@ -133,22 +136,15 @@
const Type type,
const std::string& api_call,
const std::string& args,
+ const base::ListValue& args_list,
const std::string& extra)
: Action(extension_id, time, ExtensionActivity::ACTIVITY_TYPE_CHROME),
type_(type),
api_call_(api_call),
args_(args),
+ args_list_(args_list.DeepCopy()),
extra_(extra) { }
-APIAction::APIAction(const sql::Statement& s)
- : Action(s.ColumnString(0),
- base::Time::FromInternalValue(s.ColumnInt64(1)),
- ExtensionActivity::ACTIVITY_TYPE_CHROME),
- type_(static_cast<Type>(s.ColumnInt(2))),
- api_call_(APINameMap::GetInstance()->ShortnameToApi(s.ColumnString(3))),
- args_(s.ColumnString(4)),
- extra_(s.ColumnString(5)) { }
-
APIAction::~APIAction() {
}
@@ -169,49 +165,28 @@
return formatted_activity.Pass();
}
-// static
-bool APIAction::InitializeTable(sql::Connection* db) {
- // The original table schema was different than the existing one.
- // We no longer want the api_action_type or target_type columns.
- // Sqlite doesn't let you delete or modify existing columns, so we drop it.
- // Any data loss incurred here doesn't matter since these fields existed
- // before we started using the AL for anything.
- if (db->DoesColumnExist(kTableName, "api_action_type")) {
- std::string drop_table = base::StringPrintf("DROP TABLE %s", kTableName);
- if (!db->Execute(drop_table.c_str()))
- return false;
- }
- // We also now use INTEGER instead of VARCHAR for api_type.
- if (db->DoesColumnExist(kTableName, "api_type")) {
- std::string select = base::StringPrintf(
- "SELECT api_type FROM %s ORDER BY rowid LIMIT 1", kTableName);
- sql::Statement statement(db->GetUniqueStatement(select.c_str()));
- if (statement.DeclaredColumnType(0) != sql::COLUMN_TYPE_INTEGER) {
- std::string drop_table = base::StringPrintf("DROP TABLE %s", kTableName);
- if (!db->Execute(drop_table.c_str()))
- return false;
- }
- }
- // Now initialize the table.
- return InitializeTableInternal(db,
- kTableName,
- kTableContentFields,
- kTableFieldTypes,
- arraysize(kTableContentFields));
-}
-
bool APIAction::Record(sql::Connection* db) {
- std::string sql_str = "INSERT INTO " + std::string(kTableName)
- + " (extension_id, time, api_type, api_call, args, extra) VALUES"
- " (?,?,?,?,?,?)";
+ std::string sql_str =
+ "INSERT INTO " + std::string(FullStreamUIPolicy::kTableName) +
+ " (extension_id, time, action_type, api_name, args) VALUES"
+ " (?,?,?,?,?)";
sql::Statement statement(db->GetCachedStatement(
sql::StatementID(SQL_FROM_HERE), sql_str.c_str()));
statement.BindString(0, extension_id());
statement.BindInt64(1, time().ToInternalValue());
- statement.BindInt(2, static_cast<int>(type_));
- statement.BindString(3, APINameMap::GetInstance()->ApiToShortname(api_call_));
- statement.BindString(4, args_);
- statement.BindString(5, extra_);
+ switch (type_) {
+ case CALL:
+ statement.BindInt(2, static_cast<int>(Action::ACTION_API_CALL));
+ break;
+ case EVENT_CALLBACK:
+ statement.BindInt(2, static_cast<int>(Action::ACTION_API_EVENT));
+ break;
+ default:
+ LOG(ERROR) << "Invalid action type: " << type_;
+ return false;
+ }
+ statement.BindString(3, api_call_);
+ statement.BindString(4, Serialize(*args_list_));
if (!statement.Run()) {
LOG(ERROR) << "Activity log database I/O failed: " << sql_str;
statement.Clear();
diff --git a/chrome/browser/extensions/activity_log/api_actions.h b/chrome/browser/extensions/activity_log/api_actions.h
index 4cd3cb0..9ea84ba 100644
--- a/chrome/browser/extensions/activity_log/api_actions.h
+++ b/chrome/browser/extensions/activity_log/api_actions.h
@@ -22,18 +22,11 @@
UNKNOWN_TYPE = 2,
};
- static const char* kTableName;
- static const char* kTableContentFields[];
- static const char* kTableFieldTypes[];
static const char* kAlwaysLog[];
static const int kSizeAlwaysLog;
static const char* kIncognitoUrl;
- // Create the database table for storing APIActions, or update the schema if
- // it is out of date. Any existing data is preserved.
- static bool InitializeTable(sql::Connection* db);
-
// Create a new APIAction to describe a successful API call. All
// parameters are required.
APIAction(const std::string& extension_id,
@@ -41,11 +34,9 @@
const Type type, // e.g. "CALL"
const std::string& api_call, // full method name
const std::string& args, // the argument list
+ const base::ListValue& args_list, // same as above, as a list
const std::string& extra); // any extra logging info
- // Create a new APIAction from a database row.
- explicit APIAction(const sql::Statement& s);
-
// Record the action in the database.
virtual bool Record(sql::Connection* db) OVERRIDE;
@@ -76,6 +67,7 @@
Type type_;
std::string api_call_;
std::string args_;
+ scoped_ptr<base::ListValue> args_list_;
std::string extra_;
DISALLOW_COPY_AND_ASSIGN(APIAction);
diff --git a/chrome/browser/extensions/activity_log/api_name_constants.h b/chrome/browser/extensions/activity_log/api_name_constants.h
index c8e62d9..0fe950d 100644
--- a/chrome/browser/extensions/activity_log/api_name_constants.h
+++ b/chrome/browser/extensions/activity_log/api_name_constants.h
@@ -193,7 +193,10 @@
"tabs.getSelected", "tabs.sendRequest",
"systemInfo.cpu.get", "systemInfo.memory.get",
"runtime.onRestartRequired",
- "system.cpu.getInfo"
+ "system.cpu.getInfo",
+ "system.display.getInfo",
+ "system.display.onDisplayChanged",
+ "system.display.setDisplayProperties"
};
} // namespace activity_log_api_name_constants
diff --git a/chrome/browser/extensions/activity_log/blocked_actions.cc b/chrome/browser/extensions/activity_log/blocked_actions.cc
index e8c7bda..3ac47a1 100644
--- a/chrome/browser/extensions/activity_log/blocked_actions.cc
+++ b/chrome/browser/extensions/activity_log/blocked_actions.cc
@@ -2,9 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/json/json_string_value_serializer.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/extensions/activity_log/blocked_actions.h"
+#include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
#include "content/public/browser/browser_thread.h"
using content::BrowserThread;
@@ -16,12 +18,6 @@
using api::activity_log_private::ChromeActivityDetail;
using api::activity_log_private::BlockedChromeActivityDetail;
-const char* BlockedAction::kTableName = "activitylog_blocked";
-const char* BlockedAction::kTableContentFields[] =
- {"api_call", "args", "reason", "extra"};
-const char* BlockedAction::kTableFieldTypes[] =
- {"LONGVARCHAR", "LONGVARCHAR", "INTEGER", "LONGVARCHAR"};
-
BlockedAction::BlockedAction(const std::string& extension_id,
const base::Time& time,
const std::string& api_call,
@@ -36,15 +32,6 @@
reason_(reason),
extra_(extra) { }
-BlockedAction::BlockedAction(const sql::Statement& s)
- : Action(s.ColumnString(0),
- base::Time::FromInternalValue(s.ColumnInt64(1)),
- ExtensionActivity::ACTIVITY_TYPE_BLOCKED_CHROME),
- api_call_(s.ColumnString(2)),
- args_(s.ColumnString(3)),
- reason_(static_cast<Reason>(s.ColumnInt(4))),
- extra_(s.ColumnString(5)) { }
-
BlockedAction::~BlockedAction() {
}
@@ -65,55 +52,32 @@
return formatted_activity.Pass();
}
-// static
-bool BlockedAction::InitializeTable(sql::Connection* db) {
- // The original table schema was different than the existing one.
- // Sqlite doesn't let you delete or modify existing columns, so we drop it.
- // The old version can be identified because it had a field named
- // blocked_action. Any data loss incurred here doesn't matter since these
- // fields existed before we started using the AL for anything.
- if (db->DoesColumnExist(kTableName, "blocked_action")) {
- std::string drop_table = base::StringPrintf("DROP TABLE %s", kTableName);
- if (!db->Execute(drop_table.c_str()))
- return false;
- }
- // We also now use INTEGER instead of VARCHAR for url_action_type.
- if (db->DoesColumnExist(kTableName, "reason")) {
- std::string select = base::StringPrintf(
- "SELECT reason FROM %s ORDER BY rowid LIMIT 1", kTableName);
- sql::Statement statement(db->GetUniqueStatement(select.c_str()));
- if (statement.DeclaredColumnType(0) != sql::COLUMN_TYPE_INTEGER) {
- std::string drop_table = base::StringPrintf("DROP TABLE %s", kTableName);
- if (!db->Execute(drop_table.c_str()))
- return false;
- }
- }
- return InitializeTableInternal(db,
- kTableName,
- kTableContentFields,
- kTableFieldTypes,
- arraysize(kTableContentFields));
-}
-
bool BlockedAction::Record(sql::Connection* db) {
- std::string sql_str = "INSERT INTO " + std::string(kTableName)
- + " (extension_id, time, api_call, args, reason, extra)"
- " VALUES (?,?,?,?,?,?)";
+ std::string sql_str =
+ "INSERT INTO " + std::string(FullStreamUIPolicy::kTableName) +
+ " (extension_id, time, action_type, api_name, args, other) VALUES"
+ " (?,?,?,?,?,?)";
sql::Statement statement(db->GetCachedStatement(
sql::StatementID(SQL_FROM_HERE), sql_str.c_str()));
statement.BindString(0, extension_id());
statement.BindInt64(1, time().ToInternalValue());
- statement.BindString(2, api_call_);
- statement.BindString(3, args_);
- statement.BindInt(4, static_cast<int>(reason_));
- statement.BindString(5, extra_);
+ statement.BindInt(2, static_cast<int>(Action::ACTION_API_BLOCKED));
+ statement.BindString(3, api_call_);
+ statement.BindString(4, args_);
+
+ DictionaryValue other;
+ other.SetInteger("reason", static_cast<int>(reason_));
+ std::string other_string;
+ JSONStringValueSerializer other_serializer(&other_string);
+ other_serializer.SerializeAndOmitBinaryValues(other);
+ statement.BindString(5, other_string);
+
if (!statement.Run()) {
LOG(ERROR) << "Activity log database I/O failed: " << sql_str;
statement.Clear();
return false;
- } else {
- return true;
}
+ return true;
}
std::string BlockedAction::PrintForDebug() {
diff --git a/chrome/browser/extensions/activity_log/blocked_actions.h b/chrome/browser/extensions/activity_log/blocked_actions.h
index 6f8bafd..e6f4beb 100644
--- a/chrome/browser/extensions/activity_log/blocked_actions.h
+++ b/chrome/browser/extensions/activity_log/blocked_actions.h
@@ -21,14 +21,6 @@
QUOTA_EXCEEDED = 2,
};
- static const char* kTableName;
- static const char* kTableContentFields[];
- static const char* kTableFieldTypes[];
-
- // Create a new database table for storing BlockedActions, or update the
- // schema if it is out of date. Any existing data is preserved.
- static bool InitializeTable(sql::Connection* db);
-
// You must supply the id, time, api_call, and reason.
BlockedAction(const std::string& extension_id,
const base::Time& time,
@@ -37,9 +29,6 @@
const Reason reason, // the reason it's blocked
const std::string& extra); // any extra logging info
- // Create a new BlockedAction from a database row.
- explicit BlockedAction(const sql::Statement& s);
-
// Record the action in the database.
virtual bool Record(sql::Connection* db) OVERRIDE;
diff --git a/chrome/browser/extensions/activity_log/dom_actions.cc b/chrome/browser/extensions/activity_log/dom_actions.cc
index c597d41..9158abb 100644
--- a/chrome/browser/extensions/activity_log/dom_actions.cc
+++ b/chrome/browser/extensions/activity_log/dom_actions.cc
@@ -3,10 +3,12 @@
// found in the LICENSE file.
#include "base/command_line.h"
+#include "base/json/json_string_value_serializer.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/activity_log/dom_actions.h"
+#include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
#include "chrome/browser/history/url_database.h"
#include "chrome/common/chrome_switches.h"
#include "content/public/browser/browser_thread.h"
@@ -20,14 +22,6 @@
using api::activity_log_private::ChromeActivityDetail;
using api::activity_log_private::BlockedChromeActivityDetail;
-const char* DOMAction::kTableName = "activitylog_urls";
-const char* DOMAction::kTableContentFields[] =
- {"url_action_type", "url_tld", "url_path", "url_title", "api_call",
- "args", "extra"};
-const char* DOMAction::kTableFieldTypes[] =
- {"INTEGER", "LONGVARCHAR", "LONGVARCHAR", "LONGVARCHAR", "LONGVARCHAR",
- "LONGVARCHAR", "LONGVARCHAR"};
-
DOMAction::DOMAction(const std::string& extension_id,
const base::Time& time,
const DomActionType::Type verb,
@@ -44,17 +38,6 @@
args_(args),
extra_(extra) { }
-DOMAction::DOMAction(const sql::Statement& s)
- : Action(s.ColumnString(0),
- base::Time::FromInternalValue(s.ColumnInt64(1)),
- ExtensionActivity::ACTIVITY_TYPE_DOM),
- verb_(static_cast<DomActionType::Type>(s.ColumnInt(2))),
- url_(GURL(s.ColumnString(3)+ s.ColumnString(4))),
- url_title_(s.ColumnString16(5)),
- api_call_(s.ColumnString(6)),
- args_(s.ColumnString(7)),
- extra_(s.ColumnString(8)) { }
-
DOMAction::~DOMAction() {
}
@@ -77,73 +60,55 @@
return formatted_activity.Pass();
}
-// static
-bool DOMAction::InitializeTable(sql::Connection* db) {
- // The original table schema was different than the existing one.
- // Sqlite doesn't let you delete or modify existing columns, so we drop it.
- // The old version can be identified because it had a field named
- // tech_message. Any data loss incurred here doesn't matter since these
- // fields existed before we started using the AL for anything.
- if (db->DoesColumnExist(kTableName, "tech_message")) {
- std::string drop_table = base::StringPrintf("DROP TABLE %s", kTableName);
- if (!db->Execute(drop_table.c_str()))
- return false;
- }
- // The url field is now broken into two parts - url_tld and url_path.
- // ulr_tld contains the scheme, host, and port of the url and
- // url_path contains the path.
- if (db->DoesColumnExist(kTableName, "url")) {
- std::string drop_table = base::StringPrintf("DROP TABLE %s", kTableName);
- if (!db->Execute(drop_table.c_str()))
- return false;
- }
- // We also now use INTEGER instead of VARCHAR for url_action_type.
- if (db->DoesColumnExist(kTableName, "url_action_type")) {
- std::string select = base::StringPrintf(
- "SELECT url_action_type FROM %s ORDER BY rowid LIMIT 1", kTableName);
- sql::Statement statement(db->GetUniqueStatement(select.c_str()));
- if (statement.DeclaredColumnType(0) != sql::COLUMN_TYPE_INTEGER) {
- std::string drop_table = base::StringPrintf("DROP TABLE %s", kTableName);
- if (!db->Execute(drop_table.c_str()))
- return false;
- }
- }
- // Now initialize the table.
- bool initialized = InitializeTableInternal(db,
- kTableName,
- kTableContentFields,
- kTableFieldTypes,
- arraysize(kTableContentFields));
- return initialized;
-}
-
bool DOMAction::Record(sql::Connection* db) {
- std::string sql_str = "INSERT INTO " + std::string(kTableName) +
- " (extension_id, time, url_action_type, url_tld, url_path, url_title,"
- " api_call, args, extra) VALUES (?,?,?,?,?,?,?,?,?)";
+ std::string sql_str = "INSERT INTO " +
+ std::string(FullStreamUIPolicy::kTableName) +
+ " (extension_id, time, action_type, api_name, args, "
+ "page_url, arg_url, other) VALUES (?,?,?,?,?,?,?,?)";
sql::Statement statement(db->GetCachedStatement(
sql::StatementID(SQL_FROM_HERE), sql_str.c_str()));
- std::string url_tld;
- std::string url_path;
statement.BindString(0, extension_id());
statement.BindInt64(1, time().ToInternalValue());
- statement.BindInt(2, static_cast<int>(verb_));
- url_tld = url_.GetOrigin().spec();
- // delete the extra "/"
- if ((url_tld.size() > 0) && (url_tld[url_tld.size()-1] == '/'))
- url_tld.erase(url_tld.size()-1);
- statement.BindString(3, url_tld);
- // If running in activity testing mode, store the parameters as well.
- if ((CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableExtensionActivityLogTesting)) && (url_.has_query()))
- url_path = url_.path()+"?"+url_.query();
+ if (verb_ == DomActionType::INSERTED)
+ statement.BindInt(2, static_cast<int>(Action::ACTION_CONTENT_SCRIPT));
else
- url_path = url_.path();
- statement.BindString(4, url_path);
- statement.BindString16(5, url_title_);
- statement.BindString(6, api_call_);
- statement.BindString(7, args_);
- statement.BindString(8, extra_);
+ statement.BindInt(2, static_cast<int>(Action::ACTION_DOM_ACCESS));
+ statement.BindString(3, api_call_);
+
+ ListValue args_list;
+ args_list.AppendString(args_);
+ std::string args_as_text;
+ JSONStringValueSerializer serializer(&args_as_text);
+ serializer.SerializeAndOmitBinaryValues(args_list);
+ statement.BindString(4, args_as_text);
+
+ // If running in activity testing mode, store the URL parameters as well.
+ GURL database_url;
+ if ((CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableExtensionActivityLogTesting))) {
+ database_url = url_;
+ } else {
+ url_canon::Replacements<char> sanitize;
+ sanitize.ClearQuery();
+ sanitize.ClearRef();
+ database_url = url_.ReplaceComponents(sanitize);
+ }
+ statement.BindString(5, database_url.spec());
+
+ if (verb_ == DomActionType::INSERTED)
+ statement.BindString(6, args_);
+ else
+ statement.BindNull(6);
+
+ DictionaryValue other;
+ other.SetString("extra", extra_);
+ other.SetString("page_title", url_title_);
+ other.SetInteger("dom_verb", static_cast<int>(verb_));
+ std::string other_string;
+ JSONStringValueSerializer other_serializer(&other_string);
+ other_serializer.SerializeAndOmitBinaryValues(other);
+ statement.BindString(7, other_string);
+
if (!statement.Run()) {
LOG(ERROR) << "Activity log database I/O failed: " << sql_str;
statement.Clear();
diff --git a/chrome/browser/extensions/activity_log/dom_actions.h b/chrome/browser/extensions/activity_log/dom_actions.h
index 1eff74b..9129a39 100644
--- a/chrome/browser/extensions/activity_log/dom_actions.h
+++ b/chrome/browser/extensions/activity_log/dom_actions.h
@@ -16,14 +16,6 @@
// content script insertions.
class DOMAction : public Action {
public:
- static const char* kTableName;
- static const char* kTableContentFields[];
- static const char* kTableFieldTypes[];
-
- // Create a new database table for storing DOMActions, or update the schema if
- // it is out of date. Any existing data is preserved.
- static bool InitializeTable(sql::Connection* db);
-
// Create a new DOMAction to describe a new DOM API call.
// If the DOMAction is on a background page, the url & url_title may be null.
// If the DOMAction refers to a content script insertion, api_call may be null
@@ -38,9 +30,6 @@
const std::string& args, // the args
const std::string& extra); // any extra logging info
- // Create a new DOMAction from a database row.
- explicit DOMAction(const sql::Statement& s);
-
virtual scoped_ptr<api::activity_log_private::ExtensionActivity>
ConvertToExtensionActivity() OVERRIDE;
diff --git a/chrome/browser/extensions/activity_log/fullstream_ui_policy.cc b/chrome/browser/extensions/activity_log/fullstream_ui_policy.cc
index 554d201..a6f7b22 100644
--- a/chrome/browser/extensions/activity_log/fullstream_ui_policy.cc
+++ b/chrome/browser/extensions/activity_log/fullstream_ui_policy.cc
@@ -6,6 +6,7 @@
#include "base/json/json_string_value_serializer.h"
#include "base/logging.h"
#include "base/strings/string16.h"
+#include "base/strings/stringprintf.h"
#include "chrome/browser/extensions/activity_log/activity_database.h"
#include "chrome/browser/extensions/activity_log/api_actions.h"
#include "chrome/browser/extensions/activity_log/blocked_actions.h"
@@ -32,14 +33,25 @@
const char kKeyURLTitle[] = "fsuip.urltitle";
const char kKeyDetailsString[] = "fsuip.details";
+// Obsolete database tables: these should be dropped from the database if
+// found.
+const char* kObsoleteTables[] = {"activitylog_apis", "activitylog_blocked",
+ "activitylog_urls"};
+
} // namespace
namespace extensions {
-// TODO(dbabic) This would be a fine error handler for all sql-based policies,
-// so it would make sense to introduce another class in the hierarchy,
-// SQLiteBasedPolicy as a super class of FullStreamUIPolicy and move this
-// error handler (as well as other SQLite-related functionality) there.
+const char* FullStreamUIPolicy::kTableName = "activitylog_full";
+const char* FullStreamUIPolicy::kTableContentFields[] = {
+ "extension_id", "time", "action_type", "api_name", "args", "page_url",
+ "arg_url", "other"
+};
+const char* FullStreamUIPolicy::kTableFieldTypes[] = {
+ "LONGVARCHAR NOT NULL", "INTEGER", "INTEGER", "LONGVARCHAR", "LONGVARCHAR",
+ "LONGVARCHAR", "LONGVARCHAR", "LONGVARCHAR"
+};
+const int FullStreamUIPolicy::kTableFieldCount = arraysize(kTableContentFields);
FullStreamUIPolicy::FullStreamUIPolicy(Profile* profile)
: ActivityLogPolicy(profile) {
@@ -50,14 +62,24 @@
}
bool FullStreamUIPolicy::OnDatabaseInit(sql::Connection* db) {
- if (!DOMAction::InitializeTable(db))
- return false;
- if (!APIAction::InitializeTable(db))
- return false;
- if (!BlockedAction::InitializeTable(db))
- return false;
+ // Drop old database tables.
+ for (size_t i = 0; i < arraysize(kObsoleteTables); i++) {
+ const char* table_name = kObsoleteTables[i];
+ if (db->DoesTableExist(table_name)) {
+ std::string drop_statement =
+ base::StringPrintf("DROP TABLE %s", table_name);
+ if (!db->Execute(drop_statement.c_str())) {
+ return false;
+ }
+ }
+ }
- return true;
+ // Create the unified activity log entry table.
+ return ActivityDatabase::InitializeTable(db,
+ kTableName,
+ kTableContentFields,
+ kTableFieldTypes,
+ arraysize(kTableContentFields));
}
void FullStreamUIPolicy::OnDatabaseClose() {
@@ -101,7 +123,17 @@
}
}
-std::string FullStreamUIPolicy::ProcessArguments(
+scoped_ptr<base::ListValue> FullStreamUIPolicy::ProcessArguments(
+ ActionType action_type,
+ const std::string& name,
+ const base::ListValue* args) const {
+ if (args)
+ return make_scoped_ptr(args->DeepCopy());
+ else
+ return scoped_ptr<base::ListValue>();
+}
+
+std::string FullStreamUIPolicy::JoinArguments(
ActionType action_type,
const std::string& name,
const base::ListValue* args) const {
@@ -136,9 +168,11 @@
const std::string& extension_id,
const std::string& name,
const GURL& url_param,
- const base::ListValue* args,
+ const base::ListValue* args_in,
const DictionaryValue* details) {
- std::string concatenated_args = ProcessArguments(action_type, name, args);
+ scoped_ptr<base::ListValue> args =
+ ProcessArguments(action_type, name, args_in);
+ std::string concatenated_args = JoinArguments(action_type, name, args.get());
const Time now = Time::Now();
scoped_refptr<Action> action;
std::string extra;
@@ -154,6 +188,7 @@
APIAction::CALL,
name,
concatenated_args,
+ *args,
extra);
break;
}
@@ -164,6 +199,7 @@
APIAction::EVENT_CALLBACK,
name,
concatenated_args,
+ *args,
extra);
break;
}
diff --git a/chrome/browser/extensions/activity_log/fullstream_ui_policy.h b/chrome/browser/extensions/activity_log/fullstream_ui_policy.h
index 3b33963..f915ad5 100644
--- a/chrome/browser/extensions/activity_log/fullstream_ui_policy.h
+++ b/chrome/browser/extensions/activity_log/fullstream_ui_policy.h
@@ -45,6 +45,12 @@
virtual void Close() OVERRIDE;
+ // Database table schema.
+ static const char* kTableName;
+ static const char* kTableContentFields[];
+ static const char* kTableFieldTypes[];
+ static const int kTableFieldCount;
+
protected:
// Only ever run by OnDatabaseClose() below; see the comments on the
// ActivityDatabase class for an overall discussion of how cleanup works.
@@ -55,10 +61,16 @@
virtual bool OnDatabaseInit(sql::Connection* db) OVERRIDE;
virtual void OnDatabaseClose() OVERRIDE;
- // Concatenates arguments
- virtual std::string ProcessArguments(ActionType action_type,
- const std::string& name,
- const base::ListValue* args) const;
+ // Strips arguments if needed by policy.
+ virtual scoped_ptr<base::ListValue> ProcessArguments(
+ ActionType action_type,
+ const std::string& name,
+ const base::ListValue* args) const;
+
+ // Concatenates arguments.
+ virtual std::string JoinArguments(ActionType action_type,
+ const std::string& name,
+ const base::ListValue* args) const;
virtual void ProcessWebRequestModifications(
base::DictionaryValue& details,
diff --git a/chrome/browser/extensions/activity_log/fullstream_ui_policy_unittest.cc b/chrome/browser/extensions/activity_log/fullstream_ui_policy_unittest.cc
index 0028eaa..af735b9 100644
--- a/chrome/browser/extensions/activity_log/fullstream_ui_policy_unittest.cc
+++ b/chrome/browser/extensions/activity_log/fullstream_ui_policy_unittest.cc
@@ -66,8 +66,9 @@
static void Arguments_Present(
scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
scoped_refptr<Action> last = i->front();
- std::string args = "ID: odlameecjipmbmbejkplpemijjgpljce, CATEGORY: "
- "call, API: extension.connect, ARGS: \"hello\", \"world\"";
+ std::string args =
+ "ID=odlameecjipmbmbejkplpemijjgpljce CATEGORY=api_call "
+ "API=extension.connect ARGS=[\"hello\",\"world\"] OTHER={}";
ASSERT_EQ(args, last->PrintForDebug());
}
diff --git a/chrome/browser/extensions/activity_log/stream_noargs_ui_policy.cc b/chrome/browser/extensions/activity_log/stream_noargs_ui_policy.cc
index c30d33d..180b802 100644
--- a/chrome/browser/extensions/activity_log/stream_noargs_ui_policy.cc
+++ b/chrome/browser/extensions/activity_log/stream_noargs_ui_policy.cc
@@ -16,15 +16,15 @@
StreamWithoutArgsUIPolicy::~StreamWithoutArgsUIPolicy() {}
-std::string StreamWithoutArgsUIPolicy::ProcessArguments(
+scoped_ptr<base::ListValue> StreamWithoutArgsUIPolicy::ProcessArguments(
ActionType action_type,
const std::string& name,
const base::ListValue* args) const {
if (action_type == ACTION_DOM ||
arg_whitelist_api_.find(name) != arg_whitelist_api_.end()) {
- return FullStreamUIPolicy::ProcessArguments(action_type, name, args);
+ return FullStreamUIPolicy::ProcessArguments(action_type, name, args).Pass();
} else {
- return std::string();
+ return make_scoped_ptr(new ListValue());
}
}
diff --git a/chrome/browser/extensions/activity_log/stream_noargs_ui_policy.h b/chrome/browser/extensions/activity_log/stream_noargs_ui_policy.h
index f91ffd0..46064b9 100644
--- a/chrome/browser/extensions/activity_log/stream_noargs_ui_policy.h
+++ b/chrome/browser/extensions/activity_log/stream_noargs_ui_policy.h
@@ -19,10 +19,10 @@
virtual ~StreamWithoutArgsUIPolicy();
protected:
- virtual std::string ProcessArguments(ActionType action_type,
- const std::string& name,
- const base::ListValue* args)
- const OVERRIDE;
+ virtual scoped_ptr<base::ListValue> ProcessArguments(
+ ActionType action_type,
+ const std::string& name,
+ const base::ListValue* args) const OVERRIDE;
virtual void ProcessWebRequestModifications(
base::DictionaryValue& details,
diff --git a/chrome/browser/extensions/activity_log/stream_noargs_ui_policy_unittest.cc b/chrome/browser/extensions/activity_log/stream_noargs_ui_policy_unittest.cc
index a1c806d..1a5dd4a 100644
--- a/chrome/browser/extensions/activity_log/stream_noargs_ui_policy_unittest.cc
+++ b/chrome/browser/extensions/activity_log/stream_noargs_ui_policy_unittest.cc
@@ -66,8 +66,9 @@
static void Arguments_Missing(
scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
scoped_refptr<Action> last = i->front();
- std::string noargs = "ID: odlameecjipmbmbejkplpemijjgpljce, CATEGORY: "
- "call, API: tabs.testMethod, ARGS: ";
+ std::string noargs =
+ "ID=odlameecjipmbmbejkplpemijjgpljce CATEGORY=api_call "
+ "API=tabs.testMethod ARGS=[] OTHER={}";
ASSERT_EQ(noargs, last->PrintForDebug());
}
diff --git a/chrome/browser/extensions/api/activity_log_private/activity_log_private_api_unittest.cc b/chrome/browser/extensions/api/activity_log_private/activity_log_private_api_unittest.cc
index 6aef614..841f09d 100644
--- a/chrome/browser/extensions/api/activity_log_private/activity_log_private_api_unittest.cc
+++ b/chrome/browser/extensions/api/activity_log_private/activity_log_private_api_unittest.cc
@@ -58,6 +58,7 @@
APIAction::CALL,
kApiCall,
kArgs,
+ base::ListValue(),
kExtra));
scoped_ptr<ExtensionActivity> result =
action->ConvertToExtensionActivity();
diff --git a/chrome/browser/extensions/api/app_runtime/app_runtime_api.cc b/chrome/browser/extensions/api/app_runtime/app_runtime_api.cc
index 81f5975..5b7bd40 100644
--- a/chrome/browser/extensions/api/app_runtime/app_runtime_api.cc
+++ b/chrome/browser/extensions/api/app_runtime/app_runtime_api.cc
@@ -30,17 +30,10 @@
Profile* profile) {
extensions::ExtensionSystem* system =
extensions::ExtensionSystem::Get(profile);
- // Special case: normally, extensions add their own lazy event listeners.
- // However, since the extension might have just been enabled, it hasn't had a
- // chance to register for events. So we register on its behalf. If the
- // extension does not actually have a listener, the event will just be
- // ignored (but an app that doesn't listen for the onLaunched event doesn't
- // make sense anyway).
- system->event_router()->AddLazyEventListener(kOnLaunched, extension_id);
scoped_ptr<Event> event(new Event(kOnLaunched, args.Pass()));
event->restrict_to_profile = profile;
- system->event_router()->DispatchEventToExtension(extension_id, event.Pass());
- system->event_router()->RemoveLazyEventListener(kOnLaunched, extension_id);
+ system->event_router()->DispatchEventWithLazyListener(extension_id,
+ event.Pass());
}
} // anonymous namespace
diff --git a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc
index 67d0cf1..9d25e6c 100644
--- a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc
+++ b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc
@@ -49,6 +49,7 @@
namespace GetSubtree = api::bookmark_manager_private::GetSubtree;
namespace manager_keys = bookmark_manager_api_constants;
namespace Paste = api::bookmark_manager_private::Paste;
+namespace RemoveTrees = api::bookmark_manager_private::RemoveTrees;
namespace SortChildren = api::bookmark_manager_private::SortChildren;
namespace StartDrag = api::bookmark_manager_private::StartDrag;
@@ -534,4 +535,22 @@
return true;
}
+bool BookmarkManagerPrivateRemoveTreesFunction::RunImpl() {
+ scoped_ptr<RemoveTrees::Params> params(RemoveTrees::Params::Create(*args_));
+ EXTENSION_FUNCTION_VALIDATE(params);
+
+ BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile());
+ int64 id;
+ for (size_t i = 0; i < params->id_list.size(); ++i) {
+ if (!base::StringToInt64(params->id_list[i], &id)) {
+ error_ = bookmark_api_constants::kInvalidIdError;
+ return false;
+ }
+ if (!bookmark_api_helpers::RemoveNode(model, id, true, &error_))
+ return false;
+ }
+
+ return true;
+}
+
} // namespace extensions
diff --git a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h
index aef42e9..ec699cb 100644
--- a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h
+++ b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h
@@ -217,6 +217,19 @@
virtual bool RunImpl() OVERRIDE;
};
+class BookmarkManagerPrivateRemoveTreesFunction
+ : public extensions::BookmarksFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("bookmarkManagerPrivate.removeTrees",
+ BOOKMARKMANAGERPRIVATE_REMOVETREES)
+
+ protected:
+ virtual ~BookmarkManagerPrivateRemoveTreesFunction() {}
+
+ // ExtensionFunction:
+ virtual bool RunImpl() OVERRIDE;
+};
+
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_BOOKMARK_MANAGER_PRIVATE_BOOKMARK_MANAGER_PRIVATE_API_H_
diff --git a/chrome/browser/extensions/api/content_settings/content_settings_api.cc b/chrome/browser/extensions/api/content_settings/content_settings_api.cc
index 35223b8..56631dd 100644
--- a/chrome/browser/extensions/api/content_settings/content_settings_api.cc
+++ b/chrome/browser/extensions/api/content_settings/content_settings_api.cc
@@ -40,8 +40,6 @@
namespace {
-const std::vector<webkit::WebPluginInfo>* g_testing_plugins_;
-
bool RemoveContentType(base::ListValue* args,
ContentSettingsType* content_type) {
std::string content_type_str;
@@ -260,23 +258,19 @@
return true;
}
- if (!g_testing_plugins_) {
- PluginService::GetInstance()->GetPlugins(
- base::Bind(&ContentSettingsContentSettingGetResourceIdentifiersFunction::
- OnGotPlugins,
- this));
- } else {
- OnGotPlugins(*g_testing_plugins_);
- }
+ PluginService::GetInstance()->GetPlugins(
+ base::Bind(&ContentSettingsContentSettingGetResourceIdentifiersFunction::
+ OnGotPlugins,
+ this));
return true;
}
void ContentSettingsContentSettingGetResourceIdentifiersFunction::OnGotPlugins(
- const std::vector<webkit::WebPluginInfo>& plugins) {
+ const std::vector<content::WebPluginInfo>& plugins) {
PluginFinder* finder = PluginFinder::GetInstance();
std::set<std::string> group_identifiers;
base::ListValue* list = new base::ListValue();
- for (std::vector<webkit::WebPluginInfo>::const_iterator it = plugins.begin();
+ for (std::vector<content::WebPluginInfo>::const_iterator it = plugins.begin();
it != plugins.end(); ++it) {
scoped_ptr<PluginMetadata> plugin_metadata(finder->GetPluginMetadata(*it));
const std::string& group_identifier = plugin_metadata->identifier();
@@ -298,10 +292,4 @@
true));
}
-// static
-void ContentSettingsContentSettingGetResourceIdentifiersFunction::
- SetPluginsForTesting(const std::vector<webkit::WebPluginInfo>* plugins) {
- g_testing_plugins_ = plugins;
-}
-
} // namespace extensions
diff --git a/chrome/browser/extensions/api/content_settings/content_settings_api.h b/chrome/browser/extensions/api/content_settings/content_settings_api.h
index dbd8ac1..820849f 100644
--- a/chrome/browser/extensions/api/content_settings/content_settings_api.h
+++ b/chrome/browser/extensions/api/content_settings/content_settings_api.h
@@ -9,7 +9,7 @@
class PluginFinder;
-namespace webkit {
+namespace content {
struct WebPluginInfo;
}
@@ -67,11 +67,7 @@
// Callback method that gets executed when |plugins|
// are asynchronously fetched.
- void OnGotPlugins(const std::vector<webkit::WebPluginInfo>& plugins);
-
- // Used to override the global plugin list in tests.
- static void SetPluginsForTesting(
- const std::vector<webkit::WebPluginInfo>* plugins);
+ void OnGotPlugins(const std::vector<content::WebPluginInfo>& plugins);
};
} // namespace extensions
diff --git a/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc b/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc
index b142e36..8c3bbed 100644
--- a/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc
+++ b/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc
@@ -12,7 +12,8 @@
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
-#include "webkit/plugins/npapi/mock_plugin_list.h"
+#include "content/public/browser/plugin_service.h"
+#include "content/public/common/webplugininfo.h"
namespace extensions {
@@ -94,12 +95,18 @@
url, url, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, std::string()));
}
-// Flaky on the trybots. See http://crbug.com/96725.
-IN_PROC_BROWSER_TEST_F(ExtensionApiTest,
- DISABLED_ContentSettingsGetResourceIdentifiers) {
- CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableExperimentalExtensionApis);
+class ContentSettingsGetResourceIdentifiersTest : public ExtensionApiTest {
+ public:
+ virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+ ExtensionApiTest::SetUpCommandLine(command_line);
+ command_line->AppendSwitch(switches::kDisablePluginsDiscovery);
+ command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis);
+ }
+};
+// Flaky on the trybots. See http://crbug.com/96725.
+IN_PROC_BROWSER_TEST_F(ContentSettingsGetResourceIdentifiersTest,
+ DISABLED_Test) {
base::FilePath::CharType kFooPath[] =
FILE_PATH_LITERAL("/plugins/foo.plugin");
base::FilePath::CharType kBarPath[] =
@@ -107,29 +114,21 @@
const char* kFooName = "Foo Plugin";
const char* kBarName = "Bar Plugin";
- webkit::npapi::MockPluginList plugin_list;
- plugin_list.AddPluginToLoad(
- webkit::WebPluginInfo(ASCIIToUTF16(kFooName),
- base::FilePath(kFooPath),
- ASCIIToUTF16("1.2.3"),
- ASCIIToUTF16("foo")));
- plugin_list.AddPluginToLoad(
- webkit::WebPluginInfo(ASCIIToUTF16(kBarName),
- base::FilePath(kBarPath),
- ASCIIToUTF16("2.3.4"),
- ASCIIToUTF16("bar")));
-
- std::vector<webkit::WebPluginInfo> plugins;
- plugin_list.GetPlugins(&plugins);
-
- ContentSettingsContentSettingGetResourceIdentifiersFunction::
- SetPluginsForTesting(&plugins);
+ content::PluginService::GetInstance()->RegisterInternalPlugin(
+ content::WebPluginInfo(ASCIIToUTF16(kFooName),
+ base::FilePath(kFooPath),
+ ASCIIToUTF16("1.2.3"),
+ ASCIIToUTF16("foo")),
+ false);
+ content::PluginService::GetInstance()->RegisterInternalPlugin(
+ content::WebPluginInfo(ASCIIToUTF16(kBarName),
+ base::FilePath(kBarPath),
+ ASCIIToUTF16("2.3.4"),
+ ASCIIToUTF16("bar")),
+ false);
EXPECT_TRUE(RunExtensionTest("content_settings/getresourceidentifiers"))
<< message_;
-
- ContentSettingsContentSettingGetResourceIdentifiersFunction::
- SetPluginsForTesting(NULL);
}
} // namespace extensions
diff --git a/chrome/browser/extensions/api/debugger/debugger_api.cc b/chrome/browser/extensions/api/debugger/debugger_api.cc
index bdf9722..b1d8962 100644
--- a/chrome/browser/extensions/api/debugger/debugger_api.cc
+++ b/chrome/browser/extensions/api/debugger/debugger_api.cc
@@ -68,7 +68,9 @@
namespace OnEvent = extensions::api::debugger::OnEvent;
namespace SendCommand = extensions::api::debugger::SendCommand;
+namespace {
class ExtensionDevToolsInfoBarDelegate;
+} // namespace
// ExtensionDevToolsClientHost ------------------------------------------------
@@ -82,7 +84,7 @@
const std::string& extension_id,
const std::string& extension_name,
const Debuggee& debuggee,
- ExtensionDevToolsInfoBarDelegate* infobar_delegate);
+ ExtensionDevToolsInfoBarDelegate* infobar);
virtual ~ExtensionDevToolsClientHost();
@@ -117,19 +119,37 @@
typedef std::map<int, scoped_refptr<DebuggerSendCommandFunction> >
PendingRequests;
PendingRequests pending_requests_;
- ExtensionDevToolsInfoBarDelegate* infobar_delegate_;
+ ExtensionDevToolsInfoBarDelegate* infobar_;
OnDetach::Reason detach_reason_;
DISALLOW_COPY_AND_ASSIGN(ExtensionDevToolsClientHost);
};
+// The member function declarations come after the other class declarations, so
+// they can call members on them.
+
+
+namespace {
+
+// Helpers --------------------------------------------------------------------
+
+void CopyDebuggee(Debuggee* dst, const Debuggee& src) {
+ if (src.tab_id)
+ dst->tab_id.reset(new int(*src.tab_id));
+ if (src.extension_id)
+ dst->extension_id.reset(new std::string(*src.extension_id));
+ if (src.target_id)
+ dst->target_id.reset(new std::string(*src.target_id));
+}
+
// ExtensionDevToolsInfoBarDelegate -------------------------------------------
class ExtensionDevToolsInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
- // Creates an extension dev tools delegate and adds it to |infobar_service|.
- // Returns a pointer to the delegate if it was successfully added.
+ // Creates an extension dev tools infobar delegate and adds it to the
+ // InfoBarService associated with |rvh|. Returns the delegate if it was
+ // successfully added.
static ExtensionDevToolsInfoBarDelegate* Create(
RenderViewHost* rvh,
const std::string& client_name);
@@ -214,26 +234,11 @@
}
bool ExtensionDevToolsInfoBarDelegate::Cancel() {
- if (client_host_)
- client_host_->MarkAsDismissed();
+ InfoBarDismissed();
return true;
}
-namespace {
-
-// Helpers --------------------------------------------------------------------
-
-void CopyDebuggee(Debuggee* dst, const Debuggee& src) {
- if (src.tab_id)
- dst->tab_id.reset(new int(*src.tab_id));
- if (src.extension_id)
- dst->extension_id.reset(new std::string(*src.extension_id));
- if (src.target_id)
- dst->target_id.reset(new std::string(*src.target_id));
-}
-
-
// AttachedClientHosts --------------------------------------------------------
class AttachedClientHosts {
@@ -261,6 +266,7 @@
AttachedClientHosts::~AttachedClientHosts() {
}
+
// static
AttachedClientHosts* AttachedClientHosts::GetInstance() {
return Singleton<AttachedClientHosts>::get();
@@ -299,12 +305,12 @@
const std::string& extension_id,
const std::string& extension_name,
const Debuggee& debuggee,
- ExtensionDevToolsInfoBarDelegate* infobar_delegate)
+ ExtensionDevToolsInfoBarDelegate* infobar)
: profile_(profile),
agent_host_(agent_host),
extension_id_(extension_id),
last_request_id_(0),
- infobar_delegate_(infobar_delegate),
+ infobar_(infobar),
detach_reason_(OnDetach::REASON_TARGET_CLOSED) {
CopyDebuggee(&debuggee_, debuggee);
@@ -324,8 +330,8 @@
DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(
agent_host_.get(), this);
- if (infobar_delegate_) {
- infobar_delegate_->set_client_host(this);
+ if (infobar_) {
+ infobar_->set_client_host(this);
registrar_.Add(
this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
content::Source<InfoBarService>(InfoBarService::FromWebContents(
@@ -339,12 +345,10 @@
// Close() us.
registrar_.RemoveAll();
- if (infobar_delegate_) {
- infobar_delegate_->set_client_host(NULL);
- InfoBarService* infobar_service = InfoBarService::FromWebContents(
- WebContents::FromRenderViewHost(agent_host_->GetRenderViewHost()));
- if (infobar_service)
- infobar_service->RemoveInfoBar(infobar_delegate_);
+ if (infobar_) {
+ infobar_->set_client_host(NULL);
+ InfoBarService::FromWebContents(WebContents::FromRenderViewHost(
+ agent_host_->GetRenderViewHost()))->RemoveInfoBar(infobar_);
}
AttachedClientHosts::GetInstance()->Remove(this);
}
@@ -412,9 +416,8 @@
Close();
} else {
DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type);
- if (content::Details<InfoBarRemovedDetails>(details)->first ==
- infobar_delegate_) {
- infobar_delegate_ = NULL;
+ if (content::Details<InfoBarRemovedDetails>(details)->first == infobar_) {
+ infobar_ = NULL;
SendDetachedEvent();
Close();
}
@@ -463,7 +466,7 @@
// DebuggerFunction -----------------------------------------------------------
DebuggerFunction::DebuggerFunction()
- : client_host_(0) {
+ : client_host_(NULL) {
}
DebuggerFunction::~DebuggerFunction() {
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h
index c79d482..f4c8f75 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h
@@ -13,7 +13,7 @@
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h"
#include "chrome/common/extensions/api/events.h"
-#include "webkit/glue/resource_type.h"
+#include "webkit/common/resource_type.h"
namespace base {
class Value;
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
index 6da6d0e..8d24989 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
@@ -35,7 +35,6 @@
#include "chrome/browser/sync_file_system/drive_backend/drive_file_sync_service.h"
#include "chrome/browser/ui/chrome_select_file_policy.h"
#include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
-#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/api/developer_private.h"
#include "chrome/common/extensions/background_info.h"
#include "chrome/common/extensions/incognito_handler.h"
@@ -54,6 +53,7 @@
#include "extensions/browser/view_type_utils.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension_resource.h"
+#include "extensions/common/switches.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "net/base/net_util.h"
diff --git a/chrome/browser/extensions/api/identity/identity_apitest.cc b/chrome/browser/extensions/api/identity/identity_apitest.cc
index bf5351f..b4ec91c 100644
--- a/chrome/browser/extensions/api/identity/identity_apitest.cc
+++ b/chrome/browser/extensions/api/identity/identity_apitest.cc
@@ -29,6 +29,10 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
using testing::_;
using testing::Return;
using testing::ReturnRef;
@@ -468,6 +472,12 @@
IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
NonInteractiveSuccess) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
scoped_refptr<MockGetAuthTokenFunction> func(new MockGetAuthTokenFunction());
scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
func->set_extension(extension.get());
@@ -1171,6 +1181,12 @@
IN_PROC_BROWSER_TEST_F(
LaunchWebAuthFlowFunctionTest, InteractiveFirstNavigationSuccess) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
scoped_refptr<IdentityLaunchWebAuthFlowFunction> function(
new IdentityLaunchWebAuthFlowFunction());
scoped_refptr<Extension> empty_extension(
diff --git a/chrome/browser/extensions/api/identity/web_auth_flow.cc b/chrome/browser/extensions/api/identity/web_auth_flow.cc
index a3b2126..7f3ba05 100644
--- a/chrome/browser/extensions/api/identity/web_auth_flow.cc
+++ b/chrome/browser/extensions/api/identity/web_auth_flow.cc
@@ -99,12 +99,8 @@
base::FilePath(FILE_PATH_LITERAL("identity_scope_approval_dialog")));
}
- system->event_router()->AddLazyEventListener(
- "identityPrivate.onWebFlowRequest", extension_misc::kIdentityApiUiAppId);
- system->event_router()->DispatchEventToExtension(
+ system->event_router()->DispatchEventWithLazyListener(
extension_misc::kIdentityApiUiAppId, event.Pass());
- system->event_router()->RemoveLazyEventListener(
- "identityPrivate.onWebFlowRequest", extension_misc::kIdentityApiUiAppId);
}
void WebAuthFlow::DetachDelegateAndDelete() {
diff --git a/chrome/browser/extensions/api/media_galleries_private/media_galleries_eject_apitest.cc b/chrome/browser/extensions/api/media_galleries_private/media_galleries_eject_apitest.cc
index 32055eb..ba8407e 100644
--- a/chrome/browser/extensions/api/media_galleries_private/media_galleries_eject_apitest.cc
+++ b/chrome/browser/extensions/api/media_galleries_private/media_galleries_eject_apitest.cc
@@ -53,7 +53,9 @@
class MediaGalleriesPrivateEjectApiTest : public ExtensionApiTest {
public:
- MediaGalleriesPrivateEjectApiTest() : device_id_(GetDeviceId()) {}
+ MediaGalleriesPrivateEjectApiTest()
+ : device_id_(GetDeviceId()),
+ monitor_(NULL) {}
virtual ~MediaGalleriesPrivateEjectApiTest() {}
protected:
@@ -64,6 +66,11 @@
kTestExtensionId);
}
+ virtual void SetUpOnMainThread() OVERRIDE {
+ monitor_ = chrome::test::TestStorageMonitor::CreateForBrowserTests();
+ ExtensionApiTest::SetUpOnMainThread();
+ }
+
content::RenderViewHost* GetHost() {
const extensions::Extension* extension =
LoadExtension(test_data_dir_.AppendASCII(kTestExtensionPath));
@@ -103,6 +110,8 @@
protected:
const std::string device_id_;
+ chrome::test::TestStorageMonitor* monitor_;
+
private:
DISALLOW_COPY_AND_ASSIGN(MediaGalleriesPrivateEjectApiTest);
};
@@ -113,11 +122,6 @@
///////////////////////////////////////////////////////////////////////////////
IN_PROC_BROWSER_TEST_F(MediaGalleriesPrivateEjectApiTest, EjectTest) {
- scoped_ptr<chrome::test::TestStorageMonitor> monitor(
- chrome::test::TestStorageMonitor::CreateForBrowserTests());
- monitor->Init();
- monitor->MarkInitialized();
-
content::RenderViewHost* host = GetHost();
ExecuteCmdAndCheckReply(host, kAddAttachListenerCmd, kAddAttachListenerOk);
@@ -130,18 +134,13 @@
EXPECT_TRUE(attach_finished_listener.WaitUntilSatisfied());
ExecuteCmdAndCheckReply(host, kEjectTestCmd, kEjectListenerOk);
- EXPECT_EQ(device_id_, monitor->ejected_device());
+ EXPECT_EQ(device_id_, monitor_->ejected_device());
Detach();
}
IN_PROC_BROWSER_TEST_F(MediaGalleriesPrivateEjectApiTest, EjectBadDeviceTest) {
- scoped_ptr<chrome::test::TestStorageMonitor> monitor(
- chrome::test::TestStorageMonitor::CreateForBrowserTests());
- monitor->Init();
- monitor->MarkInitialized();
-
ExecuteCmdAndCheckReply(GetHost(), kEjectFailTestCmd, kEjectFailListenerOk);
- EXPECT_EQ("", monitor->ejected_device());
+ EXPECT_EQ("", monitor_->ejected_device());
}
diff --git a/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_apitest.cc b/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_apitest.cc
index 45737e5..df662f0 100644
--- a/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_apitest.cc
+++ b/chrome/browser/extensions/api/media_galleries_private/media_galleries_private_apitest.cc
@@ -108,12 +108,8 @@
};
IN_PROC_BROWSER_TEST_F(MediaGalleriesPrivateApiTest, DeviceAttachDetachEvents) {
- scoped_ptr<chrome::test::TestStorageMonitor> monitor(
- chrome::test::TestStorageMonitor::CreateForBrowserTests());
- monitor->Init();
- monitor->MarkInitialized();
-
// Setup.
+ chrome::test::TestStorageMonitor::SyncInitialize();
const extensions::Extension* extension =
LoadExtension(test_data_dir_.AppendASCII(kTestExtensionPath));
ASSERT_TRUE(extension);
diff --git a/chrome/browser/extensions/api/page_launcher/page_launcher_api.cc b/chrome/browser/extensions/api/page_launcher/page_launcher_api.cc
deleted file mode 100644
index e0f8241..0000000
--- a/chrome/browser/extensions/api/page_launcher/page_launcher_api.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2013 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/page_launcher/page_launcher_api.h"
-
-#include "base/lazy_instance.h"
-#include "base/memory/linked_ptr.h"
-#include "chrome/browser/extensions/event_router.h"
-#include "chrome/browser/extensions/extension_system.h"
-#include "chrome/common/extensions/api/page_launcher.h"
-#include "url/gurl.h"
-
-namespace extensions {
-
-// static
-void PageLauncherAPI::DispatchOnClickedEvent(
- Profile* profile,
- const std::string& extension_id,
- const GURL& url,
- const std::string& mimetype,
- const std::string* page_title,
- const std::string* selected_text) {
- api::page_launcher::PageData data;
- data.url = url.spec();
- data.mimetype = mimetype;
- if (page_title)
- data.title.reset(new std::string(*page_title));
- if (selected_text)
- data.selection_text.reset(new std::string(*selected_text));
-
- scoped_ptr<Event> event(
- new Event("pageLauncher.onClicked",
- api::page_launcher::OnClicked::Create(data)));
- EventRouter* event_router = ExtensionSystem::Get(profile)->event_router();
- event_router->DispatchEventToExtension(extension_id, event.Pass());
-}
-
-} // namespace extensions
diff --git a/chrome/browser/extensions/api/page_launcher/page_launcher_api.h b/chrome/browser/extensions/api/page_launcher/page_launcher_api.h
deleted file mode 100644
index a5c7757..0000000
--- a/chrome/browser/extensions/api/page_launcher/page_launcher_api.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2013 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.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_API_PAGE_LAUNCHER_PAGE_LAUNCHER_API_H_
-#define CHROME_BROWSER_EXTENSIONS_API_PAGE_LAUNCHER_PAGE_LAUNCHER_API_H_
-
-#include <string>
-
-class GURL;
-class Profile;
-
-namespace extensions {
-
-class PageLauncherAPI {
- public:
- static void DispatchOnClickedEvent(Profile* profile,
- const std::string& extension_id,
- const GURL& url,
- const std::string& mimetype,
- const std::string* page_title,
- const std::string* selected_text);
-};
-
-} // namespace extensions
-
-
-#endif // CHROME_BROWSER_EXTENSIONS_API_PAGE_LAUNCHER_PAGE_LAUNCHER_API_H_
diff --git a/chrome/browser/extensions/api/preference/chrome_direct_setting.cc b/chrome/browser/extensions/api/preference/chrome_direct_setting.cc
index 161ef9b..6d1bd76 100644
--- a/chrome/browser/extensions/api/preference/chrome_direct_setting.cc
+++ b/chrome/browser/extensions/api/preference/chrome_direct_setting.cc
@@ -5,39 +5,16 @@
#include "chrome/browser/extensions/api/preference/chrome_direct_setting.h"
#include "base/containers/hash_tables.h"
+#include "base/lazy_instance.h"
#include "base/prefs/pref_service.h"
#include "base/values.h"
+#include "chrome/browser/extensions/api/preference/chrome_direct_setting_api.h"
#include "chrome/browser/extensions/api/preference/preference_api_constants.h"
#include "chrome/browser/profiles/profile.h"
namespace extensions {
namespace chromedirectsetting {
-namespace {
-
-class PreferenceWhitelist {
- public:
- PreferenceWhitelist() {
- whitelist_.insert("googlegeolocationaccess.enabled");
- }
-
- ~PreferenceWhitelist() {}
-
- bool IsPreferenceOnWhitelist(const std::string& pref_key){
- return whitelist_.find(pref_key) != whitelist_.end();
- }
-
- private:
- base::hash_set<std::string> whitelist_;
-
- DISALLOW_COPY_AND_ASSIGN(PreferenceWhitelist);
-};
-
-static base::LazyInstance<PreferenceWhitelist> preference_whitelist_ =
- LAZY_INSTANCE_INITIALIZER;
-
-} // namespace
-
DirectSettingFunctionBase::DirectSettingFunctionBase() {}
DirectSettingFunctionBase::~DirectSettingFunctionBase() {}
@@ -50,11 +27,6 @@
return GetExtension()->location() == Manifest::COMPONENT;
}
-bool DirectSettingFunctionBase::IsPreferenceOnWhitelist(
- const std::string& pref_key) {
- return preference_whitelist_.Get().IsPreferenceOnWhitelist(pref_key);
-}
-
GetDirectSettingFunction::GetDirectSettingFunction() {}
bool GetDirectSettingFunction::RunImpl() {
@@ -62,7 +34,8 @@
std::string pref_key;
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key));
- EXTENSION_FUNCTION_VALIDATE(IsPreferenceOnWhitelist(pref_key));
+ EXTENSION_FUNCTION_VALIDATE(
+ ChromeDirectSettingAPI::Get(profile())->IsPreferenceOnWhitelist(pref_key));
const PrefService::Preference* preference =
GetPrefService()->FindPreference(pref_key.c_str());
@@ -85,7 +58,8 @@
std::string pref_key;
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key));
- EXTENSION_FUNCTION_VALIDATE(IsPreferenceOnWhitelist(pref_key));
+ EXTENSION_FUNCTION_VALIDATE(
+ ChromeDirectSettingAPI::Get(profile())->IsPreferenceOnWhitelist(pref_key));
DictionaryValue* details = NULL;
EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details));
@@ -115,7 +89,8 @@
std::string pref_key;
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key));
- EXTENSION_FUNCTION_VALIDATE(IsPreferenceOnWhitelist(pref_key));
+ EXTENSION_FUNCTION_VALIDATE(
+ ChromeDirectSettingAPI::Get(profile())->IsPreferenceOnWhitelist(pref_key));
GetPrefService()->ClearPref(pref_key.c_str());
return true;
diff --git a/chrome/browser/extensions/api/preference/chrome_direct_setting.h b/chrome/browser/extensions/api/preference/chrome_direct_setting.h
index 1a8164b..7e36344 100644
--- a/chrome/browser/extensions/api/preference/chrome_direct_setting.h
+++ b/chrome/browser/extensions/api/preference/chrome_direct_setting.h
@@ -25,9 +25,6 @@
// Returns true if the caller is a component extension.
bool IsCalledFromComponentExtension();
- // Returns true if the preference is on the whitelist.
- bool IsPreferenceOnWhitelist(const std::string& pref_key);
-
private:
DISALLOW_COPY_AND_ASSIGN(DirectSettingFunctionBase);
};
diff --git a/chrome/browser/extensions/api/preference/chrome_direct_setting_api.cc b/chrome/browser/extensions/api/preference/chrome_direct_setting_api.cc
new file mode 100644
index 0000000..04b4307
--- /dev/null
+++ b/chrome/browser/extensions/api/preference/chrome_direct_setting_api.cc
@@ -0,0 +1,154 @@
+// Copyright 2013 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/preference/chrome_direct_setting_api.h"
+
+#include "base/bind.h"
+#include "base/containers/hash_tables.h"
+#include "base/lazy_instance.h"
+#include "base/prefs/pref_change_registrar.h"
+#include "base/prefs/pref_service.h"
+#include "base/strings/stringprintf.h"
+#include "chrome/browser/extensions/api/preference/preference_api_constants.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
+
+namespace extensions {
+namespace chromedirectsetting {
+
+const char kOnPrefChangeFormat[] =
+ "types.private.ChromeDirectSetting.%s.onChange";
+
+class PreferenceWhitelist {
+ public:
+ PreferenceWhitelist() {
+ whitelist_.insert("googlegeolocationaccess.enabled");
+ }
+
+ ~PreferenceWhitelist() {}
+
+ bool IsPreferenceOnWhitelist(const std::string& pref_key){
+ return whitelist_.find(pref_key) != whitelist_.end();
+ }
+
+ void RegisterEventListeners(
+ Profile* profile,
+ EventRouter::Observer* observer) {
+ for (base::hash_set<std::string>::iterator iter = whitelist_.begin();
+ iter != whitelist_.end();
+ iter++) {
+ std::string event_name = base::StringPrintf(
+ kOnPrefChangeFormat,
+ (*iter).c_str());
+ ExtensionSystem::Get(profile)->event_router()->RegisterObserver(
+ observer,
+ event_name);
+ }
+ }
+
+ void RegisterPropertyListeners(
+ Profile* profile,
+ PrefChangeRegistrar* registrar,
+ const base::Callback<void(const std::string&)>& callback) {
+ for (base::hash_set<std::string>::iterator iter = whitelist_.begin();
+ iter != whitelist_.end();
+ iter++) {
+ const char* pref_key = (*iter).c_str();
+ std::string event_name = base::StringPrintf(
+ kOnPrefChangeFormat,
+ pref_key);
+ registrar->Add(pref_key, callback);
+ }
+ }
+
+ private:
+ base::hash_set<std::string> whitelist_;
+
+ DISALLOW_COPY_AND_ASSIGN(PreferenceWhitelist);
+};
+
+base::LazyInstance<PreferenceWhitelist> preference_whitelist =
+ LAZY_INSTANCE_INITIALIZER;
+
+static base::LazyInstance<ProfileKeyedAPIFactory<ChromeDirectSettingAPI> >
+ g_factory = LAZY_INSTANCE_INITIALIZER;
+
+ChromeDirectSettingAPI::ChromeDirectSettingAPI(Profile* profile)
+ : profile_(profile) {
+ preference_whitelist.Get().RegisterEventListeners(profile, this);
+}
+
+ChromeDirectSettingAPI::~ChromeDirectSettingAPI() {}
+
+// BrowserContextKeyedService implementation.
+void ChromeDirectSettingAPI::Shutdown() {}
+
+// ProfileKeyedAPI implementation.
+ProfileKeyedAPIFactory<ChromeDirectSettingAPI>*
+ ChromeDirectSettingAPI::GetFactoryInstance() {
+ return &g_factory.Get();
+}
+
+// EventRouter::Observer implementation.
+void ChromeDirectSettingAPI::OnListenerAdded(const EventListenerInfo& details) {
+ ExtensionSystem::Get(profile_)->event_router()->UnregisterObserver(this);
+ registrar_.Init(profile_->GetPrefs());
+ preference_whitelist.Get().RegisterPropertyListeners(
+ profile_,
+ ®istrar_,
+ base::Bind(&ChromeDirectSettingAPI::OnPrefChanged,
+ base::Unretained(this),
+ registrar_.prefs()));
+}
+
+bool ChromeDirectSettingAPI::IsPreferenceOnWhitelist(
+ const std::string& pref_key) {
+ return preference_whitelist.Get().IsPreferenceOnWhitelist(pref_key);
+}
+
+ChromeDirectSettingAPI* ChromeDirectSettingAPI::Get(Profile* profile) {
+ return
+ ProfileKeyedAPIFactory<ChromeDirectSettingAPI>::GetForProfile(profile);
+}
+
+// ProfileKeyedAPI implementation.
+const char* ChromeDirectSettingAPI::service_name() {
+ return "ChromeDirectSettingAPI";
+}
+
+void ChromeDirectSettingAPI::OnPrefChanged(
+ PrefService* pref_service, const std::string& pref_key) {
+ std::string event_name = base::StringPrintf(kOnPrefChangeFormat,
+ pref_key.c_str());
+ EventRouter* router = ExtensionSystem::Get(profile_)->event_router();
+ if (router && router->HasEventListener(event_name)) {
+ const PrefService::Preference* preference =
+ profile_->GetPrefs()->FindPreference(pref_key.c_str());
+ const base::Value* value = preference->GetValue();
+
+ scoped_ptr<DictionaryValue> result(new DictionaryValue);
+ result->Set(preference_api_constants::kValue, value->DeepCopy());
+ base::ListValue args;
+ args.Append(result.release());
+
+ ExtensionService* extension_service =
+ ExtensionSystem::Get(profile_)->extension_service();
+ const ExtensionSet* extensions = extension_service->extensions();
+ for (ExtensionSet::const_iterator it = extensions->begin();
+ it != extensions->end(); ++it) {
+ if ((*it)->location() == Manifest::COMPONENT) {
+ std::string extension_id = (*it)->id();
+ if (router->ExtensionHasEventListener(extension_id, event_name)) {
+ scoped_ptr<base::ListValue> args_copy(args.DeepCopy());
+ scoped_ptr<Event> event(new Event(event_name, args_copy.Pass()));
+ router->DispatchEventToExtension(extension_id, event.Pass());
+ }
+ }
+ }
+ }
+}
+
+} // namespace chromedirectsetting
+} // namespace extensions
+
diff --git a/chrome/browser/extensions/api/preference/chrome_direct_setting_api.h b/chrome/browser/extensions/api/preference/chrome_direct_setting_api.h
new file mode 100644
index 0000000..4d5e9ff
--- /dev/null
+++ b/chrome/browser/extensions/api/preference/chrome_direct_setting_api.h
@@ -0,0 +1,60 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_API_PREFERENCE_CHROME_DIRECT_SETTING_API_H__
+#define CHROME_BROWSER_EXTENSIONS_API_PREFERENCE_CHROME_DIRECT_SETTING_API_H__
+
+#include "base/prefs/pref_change_registrar.h"
+#include "chrome/browser/extensions/api/profile_keyed_api_factory.h"
+#include "chrome/browser/extensions/event_router.h"
+
+class Profile;
+
+namespace extensions {
+namespace chromedirectsetting {
+
+class ChromeDirectSettingAPI : public ProfileKeyedAPI,
+ public EventRouter::Observer {
+ public:
+ explicit ChromeDirectSettingAPI(Profile* profile);
+
+ virtual ~ChromeDirectSettingAPI();
+
+ // BrowserContextKeyedService implementation.
+ virtual void Shutdown() OVERRIDE;
+
+ // ProfileKeyedAPI implementation.
+ static ProfileKeyedAPIFactory<ChromeDirectSettingAPI>* GetFactoryInstance();
+
+ // EventRouter::Observer implementation.
+ virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE;
+
+ // Returns true if the preference is on the whitelist.
+ bool IsPreferenceOnWhitelist(const std::string& pref_key);
+
+ // Convenience method to get the ChromeDirectSettingAPI for a profile.
+ static ChromeDirectSettingAPI* Get(Profile* profile);
+
+ private:
+ friend class ProfileKeyedAPIFactory<ChromeDirectSettingAPI>;
+
+ // ProfileKeyedAPI implementation.
+ static const char* service_name();
+
+ void OnPrefChanged(PrefService* pref_service, const std::string& pref_key);
+
+ static const bool kServiceIsNULLWhileTesting = true;
+ static const bool kServiceRedirectedInIncognito = false;
+
+ PrefChangeRegistrar registrar_;
+ Profile* profile_;
+
+ DISALLOW_COPY_AND_ASSIGN(ChromeDirectSettingAPI);
+};
+
+} // namespace chromedirectsetting
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_API_PREFERENCE_CHROME_DIRECT_SETTING_API_H__
+
diff --git a/chrome/browser/extensions/api/preference/preference_apitest.cc b/chrome/browser/extensions/api/preference/preference_apitest.cc
index 7b0aab5..98be5cd 100644
--- a/chrome/browser/extensions/api/preference/preference_apitest.cc
+++ b/chrome/browser/extensions/api/preference/preference_apitest.cc
@@ -11,7 +11,6 @@
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/ui_test_utils.h"
-#include "webkit/plugins/npapi/mock_plugin_list.h"
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, PreferenceApi) {
PrefService* pref_service = browser()->profile()->GetPrefs();
diff --git a/chrome/browser/extensions/api/push_messaging/push_messaging_apitest.cc b/chrome/browser/extensions/api/push_messaging/push_messaging_apitest.cc
index 6a38470..c766c21 100644
--- a/chrome/browser/extensions/api/push_messaging/push_messaging_apitest.cc
+++ b/chrome/browser/extensions/api/push_messaging/push_messaging_apitest.cc
@@ -81,7 +81,10 @@
void EmitInvalidation(
const invalidation::ObjectId& object_id,
const std::string& payload) {
- fake_invalidation_service_->EmitInvalidationForTest(object_id, payload);
+ fake_invalidation_service_->EmitInvalidationForTest(
+ object_id,
+ syncer::Invalidation::kUnknownVersion,
+ payload);
}
PushMessagingAPI* GetAPI() {
diff --git a/chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler_unittest.cc b/chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler_unittest.cc
index 9db3b46..2b0fac4 100644
--- a/chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler_unittest.cc
+++ b/chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler_unittest.cc
@@ -121,7 +121,10 @@
*it, syncer::AckHandle::InvalidAckHandle()));
}
handler_->OnIncomingInvalidation(
- ObjectIdSetToInvalidationMap(ids, "payload"));
+ ObjectIdSetToInvalidationMap(
+ ids,
+ syncer::Invalidation::kUnknownVersion,
+ "payload"));
}
// Tests that malformed object IDs don't trigger spurious callbacks.
@@ -158,7 +161,10 @@
*it, syncer::AckHandle::InvalidAckHandle()));
}
handler_->OnIncomingInvalidation(
- ObjectIdSetToInvalidationMap(ids, "payload"));
+ ObjectIdSetToInvalidationMap(
+ ids,
+ syncer::Invalidation::kUnknownVersion,
+ "payload"));
}
} // namespace extensions
diff --git a/chrome/browser/extensions/api/runtime/runtime_api.cc b/chrome/browser/extensions/api/runtime/runtime_api.cc
index 146410f..6143f15 100644
--- a/chrome/browser/extensions/api/runtime/runtime_api.cc
+++ b/chrome/browser/extensions/api/runtime/runtime_api.cc
@@ -142,11 +142,6 @@
if (!system)
return;
- // Special case: normally, extensions add their own lazy event listeners.
- // However, since the extension has just been installed, it hasn't had a
- // chance to register for events. So we register on its behalf. If the
- // extension does not actually have a listener, the event will just be
- // ignored.
scoped_ptr<base::ListValue> event_args(new base::ListValue());
base::DictionaryValue* info = new base::DictionaryValue();
event_args->Append(info);
@@ -159,11 +154,9 @@
info->SetString(kInstallReason, kInstallReasonInstall);
}
DCHECK(system->event_router());
- system->event_router()->AddLazyEventListener(kOnInstalledEvent, extension_id);
scoped_ptr<Event> event(new Event(kOnInstalledEvent, event_args.Pass()));
- system->event_router()->DispatchEventToExtension(extension_id, event.Pass());
- system->event_router()->RemoveLazyEventListener(kOnInstalledEvent,
- extension_id);
+ system->event_router()->DispatchEventWithLazyListener(extension_id,
+ event.Pass());
}
// static
diff --git a/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc b/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc
index 7b507b2..071d1d0 100644
--- a/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc
+++ b/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc
@@ -26,6 +26,10 @@
#include "net/test/embedded_test_server/http_response.h"
#include "testing/gmock/include/gmock/gmock.h"
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
using content::BrowserContext;
using content::BrowserThread;
using content::DownloadItem;
@@ -202,6 +206,12 @@
// installed, white-listed extension invokes the extension's
// onExecuteContentHandler event (and does not start a download).
IN_PROC_BROWSER_TEST_F(StreamsPrivateApiTest, Navigate) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
ASSERT_TRUE(LoadTestExtension()) << message_;
ResultCatcher catcher;
diff --git a/chrome/browser/extensions/api/system_info_display/display_info_provider.cc b/chrome/browser/extensions/api/system_display/display_info_provider.cc
similarity index 78%
rename from chrome/browser/extensions/api/system_info_display/display_info_provider.cc
rename to chrome/browser/extensions/api/system_display/display_info_provider.cc
index 9534ed3..c97435e 100644
--- a/chrome/browser/extensions/api/system_info_display/display_info_provider.cc
+++ b/chrome/browser/extensions/api/system_display/display_info_provider.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 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/system_info_display/display_info_provider.h"
+#include "chrome/browser/extensions/api/system_display/display_info_provider.h"
namespace extensions {
diff --git a/chrome/browser/extensions/api/system_info_display/display_info_provider.h b/chrome/browser/extensions/api/system_display/display_info_provider.h
similarity index 77%
rename from chrome/browser/extensions/api/system_info_display/display_info_provider.h
rename to chrome/browser/extensions/api/system_display/display_info_provider.h
index 63a7077..037b5f1 100644
--- a/chrome/browser/extensions/api/system_info_display/display_info_provider.h
+++ b/chrome/browser/extensions/api/system_display/display_info_provider.h
@@ -1,19 +1,19 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 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.
-#ifndef CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_DISPLAY_DISPLAY_INFO_PROVIDER_H_
-#define CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_DISPLAY_DISPLAY_INFO_PROVIDER_H_
+#ifndef CHROME_BROWSER_EXTENSIONS_API_SYSTEM_DISPLAY_DISPLAY_INFO_PROVIDER_H_
+#define CHROME_BROWSER_EXTENSIONS_API_SYSTEM_DISPLAY_DISPLAY_INFO_PROVIDER_H_
#include <string>
#include "chrome/browser/extensions/api/system_info/system_info_provider.h"
-#include "chrome/common/extensions/api/system_info_display.h"
+#include "chrome/common/extensions/api/system_display.h"
namespace extensions {
typedef std::vector<linked_ptr<
- api::system_info_display::DisplayUnitInfo> > DisplayInfo;
+ api::system_display::DisplayUnitInfo> > DisplayInfo;
class DisplayInfoProvider : public SystemInfoProvider<DisplayInfo> {
public:
@@ -39,7 +39,7 @@
// This functionality is exposed only on ChromeOS.
virtual void SetInfo(
const std::string& display_id,
- const api::system_info_display::DisplayProperties& info,
+ const api::system_display::DisplayProperties& info,
const SetInfoCallback& callback);
const DisplayInfo& display_info() const;
@@ -59,4 +59,4 @@
} // namespace extensions
-#endif // CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_DISPLAY_DISPLAY_INFO_PROVIDER_H_
+#endif // CHROME_BROWSER_EXTENSIONS_API_SYSTEM_DISPLAY_DISPLAY_INFO_PROVIDER_H_
diff --git a/chrome/browser/extensions/api/system_info_display/display_info_provider_chromeos.cc b/chrome/browser/extensions/api/system_display/display_info_provider_chromeos.cc
similarity index 96%
rename from chrome/browser/extensions/api/system_info_display/display_info_provider_chromeos.cc
rename to chrome/browser/extensions/api/system_display/display_info_provider_chromeos.cc
index e680bc2..712bc52 100644
--- a/chrome/browser/extensions/api/system_info_display/display_info_provider_chromeos.cc
+++ b/chrome/browser/extensions/api/system_display/display_info_provider_chromeos.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright 2013 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/system_info_display/display_info_provider.h"
+#include "chrome/browser/extensions/api/system_display/display_info_provider.h"
#include "ash/display/display_controller.h"
#include "ash/display/display_manager.h"
@@ -18,10 +18,10 @@
namespace extensions {
-using api::system_info_display::Bounds;
-using api::system_info_display::DisplayUnitInfo;
-using api::system_info_display::DisplayProperties;
-using api::system_info_display::Insets;
+using api::system_display::Bounds;
+using api::system_display::DisplayUnitInfo;
+using api::system_display::DisplayProperties;
+using api::system_display::Insets;
namespace {
@@ -73,8 +73,8 @@
DisplayManager* display_manager,
int64 primary_display_id,
DisplayInfo* list) {
- linked_ptr<extensions::api::system_info_display::DisplayUnitInfo> unit(
- new extensions::api::system_info_display::DisplayUnitInfo());
+ linked_ptr<extensions::api::system_display::DisplayUnitInfo> unit(
+ new extensions::api::system_display::DisplayUnitInfo());
const gfx::Rect& bounds = display.bounds();
const gfx::Rect& work_area = display.work_area();
const float dpi = display.device_scale_factor() * kDpi96;
@@ -437,7 +437,7 @@
int64 primary_id = ash::Shell::GetScreen()->GetPrimaryDisplay().id();
for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
- AddInfoForDisplay(*display_manager->GetDisplayAt(i), display_manager,
+ AddInfoForDisplay(display_manager->GetDisplayAt(i), display_manager,
primary_id, &info_);
}
diff --git a/chrome/browser/extensions/api/system_info_display/display_info_provider_chromeos_unittest.cc b/chrome/browser/extensions/api/system_display/display_info_provider_chromeos_unittest.cc
similarity index 73%
rename from chrome/browser/extensions/api/system_info_display/display_info_provider_chromeos_unittest.cc
rename to chrome/browser/extensions/api/system_display/display_info_provider_chromeos_unittest.cc
index d157a26..5960313 100644
--- a/chrome/browser/extensions/api/system_info_display/display_info_provider_chromeos_unittest.cc
+++ b/chrome/browser/extensions/api/system_display/display_info_provider_chromeos_unittest.cc
@@ -2,10 +2,11 @@
// 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/system_info_display/display_info_provider.h"
+#include "chrome/browser/extensions/api/system_display/display_info_provider.h"
#include "ash/display/display_controller.h"
#include "ash/display/display_manager.h"
+#include "ash/screen_ash.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/display_manager_test_api.h"
@@ -45,7 +46,7 @@
void CallSetDisplayUnitInfo(
const std::string& display_id,
- const api::system_info_display::DisplayProperties& info,
+ const api::system_display::DisplayProperties& info,
bool* success,
std::string* error) {
DisplayInfoProvider::GetProvider()->SetInfo(display_id, info,
@@ -68,14 +69,14 @@
}
std::string SystemInfoDisplayInsetsToString(
- const api::system_info_display::Insets& insets) const {
+ const api::system_display::Insets& insets) const {
// Order to match gfx::Insets::ToString().
return base::StringPrintf("%d,%d,%d,%d",
insets.top, insets.left, insets.bottom, insets.right);
}
std::string SystemInfoDisplayBoundsToString(
- const api::system_info_display::Bounds& bounds) const {
+ const api::system_display::Bounds& bounds) const {
// Order to match gfx::Rect::ToString().
return base::StringPrintf("%d,%d %dx%d",
bounds.left, bounds.top, bounds.width, bounds.height);
@@ -331,347 +332,347 @@
TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginLeftExact) {
UpdateDisplay("1200x600,520x400");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
info.bounds_origin_x.reset(new int(-520));
info.bounds_origin_y.reset(new int(50));
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_TRUE(success);
ASSERT_TRUE(error.empty());
- EXPECT_EQ("-520,50 520x400", secondary->bounds().ToString());
+ EXPECT_EQ("-520,50 520x400", secondary.bounds().ToString());
}
TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginRightExact) {
UpdateDisplay("1200x600,520x400");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
info.bounds_origin_x.reset(new int(1200));
info.bounds_origin_y.reset(new int(100));
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_TRUE(success);
ASSERT_TRUE(error.empty());
- EXPECT_EQ("1200,100 520x400", secondary->bounds().ToString());
+ EXPECT_EQ("1200,100 520x400", secondary.bounds().ToString());
}
TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginTopExact) {
UpdateDisplay("1200x600,520x400");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
info.bounds_origin_x.reset(new int(1100));
info.bounds_origin_y.reset(new int(-400));
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_TRUE(success);
ASSERT_TRUE(error.empty());
- EXPECT_EQ("1100,-400 520x400", secondary->bounds().ToString());
+ EXPECT_EQ("1100,-400 520x400", secondary.bounds().ToString());
}
TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginBottomExact) {
UpdateDisplay("1200x600,520x400");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
info.bounds_origin_x.reset(new int(-350));
info.bounds_origin_y.reset(new int(600));
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_TRUE(success);
ASSERT_TRUE(error.empty());
- EXPECT_EQ("-350,600 520x400", secondary->bounds().ToString());
+ EXPECT_EQ("-350,600 520x400", secondary.bounds().ToString());
}
TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginSameCenter) {
UpdateDisplay("1200x600,520x400");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
info.bounds_origin_x.reset(new int(340));
info.bounds_origin_y.reset(new int(100));
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_TRUE(success);
ASSERT_TRUE(error.empty());
- EXPECT_EQ("1200,100 520x400", secondary->bounds().ToString());
+ EXPECT_EQ("1200,100 520x400", secondary.bounds().ToString());
}
TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginLeftOutside) {
UpdateDisplay("1200x600,520x400");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
info.bounds_origin_x.reset(new int(-1040));
info.bounds_origin_y.reset(new int(100));
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_TRUE(success);
ASSERT_TRUE(error.empty());
- EXPECT_EQ("-520,100 520x400", secondary->bounds().ToString());
+ EXPECT_EQ("-520,100 520x400", secondary.bounds().ToString());
}
TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginTopOutside) {
UpdateDisplay("1200x600,520x400");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
info.bounds_origin_x.reset(new int(-360));
info.bounds_origin_y.reset(new int(-301));
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_TRUE(success);
ASSERT_TRUE(error.empty());
- EXPECT_EQ("-360,-400 520x400", secondary->bounds().ToString());
+ EXPECT_EQ("-360,-400 520x400", secondary.bounds().ToString());
}
TEST_F(DisplayInfoProviderChromeosTest,
SetBoundsOriginLeftButSharesBottomSide) {
UpdateDisplay("1200x600,1000x100");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
info.bounds_origin_x.reset(new int(-650));
info.bounds_origin_y.reset(new int(700));
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_TRUE(success);
ASSERT_TRUE(error.empty());
- EXPECT_EQ("-650,600 1000x100", secondary->bounds().ToString());
+ EXPECT_EQ("-650,600 1000x100", secondary.bounds().ToString());
}
TEST_F(DisplayInfoProviderChromeosTest,
SetBoundsOriginRightButSharesTopSide) {
UpdateDisplay("1200x600,1000x100");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
info.bounds_origin_x.reset(new int(850));
info.bounds_origin_y.reset(new int(-150));
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_TRUE(success);
ASSERT_TRUE(error.empty());
- EXPECT_EQ("850,-100 1000x100", secondary->bounds().ToString());
+ EXPECT_EQ("850,-100 1000x100", secondary.bounds().ToString());
}
TEST_F(DisplayInfoProviderChromeosTest,
SetBoundsOriginTopButSharesLeftSide) {
UpdateDisplay("1200x600,1000x100/l");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
info.bounds_origin_x.reset(new int(-150));
info.bounds_origin_y.reset(new int(-650));
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_TRUE(success);
ASSERT_TRUE(error.empty());
- EXPECT_EQ("-100,-650 100x1000", secondary->bounds().ToString());
+ EXPECT_EQ("-100,-650 100x1000", secondary.bounds().ToString());
}
TEST_F(DisplayInfoProviderChromeosTest,
SetBoundsOriginBottomButSharesRightSide) {
UpdateDisplay("1200x600,1000x100/l");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
info.bounds_origin_x.reset(new int(1350));
info.bounds_origin_y.reset(new int(450));
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_TRUE(success);
ASSERT_TRUE(error.empty());
- EXPECT_EQ("1200,450 100x1000", secondary->bounds().ToString());
+ EXPECT_EQ("1200,450 100x1000", secondary.bounds().ToString());
}
TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginPrimaryHiDPI) {
UpdateDisplay("1200x600*2,500x500");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
info.bounds_origin_x.reset(new int(250));
info.bounds_origin_y.reset(new int(-100));
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_TRUE(success);
ASSERT_TRUE(error.empty());
- EXPECT_EQ("600,-100 500x500", secondary->bounds().ToString());
+ EXPECT_EQ("600,-100 500x500", secondary.bounds().ToString());
}
TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginSecondaryHiDPI) {
UpdateDisplay("1200x600,600x1000*2");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
info.bounds_origin_x.reset(new int(450));
info.bounds_origin_y.reset(new int(-100));
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_TRUE(success);
ASSERT_TRUE(error.empty());
- EXPECT_EQ("450,-500 300x500", secondary->bounds().ToString());
+ EXPECT_EQ("450,-500 300x500", secondary.bounds().ToString());
}
TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginOutOfBounds) {
UpdateDisplay("1200x600,600x1000*2");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
info.bounds_origin_x.reset(new int(0x200001));
info.bounds_origin_y.reset(new int(-100));
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_FALSE(success);
ASSERT_EQ("Bounds origin x out of bounds.", error);
- EXPECT_EQ("1200,0 300x500", secondary->bounds().ToString());
+ EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString());
}
TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginOutOfBoundsNegative) {
UpdateDisplay("1200x600,600x1000*2");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
info.bounds_origin_x.reset(new int(300));
info.bounds_origin_y.reset(new int(-0x200001));
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_FALSE(success);
ASSERT_EQ("Bounds origin y out of bounds.", error);
- EXPECT_EQ("1200,0 300x500", secondary->bounds().ToString());
+ EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString());
}
TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginMaxValues) {
UpdateDisplay("1200x4600,600x1000*2");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
info.bounds_origin_x.reset(new int(200000));
info.bounds_origin_y.reset(new int(10));
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_TRUE(success);
EXPECT_TRUE(error.empty());
- EXPECT_EQ("1200,10 300x500", secondary->bounds().ToString());
+ EXPECT_EQ("1200,10 300x500", secondary.bounds().ToString());
}
TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginOnPrimary) {
UpdateDisplay("1200x600,600x1000*2");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
info.bounds_origin_x.reset(new int(300));
info.is_primary.reset(new bool(true));
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_FALSE(success);
ASSERT_EQ("Bounds origin not allowed for the primary display.", error);
- EXPECT_EQ("1200,0 300x500", secondary->bounds().ToString());
+ EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString());
// The operation failed because the primary property would be set before
// setting bounds. The primary display shouldn't have been changed, though.
- EXPECT_NE(ash::DisplayController::GetPrimaryDisplay().id(), secondary->id());
+ EXPECT_NE(ash::DisplayController::GetPrimaryDisplay().id(), secondary.id());
}
TEST_F(DisplayInfoProviderChromeosTest, SetBoundsOriginWithMirroring) {
UpdateDisplay("1200x600,600x1000*2");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
const gfx::Display& primary = GetDisplayController()->GetPrimaryDisplay();
- api::system_info_display::DisplayProperties info;
+ api::system_display::DisplayProperties info;
info.bounds_origin_x.reset(new int(300));
info.mirroring_source_id.reset(
new std::string(base::Int64ToString(primary.id())));
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_FALSE(success);
@@ -682,66 +683,66 @@
TEST_F(DisplayInfoProviderChromeosTest, SetRotation) {
UpdateDisplay("1200x600,600x1000*2");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
info.rotation.reset(new int(90));
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_TRUE(success);
EXPECT_TRUE(error.empty());
- EXPECT_EQ("1200,0 500x300", secondary->bounds().ToString());
- EXPECT_EQ(gfx::Display::ROTATE_90, secondary->rotation());
+ EXPECT_EQ("1200,0 500x300", secondary.bounds().ToString());
+ EXPECT_EQ(gfx::Display::ROTATE_90, secondary.rotation());
info.rotation.reset(new int(270));
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_TRUE(success);
EXPECT_TRUE(error.empty());
- EXPECT_EQ("1200,0 500x300", secondary->bounds().ToString());
- EXPECT_EQ(gfx::Display::ROTATE_270, secondary->rotation());
+ EXPECT_EQ("1200,0 500x300", secondary.bounds().ToString());
+ EXPECT_EQ(gfx::Display::ROTATE_270, secondary.rotation());
info.rotation.reset(new int(180));
// Switch primary display.
info.is_primary.reset(new bool(true));
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_TRUE(success);
EXPECT_TRUE(error.empty());
- EXPECT_EQ("0,0 300x500", secondary->bounds().ToString());
- EXPECT_EQ(gfx::Display::ROTATE_180, secondary->rotation());
- EXPECT_EQ(ash::DisplayController::GetPrimaryDisplay().id(), secondary->id());
+ EXPECT_EQ("0,0 300x500", secondary.bounds().ToString());
+ EXPECT_EQ(gfx::Display::ROTATE_180, secondary.rotation());
+ EXPECT_EQ(ash::DisplayController::GetPrimaryDisplay().id(), secondary.id());
info.rotation.reset(new int(0));
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_TRUE(success);
EXPECT_TRUE(error.empty());
- EXPECT_EQ("0,0 300x500", secondary->bounds().ToString());
- EXPECT_EQ(gfx::Display::ROTATE_0, secondary->rotation());
- EXPECT_EQ(ash::DisplayController::GetPrimaryDisplay().id(), secondary->id());
+ EXPECT_EQ("0,0 300x500", secondary.bounds().ToString());
+ EXPECT_EQ(gfx::Display::ROTATE_0, secondary.rotation());
+ EXPECT_EQ(ash::DisplayController::GetPrimaryDisplay().id(), secondary.id());
}
TEST_F(DisplayInfoProviderChromeosTest, SetInvalidRotation) {
UpdateDisplay("1200x600,600x1000*2");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
info.rotation.reset(new int(91));
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_FALSE(success);
@@ -751,72 +752,72 @@
TEST_F(DisplayInfoProviderChromeosTest, SetNegativeOverscan) {
UpdateDisplay("1200x600,600x1000*2");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
- info.overscan.reset(new api::system_info_display::Insets);
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
+ info.overscan.reset(new api::system_display::Insets);
info.overscan->left= -10;
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_FALSE(success);
EXPECT_EQ("Negative overscan not allowed.", error);
- EXPECT_EQ("1200,0 300x500", secondary->bounds().ToString());
+ EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString());
info.overscan->left= 0;
info.overscan->right = -200;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_FALSE(success);
EXPECT_EQ("Negative overscan not allowed.", error);
- EXPECT_EQ("1200,0 300x500", secondary->bounds().ToString());
+ EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString());
info.overscan->right= 0;
info.overscan->top = -300;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_FALSE(success);
EXPECT_EQ("Negative overscan not allowed.", error);
- EXPECT_EQ("1200,0 300x500", secondary->bounds().ToString());
+ EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString());
info.overscan->right= 0;
info.overscan->top = -1000;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_FALSE(success);
EXPECT_EQ("Negative overscan not allowed.", error);
- EXPECT_EQ("1200,0 300x500", secondary->bounds().ToString());
+ EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString());
info.overscan->right= 0;
info.overscan->top = 0;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_TRUE(success);
EXPECT_TRUE(error.empty());
- EXPECT_EQ("1200,0 300x500", secondary->bounds().ToString());
+ EXPECT_EQ("1200,0 300x500", secondary.bounds().ToString());
}
TEST_F(DisplayInfoProviderChromeosTest, SetOverscanLargerThanHorizontalBounds) {
UpdateDisplay("1200x600,600x1000*2");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
- info.overscan.reset(new api::system_info_display::Insets);
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
+ info.overscan.reset(new api::system_display::Insets);
// Horizontal overscan is 151, which would make the bounds width 149.
info.overscan->left= 50;
info.overscan->top = 10;
@@ -825,7 +826,7 @@
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_FALSE(success);
@@ -836,9 +837,9 @@
TEST_F(DisplayInfoProviderChromeosTest, SetOverscanLargerThanVerticalBounds) {
UpdateDisplay("1200x600,600x1000");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
- info.overscan.reset(new api::system_info_display::Insets);
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
+ info.overscan.reset(new api::system_display::Insets);
// Vertical overscan is 501, which would make the bounds height 499.
info.overscan->left= 20;
info.overscan->top = 250;
@@ -847,7 +848,7 @@
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_FALSE(success);
@@ -858,9 +859,9 @@
TEST_F(DisplayInfoProviderChromeosTest, SetOverscan) {
UpdateDisplay("1200x600,600x1000*2");
- const gfx::Display* secondary = GetDisplayController()->GetSecondaryDisplay();
- api::system_info_display::DisplayProperties info;
- info.overscan.reset(new api::system_info_display::Insets);
+ const gfx::Display& secondary = ash::ScreenAsh::GetSecondaryDisplay();
+ api::system_display::DisplayProperties info;
+ info.overscan.reset(new api::system_display::Insets);
info.overscan->left= 20;
info.overscan->top = 199;
info.overscan->right = 130;
@@ -868,15 +869,15 @@
bool success = false;
std::string error;
- CallSetDisplayUnitInfo(base::Int64ToString(secondary->id()), info,
+ CallSetDisplayUnitInfo(base::Int64ToString(secondary.id()), info,
&success, &error);
ASSERT_TRUE(success);
EXPECT_TRUE(error.empty());
- EXPECT_EQ("1200,0 150x250", secondary->bounds().ToString());
+ EXPECT_EQ("1200,0 150x250", secondary.bounds().ToString());
const gfx::Insets overscan =
- GetDisplayManager()->GetOverscanInsets(secondary->id());
+ GetDisplayManager()->GetOverscanInsets(secondary.id());
EXPECT_EQ(20, overscan.left());
EXPECT_EQ(199, overscan.top());
@@ -890,8 +891,8 @@
ash::test::DisplayManagerTestApi(GetDisplayManager()).
SetFirstDisplayAsInternalDisplay();
- api::system_info_display::DisplayProperties info;
- info.overscan.reset(new api::system_info_display::Insets);
+ api::system_display::DisplayProperties info;
+ info.overscan.reset(new api::system_display::Insets);
// Vertical overscan is 501, which would make the bounds height 499.
info.overscan->left= 20;
info.overscan->top = 20;
diff --git a/chrome/browser/extensions/api/system_info_display/display_info_provider_mac.cc b/chrome/browser/extensions/api/system_display/display_info_provider_mac.cc
similarity index 75%
rename from chrome/browser/extensions/api/system_info_display/display_info_provider_mac.cc
rename to chrome/browser/extensions/api/system_display/display_info_provider_mac.cc
index 3ff9d6b..2b22e1e 100644
--- a/chrome/browser/extensions/api/system_info_display/display_info_provider_mac.cc
+++ b/chrome/browser/extensions/api/system_display/display_info_provider_mac.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 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/system_info_display/display_info_provider.h"
+#include "chrome/browser/extensions/api/system_display/display_info_provider.h"
namespace extensions {
@@ -13,7 +13,7 @@
void DisplayInfoProvider::SetInfo(
const std::string& display_id,
- const api::system_info_display::DisplayProperties& info,
+ const api::system_display::DisplayProperties& info,
const SetInfoCallback& callback) {
base::MessageLoopProxy::current()->PostTask(
FROM_HERE,
diff --git a/chrome/browser/extensions/api/system_info_display/display_info_provider_win.cc b/chrome/browser/extensions/api/system_display/display_info_provider_win.cc
similarity index 89%
rename from chrome/browser/extensions/api/system_info_display/display_info_provider_win.cc
rename to chrome/browser/extensions/api/system_display/display_info_provider_win.cc
index e242fbb..9d21278 100644
--- a/chrome/browser/extensions/api/system_info_display/display_info_provider_win.cc
+++ b/chrome/browser/extensions/api/system_display/display_info_provider_win.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 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/system_info_display/display_info_provider.h"
+#include "chrome/browser/extensions/api/system_display/display_info_provider.h"
#include <windows.h>
@@ -13,8 +13,8 @@
namespace extensions {
-using api::system_info_display::Bounds;
-using api::system_info_display::DisplayUnitInfo;
+using api::system_display::Bounds;
+using api::system_display::DisplayUnitInfo;
namespace {
@@ -74,7 +74,7 @@
void DisplayInfoProvider::SetInfo(
const std::string& display_id,
- const api::system_info_display::DisplayProperties& info,
+ const api::system_display::DisplayProperties& info,
const SetInfoCallback& callback) {
base::MessageLoopProxy::current()->PostTask(
FROM_HERE,
diff --git a/chrome/browser/extensions/api/system_info_display/display_info_provider_x11.cc b/chrome/browser/extensions/api/system_display/display_info_provider_x11.cc
similarity index 75%
rename from chrome/browser/extensions/api/system_info_display/display_info_provider_x11.cc
rename to chrome/browser/extensions/api/system_display/display_info_provider_x11.cc
index a3f46d0..adfdb14 100644
--- a/chrome/browser/extensions/api/system_info_display/display_info_provider_x11.cc
+++ b/chrome/browser/extensions/api/system_display/display_info_provider_x11.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 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/system_info_display/display_info_provider.h"
+#include "chrome/browser/extensions/api/system_display/display_info_provider.h"
namespace extensions {
@@ -13,7 +13,7 @@
void DisplayInfoProvider::SetInfo(
const std::string& display_id,
- const api::system_info_display::DisplayProperties& info,
+ const api::system_display::DisplayProperties& info,
const SetInfoCallback& callback) {
base::MessageLoopProxy::current()->PostTask(
FROM_HERE,
diff --git a/chrome/browser/extensions/api/system_info_display/system_info_display_api.cc b/chrome/browser/extensions/api/system_display/system_display_api.cc
similarity index 60%
rename from chrome/browser/extensions/api/system_info_display/system_info_display_api.cc
rename to chrome/browser/extensions/api/system_display/system_display_api.cc
index d2c8748..8819a8c 100644
--- a/chrome/browser/extensions/api/system_info_display/system_info_display_api.cc
+++ b/chrome/browser/extensions/api/system_display/system_display_api.cc
@@ -1,30 +1,30 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 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/system_info_display/system_info_display_api.h"
+#include "chrome/browser/extensions/api/system_display/system_display_api.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/common/extensions/manifest_handlers/kiosk_enabled_info.h"
namespace extensions {
-using api::system_info_display::DisplayUnitInfo;
+using api::system_display::DisplayUnitInfo;
-namespace SetDisplayProperties = api::system_info_display::SetDisplayProperties;
+namespace SetDisplayProperties = api::system_display::SetDisplayProperties;
-bool SystemInfoDisplayGetDisplayInfoFunction::RunImpl() {
+bool SystemDisplayGetInfoFunction::RunImpl() {
DisplayInfoProvider::GetProvider()->RequestInfo(
base::Bind(
- &SystemInfoDisplayGetDisplayInfoFunction::OnGetDisplayInfoCompleted,
+ &SystemDisplayGetInfoFunction::OnGetDisplayInfoCompleted,
this));
return true;
}
-void SystemInfoDisplayGetDisplayInfoFunction::OnGetDisplayInfoCompleted(
+void SystemDisplayGetInfoFunction::OnGetDisplayInfoCompleted(
bool success) {
if (success) {
- results_ = api::system_info_display::GetDisplayInfo::Results::Create(
+ results_ = api::system_display::GetInfo::Results::Create(
DisplayInfoProvider::GetProvider()->display_info());
} else {
SetError("Error occurred when querying display information.");
@@ -32,7 +32,7 @@
SendResponse(success);
}
-bool SystemInfoDisplaySetDisplayPropertiesFunction::RunImpl() {
+bool SystemDisplaySetDisplayPropertiesFunction::RunImpl() {
#if !defined(OS_CHROMEOS)
SetError("Function available only on ChromeOS.");
return false;
@@ -46,13 +46,13 @@
SetDisplayProperties::Params::Create(*args_));
DisplayInfoProvider::GetProvider()->SetInfo(params->id, params->info,
base::Bind(
- &SystemInfoDisplaySetDisplayPropertiesFunction::OnPropertiesSet,
+ &SystemDisplaySetDisplayPropertiesFunction::OnPropertiesSet,
this));
return true;
#endif
}
-void SystemInfoDisplaySetDisplayPropertiesFunction::OnPropertiesSet(
+void SystemDisplaySetDisplayPropertiesFunction::OnPropertiesSet(
bool success, const std::string& error) {
if (!success)
SetError(error);
diff --git a/chrome/browser/extensions/api/system_display/system_display_api.h b/chrome/browser/extensions/api/system_display/system_display_api.h
new file mode 100644
index 0000000..ee63e74
--- /dev/null
+++ b/chrome/browser/extensions/api/system_display/system_display_api.h
@@ -0,0 +1,44 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_API_SYSTEM_DISPLAY_SYSTEM_DISPLAY_API_H_
+#define CHROME_BROWSER_EXTENSIONS_API_SYSTEM_DISPLAY_SYSTEM_DISPLAY_API_H_
+
+#include <string>
+
+#include "chrome/browser/extensions/api/system_display/display_info_provider.h"
+#include "chrome/browser/extensions/extension_function.h"
+
+namespace extensions {
+
+class SystemDisplayGetInfoFunction : public AsyncExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("system.display.getInfo",
+ SYSTEM_DISPLAY_GETINFO);
+
+ protected:
+ virtual ~SystemDisplayGetInfoFunction() {}
+ virtual bool RunImpl() OVERRIDE;
+
+ private:
+ void OnGetDisplayInfoCompleted(bool success);
+};
+
+class SystemDisplaySetDisplayPropertiesFunction
+ : public AsyncExtensionFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION("system.display.setDisplayProperties",
+ SYSTEM_DISPLAY_SETDISPLAYPROPERTIES);
+
+ protected:
+ virtual ~SystemDisplaySetDisplayPropertiesFunction() {}
+ virtual bool RunImpl() OVERRIDE;
+
+ private:
+ void OnPropertiesSet(bool success, const std::string& error);
+};
+
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_API_SYSTEM_DISPLAY_SYSTEM_DISPLAY_API_H_
diff --git a/chrome/browser/extensions/api/system_info_display/system_info_display_apitest.cc b/chrome/browser/extensions/api/system_display/system_display_apitest.cc
similarity index 81%
rename from chrome/browser/extensions/api/system_info_display/system_info_display_apitest.cc
rename to chrome/browser/extensions/api/system_display/system_display_apitest.cc
index ec254d7..7880c46 100644
--- a/chrome/browser/extensions/api/system_info_display/system_info_display_apitest.cc
+++ b/chrome/browser/extensions/api/system_display/system_display_apitest.cc
@@ -1,11 +1,11 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2013 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/system_info_display/system_info_display_api.h"
+#include "chrome/browser/extensions/api/system_display/system_display_api.h"
#include "base/strings/string_number_conversions.h"
-#include "chrome/browser/extensions/api/system_info_display/display_info_provider.h"
+#include "chrome/browser/extensions/api/system_display/display_info_provider.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_function_test_utils.h"
@@ -13,8 +13,8 @@
namespace extensions {
-using api::system_info_display::Bounds;
-using api::system_info_display::DisplayUnitInfo;
+using api::system_display::Bounds;
+using api::system_display::DisplayUnitInfo;
class MockDisplayInfoProvider : public DisplayInfoProvider {
public:
@@ -55,7 +55,7 @@
virtual void SetInfo(
const std::string& display_id,
- const api::system_info_display::DisplayProperties& params,
+ const api::system_display::DisplayProperties& params,
const SetInfoCallback& callback) OVERRIDE {
// Should get called only once per test case.
EXPECT_FALSE(set_info_value_);
@@ -81,10 +81,10 @@
DISALLOW_COPY_AND_ASSIGN(MockDisplayInfoProvider);
};
-class SystemInfoDisplayApiTest: public ExtensionApiTest {
+class SystemDisplayApiTest: public ExtensionApiTest {
public:
- SystemInfoDisplayApiTest() {}
- virtual ~SystemInfoDisplayApiTest() {}
+ SystemDisplayApiTest() {}
+ virtual ~SystemDisplayApiTest() {}
virtual void SetUpOnMainThread() OVERRIDE {
ExtensionApiTest::SetUpOnMainThread();
@@ -102,17 +102,17 @@
protected:
scoped_refptr<MockDisplayInfoProvider> provider_;
- DISALLOW_COPY_AND_ASSIGN(SystemInfoDisplayApiTest);
+ DISALLOW_COPY_AND_ASSIGN(SystemDisplayApiTest);
};
-IN_PROC_BROWSER_TEST_F(SystemInfoDisplayApiTest, GetDisplay) {
- ASSERT_TRUE(RunPlatformAppTest("systeminfo/display")) << message_;
+IN_PROC_BROWSER_TEST_F(SystemDisplayApiTest, GetDisplay) {
+ ASSERT_TRUE(RunPlatformAppTest("system/display")) << message_;
}
#if !defined(OS_CHROMEOS)
-IN_PROC_BROWSER_TEST_F(SystemInfoDisplayApiTest, SetDisplay) {
- scoped_refptr<SystemInfoDisplaySetDisplayPropertiesFunction>
- set_info_function(new SystemInfoDisplaySetDisplayPropertiesFunction());
+IN_PROC_BROWSER_TEST_F(SystemDisplayApiTest, SetDisplay) {
+ scoped_refptr<SystemDisplaySetDisplayPropertiesFunction>
+ set_info_function(new SystemDisplaySetDisplayPropertiesFunction());
set_info_function->set_has_callback(true);
@@ -127,7 +127,7 @@
#endif // !defined(OS_CHROMEOS)
#if defined(OS_CHROMEOS)
-IN_PROC_BROWSER_TEST_F(SystemInfoDisplayApiTest, SetDisplayNotKioskEnabled) {
+IN_PROC_BROWSER_TEST_F(SystemDisplayApiTest, SetDisplayNotKioskEnabled) {
scoped_ptr<base::DictionaryValue> test_extension_value(utils::ParseDictionary(
"{\n"
" \"name\": \"Test\",\n"
@@ -141,8 +141,8 @@
scoped_refptr<Extension> test_extension(
utils::CreateExtension(test_extension_value.get()));
- scoped_refptr<SystemInfoDisplaySetDisplayPropertiesFunction>
- set_info_function(new SystemInfoDisplaySetDisplayPropertiesFunction());
+ scoped_refptr<SystemDisplaySetDisplayPropertiesFunction>
+ set_info_function(new SystemDisplaySetDisplayPropertiesFunction());
set_info_function->set_extension(test_extension.get());
set_info_function->set_has_callback(true);
@@ -156,7 +156,7 @@
EXPECT_FALSE(set_info);
}
-IN_PROC_BROWSER_TEST_F(SystemInfoDisplayApiTest, SetDisplayKioskEnabled) {
+IN_PROC_BROWSER_TEST_F(SystemDisplayApiTest, SetDisplayKioskEnabled) {
scoped_ptr<base::DictionaryValue> test_extension_value(utils::ParseDictionary(
"{\n"
" \"name\": \"Test\",\n"
@@ -171,8 +171,8 @@
scoped_refptr<Extension> test_extension(
utils::CreateExtension(test_extension_value.get()));
- scoped_refptr<SystemInfoDisplaySetDisplayPropertiesFunction>
- set_info_function(new SystemInfoDisplaySetDisplayPropertiesFunction());
+ scoped_refptr<SystemDisplaySetDisplayPropertiesFunction>
+ set_info_function(new SystemDisplaySetDisplayPropertiesFunction());
set_info_function->set_has_callback(true);
set_info_function->set_extension(test_extension.get());
diff --git a/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc b/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc
index f708074..4297abe 100644
--- a/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc
+++ b/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc
@@ -167,7 +167,8 @@
return;
}
- StatusIcon* indicator_icon = status_tray_->CreateStatusIcon();
+ StatusIcon* indicator_icon =
+ status_tray_->CreateStatusIcon(StatusTray::OTHER_ICON);
if (indicator_icon != NULL) {
ExtensionIndicatorIcon* status_icon = new ExtensionIndicatorIcon(
extension,
diff --git a/chrome/browser/extensions/api/system_info_display/system_info_display_api.h b/chrome/browser/extensions/api/system_info_display/system_info_display_api.h
deleted file mode 100644
index db427e5..0000000
--- a/chrome/browser/extensions/api/system_info_display/system_info_display_api.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_DISPLAY_SYSTEM_INFO_DISPLAY_API_H_
-#define CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_DISPLAY_SYSTEM_INFO_DISPLAY_API_H_
-
-#include <string>
-
-#include "chrome/browser/extensions/api/system_info_display/display_info_provider.h"
-#include "chrome/browser/extensions/extension_function.h"
-
-namespace extensions {
-
-class SystemInfoDisplayGetDisplayInfoFunction : public AsyncExtensionFunction {
- public:
- DECLARE_EXTENSION_FUNCTION("systemInfo.display.getDisplayInfo",
- SYSTEMINFO_DISPLAY_GETDISPLAYINFO);
-
- protected:
- virtual ~SystemInfoDisplayGetDisplayInfoFunction() {}
- virtual bool RunImpl() OVERRIDE;
-
- private:
- void OnGetDisplayInfoCompleted(bool success);
-};
-
-class SystemInfoDisplaySetDisplayPropertiesFunction
- : public AsyncExtensionFunction {
- public:
- DECLARE_EXTENSION_FUNCTION("systemInfo.display.setDisplayProperties",
- SYSTEMINFO_DISPLAY_SETDISPLAYPROPERTIES);
-
- protected:
- virtual ~SystemInfoDisplaySetDisplayPropertiesFunction() {}
- virtual bool RunImpl() OVERRIDE;
-
- private:
- void OnPropertiesSet(bool success, const std::string& error);
-};
-
-} // namespace extensions
-
-#endif // CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_DISPLAY_SYSTEM_INFO_DISPLAY_API_H__
diff --git a/chrome/browser/extensions/api/system_info_storage/system_info_storage_apitest.cc b/chrome/browser/extensions/api/system_info_storage/system_info_storage_apitest.cc
index f05dc88..671f628 100644
--- a/chrome/browser/extensions/api/system_info_storage/system_info_storage_apitest.cc
+++ b/chrome/browser/extensions/api/system_info_storage/system_info_storage_apitest.cc
@@ -11,14 +11,12 @@
#include "chrome/browser/extensions/extension_test_message_listener.h"
#include "chrome/browser/storage_monitor/storage_info.h"
#include "chrome/browser/storage_monitor/storage_monitor.h"
-#include "chrome/browser/storage_monitor/test_storage_monitor.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/ui_test_utils.h"
namespace {
using chrome::StorageMonitor;
-using chrome::test::TestStorageMonitor;
using extensions::api::experimental_system_info_storage::ParseStorageUnitType;
using extensions::api::experimental_system_info_storage::StorageUnitInfo;
using extensions::StorageInfoProvider;
@@ -87,9 +85,6 @@
}
IN_PROC_BROWSER_TEST_F(SystemInfoStorageApiTest, StorageAttachment) {
- scoped_ptr<TestStorageMonitor> monitor(
- TestStorageMonitor::CreateForBrowserTests());
-
TestStorageInfoProvider* provider =
new TestStorageInfoProvider(kRemovableStorageData,
arraysize(kRemovableStorageData));
diff --git a/chrome/browser/extensions/api/system_info_storage/system_info_storage_eject_apitest.cc b/chrome/browser/extensions/api/system_info_storage/system_info_storage_eject_apitest.cc
index ba51993..7f66a00 100644
--- a/chrome/browser/extensions/api/system_info_storage/system_info_storage_eject_apitest.cc
+++ b/chrome/browser/extensions/api/system_info_storage/system_info_storage_eject_apitest.cc
@@ -35,7 +35,7 @@
class SystemInfoStorageEjectApiTest : public ExtensionApiTest {
public:
- SystemInfoStorageEjectApiTest() {}
+ SystemInfoStorageEjectApiTest() : monitor_(NULL) {}
virtual ~SystemInfoStorageEjectApiTest() {}
protected:
@@ -45,6 +45,11 @@
command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis);
}
+ virtual void SetUpOnMainThread() OVERRIDE {
+ monitor_ = chrome::test::TestStorageMonitor::CreateForBrowserTests();
+ ExtensionApiTest::SetUpOnMainThread();
+ }
+
content::RenderViewHost* GetHost() {
const extensions::Extension* extension =
LoadExtension(test_data_dir_.AppendASCII("systeminfo/storage_eject"));
@@ -75,17 +80,15 @@
content::RunAllPendingInMessageLoop();
}
+ protected:
+ chrome::test::TestStorageMonitor* monitor_;
+
private:
DISALLOW_COPY_AND_ASSIGN(SystemInfoStorageEjectApiTest);
};
IN_PROC_BROWSER_TEST_F(SystemInfoStorageEjectApiTest, EjectTest) {
- scoped_ptr<chrome::test::TestStorageMonitor> monitor(
- chrome::test::TestStorageMonitor::CreateForBrowserTests());
- monitor->Init();
- monitor->MarkInitialized();
-
TestStorageInfoProvider* provider =
new TestStorageInfoProvider(kRemovableStorageData,
arraysize(kRemovableStorageData));
@@ -104,17 +107,12 @@
EXPECT_TRUE(attach_finished_listener.WaitUntilSatisfied());
ExecuteCmdAndCheckReply(host, "ejectTest()", "eject_ok");
- EXPECT_EQ(kRemovableStorageData[0].device_id, monitor->ejected_device());
+ EXPECT_EQ(kRemovableStorageData[0].device_id, monitor_->ejected_device());
Detach();
}
IN_PROC_BROWSER_TEST_F(SystemInfoStorageEjectApiTest, EjectBadDeviceTest) {
- scoped_ptr<chrome::test::TestStorageMonitor> monitor(
- chrome::test::TestStorageMonitor::CreateForBrowserTests());
- monitor->Init();
- monitor->MarkInitialized();
-
TestStorageInfoProvider* provider =
new TestStorageInfoProvider(kRemovableStorageData,
arraysize(kRemovableStorageData));
@@ -122,5 +120,5 @@
ExecuteCmdAndCheckReply(GetHost(), "ejectFailTest()", "eject_no_such_device");
- EXPECT_EQ("", monitor->ejected_device());
+ EXPECT_EQ("", monitor_->ejected_device());
}
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc b/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc
index cfef6e3..4f4555d 100644
--- a/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc
+++ b/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc
@@ -43,7 +43,13 @@
} // namespace
-IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, ApiTests) {
+// http://crbug.com/261493
+#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#define MAYBE_ApiTests DISABLED_ApiTests
+#else
+#define MAYBE_ApiTests ApiTests
+#endif
+IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, MAYBE_ApiTests) {
extensions::FeatureSwitch::ScopedOverride tab_capture(
extensions::FeatureSwitch::tab_capture(), true);
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc
index 673f4b7..fcccd07 100644
--- a/chrome/browser/extensions/api/tabs/tabs_api.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -62,7 +62,6 @@
#include "chrome/common/extensions/incognito_handler.h"
#include "chrome/common/extensions/message_bundle.h"
#include "chrome/common/extensions/permissions/permissions_data.h"
-#include "chrome/common/extensions/user_script.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/translate/language_detection_details.h"
#include "chrome/common/url_constants.h"
@@ -80,6 +79,7 @@
#include "extensions/browser/file_reader.h"
#include "extensions/common/constants.h"
#include "extensions/common/error_utils.h"
+#include "extensions/common/user_script.h"
#include "skia/ext/image_operations.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/skia/include/core/SkBitmap.h"
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.h b/chrome/browser/extensions/api/tabs/tabs_api.h
index 15f47eb..1313b71 100644
--- a/chrome/browser/extensions/api/tabs/tabs_api.h
+++ b/chrome/browser/extensions/api/tabs/tabs_api.h
@@ -12,10 +12,10 @@
#include "chrome/browser/extensions/api/execute_code_function.h"
#include "chrome/browser/extensions/extension_function.h"
#include "chrome/common/extensions/api/tabs.h"
-#include "chrome/common/extensions/user_script.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "extensions/common/extension_resource.h"
+#include "extensions/common/user_script.h"
#include "url/gurl.h"
class BackingStore;
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc
index 5f70e7a..e62f3f9 100644
--- a/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc
+++ b/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc
@@ -24,7 +24,6 @@
#include "chrome/browser/tab_contents/render_view_context_menu.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
@@ -36,11 +35,12 @@
#include "content/public/common/context_menu_params.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_test_utils.h"
+#include "extensions/common/switches.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "third_party/WebKit/public/web/WebContextMenuData.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
-#include "webkit/glue/resource_type.h"
+#include "webkit/common/resource_type.h"
using content::WebContents;
diff --git a/chrome/browser/extensions/api/web_request/web_request_api.h b/chrome/browser/extensions/api/web_request/web_request_api.h
index 4e9ea49..e0339fc 100644
--- a/chrome/browser/extensions/api/web_request/web_request_api.h
+++ b/chrome/browser/extensions/api/web_request/web_request_api.h
@@ -25,7 +25,7 @@
#include "net/base/completion_callback.h"
#include "net/base/network_delegate.h"
#include "net/http/http_request_headers.h"
-#include "webkit/glue/resource_type.h"
+#include "webkit/common/resource_type.h"
class ExtensionInfoMap;
class ExtensionWebRequestTimeTracker;
diff --git a/chrome/browser/extensions/api/web_request/web_request_api_helpers.h b/chrome/browser/extensions/api/web_request/web_request_api_helpers.h
index 9b849c1..90b2f84 100644
--- a/chrome/browser/extensions/api/web_request/web_request_api_helpers.h
+++ b/chrome/browser/extensions/api/web_request/web_request_api_helpers.h
@@ -20,7 +20,7 @@
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "url/gurl.h"
-#include "webkit/glue/resource_type.h"
+#include "webkit/common/resource_type.h"
namespace base {
class ListValue;
diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
index f64add1..0655d6e 100644
--- a/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
+++ b/chrome/browser/extensions/api/webstore_private/webstore_private_api.cc
@@ -566,7 +566,7 @@
// Show the app list to show download is progressing. Don't show the app
// list on first app install so users can be trained to open it themselves.
if (approval_->manifest->is_app() && !approval_->enable_launcher)
- AppListService::Get()->ShowAppList(profile());
+ AppListService::Get()->ShowForProfile(profile());
}
// The extension will install through the normal extension install flow, but
diff --git a/chrome/browser/extensions/app_process_apitest.cc b/chrome/browser/extensions/app_process_apitest.cc
index 7f4dd7b..ee5a829 100644
--- a/chrome/browser/extensions/app_process_apitest.cc
+++ b/chrome/browser/extensions/app_process_apitest.cc
@@ -31,6 +31,10 @@
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "sync/api/string_ordinal.h"
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
using content::NavigationController;
using content::RenderViewHost;
using content::WebContents;
@@ -599,6 +603,12 @@
// empty.html) results in the new window being in an app process. See
// http://crbug.com/89272 for more details.
IN_PROC_BROWSER_TEST_F(AppApiTest, OpenAppFromIframe) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
extensions::ProcessMap* process_map = extensions::ExtensionSystem::Get(
browser()->profile())->extension_service()->process_map();
diff --git a/chrome/browser/extensions/blacklist_unittest.cc b/chrome/browser/extensions/blacklist_unittest.cc
index ad52f41..1ccaf4c 100644
--- a/chrome/browser/extensions/blacklist_unittest.cc
+++ b/chrome/browser/extensions/blacklist_unittest.cc
@@ -3,7 +3,7 @@
// found in the LICENSE file.
#include "base/bind.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "chrome/browser/extensions/blacklist.h"
#include "chrome/browser/extensions/extension_prefs.h"
diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc
index 152e92f..1c4fe8d 100644
--- a/chrome/browser/extensions/component_loader.cc
+++ b/chrome/browser/extensions/component_loader.cc
@@ -452,6 +452,9 @@
Add(IDR_NETWORK_CONFIGURATION_MANIFEST,
base::FilePath(FILE_PATH_LITERAL("chromeos/network_configuration")));
+
+ Add(IDR_CONNECTIVITY_DIAGNOSTICS_MANIFEST,
+ base::FilePath(extension_misc::kConnectivityDiagnosticsPath));
}
// Load ChromeVox extension now if spoken feedback is enabled.
diff --git a/chrome/browser/extensions/convert_user_script.cc b/chrome/browser/extensions/convert_user_script.cc
index 0d79540..f6fbea7 100644
--- a/chrome/browser/extensions/convert_user_script.cc
+++ b/chrome/browser/extensions/convert_user_script.cc
@@ -20,9 +20,9 @@
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/extensions/extension_manifest_constants.h"
-#include "chrome/common/extensions/user_script.h"
#include "crypto/sha2.h"
#include "extensions/common/constants.h"
+#include "extensions/common/user_script.h"
#include "url/gurl.h"
namespace keys = extension_manifest_keys;
diff --git a/chrome/browser/extensions/convert_web_app_browsertest.cc b/chrome/browser/extensions/convert_web_app_browsertest.cc
index c9ed528..f094e14 100644
--- a/chrome/browser/extensions/convert_web_app_browsertest.cc
+++ b/chrome/browser/extensions/convert_web_app_browsertest.cc
@@ -24,6 +24,10 @@
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
namespace extensions {
class ExtensionFromWebAppTest
@@ -59,6 +63,12 @@
#endif
IN_PROC_BROWSER_TEST_F(ExtensionFromWebAppTest, MAYBE_Basic) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
browser()->profile()->GetExtensionService()->set_show_extensions_prompts(
false);
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc
index 2d2e0ae..588e2f1 100644
--- a/chrome/browser/extensions/crx_installer.cc
+++ b/chrome/browser/extensions/crx_installer.cc
@@ -41,11 +41,11 @@
#include "chrome/common/extensions/manifest.h"
#include "chrome/common/extensions/manifest_handlers/shared_module_info.h"
#include "chrome/common/extensions/manifest_url_handler.h"
-#include "chrome/common/extensions/user_script.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/user_metrics.h"
+#include "extensions/common/user_script.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
diff --git a/chrome/browser/extensions/default_apps_unittest.cc b/chrome/browser/extensions/default_apps_unittest.cc
index 1104e7b..1f16f2d 100644
--- a/chrome/browser/extensions/default_apps_unittest.cc
+++ b/chrome/browser/extensions/default_apps_unittest.cc
@@ -3,7 +3,7 @@
// found in the LICENSE file.
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/prefs/pref_service.h"
#include "chrome/browser/extensions/default_apps.h"
#include "chrome/browser/extensions/external_pref_loader.h"
diff --git a/chrome/browser/extensions/event_names.cc b/chrome/browser/extensions/event_names.cc
index 3270043..c5eeeba 100644
--- a/chrome/browser/extensions/event_names.cc
+++ b/chrome/browser/extensions/event_names.cc
@@ -71,7 +71,7 @@
const char kOnPushMessage[] = "pushMessaging.onMessage";
-const char kOnDisplayChanged[] = "systemInfo.display.onDisplayChanged";
+const char kOnDisplayChanged[] = "system.display.onDisplayChanged";
const char kOnStorageAvailableCapacityChanged[] =
"experimental.systemInfo.storage.onAvailableCapacityChanged";
const char kOnStorageAttached[] = "experimental.systemInfo.storage.onAttached";
diff --git a/chrome/browser/extensions/event_router.cc b/chrome/browser/extensions/event_router.cc
index bcb7c2a..e3673d5 100644
--- a/chrome/browser/extensions/event_router.cc
+++ b/chrome/browser/extensions/event_router.cc
@@ -8,7 +8,7 @@
#include "base/bind.h"
#include "base/command_line.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
#include "base/values.h"
#include "base/version.h"
@@ -492,6 +492,18 @@
DispatchEventImpl(extension_id, linked_ptr<Event>(event.release()));
}
+void EventRouter::DispatchEventWithLazyListener(const std::string& extension_id,
+ scoped_ptr<Event> event) {
+ DCHECK(!extension_id.empty());
+ std::string event_name = event->event_name;
+ bool has_listener = ExtensionHasEventListener(extension_id, event_name);
+ if (!has_listener)
+ AddLazyEventListener(event_name, extension_id);
+ DispatchEventToExtension(extension_id, event.Pass());
+ if (!has_listener)
+ RemoveLazyEventListener(event_name, extension_id);
+}
+
void EventRouter::DispatchEventImpl(const std::string& restrict_to_extension_id,
const linked_ptr<Event>& event) {
// We don't expect to get events from a completely different profile.
diff --git a/chrome/browser/extensions/event_router.h b/chrome/browser/extensions/event_router.h
index 16f64e9..cd1ea1d 100644
--- a/chrome/browser/extensions/event_router.h
+++ b/chrome/browser/extensions/event_router.h
@@ -143,6 +143,13 @@
virtual void DispatchEventToExtension(const std::string& extension_id,
scoped_ptr<Event> event);
+ // Dispatches |event| to the given extension as if the extension has a lazy
+ // listener for it. NOTE: This should be used rarely, for dispatching events
+ // to extensions that haven't had a chance to add their own listeners yet, eg:
+ // newly installed extensions.
+ void DispatchEventWithLazyListener(const std::string& extension_id,
+ scoped_ptr<Event> event);
+
// Record the Event Ack from the renderer. (One less event in-flight.)
void OnEventAck(Profile* profile, const std::string& extension_id);
diff --git a/chrome/browser/extensions/event_router_forwarder_unittest.cc b/chrome/browser/extensions/event_router_forwarder_unittest.cc
index bb80d11..c77ecbf 100644
--- a/chrome/browser/extensions/event_router_forwarder_unittest.cc
+++ b/chrome/browser/extensions/event_router_forwarder_unittest.cc
@@ -5,7 +5,7 @@
#include "chrome/browser/extensions/event_router_forwarder.h"
#include "base/bind.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/power_monitor/power_monitor.h"
#include "base/test/thread_test_helper.h"
#include "chrome/browser/profiles/profile_manager.h"
diff --git a/chrome/browser/extensions/extension_action.cc b/chrome/browser/extensions/extension_action.cc
index 264c548..7d3ecd1 100644
--- a/chrome/browser/extensions/extension_action.cc
+++ b/chrome/browser/extensions/extension_action.cc
@@ -8,7 +8,7 @@
#include "base/bind.h"
#include "base/logging.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "chrome/common/badge_util.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/icon_with_badge_image_source.h"
diff --git a/chrome/browser/extensions/extension_action_icon_factory_unittest.cc b/chrome/browser/extensions/extension_action_icon_factory_unittest.cc
index 5e9d952..39ea0d6 100644
--- a/chrome/browser/extensions/extension_action_icon_factory_unittest.cc
+++ b/chrome/browser/extensions/extension_action_icon_factory_unittest.cc
@@ -7,7 +7,7 @@
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/json/json_file_value_serializer.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "chrome/browser/extensions/extension_action.h"
#include "chrome/browser/extensions/extension_action_manager.h"
diff --git a/chrome/browser/extensions/extension_action_unittest.cc b/chrome/browser/extensions/extension_action_unittest.cc
index 7656b46..c71e7b1 100644
--- a/chrome/browser/extensions/extension_action_unittest.cc
+++ b/chrome/browser/extensions/extension_action_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "chrome/browser/extensions/extension_action.h"
#include "chrome/common/extensions/api/extension_action/action_info.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/extensions/extension_disabled_ui.cc b/chrome/browser/extensions/extension_disabled_ui.cc
index 07f7555..d1c3b5c 100644
--- a/chrome/browser/extensions/extension_disabled_ui.cc
+++ b/chrome/browser/extensions/extension_disabled_ui.cc
@@ -10,7 +10,7 @@
#include "base/lazy_instance.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
diff --git a/chrome/browser/extensions/extension_error_reporter.cc b/chrome/browser/extensions/extension_error_reporter.cc
index d94fd81..6448712 100644
--- a/chrome/browser/extensions/extension_error_reporter.cc
+++ b/chrome/browser/extensions/extension_error_reporter.cc
@@ -9,7 +9,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/simple_message_box.h"
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index 14e384a..47241e9 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -36,13 +36,11 @@
#include "content/public/common/result_codes.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_macros.h"
-#include "third_party/WebKit/public/web/WebSecurityOrigin.h"
-#include "webkit/glue/resource_type.h"
+#include "webkit/common/resource_type.h"
using extensions::Extension;
using extensions::ExtensionAPI;
using content::RenderViewHost;
-using WebKit::WebSecurityOrigin;
namespace {
@@ -362,9 +360,7 @@
const Extension* extension = service->extensions()->GetByID(
params.extension_id);
if (!extension)
- extension = service->extensions()->GetHostedAppByURL(ExtensionURLInfo(
- WebSecurityOrigin::createFromString(params.source_origin),
- params.source_url));
+ extension = service->extensions()->GetHostedAppByURL(params.source_url);
scoped_refptr<ExtensionFunction> function(
CreateExtensionFunction(params, extension,
diff --git a/chrome/browser/extensions/extension_function_histogram_value.h b/chrome/browser/extensions/extension_function_histogram_value.h
index 0bf7f56..2bc33fc 100644
--- a/chrome/browser/extensions/extension_function_histogram_value.h
+++ b/chrome/browser/extensions/extension_function_histogram_value.h
@@ -122,7 +122,7 @@
APP_CURRENTWINDOWINTERNAL_SHOW,
WEBSTOREPRIVATE_GETBROWSERLOGIN,
EXPERIMENTAL_IDENTITY_GETAUTHTOKEN,
- SYSTEMINFO_DISPLAY_GETDISPLAYINFO,
+ DELETED_SYSTEMINFO_DISPLAY_GETDISPLAYINFO,
BROWSINGDATA_REMOVEPLUGINDATA,
SOCKET_LISTEN,
MEDIAGALLERIES_GETMEDIAFILESYSTEMS,
@@ -548,7 +548,7 @@
SYSTEMINFO_MEMORY_GET,
ACTIVITYLOGPRIVATE_GETEXTENSIONACTIVITIES,
RUNTIME_GETPACKAGEDIRECTORYENTRY,
- SYSTEMINFO_DISPLAY_SETDISPLAYPROPERTIES,
+ DELETED_SYSTEMINFO_DISPLAY_SETDISPLAYPROPERTIES,
FEEDBACKPRIVATE_GETUSEREMAIL,
FEEDBACKPRIVATE_GETSYSTEMINFORMATION,
FEEDBACKPRIVATE_SENDFEEDBACK,
@@ -567,6 +567,9 @@
TYPES_PRIVATE_CHROMEDIRECTSETTING_CLEAR,
EXPERIMENTAL_SYSTEMINFO_STORAGE_EJECTDEVICE,
SYSTEM_CPU_GETINFO,
+ BOOKMARKMANAGERPRIVATE_REMOVETREES,
+ SYSTEM_DISPLAY_GETINFO,
+ SYSTEM_DISPLAY_SETDISPLAYPROPERTIES,
ENUM_BOUNDARY // Last entry: Add new entries above.
};
diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc
index e945bad..f6462a2 100644
--- a/chrome/browser/extensions/extension_host.cc
+++ b/chrome/browser/extensions/extension_host.cc
@@ -9,7 +9,7 @@
#include "base/bind.h"
#include "base/memory/singleton.h"
#include "base/memory/weak_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
diff --git a/chrome/browser/extensions/extension_icon_image_unittest.cc b/chrome/browser/extensions/extension_icon_image_unittest.cc
index 13706bd..346a2ff 100644
--- a/chrome/browser/extensions/extension_icon_image_unittest.cc
+++ b/chrome/browser/extensions/extension_icon_image_unittest.cc
@@ -5,7 +5,7 @@
#include "chrome/browser/extensions/extension_icon_image.h"
#include "base/json/json_file_value_serializer.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "chrome/browser/extensions/image_loader.h"
#include "chrome/common/chrome_paths.h"
diff --git a/chrome/browser/extensions/extension_icon_manager_unittest.cc b/chrome/browser/extensions/extension_icon_manager_unittest.cc
index d092c2d..287f98b 100644
--- a/chrome/browser/extensions/extension_icon_manager_unittest.cc
+++ b/chrome/browser/extensions/extension_icon_manager_unittest.cc
@@ -3,7 +3,7 @@
// found in the LICENSE file.
#include "base/json/json_file_value_serializer.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/values.h"
#include "chrome/browser/extensions/extension_icon_manager.h"
diff --git a/chrome/browser/extensions/extension_icon_source_apitest.cc b/chrome/browser/extensions/extension_icon_source_apitest.cc
index 8406ed7..db7a808 100644
--- a/chrome/browser/extensions/extension_icon_source_apitest.cc
+++ b/chrome/browser/extensions/extension_icon_source_apitest.cc
@@ -8,10 +8,10 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
+#include "extensions/common/switches.h"
#include "net/dns/mock_host_resolver.h"
#include "url/gurl.h"
@@ -19,7 +19,8 @@
protected:
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
ExtensionApiTest::SetUpCommandLine(command_line);
- command_line->AppendSwitch(switches::kAllowLegacyExtensionManifests);
+ command_line->AppendSwitch(
+ extensions::switches::kAllowLegacyExtensionManifests);
}
};
diff --git a/chrome/browser/extensions/extension_info_map_unittest.cc b/chrome/browser/extensions/extension_info_map_unittest.cc
index 3fbefc4..10dace7 100644
--- a/chrome/browser/extensions/extension_info_map_unittest.cc
+++ b/chrome/browser/extensions/extension_info_map_unittest.cc
@@ -3,7 +3,7 @@
// found in the LICENSE file.
#include "base/json/json_file_value_serializer.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "chrome/browser/extensions/extension_info_map.h"
#include "chrome/common/chrome_paths.h"
@@ -11,15 +11,11 @@
#include "chrome/common/extensions/extension_manifest_constants.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/platform/WebString.h"
-#include "third_party/WebKit/public/platform/WebURL.h"
using content::BrowserThread;
using extensions::APIPermission;
using extensions::Extension;
using extensions::Manifest;
-using WebKit::WebSecurityOrigin;
-using WebKit::WebString;
namespace keys = extension_manifest_keys;
@@ -139,8 +135,6 @@
"tabs_extension.json"));
GURL app_url("http://www.google.com/mail/foo.html");
- WebSecurityOrigin app_origin = WebSecurityOrigin::create(
- GURL("http://www.google.com/mail/foo.html"));
ASSERT_TRUE(app->is_app());
ASSERT_TRUE(app->web_extent().MatchesURL(app_url));
@@ -150,11 +144,10 @@
// The app should have the notifications permission, either from a
// chrome-extension URL or from its web extent.
const Extension* match = info_map->extensions().GetExtensionOrAppByURL(
- ExtensionURLInfo(app_origin, app->GetResourceURL("a.html")));
+ app->GetResourceURL("a.html"));
EXPECT_TRUE(match &&
match->HasAPIPermission(APIPermission::kNotification));
- match = info_map->extensions().GetExtensionOrAppByURL(
- ExtensionURLInfo(app_origin, app_url));
+ match = info_map->extensions().GetExtensionOrAppByURL(app_url);
EXPECT_TRUE(match &&
match->HasAPIPermission(APIPermission::kNotification));
EXPECT_FALSE(match &&
@@ -162,7 +155,7 @@
// The extension should have the tabs permission.
match = info_map->extensions().GetExtensionOrAppByURL(
- ExtensionURLInfo(app_origin, extension->GetResourceURL("a.html")));
+ extension->GetResourceURL("a.html"));
EXPECT_TRUE(match &&
match->HasAPIPermission(APIPermission::kTab));
EXPECT_FALSE(match &&
@@ -170,14 +163,7 @@
// Random URL should not have any permissions.
GURL evil_url("http://evil.com/a.html");
- match = info_map->extensions().GetExtensionOrAppByURL(
- ExtensionURLInfo(WebSecurityOrigin::create(evil_url), evil_url));
- EXPECT_FALSE(match);
-
- // Sandboxed origins should not have any permissions.
- match = info_map->extensions().GetExtensionOrAppByURL(ExtensionURLInfo(
- WebSecurityOrigin::createFromString(WebString::fromUTF8("null")),
- app_url));
+ match = info_map->extensions().GetExtensionOrAppByURL(evil_url);
EXPECT_FALSE(match);
}
diff --git a/chrome/browser/extensions/extension_infobar_delegate.cc b/chrome/browser/extensions/extension_infobar_delegate.cc
index 0bcedd3..a752583 100644
--- a/chrome/browser/extensions/extension_infobar_delegate.cc
+++ b/chrome/browser/extensions/extension_infobar_delegate.cc
@@ -30,7 +30,7 @@
int height) {
infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
new ExtensionInfoBarDelegate(browser, infobar_service, extension, url,
- height)));
+ infobar_service->web_contents(), height)));
}
ExtensionInfoBarDelegate::ExtensionInfoBarDelegate(
@@ -38,6 +38,7 @@
InfoBarService* infobar_service,
const extensions::Extension* extension,
const GURL& url,
+ content::WebContents* web_contents,
int height)
: InfoBarDelegate(infobar_service),
#if defined(TOOLKIT_VIEWS)
@@ -49,23 +50,21 @@
ExtensionProcessManager* manager =
extensions::ExtensionSystem::Get(browser->profile())->process_manager();
extension_host_.reset(manager->CreateInfobarHost(url, browser));
- extension_host_->SetAssociatedWebContents(infobar_service->web_contents());
+ extension_host_->SetAssociatedWebContents(web_contents);
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,
content::Source<Profile>(browser->profile()));
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
content::Source<Profile>(browser->profile()));
-#if defined(TOOLKIT_VIEWS) || defined(TOOLKIT_GTK)
+#if defined(TOOLKIT_VIEWS) || defined(TOOLKIT_GTK) || defined(OS_ANDROID)
+ // TODO(dtrainor): On Android, this is not used. Might need to pull this from
+ // Android UI level in the future. Tracked via issue 115303.
int default_height = InfoBar::kDefaultBarTargetHeight;
#elif defined(OS_MACOSX)
// TODO(pkasting): Once Infobars have been ported to Mac, we can remove the
// ifdefs and just use the Infobar constant below.
int default_height = 36;
-#elif defined(OS_ANDROID)
- // TODO(dtrainor): This is not used. Might need to pull this from Android UI
- // level in the future. Tracked via issue 115303.
- int default_height = 36;
#endif
height_ = std::max(0, height);
height_ = std::min(2 * default_height, height_);
diff --git a/chrome/browser/extensions/extension_infobar_delegate.h b/chrome/browser/extensions/extension_infobar_delegate.h
index a8a2f62..0d549d7 100644
--- a/chrome/browser/extensions/extension_infobar_delegate.h
+++ b/chrome/browser/extensions/extension_infobar_delegate.h
@@ -35,7 +35,7 @@
virtual ~ExtensionInfoBarDelegate();
- // Creates an extension delegate and adds it to |infobar_service|.
+ // Creates an extension infobar delegate and adds it to |infobar_service|.
static void Create(InfoBarService* infobar_service,
Browser* browser,
const extensions::Extension* extension,
@@ -55,6 +55,7 @@
InfoBarService* infobar_service,
const extensions::Extension* extension,
const GURL& url,
+ content::WebContents* web_contents,
int height);
// InfoBarDelegate:
diff --git a/chrome/browser/extensions/extension_install_prompt.cc b/chrome/browser/extensions/extension_install_prompt.cc
index 66521c4..e0c2f6f 100644
--- a/chrome/browser/extensions/extension_install_prompt.cc
+++ b/chrome/browser/extensions/extension_install_prompt.cc
@@ -7,7 +7,7 @@
#include <map>
#include "base/command_line.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/prefs/pref_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
diff --git a/chrome/browser/extensions/extension_install_ui_browsertest.cc b/chrome/browser/extensions/extension_install_ui_browsertest.cc
index cc059f1..d5b86ee 100644
--- a/chrome/browser/extensions/extension_install_ui_browsertest.cc
+++ b/chrome/browser/extensions/extension_install_ui_browsertest.cc
@@ -8,7 +8,7 @@
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_sorting.h"
-#include "chrome/browser/extensions/theme_installed_infobar_delegate.h"
+#include "chrome/browser/infobars/confirm_infobar_delegate.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/themes/theme_service.h"
@@ -24,6 +24,10 @@
#include "content/public/test/browser_test_utils.h"
#include "extensions/common/id_util.h"
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
using content::WebContents;
using extensions::Extension;
@@ -70,6 +74,12 @@
IN_PROC_BROWSER_TEST_F(ExtensionInstallUIBrowserTest,
MAYBE_TestThemeInstallUndoResetsToDefault) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
// Install theme once and undo to verify we go back to default theme.
base::FilePath theme_crx = PackExtension(test_data_dir_.AppendASCII("theme"));
ASSERT_TRUE(InstallExtensionWithUIAutoConfirm(theme_crx, 1, browser()));
@@ -94,6 +104,12 @@
IN_PROC_BROWSER_TEST_F(ExtensionInstallUIBrowserTest,
TestThemeInstallUndoResetsToPreviousTheme) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
// Install first theme.
InstallThemeAndVerify("theme", "camo theme");
const Extension* theme = GetTheme();
diff --git a/chrome/browser/extensions/extension_nacl_browsertest.cc b/chrome/browser/extensions/extension_nacl_browsertest.cc
index 160c9f8..df151de 100644
--- a/chrome/browser/extensions/extension_nacl_browsertest.cc
+++ b/chrome/browser/extensions/extension_nacl_browsertest.cc
@@ -20,9 +20,9 @@
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/common/webplugininfo.h"
#include "content/public/test/browser_test_utils.h"
#include "net/dns/mock_host_resolver.h"
-#include "webkit/plugins/webplugininfo.h"
using content::PluginService;
using content::WebContents;
@@ -107,7 +107,7 @@
bool IsNaClPluginLoaded() {
base::FilePath path;
if (PathService::Get(chrome::FILE_NACL_PLUGIN, &path)) {
- webkit::WebPluginInfo info;
+ content::WebPluginInfo info;
return PluginService::GetInstance()->GetPluginInfoByPath(path, &info);
}
return false;
diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc
index ab300ff..904527d 100644
--- a/chrome/browser/extensions/extension_prefs.cc
+++ b/chrome/browser/extensions/extension_prefs.cc
@@ -26,13 +26,13 @@
#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/extensions/permissions/permission_set.h"
#include "chrome/common/extensions/permissions/permissions_info.h"
-#include "chrome/common/extensions/user_script.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "components/user_prefs/pref_registry_syncable.h"
#include "content/public/browser/notification_service.h"
#include "extensions/browser/pref_names.h"
#include "extensions/common/url_pattern.h"
+#include "extensions/common/user_script.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
@@ -538,7 +538,9 @@
const ListValue* api_values = NULL;
std::string api_pref = JoinPrefs(pref_key, kPrefAPIs);
if (ReadPrefAsList(extension_id, api_pref, &api_values)) {
- APIPermissionSet::ParseFromJSON(api_values, &apis, NULL, NULL);
+ APIPermissionSet::ParseFromJSON(api_values,
+ APIPermissionSet::kAllowInternalPermissions,
+ &apis, NULL, NULL);
}
// Retrieve the explicit host permissions.
diff --git a/chrome/browser/extensions/extension_prefs_unittest.h b/chrome/browser/extensions/extension_prefs_unittest.h
index 0f42488..fc0ae8e 100644
--- a/chrome/browser/extensions/extension_prefs_unittest.h
+++ b/chrome/browser/extensions/extension_prefs_unittest.h
@@ -5,7 +5,7 @@
#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_PREFS_UNITTEST_H_
#define CHROME_BROWSER_EXTENSIONS_EXTENSION_PREFS_UNITTEST_H_
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "chrome/browser/extensions/test_extension_prefs.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc
index b18b2af..ae861fa 100644
--- a/chrome/browser/extensions/extension_process_manager.cc
+++ b/chrome/browser/extensions/extension_process_manager.cc
@@ -8,7 +8,7 @@
#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
@@ -856,8 +856,8 @@
const GURL& url) {
ExtensionService* service = GetProfile()->GetExtensionService();
if (service) {
- const Extension* extension = service->extensions()->GetExtensionOrAppByURL(
- ExtensionURLInfo(url));
+ const Extension* extension =
+ service->extensions()->GetExtensionOrAppByURL(url);
if (extension &&
!extensions::IncognitoInfo::IsSplitMode(extension)) {
return original_manager_->GetSiteInstanceForURL(url);
diff --git a/chrome/browser/extensions/extension_protocols.cc b/chrome/browser/extensions/extension_protocols.cc
index 5bb7a98..2ec1145 100644
--- a/chrome/browser/extensions/extension_protocols.cc
+++ b/chrome/browser/extensions/extension_protocols.cc
@@ -13,7 +13,7 @@
#include "base/format_macros.h"
#include "base/logging.h"
#include "base/memory/weak_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/sha1.h"
#include "base/strings/string_util.h"
diff --git a/chrome/browser/extensions/extension_protocols_unittest.cc b/chrome/browser/extensions/extension_protocols_unittest.cc
index b096d98..0e41a0d 100644
--- a/chrome/browser/extensions/extension_protocols_unittest.cc
+++ b/chrome/browser/extensions/extension_protocols_unittest.cc
@@ -5,7 +5,7 @@
#include <string>
#include "base/file_util.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/strings/string_util.h"
#include "base/values.h"
#include "chrome/browser/extensions/extension_info_map.h"
diff --git a/chrome/browser/extensions/extension_resource_request_policy_apitest.cc b/chrome/browser/extensions/extension_resource_request_policy_apitest.cc
index 05e3588..3eea53c 100644
--- a/chrome/browser/extensions/extension_resource_request_policy_apitest.cc
+++ b/chrome/browser/extensions/extension_resource_request_policy_apitest.cc
@@ -6,10 +6,10 @@
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
+#include "extensions/common/switches.h"
#include "net/dns/mock_host_resolver.h"
#include "url/gurl.h"
@@ -17,7 +17,8 @@
protected:
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
ExtensionApiTest::SetUpCommandLine(command_line);
- command_line->AppendSwitch(switches::kAllowLegacyExtensionManifests);
+ command_line->AppendSwitch(
+ extensions::switches::kAllowLegacyExtensionManifests);
}
};
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 73a7c63..e3ae629 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -264,8 +264,7 @@
}
const Extension* ExtensionService::GetInstalledApp(const GURL& url) const {
- const Extension* extension = extensions_.GetExtensionOrAppByURL(
- ExtensionURLInfo(url));
+ const Extension* extension = extensions_.GetExtensionOrAppByURL(url);
return (extension && extension->is_app()) ? extension : NULL;
}
@@ -704,6 +703,8 @@
}
path = current_extension->path();
+ // BeingUpgraded is set back to false when the extension is added.
+ SetBeingUpgraded(current_extension, true);
DisableExtension(extension_id, Extension::DISABLE_RELOAD);
reloading_extensions_.insert(extension_id);
} else {
@@ -2584,15 +2585,13 @@
bool ExtensionService::ExtensionBindingsAllowed(const GURL& url) {
// Allow bindings for all packaged extensions and component hosted apps.
- const Extension* extension = extensions_.GetExtensionOrAppByURL(
- ExtensionURLInfo(url));
+ const Extension* extension = extensions_.GetExtensionOrAppByURL(url);
return extension && (!extension->is_hosted_app() ||
extension->location() == Manifest::COMPONENT);
}
bool ExtensionService::ShouldBlockUrlInBrowserTab(GURL* url) {
- const Extension* extension = extensions_.GetExtensionOrAppByURL(
- ExtensionURLInfo(*url));
+ const Extension* extension = extensions_.GetExtensionOrAppByURL(*url);
if (extension && extension->is_platform_app()) {
*url = GURL(chrome::kExtensionInvalidRequestURL);
return true;
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index 8811e48..580e728 100644
--- a/chrome/browser/extensions/extension_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -20,7 +20,7 @@
#include "base/json/json_string_value_serializer.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/stl_util.h"
#include "base/strings/string16.h"
@@ -47,6 +47,9 @@
#include "chrome/browser/extensions/external_pref_loader.h"
#include "chrome/browser/extensions/external_provider_impl.h"
#include "chrome/browser/extensions/external_provider_interface.h"
+#include "chrome/browser/extensions/install_observer.h"
+#include "chrome/browser/extensions/install_tracker.h"
+#include "chrome/browser/extensions/install_tracker_factory.h"
#include "chrome/browser/extensions/installed_loader.h"
#include "chrome/browser/extensions/management_policy.h"
#include "chrome/browser/extensions/pack_extension_job.h"
@@ -110,7 +113,6 @@
#include "webkit/browser/database/database_tracker.h"
#include "webkit/browser/quota/quota_manager.h"
#include "webkit/common/database/database_identifier.h"
-#include "webkit/plugins/npapi/mock_plugin_list.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/extensions/install_limiter.h"
@@ -441,7 +443,6 @@
expected_extensions_count_(0),
ui_thread_(BrowserThread::UI, &loop_),
db_thread_(BrowserThread::DB, &loop_),
- webkit_thread_(BrowserThread::WEBKIT_DEPRECATED, &loop_),
file_thread_(BrowserThread::FILE, &loop_),
file_user_blocking_thread_(BrowserThread::FILE_USER_BLOCKING, &loop_),
io_thread_(BrowserThread::IO, &loop_) {
@@ -468,12 +469,18 @@
TestingProfile::Builder profile_builder;
// Create a PrefService that only contains user defined preference values.
PrefServiceMockBuilder builder;
- builder.WithUserFilePrefs(params.pref_file, loop_.message_loop_proxy().get());
- scoped_refptr<user_prefs::PrefRegistrySyncable> registry(
- new user_prefs::PrefRegistrySyncable);
- scoped_ptr<PrefServiceSyncable> prefs(builder.CreateSyncable(registry.get()));
- chrome::RegisterUserProfilePrefs(registry.get());
- profile_builder.SetPrefService(prefs.Pass());
+ // If pref_file is empty, TestingProfile automatically creates
+ // TestingPrefServiceSyncable instance.
+ if (!params.pref_file.empty()) {
+ builder.WithUserFilePrefs(params.pref_file,
+ loop_.message_loop_proxy().get());
+ scoped_refptr<user_prefs::PrefRegistrySyncable> registry(
+ new user_prefs::PrefRegistrySyncable);
+ scoped_ptr<PrefServiceSyncable> prefs(
+ builder.CreateSyncable(registry.get()));
+ chrome::RegisterUserProfilePrefs(registry.get());
+ profile_builder.SetPrefService(prefs.Pass());
+ }
profile_builder.SetPath(params.profile_path);
profile_ = profile_builder.Build();
@@ -1608,6 +1615,80 @@
// TODO(erikkay): add tests for upgrade cases.
}
+struct MockInstallObserver : public extensions::InstallObserver {
+ MockInstallObserver() {
+ }
+
+ virtual ~MockInstallObserver() {
+ }
+
+ virtual void OnBeginExtensionInstall(
+ const std::string& extension_id,
+ const std::string& extension_name,
+ const gfx::ImageSkia& installing_icon,
+ bool is_app,
+ bool is_platform_app) OVERRIDE {
+ }
+
+ virtual void OnDownloadProgress(const std::string& extension_id,
+ int percent_downloaded) OVERRIDE {
+ }
+
+ virtual void OnExtensionInstalled(const Extension* extension) OVERRIDE {
+ last_extension_installed = extension->id();
+ }
+
+ virtual void OnInstallFailure(const std::string& extension_id) OVERRIDE {
+ }
+
+ virtual void OnExtensionLoaded(const Extension* extension) OVERRIDE {
+ }
+
+ virtual void OnExtensionUnloaded(const Extension* extension) OVERRIDE {
+ }
+
+ virtual void OnExtensionUninstalled(const Extension* extension) OVERRIDE {
+ last_extension_uninstalled = extension->id();
+ }
+
+ virtual void OnAppsReordered() OVERRIDE {
+ }
+
+ virtual void OnAppInstalledToAppList(
+ const std::string& extension_id) OVERRIDE {
+ }
+
+ virtual void OnShutdown() OVERRIDE {
+ }
+
+ std::string last_extension_installed;
+ std::string last_extension_uninstalled;
+};
+
+// Test that correct notifications are sent to InstallTracker observers on
+// extension install and uninstall.
+TEST_F(ExtensionServiceTest, InstallObserverNotified) {
+ InitializeEmptyExtensionService();
+
+ extensions::InstallTracker* tracker(
+ extensions::InstallTrackerFactory::GetForProfile(profile_.get()));
+ MockInstallObserver observer;
+ tracker->AddObserver(&observer);
+
+ // A simple extension that should install without error.
+ ASSERT_TRUE(observer.last_extension_installed.empty());
+ base::FilePath path = data_dir_.AppendASCII("good.crx");
+ InstallCRX(path, INSTALL_NEW);
+ ASSERT_EQ(good_crx, observer.last_extension_installed);
+
+ // Uninstall the extension.
+ ASSERT_TRUE(observer.last_extension_uninstalled.empty());
+ UninstallExtension(good_crx, false);
+ ASSERT_EQ(good_crx, observer.last_extension_uninstalled);
+
+ tracker->RemoveObserver(&observer);
+}
+
// Tests that flags passed to OnExternalExtensionFileFound() make it to the
// extension object.
TEST_F(ExtensionServiceTest, InstallingExternalExtensionWithFlags) {
@@ -2911,6 +2992,7 @@
EXPECT_EQ(0u, service_->disabled_extensions()->size());
// But the extension with no plugin should since there's no prompt.
+ ExtensionErrorReporter::GetInstance()->ClearErrors();
extensions::UnpackedInstaller::Create(service_)->Load(
extension_no_plugin_path);
loop_.RunUntilIdle();
@@ -2925,6 +3007,7 @@
switches::kAppsGalleryInstallAutoConfirmForTests,
"accept");
+ ExtensionErrorReporter::GetInstance()->ClearErrors();
extensions::UnpackedInstaller::Create(service_)->Load(
extension_with_plugin_path);
loop_.RunUntilIdle();
@@ -4844,6 +4927,10 @@
TEST(ExtensionServiceTestSimple, Enabledness) {
// Make sure the PluginService singleton is destroyed at the end of the test.
base::ShadowingAtExitManager at_exit_manager;
+#if defined(ENABLE_PLUGINS)
+ content::PluginService::GetInstance()->Init();
+ content::PluginService::GetInstance()->DisablePluginsDiscoveryForTesting();
+#endif
ExtensionErrorReporter::Init(false); // no noisy errors
ExtensionsReadyRecorder recorder;
@@ -4861,11 +4948,6 @@
base::FilePath install_dir = profile->GetPath()
.AppendASCII(extensions::kInstallDirectoryName);
-#if defined(ENABLE_PLUGINS)
- webkit::npapi::MockPluginList plugin_list;
- PluginService::GetInstance()->SetPluginListForTesting(&plugin_list);
-#endif
-
// By default, we are enabled.
command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
ExtensionService* service = static_cast<extensions::TestExtensionSystem*>(
@@ -4931,13 +5013,6 @@
service = NULL;
// Execute any pending deletion tasks.
loop.RunUntilIdle();
-
-#if defined(ENABLE_PLUGINS)
- // Ensure that even if the PluginService is re-used for a later test, it
- // won't still hold a reference to the stack position of our MockPluginList.
- // See crbug.com/159754.
- PluginService::GetInstance()->SetPluginListForTesting(NULL);
-#endif
}
// Test loading extensions that require limited and unlimited storage quotas.
diff --git a/chrome/browser/extensions/extension_service_unittest.h b/chrome/browser/extensions/extension_service_unittest.h
index e6d70c8..24be033 100644
--- a/chrome/browser/extensions/extension_service_unittest.h
+++ b/chrome/browser/extensions/extension_service_unittest.h
@@ -10,7 +10,7 @@
#include "base/files/scoped_temp_dir.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/common/extensions/feature_switch.h"
#include "content/public/test/test_browser_thread.h"
@@ -82,7 +82,6 @@
size_t expected_extensions_count_;
content::TestBrowserThread ui_thread_;
content::TestBrowserThread db_thread_;
- content::TestBrowserThread webkit_thread_;
content::TestBrowserThread file_thread_;
content::TestBrowserThread file_user_blocking_thread_;
content::TestBrowserThread io_thread_;
diff --git a/chrome/browser/extensions/extension_special_storage_policy_unittest.cc b/chrome/browser/extensions/extension_special_storage_policy_unittest.cc
index 7e07052..74f34fe 100644
--- a/chrome/browser/extensions/extension_special_storage_policy_unittest.cc
+++ b/chrome/browser/extensions/extension_special_storage_policy_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/values.h"
#include "chrome/browser/content_settings/cookie_settings.h"
#include "chrome/browser/extensions/extension_special_storage_policy.h"
diff --git a/chrome/browser/extensions/extension_ui_unittest.cc b/chrome/browser/extensions/extension_ui_unittest.cc
index 0ebcde7..8581038 100644
--- a/chrome/browser/extensions/extension_ui_unittest.cc
+++ b/chrome/browser/extensions/extension_ui_unittest.cc
@@ -4,7 +4,7 @@
#include "base/command_line.h"
#include "base/json/json_file_value_serializer.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "chrome/browser/extensions/extension_service.h"
diff --git a/chrome/browser/extensions/extension_uninstall_dialog.cc b/chrome/browser/extensions/extension_uninstall_dialog.cc
index e91fbff..0eb8dcf 100644
--- a/chrome/browser/extensions/extension_uninstall_dialog.cc
+++ b/chrome/browser/extensions/extension_uninstall_dialog.cc
@@ -6,7 +6,7 @@
#include "base/bind.h"
#include "base/logging.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/image_loader.h"
#include "chrome/browser/ui/browser.h"
diff --git a/chrome/browser/extensions/extension_web_ui.cc b/chrome/browser/extensions/extension_web_ui.cc
index 3ea194b..40a4deb 100644
--- a/chrome/browser/extensions/extension_web_ui.cc
+++ b/chrome/browser/extensions/extension_web_ui.cc
@@ -129,7 +129,7 @@
Profile* profile = Profile::FromWebUI(web_ui);
ExtensionService* service = profile->GetExtensionService();
const Extension* extension =
- service->extensions()->GetExtensionOrAppByURL(ExtensionURLInfo(url));
+ service->extensions()->GetExtensionOrAppByURL(url);
DCHECK(extension);
// The base class defaults to enabling WebUI bindings, but we don't need
diff --git a/chrome/browser/extensions/extensions_quota_service.cc b/chrome/browser/extensions/extensions_quota_service.cc
index f776c40..830c93a 100644
--- a/chrome/browser/extensions/extensions_quota_service.cc
+++ b/chrome/browser/extensions/extensions_quota_service.cc
@@ -4,7 +4,7 @@
#include "chrome/browser/extensions/extensions_quota_service.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
#include "chrome/browser/extensions/extension_function.h"
#include "extensions/common/error_utils.h"
diff --git a/chrome/browser/extensions/extensions_quota_service_unittest.cc b/chrome/browser/extensions/extensions_quota_service_unittest.cc
index 4ebbf5a..9cb6fdc 100644
--- a/chrome/browser/extensions/extensions_quota_service_unittest.cc
+++ b/chrome/browser/extensions/extensions_quota_service_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/process.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
diff --git a/chrome/browser/extensions/external_install_ui.cc b/chrome/browser/extensions/external_install_ui.cc
index fe7fc25..0888c97 100644
--- a/chrome/browser/extensions/external_install_ui.cc
+++ b/chrome/browser/extensions/external_install_ui.cc
@@ -10,7 +10,7 @@
#include "base/lazy_instance.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
diff --git a/chrome/browser/extensions/external_policy_loader_unittest.cc b/chrome/browser/extensions/external_policy_loader_unittest.cc
index f8e0340..4270a24 100644
--- a/chrome/browser/extensions/external_policy_loader_unittest.cc
+++ b/chrome/browser/extensions/external_policy_loader_unittest.cc
@@ -6,7 +6,7 @@
#include <string>
#include "base/logging.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/values.h"
#include "base/version.h"
#include "chrome/browser/extensions/external_policy_loader.h"
diff --git a/chrome/browser/extensions/image_loader_unittest.cc b/chrome/browser/extensions/image_loader_unittest.cc
index 4d50f6b..8c541a6 100644
--- a/chrome/browser/extensions/image_loader_unittest.cc
+++ b/chrome/browser/extensions/image_loader_unittest.cc
@@ -5,7 +5,7 @@
#include "chrome/browser/extensions/image_loader.h"
#include "base/json/json_file_value_serializer.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/common/chrome_paths.h"
diff --git a/chrome/browser/extensions/menu_manager_unittest.cc b/chrome/browser/extensions/menu_manager_unittest.cc
index 40dfeed..e8ad2c6 100644
--- a/chrome/browser/extensions/menu_manager_unittest.cc
+++ b/chrome/browser/extensions/menu_manager_unittest.cc
@@ -7,7 +7,7 @@
#include "base/files/scoped_temp_dir.h"
#include "base/json/json_reader.h"
#include "base/memory/scoped_vector.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
diff --git a/chrome/browser/extensions/navigation_observer.cc b/chrome/browser/extensions/navigation_observer.cc
index f8030e9..3e3bde3 100644
--- a/chrome/browser/extensions/navigation_observer.cc
+++ b/chrome/browser/extensions/navigation_observer.cc
@@ -59,7 +59,7 @@
ExtensionService* extension_service =
extensions::ExtensionSystem::Get(profile_)->extension_service();
const Extension* extension = extension_service->disabled_extensions()->
- GetExtensionOrAppByURL(ExtensionURLInfo(nav_entry->GetURL()));
+ GetExtensionOrAppByURL(nav_entry->GetURL());
if (!extension)
return;
diff --git a/chrome/browser/extensions/pack_extension_job.cc b/chrome/browser/extensions/pack_extension_job.cc
index 1af8399..744eb62 100644
--- a/chrome/browser/extensions/pack_extension_job.cc
+++ b/chrome/browser/extensions/pack_extension_job.cc
@@ -5,7 +5,7 @@
#include "chrome/browser/extensions/pack_extension_job.h"
#include "base/bind.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/extension_creator.h"
diff --git a/chrome/browser/extensions/pack_extension_unittest.cc b/chrome/browser/extensions/pack_extension_unittest.cc
index dddfe4d..dac4608 100644
--- a/chrome/browser/extensions/pack_extension_unittest.cc
+++ b/chrome/browser/extensions/pack_extension_unittest.cc
@@ -6,7 +6,7 @@
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "chrome/browser/extensions/startup_helper.h"
#include "chrome/common/chrome_paths.h"
diff --git a/chrome/browser/extensions/page_action_browsertest.cc b/chrome/browser/extensions/page_action_browsertest.cc
index 90e8ef7..52a0dd4 100644
--- a/chrome/browser/extensions/page_action_browsertest.cc
+++ b/chrome/browser/extensions/page_action_browsertest.cc
@@ -11,9 +11,9 @@
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/test/base/ui_test_utils.h"
+#include "extensions/common/switches.h"
namespace extensions {
namespace {
diff --git a/chrome/browser/extensions/page_action_controller_unittest.cc b/chrome/browser/extensions/page_action_controller_unittest.cc
index 70358eb..ed35108 100644
--- a/chrome/browser/extensions/page_action_controller_unittest.cc
+++ b/chrome/browser/extensions/page_action_controller_unittest.cc
@@ -6,7 +6,7 @@
#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "chrome/browser/extensions/extension_action.h"
#include "chrome/browser/extensions/extension_action_manager.h"
#include "chrome/browser/extensions/extension_service.h"
diff --git a/chrome/browser/extensions/platform_app_browsertest.cc b/chrome/browser/extensions/platform_app_browsertest.cc
index e301d3d..d193507 100644
--- a/chrome/browser/extensions/platform_app_browsertest.cc
+++ b/chrome/browser/extensions/platform_app_browsertest.cc
@@ -45,6 +45,10 @@
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "url/gurl.h"
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
using apps::ShellWindow;
using content::WebContents;
using web_modal::WebContentsModalDialogManager;
@@ -792,6 +796,11 @@
#define MAYBE_ReOpenedWithID ReOpenedWithID
#endif
IN_PROC_BROWSER_TEST_F(PlatformAppDevToolsBrowserTest, MAYBE_ReOpenedWithID) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/179830).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
RunTestWithDevTools("minimal_id", RELAUNCH | HAS_ID);
}
@@ -950,19 +959,12 @@
extensions::ExtensionSystem::Get(browser()->profile())->event_router()->
SetRegisteredEvents(extension->id(), std::set<std::string>());
- const base::StringValue old_version("1");
- std::string pref_path("extensions.settings.");
- pref_path += extension->id();
- pref_path += ".manifest.version";
- // TODO(joi): Do registrations up front.
- user_prefs::PrefRegistrySyncable* registry =
- static_cast<user_prefs::PrefRegistrySyncable*>(
- extension_prefs->pref_service()->DeprecatedGetPrefRegistry());
- registry->RegisterStringPref(
- pref_path.c_str(),
- std::string(),
- user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
- extension_prefs->pref_service()->Set(pref_path.c_str(), old_version);
+ DictionaryPrefUpdate update(extension_prefs->pref_service(),
+ ExtensionPrefs::kExtensionsPref);
+ DictionaryValue* dict = update.Get();
+ std::string key(extension->id());
+ key += ".manifest.version";
+ dict->SetString(key, "1");
}
// Component App Test 3 of 3: simulate a component extension upgrade that
diff --git a/chrome/browser/extensions/plugin_apitest.cc b/chrome/browser/extensions/plugin_apitest.cc
index 39b1118..16d5ed9 100644
--- a/chrome/browser/extensions/plugin_apitest.cc
+++ b/chrome/browser/extensions/plugin_apitest.cc
@@ -15,10 +15,14 @@
#include "chrome/common/pref_names.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/plugin_service.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
#include "net/base/net_util.h"
-#include "webkit/plugins/npapi/plugin_utils.h"
+
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
using content::NavigationController;
using content::WebContents;
@@ -41,7 +45,7 @@
// Tests that a renderer's plugin list is properly updated when we load and
// unload an extension that contains a plugin.
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, MAYBE_PluginLoadUnload) {
- if (!webkit::npapi::NPAPIPluginsSupported())
+ if (!content::PluginService::GetInstance()->NPAPIPluginsSupported())
return;
browser()->profile()->GetPrefs()->SetBoolean(prefs::kPluginsAlwaysAuthorize,
true);
@@ -124,7 +128,13 @@
#endif
// Tests that private extension plugins are only visible to the extension.
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, MAYBE_PluginPrivate) {
- if (!webkit::npapi::NPAPIPluginsSupported())
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
+ if (!content::PluginService::GetInstance()->NPAPIPluginsSupported())
return;
browser()->profile()->GetPrefs()->SetBoolean(prefs::kPluginsAlwaysAuthorize,
diff --git a/chrome/browser/extensions/plugin_manager.cc b/chrome/browser/extensions/plugin_manager.cc
index f797cda..ff77620 100644
--- a/chrome/browser/extensions/plugin_manager.cc
+++ b/chrome/browser/extensions/plugin_manager.cc
@@ -148,7 +148,7 @@
if (!pepper_info)
return;
- std::vector<webkit::WebPluginMimeType>::const_iterator mime_iter;
+ std::vector<content::WebPluginMimeType>::const_iterator mime_iter;
// Check each MIME type the plugins handle for the NaCl MIME type.
for (mime_iter = pepper_info->mime_types.begin();
mime_iter != pepper_info->mime_types.end(); ++mime_iter) {
@@ -157,7 +157,7 @@
PluginService::GetInstance()->UnregisterInternalPlugin(pepper_info->path);
- webkit::WebPluginInfo info = pepper_info->ToWebPluginInfo();
+ content::WebPluginInfo info = pepper_info->ToWebPluginInfo();
for (NaClModuleInfo::List::const_iterator iter =
nacl_module_list_.begin();
@@ -165,7 +165,7 @@
// Add the MIME type specified in the extension to this NaCl plugin,
// With an extra "nacl" argument to specify the location of the NaCl
// manifest file.
- webkit::WebPluginMimeType mime_type_info;
+ content::WebPluginMimeType mime_type_info;
mime_type_info.mime_type = iter->mime_type;
mime_type_info.additional_param_names.push_back(UTF8ToUTF16("nacl"));
mime_type_info.additional_param_values.push_back(
diff --git a/chrome/browser/extensions/requirements_checker_browsertest.cc b/chrome/browser/extensions/requirements_checker_browsertest.cc
index 337c31f..30b01d6 100644
--- a/chrome/browser/extensions/requirements_checker_browsertest.cc
+++ b/chrome/browser/extensions/requirements_checker_browsertest.cc
@@ -8,7 +8,7 @@
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/threading/sequenced_worker_pool.h"
diff --git a/chrome/browser/extensions/sandboxed_unpacker.cc b/chrome/browser/extensions/sandboxed_unpacker.cc
index cb40deb..e2b317f 100644
--- a/chrome/browser/extensions/sandboxed_unpacker.cc
+++ b/chrome/browser/extensions/sandboxed_unpacker.cc
@@ -13,7 +13,7 @@
#include "base/files/file_util_proxy.h"
#include "base/json/json_string_value_serializer.h"
#include "base/memory/scoped_handle.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/path_service.h"
#include "base/sequenced_task_runner.h"
diff --git a/chrome/browser/extensions/sandboxed_unpacker_unittest.cc b/chrome/browser/extensions/sandboxed_unpacker_unittest.cc
index 55fe555..1bf0018 100644
--- a/chrome/browser/extensions/sandboxed_unpacker_unittest.cc
+++ b/chrome/browser/extensions/sandboxed_unpacker_unittest.cc
@@ -5,7 +5,7 @@
#include "base/bind.h"
#include "base/file_util.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
diff --git a/chrome/browser/extensions/script_badge_controller_unittest.cc b/chrome/browser/extensions/script_badge_controller_unittest.cc
index 6eed1ad..9b0eddc 100644
--- a/chrome/browser/extensions/script_badge_controller_unittest.cc
+++ b/chrome/browser/extensions/script_badge_controller_unittest.cc
@@ -6,7 +6,7 @@
#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/extension_action_manager.h"
diff --git a/chrome/browser/extensions/script_bubble_controller_unittest.cc b/chrome/browser/extensions/script_bubble_controller_unittest.cc
index 8f7a269..cce310c 100644
--- a/chrome/browser/extensions/script_bubble_controller_unittest.cc
+++ b/chrome/browser/extensions/script_bubble_controller_unittest.cc
@@ -7,7 +7,7 @@
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "chrome/browser/extensions/component_loader.h"
#include "chrome/browser/extensions/extension_action.h"
#include "chrome/browser/extensions/extension_action_manager.h"
diff --git a/chrome/browser/extensions/script_executor.h b/chrome/browser/extensions/script_executor.h
index 7bfbf79..d463bf0 100644
--- a/chrome/browser/extensions/script_executor.h
+++ b/chrome/browser/extensions/script_executor.h
@@ -10,7 +10,7 @@
#include "base/callback_forward.h"
#include "base/observer_list.h"
#include "chrome/browser/extensions/tab_helper.h"
-#include "chrome/common/extensions/user_script.h"
+#include "extensions/common/user_script.h"
class GURL;
diff --git a/chrome/browser/extensions/standard_management_policy_provider_unittest.cc b/chrome/browser/extensions/standard_management_policy_provider_unittest.cc
index d4f9605..ae6f6e5 100644
--- a/chrome/browser/extensions/standard_management_policy_provider_unittest.cc
+++ b/chrome/browser/extensions/standard_management_policy_provider_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "chrome/browser/extensions/blacklist.h"
diff --git a/chrome/browser/extensions/startup_helper.cc b/chrome/browser/extensions/startup_helper.cc
index 7bc9524..09f45f3 100644
--- a/chrome/browser/extensions/startup_helper.cc
+++ b/chrome/browser/extensions/startup_helper.cc
@@ -8,7 +8,7 @@
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
diff --git a/chrome/browser/extensions/state_store.cc b/chrome/browser/extensions/state_store.cc
index c89cfc3..0169ee5 100644
--- a/chrome/browser/extensions/state_store.cc
+++ b/chrome/browser/extensions/state_store.cc
@@ -5,7 +5,7 @@
#include "chrome/browser/extensions/state_store.h"
#include "base/bind.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/common/extensions/extension.h"
#include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/extensions/tab_helper.cc b/chrome/browser/extensions/tab_helper.cc
index cfd07b7..ac7620c 100644
--- a/chrome/browser/extensions/tab_helper.cc
+++ b/chrome/browser/extensions/tab_helper.cc
@@ -311,11 +311,10 @@
const ExtensionSet* extensions = extension_service->extensions();
const ExtensionSet* disabled = extension_service->disabled_extensions();
- ExtensionURLInfo url(requestor_url);
std::string state;
- if (extensions->GetHostedAppByURL(url))
+ if (extensions->GetHostedAppByURL(requestor_url))
state = extension_misc::kAppStateInstalled;
- else if (disabled->GetHostedAppByURL(url))
+ else if (disabled->GetHostedAppByURL(requestor_url))
state = extension_misc::kAppStateDisabled;
else
state = extension_misc::kAppStateNotInstalled;
diff --git a/chrome/browser/extensions/test_blacklist.cc b/chrome/browser/extensions/test_blacklist.cc
index 249d929..77b75b2 100644
--- a/chrome/browser/extensions/test_blacklist.cc
+++ b/chrome/browser/extensions/test_blacklist.cc
@@ -7,7 +7,7 @@
#include <set>
#include "base/bind.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "chrome/browser/extensions/blacklist.h"
diff --git a/chrome/browser/extensions/test_extension_environment.h b/chrome/browser/extensions/test_extension_environment.h
index a193345..904f961 100644
--- a/chrome/browser/extensions/test_extension_environment.h
+++ b/chrome/browser/extensions/test_extension_environment.h
@@ -6,7 +6,7 @@
#define CHROME_BROWSER_EXTENSIONS_TEST_EXTENSION_ENVIRONMENT_H_
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "content/public/test/test_browser_thread.h"
#if defined(OS_CHROMEOS)
diff --git a/chrome/browser/extensions/test_extension_prefs.cc b/chrome/browser/extensions/test_extension_prefs.cc
index 6c21f20..e2d8a70 100644
--- a/chrome/browser/extensions/test_extension_prefs.cc
+++ b/chrome/browser/extensions/test_extension_prefs.cc
@@ -8,7 +8,7 @@
#include "base/bind_helpers.h"
#include "base/file_util.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/prefs/json_pref_store.h"
#include "base/prefs/pref_value_store.h"
diff --git a/chrome/browser/extensions/theme_installed_infobar_delegate.cc b/chrome/browser/extensions/theme_installed_infobar_delegate.cc
index 3a0ae75..be6ede8 100644
--- a/chrome/browser/extensions/theme_installed_infobar_delegate.cc
+++ b/chrome/browser/extensions/theme_installed_infobar_delegate.cc
@@ -54,15 +54,15 @@
// If there's a previous theme infobar, just replace that instead of adding a
// new one.
for (size_t i = 0; i < infobar_service->infobar_count(); ++i) {
- InfoBarDelegate* delegate = infobar_service->infobar_at(i);
+ InfoBarDelegate* old_infobar = infobar_service->infobar_at(i);
ThemeInstalledInfoBarDelegate* theme_infobar =
- delegate->AsThemePreviewInfobarDelegate();
+ old_infobar->AsThemePreviewInfobarDelegate();
if (theme_infobar) {
// If the user installed the same theme twice, ignore the second install
// and keep the first install info bar, so that they can easily undo to
// get back the previous theme.
if (theme_infobar->theme_id_ != new_theme->id()) {
- infobar_service->ReplaceInfoBar(delegate, new_infobar.Pass());
+ infobar_service->ReplaceInfoBar(old_infobar, new_infobar.Pass());
theme_service->OnInfobarDisplayed();
}
return;
@@ -135,7 +135,7 @@
extension_service_->GetExtensionById(previous_theme_id_, true);
if (previous_theme) {
theme_service_->SetTheme(previous_theme);
- return false; // The theme change will close us.
+ return false; // The theme change will close us.
}
}
diff --git a/chrome/browser/extensions/theme_installed_infobar_delegate.h b/chrome/browser/extensions/theme_installed_infobar_delegate.h
index 14ba85d..f37efcc 100644
--- a/chrome/browser/extensions/theme_installed_infobar_delegate.h
+++ b/chrome/browser/extensions/theme_installed_infobar_delegate.h
@@ -26,8 +26,8 @@
class ThemeInstalledInfoBarDelegate : public ConfirmInfoBarDelegate,
public content::NotificationObserver {
public:
- // Creates a theme installed delegate and adds it to the last active tab on
- // |profile|.
+ // Creates a theme installed infobar delegate and adds it to the last active
+ // tab on |profile|.
static void Create(const extensions::Extension* new_theme,
Profile* profile,
const std::string& previous_theme_id,
diff --git a/chrome/browser/extensions/updater/extension_updater_unittest.cc b/chrome/browser/extensions/updater/extension_updater_unittest.cc
index 07599e1..8fdd4bf 100644
--- a/chrome/browser/extensions/updater/extension_updater_unittest.cc
+++ b/chrome/browser/extensions/updater/extension_updater_unittest.cc
@@ -13,7 +13,7 @@
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/sequenced_task_runner.h"
#include "base/stl_util.h"
diff --git a/chrome/browser/extensions/updater/request_queue_impl.h b/chrome/browser/extensions/updater/request_queue_impl.h
index baa2d4d..db167e8 100644
--- a/chrome/browser/extensions/updater/request_queue_impl.h
+++ b/chrome/browser/extensions/updater/request_queue_impl.h
@@ -9,7 +9,7 @@
#include "base/bind.h"
#include "base/compiler_specific.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
#include "chrome/browser/extensions/updater/request_queue.h"
diff --git a/chrome/browser/extensions/user_script_listener.h b/chrome/browser/extensions/user_script_listener.h
index d4f6c4a..009a9d7 100644
--- a/chrome/browser/extensions/user_script_listener.h
+++ b/chrome/browser/extensions/user_script_listener.h
@@ -15,7 +15,7 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
-#include "webkit/glue/resource_type.h"
+#include "webkit/common/resource_type.h"
class GURL;
class URLPattern;
diff --git a/chrome/browser/extensions/user_script_listener_unittest.cc b/chrome/browser/extensions/user_script_listener_unittest.cc
index 23ea469..1f5dc67 100644
--- a/chrome/browser/extensions/user_script_listener_unittest.cc
+++ b/chrome/browser/extensions/user_script_listener_unittest.cc
@@ -4,7 +4,7 @@
#include "base/file_util.h"
#include "base/json/json_file_value_serializer.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/threading/thread.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/extension_service_unittest.h"
diff --git a/chrome/browser/extensions/user_script_master.h b/chrome/browser/extensions/user_script_master.h
index b805f7c..44aeb93 100644
--- a/chrome/browser/extensions/user_script_master.h
+++ b/chrome/browser/extensions/user_script_master.h
@@ -17,10 +17,10 @@
#include "chrome/browser/extensions/extension_info_map.h"
#include "chrome/common/extensions/extension_messages.h"
#include "chrome/common/extensions/extension_set.h"
-#include "chrome/common/extensions/user_script.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
+#include "extensions/common/user_script.h"
namespace content {
class RenderProcessHost;
diff --git a/chrome/browser/extensions/user_script_master_unittest.cc b/chrome/browser/extensions/user_script_master_unittest.cc
index d072c30..dc55c56 100644
--- a/chrome/browser/extensions/user_script_master_unittest.cc
+++ b/chrome/browser/extensions/user_script_master_unittest.cc
@@ -9,7 +9,7 @@
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "chrome/browser/chrome_notification_types.h"
diff --git a/chrome/browser/extensions/web_view_interactive_browsertest.cc b/chrome/browser/extensions/web_view_interactive_browsertest.cc
index 04d6e4b..95fcfb8 100644
--- a/chrome/browser/extensions/web_view_interactive_browsertest.cc
+++ b/chrome/browser/extensions/web_view_interactive_browsertest.cc
@@ -143,6 +143,12 @@
LoadAndLaunchPlatformApp(app_location.c_str());
ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
+ ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(
+ GetPlatformAppWindow()));
+
+ // Flush any pending events to make sure we start with a clean slate.
+ content::RunAllPendingInMessageLoop();
+
content::WebContents* embedder_web_contents =
GetFirstShellWindowWebContents();
ASSERT_TRUE(embedder_web_contents);
@@ -654,3 +660,12 @@
ASSERT_TRUE(done_listener.WaitUntilSatisfied());
}
+
+IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest,
+ PointerLock_PointerLockLostWithFocus) {
+ TestHelper("testPointerLockLostWithFocus",
+ "DonePointerLockTest.PASSED",
+ "DonePointerLockTest.FAILED",
+ "web_view/pointerlock");
+}
+
diff --git a/chrome/browser/extensions/webstore_startup_installer_browsertest.cc b/chrome/browser/extensions/webstore_startup_installer_browsertest.cc
index 6b727f4..1ff011b 100644
--- a/chrome/browser/extensions/webstore_startup_installer_browsertest.cc
+++ b/chrome/browser/extensions/webstore_startup_installer_browsertest.cc
@@ -33,6 +33,10 @@
#include "net/dns/mock_host_resolver.h"
#include "url/gurl.h"
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
using content::WebContents;
using extensions::DictionaryBuilder;
using extensions::Extension;
@@ -236,6 +240,12 @@
IN_PROC_BROWSER_TEST_F(WebstoreStartupInstallerTest,
InstallProhibitedForManagedUsers) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kAppsGalleryInstallAutoConfirmForTests, "accept");
diff --git a/chrome/browser/extensions/window_open_apitest.cc b/chrome/browser/extensions/window_open_apitest.cc
index 840ff58..1563afb 100644
--- a/chrome/browser/extensions/window_open_apitest.cc
+++ b/chrome/browser/extensions/window_open_apitest.cc
@@ -29,6 +29,10 @@
#include "chrome/browser/extensions/shell_window_registry.h"
#endif
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
#if defined(USE_ASH) && !defined(OS_WIN)
// TODO(stevenjb): Figure out the correct behavior for Ash + Win
#define USE_ASH_PANELS
@@ -254,6 +258,12 @@
IN_PROC_BROWSER_TEST_F(WindowOpenPanelTest,
CloseNonExtensionPanelsOnUninstall) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
#if defined(USE_ASH_PANELS)
// On Ash, new panel windows open as popup windows instead.
int num_popups, num_panels;
diff --git a/chrome/browser/external_protocol/external_protocol_handler.cc b/chrome/browser/external_protocol/external_protocol_handler.cc
index 04d59e8..ac4f5f5 100644
--- a/chrome/browser/external_protocol/external_protocol_handler.cc
+++ b/chrome/browser/external_protocol/external_protocol_handler.cc
@@ -8,7 +8,7 @@
#include "base/bind.h"
#include "base/logging.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/pref_service.h"
#include "base/strings/string_util.h"
diff --git a/chrome/browser/external_protocol/external_protocol_handler_unittest.cc b/chrome/browser/external_protocol/external_protocol_handler_unittest.cc
index d8a3679..57a6db6 100644
--- a/chrome/browser/external_protocol/external_protocol_handler_unittest.cc
+++ b/chrome/browser/external_protocol/external_protocol_handler_unittest.cc
@@ -4,7 +4,7 @@
#include "chrome/browser/external_protocol/external_protocol_handler.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/feedback/feedback_data.cc b/chrome/browser/feedback/feedback_data.cc
index 2e1cde3..4b4c71f 100644
--- a/chrome/browser/feedback/feedback_data.cc
+++ b/chrome/browser/feedback/feedback_data.cc
@@ -19,17 +19,11 @@
#include "ash/shell_delegate.h"
#endif
-#if defined(OS_CHROMEOS)
-#include "third_party/zlib/google/zip.h"
-#endif
-
using content::BrowserThread;
#if defined(OS_CHROMEOS)
namespace {
-const char kLogsFilename[] = "system_logs.txt";
-
const char kMultilineIndicatorString[] = "<multiline>\n";
const char kMultilineStartString[] = "---------- START ----------\n";
const char kMultilineEndString[] = "---------- END ----------\n\n";
@@ -57,35 +51,11 @@
return syslogs_string;
}
-bool ZipString(const std::string& logs,
- std::string* compressed_logs) {
- base::FilePath temp_path;
- base::FilePath zip_file;
-
- // Create a temporary directory, put the logs into a file in it. Create
- // another temporary file to receive the zip file in.
- if (!file_util::CreateNewTempDirectory("", &temp_path))
- return false;
- if (file_util::WriteFile(
- temp_path.Append(kLogsFilename), logs.c_str(), logs.size()) == -1)
- return false;
- if (!file_util::CreateTemporaryFile(&zip_file))
- return false;
-
- if (!zip::Zip(temp_path, zip_file, false))
- return false;
-
- if (!file_util::ReadFileToString(zip_file, compressed_logs))
- return false;
-
- return true;
-}
-
void ZipLogs(chromeos::SystemLogsResponse* sys_info,
std::string* compressed_logs) {
DCHECK(compressed_logs);
std::string logs_string = LogsToString(sys_info);
- if (!ZipString(logs_string, compressed_logs)) {
+ if (!FeedbackUtil::ZipString(logs_string, compressed_logs)) {
compressed_logs->clear();
}
}
diff --git a/chrome/browser/feedback/feedback_util.cc b/chrome/browser/feedback/feedback_util.cc
index 7096dc9..8095fad 100644
--- a/chrome/browser/feedback/feedback_util.cc
+++ b/chrome/browser/feedback/feedback_util.cc
@@ -10,6 +10,7 @@
#include "base/bind.h"
#include "base/command_line.h"
+#include "base/file_util.h"
#include "base/file_version_info.h"
#include "base/memory/singleton.h"
#include "base/message_loop/message_loop.h"
@@ -36,12 +37,20 @@
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_status.h"
-#include "third_party/icu/public/common/unicode/locid.h"
+#include "third_party/icu/source/common/unicode/locid.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"
+#if defined(OS_CHROMEOS)
+#include "third_party/zlib/google/zip.h"
+#endif
+
using content::WebContents;
+namespace {
+const char kLogsFilename[] = "system_logs.txt";
+}
+
namespace chrome {
const char kAppLauncherCategoryTag[] = "AppLauncher";
} // namespace chrome
@@ -424,3 +433,31 @@
gfx::Rect& screen_size = GetScreenshotSize();
screen_size = rect;
}
+
+#if defined(OS_CHROMEOS)
+// static
+bool FeedbackUtil::ZipString(const std::string& logs,
+ std::string* compressed_logs) {
+ base::FilePath temp_path;
+ base::FilePath zip_file;
+
+ // Create a temporary directory, put the logs into a file in it. Create
+ // another temporary file to receive the zip file in.
+ if (!file_util::CreateNewTempDirectory("", &temp_path))
+ return false;
+ if (file_util::WriteFile(
+ temp_path.Append(kLogsFilename), logs.c_str(), logs.size()) == -1)
+ return false;
+ if (!file_util::CreateTemporaryFile(&zip_file))
+ return false;
+
+ if (!zip::Zip(temp_path, zip_file, false))
+ return false;
+
+ if (!file_util::ReadFileToString(zip_file, compressed_logs))
+ return false;
+
+ return true;
+}
+#endif // OS_CHROMEOS
+
diff --git a/chrome/browser/feedback/feedback_util.h b/chrome/browser/feedback/feedback_util.h
index 0c0cec6..163317d 100644
--- a/chrome/browser/feedback/feedback_util.h
+++ b/chrome/browser/feedback/feedback_util.h
@@ -76,6 +76,9 @@
static void ClearScreenshotPng();
static void SetScreenshotSize(const gfx::Rect& rect);
static gfx::Rect& GetScreenshotSize();
+#if defined(OS_CHROMEOS)
+ static bool ZipString(const std::string& logs, std::string* compressed_logs);
+#endif
class PostCleanup;
diff --git a/chrome/browser/first_run/first_run.cc b/chrome/browser/first_run/first_run.cc
index c5cd11f..315d6f9 100644
--- a/chrome/browser/first_run/first_run.cc
+++ b/chrome/browser/first_run/first_run.cc
@@ -11,7 +11,7 @@
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/path_service.h"
#include "base/prefs/pref_service.h"
diff --git a/chrome/browser/geolocation/OWNERS b/chrome/browser/geolocation/OWNERS
index 765d513..c2252ab 100644
--- a/chrome/browser/geolocation/OWNERS
+++ b/chrome/browser/geolocation/OWNERS
@@ -1,2 +1,6 @@
-joth@chromium.org
+# Reviews:
+# Not yet owner - mvanouwerkerk@chromium.org
bulach@chromium.org
+
+# Just owners:
+joth@chromium.org
diff --git a/chrome/browser/geolocation/chrome_geolocation_permission_context.cc b/chrome/browser/geolocation/chrome_geolocation_permission_context.cc
index e81d950..cdf6bc4 100644
--- a/chrome/browser/geolocation/chrome_geolocation_permission_context.cc
+++ b/chrome/browser/geolocation/chrome_geolocation_permission_context.cc
@@ -24,8 +24,6 @@
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/view_type_utils.h"
-#include "third_party/WebKit/public/platform/WebString.h"
-#include "third_party/WebKit/public/web/WebSecurityOrigin.h"
using extensions::APIPermission;
@@ -71,9 +69,7 @@
if (extension_service) {
const extensions::Extension* extension =
extension_service->extensions()->GetExtensionOrAppByURL(
- ExtensionURLInfo(WebKit::WebSecurityOrigin::createFromString(
- UTF8ToUTF16(requesting_frame.spec())),
- requesting_frame));
+ requesting_frame);
if (IsExtensionWithPermissionOrSuggestInConsole(APIPermission::kGeolocation,
extension,
profile_)) {
diff --git a/chrome/browser/geolocation/chrome_geolocation_permission_context_unittest.cc b/chrome/browser/geolocation/chrome_geolocation_permission_context_unittest.cc
index c5f7911..10eae81 100644
--- a/chrome/browser/geolocation/chrome_geolocation_permission_context_unittest.cc
+++ b/chrome/browser/geolocation/chrome_geolocation_permission_context_unittest.cc
@@ -41,55 +41,53 @@
using content::MockRenderProcessHost;
-// ClosedDelegateTracker ------------------------------------------------------
+// ClosedInfoBarTracker -------------------------------------------------------
// We need to track which infobars were closed.
-class ClosedDelegateTracker : public content::NotificationObserver {
+class ClosedInfoBarTracker : public content::NotificationObserver {
public:
- ClosedDelegateTracker();
- virtual ~ClosedDelegateTracker();
+ ClosedInfoBarTracker();
+ virtual ~ClosedInfoBarTracker();
// content::NotificationObserver:
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
- size_t size() const {
- return removed_infobar_delegates_.size();
- }
+ size_t size() const { return removed_infobars_.size(); }
- bool Contains(InfoBarDelegate* delegate) const;
+ bool Contains(InfoBarDelegate* infobar) const;
void Clear();
private:
FRIEND_TEST_ALL_PREFIXES(GeolocationPermissionContextTests, TabDestroyed);
content::NotificationRegistrar registrar_;
- std::set<InfoBarDelegate*> removed_infobar_delegates_;
+ std::set<InfoBarDelegate*> removed_infobars_;
};
-ClosedDelegateTracker::ClosedDelegateTracker() {
+ClosedInfoBarTracker::ClosedInfoBarTracker() {
registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
content::NotificationService::AllSources());
}
-ClosedDelegateTracker::~ClosedDelegateTracker() {
+ClosedInfoBarTracker::~ClosedInfoBarTracker() {
}
-void ClosedDelegateTracker::Observe(
+void ClosedInfoBarTracker::Observe(
int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
DCHECK(type == chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED);
- removed_infobar_delegates_.insert(
+ removed_infobars_.insert(
content::Details<InfoBarRemovedDetails>(details)->first);
}
-bool ClosedDelegateTracker::Contains(InfoBarDelegate* delegate) const {
- return removed_infobar_delegates_.count(delegate) != 0;
+bool ClosedInfoBarTracker::Contains(InfoBarDelegate* infobar) const {
+ return removed_infobars_.count(infobar) != 0;
}
-void ClosedDelegateTracker::Clear() {
- removed_infobar_delegates_.clear();
+void ClosedInfoBarTracker::Clear() {
+ removed_infobars_.clear();
}
@@ -130,7 +128,7 @@
scoped_refptr<ChromeGeolocationPermissionContext>
geolocation_permission_context_;
- ClosedDelegateTracker closed_delegate_tracker_;
+ ClosedInfoBarTracker closed_infobar_tracker_;
ScopedVector<content::WebContents> extra_tabs_;
// A map between renderer child id and a pair represending the bridge id and
@@ -223,11 +221,11 @@
ContentSetting expected_content_setting) {
TabSpecificContentSettings* content_settings =
TabSpecificContentSettings::FromWebContents(web_contents());
- const GeolocationSettingsState::StateMap& state_map =
- content_settings->geolocation_settings_state().state_map();
+ const ContentSettingsUsagesState::StateMap& state_map =
+ content_settings->geolocation_usages_state().state_map();
EXPECT_EQ(1U, state_map.count(requesting_frame.GetOrigin()));
EXPECT_EQ(0U, state_map.count(requesting_frame));
- GeolocationSettingsState::StateMap::const_iterator settings =
+ ContentSettingsUsagesState::StateMap::const_iterator settings =
state_map.find(requesting_frame.GetOrigin());
ASSERT_FALSE(settings == state_map.end())
<< "geolocation state not found " << requesting_frame;
@@ -261,13 +259,14 @@
EXPECT_EQ(0U, infobar_service()->infobar_count());
RequestGeolocationPermission(RequestID(0), requesting_frame);
ASSERT_EQ(1U, infobar_service()->infobar_count());
- ConfirmInfoBarDelegate* infobar_0 =
+ ConfirmInfoBarDelegate* infobar_delegate =
infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
- infobar_0->Cancel();
- infobar_service()->RemoveInfoBar(infobar_0);
- EXPECT_EQ(1U, closed_delegate_tracker_.size());
- EXPECT_TRUE(closed_delegate_tracker_.Contains(infobar_0));
- delete infobar_0;
+ ASSERT_TRUE(infobar_delegate);
+ infobar_delegate->Cancel();
+ infobar_service()->RemoveInfoBar(infobar_delegate);
+ EXPECT_EQ(1U, closed_infobar_tracker_.size());
+ EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate));
+ delete infobar_delegate;
}
#if defined(OS_ANDROID)
@@ -278,10 +277,10 @@
EXPECT_EQ(0U, infobar_service()->infobar_count());
RequestGeolocationPermission(RequestID(0), requesting_frame);
EXPECT_EQ(1U, infobar_service()->infobar_count());
- ConfirmInfoBarDelegate* infobar_0 =
+ ConfirmInfoBarDelegate* infobar_delegate_0 =
infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
- ASSERT_TRUE(infobar_0);
- string16 text_0 = infobar_0->GetButtonLabel(
+ ASSERT_TRUE(infobar_delegate_0);
+ string16 text_0 = infobar_delegate_0->GetButtonLabel(
ConfirmInfoBarDelegate::BUTTON_OK);
NavigateAndCommit(requesting_frame);
@@ -289,10 +288,10 @@
EXPECT_EQ(0U, infobar_service()->infobar_count());
RequestGeolocationPermission(RequestID(0), requesting_frame);
EXPECT_EQ(1U, infobar_service()->infobar_count());
- ConfirmInfoBarDelegate* infobar_1 =
+ ConfirmInfoBarDelegate* infobar_delegate_1 =
infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
- ASSERT_TRUE(infobar_1);
- string16 text_1 = infobar_1->GetButtonLabel(
+ ASSERT_TRUE(infobar_delegate_1);
+ string16 text_1 = infobar_delegate_1->GetButtonLabel(
ConfirmInfoBarDelegate::BUTTON_OK);
EXPECT_NE(text_0, text_1);
@@ -310,10 +309,10 @@
EXPECT_EQ(0U, infobar_service()->infobar_count());
RequestGeolocationPermission(RequestID(0), requesting_frame);
EXPECT_EQ(1U, infobar_service()->infobar_count());
- ConfirmInfoBarDelegate* infobar_0 =
+ ConfirmInfoBarDelegate* infobar_delegate =
infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
- ASSERT_TRUE(infobar_0);
- infobar_0->Accept();
+ ASSERT_TRUE(infobar_delegate);
+ infobar_delegate->Accept();
CheckTabContentsState(requesting_frame, CONTENT_SETTING_ALLOW);
CheckPermissionMessageSent(0, true);
}
@@ -325,10 +324,10 @@
EXPECT_EQ(0U, infobar_service()->infobar_count());
RequestGeolocationPermission(RequestID(0), requesting_frame);
EXPECT_EQ(1U, infobar_service()->infobar_count());
- ConfirmInfoBarDelegate* infobar_0 =
+ ConfirmInfoBarDelegate* infobar_delegate =
infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
- ASSERT_TRUE(infobar_0);
- infobar_0->Accept();
+ ASSERT_TRUE(infobar_delegate);
+ infobar_delegate->Accept();
EXPECT_TRUE(
MockGoogleLocationSettingsHelper::WasGoogleLocationSettingsCalled());
}
@@ -353,49 +352,49 @@
RequestGeolocationPermission(RequestID(1), requesting_frame_1);
// Ensure only one infobar is created.
ASSERT_EQ(1U, infobar_service()->infobar_count());
- ConfirmInfoBarDelegate* infobar_0 =
+ ConfirmInfoBarDelegate* infobar_delegate_0 =
infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
- ASSERT_TRUE(infobar_0);
- string16 text_0 = infobar_0->GetMessageText();
+ ASSERT_TRUE(infobar_delegate_0);
+ string16 text_0 = infobar_delegate_0->GetMessageText();
// Accept the first frame.
- infobar_0->Accept();
+ infobar_delegate_0->Accept();
CheckTabContentsState(requesting_frame_0, CONTENT_SETTING_ALLOW);
CheckPermissionMessageSent(0, true);
- infobar_service()->RemoveInfoBar(infobar_0);
- EXPECT_EQ(1U, closed_delegate_tracker_.size());
- EXPECT_TRUE(closed_delegate_tracker_.Contains(infobar_0));
- closed_delegate_tracker_.Clear();
- delete infobar_0;
+ infobar_service()->RemoveInfoBar(infobar_delegate_0);
+ EXPECT_EQ(1U, closed_infobar_tracker_.size());
+ EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_0));
+ closed_infobar_tracker_.Clear();
+ delete infobar_delegate_0;
// Now we should have a new infobar for the second frame.
ASSERT_EQ(1U, infobar_service()->infobar_count());
- ConfirmInfoBarDelegate* infobar_1 =
+ ConfirmInfoBarDelegate* infobar_delegate_1 =
infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
- ASSERT_TRUE(infobar_1);
- string16 text_1 = infobar_1->GetMessageText();
+ ASSERT_TRUE(infobar_delegate_1);
+ string16 text_1 = infobar_delegate_1->GetMessageText();
EXPECT_NE(text_0, text_1);
// Cancel (block) this frame.
- infobar_1->Cancel();
+ infobar_delegate_1->Cancel();
CheckTabContentsState(requesting_frame_1, CONTENT_SETTING_BLOCK);
CheckPermissionMessageSent(1, false);
- infobar_service()->RemoveInfoBar(infobar_1);
- EXPECT_EQ(1U, closed_delegate_tracker_.size());
- EXPECT_TRUE(closed_delegate_tracker_.Contains(infobar_1));
- delete infobar_1;
+ infobar_service()->RemoveInfoBar(infobar_delegate_1);
+ EXPECT_EQ(1U, closed_infobar_tracker_.size());
+ EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_1));
+ delete infobar_delegate_1;
EXPECT_EQ(0U, infobar_service()->infobar_count());
// Ensure the persisted permissions are ok.
EXPECT_EQ(CONTENT_SETTING_ALLOW,
- profile()->GetHostContentSettingsMap()->GetContentSetting(
- requesting_frame_0, requesting_frame_0,
- CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
+ profile()->GetHostContentSettingsMap()->GetContentSetting(
+ requesting_frame_0, requesting_frame_0,
+ CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
EXPECT_EQ(CONTENT_SETTING_BLOCK,
- profile()->GetHostContentSettingsMap()->GetContentSetting(
- requesting_frame_1, requesting_frame_0,
- CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
+ profile()->GetHostContentSettingsMap()->GetContentSetting(
+ requesting_frame_1, requesting_frame_0,
+ CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
}
TEST_F(GeolocationPermissionContextTests, PermissionForFileScheme) {
@@ -404,15 +403,15 @@
EXPECT_EQ(0U, infobar_service()->infobar_count());
RequestGeolocationPermission(RequestID(0), requesting_frame);
EXPECT_EQ(1U, infobar_service()->infobar_count());
- ConfirmInfoBarDelegate* infobar =
+ ConfirmInfoBarDelegate* infobar_delegate =
infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
- ASSERT_TRUE(infobar);
+ ASSERT_TRUE(infobar_delegate);
// Accept the frame
- infobar->Accept();
+ infobar_delegate->Accept();
CheckTabContentsState(requesting_frame, CONTENT_SETTING_ALLOW);
CheckPermissionMessageSent(0, true);
- infobar_service()->RemoveInfoBar(infobar);
- delete infobar;
+ infobar_service()->RemoveInfoBar(infobar_delegate);
+ delete infobar_delegate;
// Make sure the setting is not stored.
EXPECT_EQ(CONTENT_SETTING_ASK,
@@ -443,34 +442,34 @@
RequestGeolocationPermission(RequestID(1), requesting_frame_1);
ASSERT_EQ(1U, infobar_service()->infobar_count());
- ConfirmInfoBarDelegate* infobar_0 =
+ ConfirmInfoBarDelegate* infobar_delegate_0 =
infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
- ASSERT_TRUE(infobar_0);
- string16 text_0 = infobar_0->GetMessageText();
+ ASSERT_TRUE(infobar_delegate_0);
+ string16 text_0 = infobar_delegate_0->GetMessageText();
// Simulate the frame going away, ensure the infobar for this frame
// is removed and the next pending infobar is created.
CancelGeolocationPermissionRequest(RequestID(0), requesting_frame_0);
- EXPECT_EQ(1U, closed_delegate_tracker_.size());
- EXPECT_TRUE(closed_delegate_tracker_.Contains(infobar_0));
- closed_delegate_tracker_.Clear();
- delete infobar_0;
+ EXPECT_EQ(1U, closed_infobar_tracker_.size());
+ EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_0));
+ closed_infobar_tracker_.Clear();
+ delete infobar_delegate_0;
ASSERT_EQ(1U, infobar_service()->infobar_count());
- ConfirmInfoBarDelegate* infobar_1 =
+ ConfirmInfoBarDelegate* infobar_delegate_1 =
infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
- ASSERT_TRUE(infobar_1);
- string16 text_1 = infobar_1->GetMessageText();
+ ASSERT_TRUE(infobar_delegate_1);
+ string16 text_1 = infobar_delegate_1->GetMessageText();
EXPECT_NE(text_0, text_1);
// Allow this frame.
- infobar_1->Accept();
+ infobar_delegate_1->Accept();
CheckTabContentsState(requesting_frame_1, CONTENT_SETTING_ALLOW);
CheckPermissionMessageSent(1, true);
- infobar_service()->RemoveInfoBar(infobar_1);
- EXPECT_EQ(1U, closed_delegate_tracker_.size());
- EXPECT_TRUE(closed_delegate_tracker_.Contains(infobar_1));
- delete infobar_1;
+ infobar_service()->RemoveInfoBar(infobar_delegate_1);
+ EXPECT_EQ(1U, closed_infobar_tracker_.size());
+ EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_1));
+ delete infobar_delegate_1;
EXPECT_EQ(0U, infobar_service()->infobar_count());
// Ensure the persisted permissions are ok.
EXPECT_EQ(CONTENT_SETTING_ASK,
@@ -515,32 +514,32 @@
infobar_service_for_tab(1)->infobar_at(0)->AsConfirmInfoBarDelegate();
// Accept the first tab.
- ConfirmInfoBarDelegate* infobar_0 =
+ ConfirmInfoBarDelegate* infobar_delegate_0 =
infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
- ASSERT_TRUE(infobar_0);
- infobar_0->Accept();
+ ASSERT_TRUE(infobar_delegate_0);
+ infobar_delegate_0->Accept();
CheckPermissionMessageSent(0, true);
- infobar_service()->RemoveInfoBar(infobar_0);
- EXPECT_EQ(2U, closed_delegate_tracker_.size());
- EXPECT_TRUE(closed_delegate_tracker_.Contains(infobar_0));
- delete infobar_0;
+ infobar_service()->RemoveInfoBar(infobar_delegate_0);
+ EXPECT_EQ(2U, closed_infobar_tracker_.size());
+ EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_0));
+ delete infobar_delegate_0;
// Now the infobar for the tab with the same origin should have gone.
EXPECT_EQ(0U, infobar_service_for_tab(1)->infobar_count());
CheckPermissionMessageSentForTab(1, 0, true);
- EXPECT_TRUE(closed_delegate_tracker_.Contains(removed_infobar));
- closed_delegate_tracker_.Clear();
+ EXPECT_TRUE(closed_infobar_tracker_.Contains(removed_infobar));
+ closed_infobar_tracker_.Clear();
// Destroy the infobar that has just been removed.
delete removed_infobar;
// But the other tab should still have the info bar...
ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
- ConfirmInfoBarDelegate* infobar_1 =
+ ConfirmInfoBarDelegate* infobar_delegate_1 =
infobar_service_for_tab(0)->infobar_at(0)->AsConfirmInfoBarDelegate();
- infobar_1->Cancel();
- infobar_service_for_tab(0)->RemoveInfoBar(infobar_1);
- EXPECT_EQ(1U, closed_delegate_tracker_.size());
- EXPECT_TRUE(closed_delegate_tracker_.Contains(infobar_1));
- delete infobar_1;
+ infobar_delegate_1->Cancel();
+ infobar_service_for_tab(0)->RemoveInfoBar(infobar_delegate_1);
+ EXPECT_EQ(1U, closed_infobar_tracker_.size());
+ EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_1));
+ delete infobar_delegate_1;
}
TEST_F(GeolocationPermissionContextTests, QueuedOriginMultipleTabs) {
@@ -563,36 +562,35 @@
infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
// Accept the second tab.
- ConfirmInfoBarDelegate* infobar_0 =
+ ConfirmInfoBarDelegate* infobar_delegate_0 =
infobar_service_for_tab(0)->infobar_at(0)->AsConfirmInfoBarDelegate();
- ASSERT_TRUE(infobar_0);
- infobar_0->Accept();
+ ASSERT_TRUE(infobar_delegate_0);
+ infobar_delegate_0->Accept();
CheckPermissionMessageSentForTab(0, 0, true);
- infobar_service_for_tab(0)->RemoveInfoBar(infobar_0);
- EXPECT_EQ(2U, closed_delegate_tracker_.size());
- EXPECT_TRUE(closed_delegate_tracker_.Contains(infobar_0));
- delete infobar_0;
+ infobar_service_for_tab(0)->RemoveInfoBar(infobar_delegate_0);
+ EXPECT_EQ(2U, closed_infobar_tracker_.size());
+ EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_0));
+ delete infobar_delegate_0;
// Now the infobar for the tab with the same origin should have gone.
EXPECT_EQ(0U, infobar_service()->infobar_count());
CheckPermissionMessageSent(0, true);
- EXPECT_TRUE(closed_delegate_tracker_.Contains(removed_infobar));
- closed_delegate_tracker_.Clear();
- // Destroy the infobar that has just been removed.
+ EXPECT_TRUE(closed_infobar_tracker_.Contains(removed_infobar));
+ closed_infobar_tracker_.Clear();
delete removed_infobar;
// And we should have the queued infobar displayed now.
ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
// Accept the second infobar.
- ConfirmInfoBarDelegate* infobar_1 =
+ ConfirmInfoBarDelegate* infobar_delegate_1 =
infobar_service_for_tab(0)->infobar_at(0)->AsConfirmInfoBarDelegate();
- ASSERT_TRUE(infobar_1);
- infobar_1->Accept();
+ ASSERT_TRUE(infobar_delegate_1);
+ infobar_delegate_1->Accept();
CheckPermissionMessageSentForTab(0, 1, true);
- infobar_service_for_tab(0)->RemoveInfoBar(infobar_1);
- EXPECT_EQ(1U, closed_delegate_tracker_.size());
- EXPECT_TRUE(closed_delegate_tracker_.Contains(infobar_1));
- delete infobar_1;
+ infobar_service_for_tab(0)->RemoveInfoBar(infobar_delegate_1);
+ EXPECT_EQ(1U, closed_infobar_tracker_.size());
+ EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_1));
+ delete infobar_delegate_1;
}
TEST_F(GeolocationPermissionContextTests, TabDestroyed) {
@@ -615,18 +613,18 @@
RequestGeolocationPermission(RequestID(1), requesting_frame_1);
// Ensure only one infobar is created.
ASSERT_EQ(1U, infobar_service()->infobar_count());
- ConfirmInfoBarDelegate* infobar_0 =
+ ConfirmInfoBarDelegate* infobar =
infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
- ASSERT_TRUE(infobar_0);
+ ASSERT_TRUE(infobar);
// Delete the tab contents.
DeleteContents();
- delete infobar_0;
+ delete infobar;
// During contents destruction, the infobar will have been closed, and the
// pending request should have been cleared without an infobar being created.
- ASSERT_EQ(1U, closed_delegate_tracker_.size());
- ASSERT_TRUE(closed_delegate_tracker_.Contains(infobar_0));
+ ASSERT_EQ(1U, closed_infobar_tracker_.size());
+ ASSERT_TRUE(closed_infobar_tracker_.Contains(infobar));
}
TEST_F(GeolocationPermissionContextTests, InfoBarUsesCommittedEntry) {
@@ -642,17 +640,17 @@
RequestGeolocationPermission(RequestID(0), requesting_frame_1);
// Ensure the infobar is created.
ASSERT_EQ(1U, infobar_service()->infobar_count());
- InfoBarDelegate* infobar_0 = infobar_service()->infobar_at(0);
- ASSERT_TRUE(infobar_0);
+ InfoBarDelegate* infobar_delegate = infobar_service()->infobar_at(0);
+ ASSERT_TRUE(infobar_delegate);
// Ensure the infobar wouldn't expire for a navigation to the committed entry.
content::LoadCommittedDetails details;
details.entry = web_contents()->GetController().GetLastCommittedEntry();
- EXPECT_FALSE(infobar_0->ShouldExpire(details));
+ EXPECT_FALSE(infobar_delegate->ShouldExpire(details));
// Ensure the infobar will expire when we commit the pending navigation.
details.entry = web_contents()->GetController().GetActiveEntry();
- EXPECT_TRUE(infobar_0->ShouldExpire(details));
+ EXPECT_TRUE(infobar_delegate->ShouldExpire(details));
// Delete the tab contents.
DeleteContents();
- delete infobar_0;
+ delete infobar_delegate;
}
diff --git a/chrome/browser/geolocation/geolocation_browsertest.cc b/chrome/browser/geolocation/geolocation_browsertest.cc
index f5b8439..95158db 100644
--- a/chrome/browser/geolocation/geolocation_browsertest.cc
+++ b/chrome/browser/geolocation/geolocation_browsertest.cc
@@ -9,9 +9,9 @@
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/content_settings/content_settings_usages_state.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/content_settings/tab_specific_content_settings.h"
-#include "chrome/browser/geolocation/geolocation_settings_state.h"
#include "chrome/browser/infobars/confirm_infobar_delegate.h"
#include "chrome/browser/infobars/infobar.h"
#include "chrome/browser/infobars/infobar_service.h"
@@ -376,9 +376,9 @@
current_browser_->tab_strip_model()->GetActiveWebContents();
TabSpecificContentSettings* content_settings =
TabSpecificContentSettings::FromWebContents(web_contents);
- const GeolocationSettingsState& settings_state =
- content_settings->geolocation_settings_state();
- size_t state_map_size = settings_state.state_map().size();
+ const ContentSettingsUsagesState& usages_state =
+ content_settings->geolocation_usages_state();
+ size_t state_map_size = usages_state.state_map().size();
ASSERT_TRUE(infobar_);
LOG(WARNING) << "will set infobar response";
{
@@ -395,13 +395,13 @@
InfoBarService::FromWebContents(web_contents)->RemoveInfoBar(infobar_);
LOG(WARNING) << "infobar response set";
infobar_ = NULL;
- EXPECT_GT(settings_state.state_map().size(), state_map_size);
+ EXPECT_GT(usages_state.state_map().size(), state_map_size);
GURL requesting_origin(requesting_url.GetOrigin());
- EXPECT_EQ(1U, settings_state.state_map().count(requesting_origin));
+ EXPECT_EQ(1U, usages_state.state_map().count(requesting_origin));
ContentSetting expected_setting =
allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
EXPECT_EQ(expected_setting,
- settings_state.state_map().find(requesting_origin)->second);
+ usages_state.state_map().find(requesting_origin)->second);
}
void GeolocationBrowserTest::CheckStringValueFromJavascriptForTab(
diff --git a/chrome/browser/geolocation/geolocation_infobar_delegate.cc b/chrome/browser/geolocation/geolocation_infobar_delegate.cc
index 93f500d..017c570 100644
--- a/chrome/browser/geolocation/geolocation_infobar_delegate.cc
+++ b/chrome/browser/geolocation/geolocation_infobar_delegate.cc
@@ -31,8 +31,11 @@
const GeolocationPermissionRequestID& id,
const GURL& requesting_frame,
const std::string& display_languages) {
+ const content::NavigationEntry* committed_entry =
+ infobar_service->web_contents()->GetController().GetLastCommittedEntry();
return infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
new DelegateType(infobar_service, controller, id, requesting_frame,
+ committed_entry ? committed_entry->GetUniqueID() : 0,
display_languages)));
}
@@ -41,15 +44,14 @@
GeolocationInfoBarQueueController* controller,
const GeolocationPermissionRequestID& id,
const GURL& requesting_frame,
+ int contents_unique_id,
const std::string& display_languages)
: ConfirmInfoBarDelegate(infobar_service),
controller_(controller),
id_(id),
requesting_frame_(requesting_frame),
+ contents_unique_id_(contents_unique_id),
display_languages_(display_languages) {
- const content::NavigationEntry* committed_entry = infobar_service->
- web_contents()->GetController().GetLastCommittedEntry();
- contents_unique_id_ = committed_entry ? committed_entry->GetUniqueID() : 0;
}
GeolocationInfoBarDelegate::~GeolocationInfoBarDelegate() {
diff --git a/chrome/browser/geolocation/geolocation_infobar_delegate.h b/chrome/browser/geolocation/geolocation_infobar_delegate.h
index f1656ad..4e63f64 100644
--- a/chrome/browser/geolocation/geolocation_infobar_delegate.h
+++ b/chrome/browser/geolocation/geolocation_infobar_delegate.h
@@ -19,8 +19,8 @@
// and handling of geolocation permission infobars to the user.
class GeolocationInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
- // Creates a geolocation delegate and adds it to |infobar_service|. Returns
- // the delegate if it was successfully added.
+ // Creates a geolocation infobar delegate and adds it to |infobar_service|.
+ // Returns the delegate if it was successfully added.
static InfoBarDelegate* Create(InfoBarService* infobar_service,
GeolocationInfoBarQueueController* controller,
const GeolocationPermissionRequestID& id,
@@ -32,6 +32,7 @@
GeolocationInfoBarQueueController* controller,
const GeolocationPermissionRequestID& id,
const GURL& requesting_frame,
+ int contents_unique_id,
const std::string& display_languages);
virtual ~GeolocationInfoBarDelegate();
@@ -53,7 +54,6 @@
virtual string16 GetLinkText() const OVERRIDE;
virtual bool LinkClicked(WindowOpenDisposition disposition) OVERRIDE;
- private:
GeolocationInfoBarQueueController* controller_;
const GeolocationPermissionRequestID id_;
GURL requesting_frame_;
diff --git a/chrome/browser/geolocation/geolocation_infobar_delegate_android.cc b/chrome/browser/geolocation/geolocation_infobar_delegate_android.cc
index 062e200..032b7f4 100644
--- a/chrome/browser/geolocation/geolocation_infobar_delegate_android.cc
+++ b/chrome/browser/geolocation/geolocation_infobar_delegate_android.cc
@@ -16,9 +16,11 @@
GeolocationInfoBarQueueController* controller,
const GeolocationPermissionRequestID& id,
const GURL& requesting_frame_url,
+ int contents_unique_id,
const std::string& display_languages)
: GeolocationInfoBarDelegate(infobar_service, controller, id,
- requesting_frame_url, display_languages),
+ requesting_frame_url, contents_unique_id,
+ display_languages),
google_location_settings_helper_(
GoogleLocationSettingsHelper::Create()) {
}
diff --git a/chrome/browser/geolocation/geolocation_infobar_delegate_android.h b/chrome/browser/geolocation/geolocation_infobar_delegate_android.h
index 7f1a210..f5059e3 100644
--- a/chrome/browser/geolocation/geolocation_infobar_delegate_android.h
+++ b/chrome/browser/geolocation/geolocation_infobar_delegate_android.h
@@ -17,6 +17,7 @@
GeolocationInfoBarQueueController* controller,
const GeolocationPermissionRequestID& id,
const GURL& requesting_frame_url,
+ int contents_unique_id,
const std::string& display_languages);
private:
diff --git a/chrome/browser/geolocation/geolocation_infobar_queue_controller.cc b/chrome/browser/geolocation/geolocation_infobar_queue_controller.cc
index 6607c25..69eb13e 100644
--- a/chrome/browser/geolocation/geolocation_infobar_queue_controller.cc
+++ b/chrome/browser/geolocation/geolocation_infobar_queue_controller.cc
@@ -49,19 +49,19 @@
const GeolocationPermissionRequestID& id() const { return id_; }
const GURL& requesting_frame() const { return requesting_frame_; }
- bool has_infobar_delegate() const { return !!infobar_delegate_; }
- InfoBarDelegate* infobar_delegate() { return infobar_delegate_; }
+ bool has_infobar() const { return !!infobar_; }
+ InfoBarDelegate* infobar() { return infobar_; }
void RunCallback(bool allowed);
- void CreateInfoBarDelegate(GeolocationInfoBarQueueController* controller,
- const std::string& display_languages);
+ void CreateInfoBar(GeolocationInfoBarQueueController* controller,
+ const std::string& display_languages);
private:
GeolocationPermissionRequestID id_;
GURL requesting_frame_;
GURL embedder_;
PermissionDecidedCallback callback_;
- InfoBarDelegate* infobar_delegate_;
+ InfoBarDelegate* infobar_;
// Purposefully do not disable copying, as this is stored in STL containers.
};
@@ -75,7 +75,7 @@
requesting_frame_(requesting_frame),
embedder_(embedder),
callback_(callback),
- infobar_delegate_(NULL) {
+ infobar_(NULL) {
}
GeolocationInfoBarQueueController::PendingInfoBarRequest::
@@ -94,9 +94,9 @@
}
void GeolocationInfoBarQueueController::PendingInfoBarRequest::
- CreateInfoBarDelegate(GeolocationInfoBarQueueController* controller,
- const std::string& display_languages) {
- infobar_delegate_ = GeolocationInfoBarDelegate::Create(
+ CreateInfoBar(GeolocationInfoBarQueueController* controller,
+ const std::string& display_languages) {
+ infobar_ = GeolocationInfoBarDelegate::Create(
GetInfoBarService(id_), controller, id_, requesting_frame_,
display_languages);
}
@@ -138,8 +138,8 @@
for (PendingInfoBarRequests::iterator i(pending_infobar_requests_.begin());
i != pending_infobar_requests_.end(); ++i) {
if (i->id().Equals(id)) {
- if (i->has_infobar_delegate())
- GetInfoBarService(id)->RemoveInfoBar(i->infobar_delegate());
+ if (i->has_infobar())
+ GetInfoBarService(id)->RemoveInfoBar(i->infobar());
else
pending_infobar_requests_.erase(i);
return;
@@ -167,18 +167,18 @@
if (i->IsForPair(requesting_frame, embedder)) {
requests_to_notify.push_back(*i);
if (i->id().Equals(id)) {
- // The delegate that called us is i, and it's currently in either
- // Accept() or Cancel(). This means that the owning InfoBar will call
- // RemoveInfoBar() later on, and that will trigger a notification we're
+ // The infobar that called us is i->infobar(), and it's currently in
+ // either Accept() or Cancel(). This means that RemoveInfoBar() will be
+ // called later on, and that will trigger a notification we're
// observing.
++i;
- } else if (i->has_infobar_delegate()) {
- // This InfoBar is for the same frame/embedder pair, but in a different
+ } else if (i->has_infobar()) {
+ // This infobar is for the same frame/embedder pair, but in a different
// tab. We should remove it now that we've got an answer for it.
infobars_to_remove.push_back(*i);
++i;
} else {
- // We haven't created an InfoBar yet, just remove the pending request.
+ // We haven't created an infobar yet, just remove the pending request.
i = pending_infobar_requests_.erase(i);
}
} else {
@@ -186,10 +186,10 @@
}
}
- // Remove all InfoBars for the same |requesting_frame| and |embedder|.
+ // Remove all infobars for the same |requesting_frame| and |embedder|.
for (PendingInfoBarRequests::iterator i = infobars_to_remove.begin();
i != infobars_to_remove.end(); ++i)
- GetInfoBarService(i->id())->RemoveInfoBar(i->infobar_delegate());
+ GetInfoBarService(i->id())->RemoveInfoBar(i->infobar());
// Send out the permission notifications.
for (PendingInfoBarRequests::iterator i = requests_to_notify.begin();
@@ -205,17 +205,17 @@
// We will receive this notification for all infobar closures, so we need to
// check whether this is the geolocation infobar we're tracking. Note that the
// InfoBarContainer (if any) may have received this notification before us and
- // caused the delegate to be deleted, so it's not safe to dereference the
- // contents of the delegate. The address of the delegate, however, is OK to
+ // caused the infobar to be deleted, so it's not safe to dereference the
+ // contents of the infobar. The address of the infobar, however, is OK to
// use to find the PendingInfoBarRequest to remove because
// pending_infobar_requests_ will not have received any new entries between
// the NotificationService's call to InfoBarContainer::Observe and this
// method.
- InfoBarDelegate* delegate =
+ InfoBarDelegate* infobar =
content::Details<InfoBarRemovedDetails>(details)->first;
for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin();
i != pending_infobar_requests_.end(); ++i) {
- if (i->infobar_delegate() == delegate) {
+ if (i->infobar() == infobar) {
GeolocationPermissionRequestID id(i->id());
pending_infobar_requests_.erase(i);
ShowQueuedInfoBarForTab(id);
@@ -229,7 +229,7 @@
for (PendingInfoBarRequests::const_iterator i(
pending_infobar_requests_.begin());
i != pending_infobar_requests_.end(); ++i) {
- if (i->id().IsForSameTabAs(id) && i->has_infobar_delegate())
+ if (i->id().IsForSameTabAs(id) && i->has_infobar())
return true;
}
return false;
@@ -253,9 +253,9 @@
for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin();
i != pending_infobar_requests_.end(); ++i) {
- if (i->id().IsForSameTabAs(id) && !i->has_infobar_delegate()) {
+ if (i->id().IsForSameTabAs(id) && !i->has_infobar()) {
RegisterForInfoBarNotifications(infobar_service);
- i->CreateInfoBarDelegate(
+ i->CreateInfoBar(
this, profile_->GetPrefs()->GetString(prefs::kAcceptLanguages));
return;
}
@@ -269,7 +269,7 @@
for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin();
i != pending_infobar_requests_.end(); ) {
if (i->id().IsForSameTabAs(id)) {
- DCHECK(!i->has_infobar_delegate());
+ DCHECK(!i->has_infobar());
i = pending_infobar_requests_.erase(i);
} else {
++i;
diff --git a/chrome/browser/google/google_url_tracker.cc b/chrome/browser/google/google_url_tracker.cc
index 4ed0c28..768de18 100644
--- a/chrome/browser/google/google_url_tracker.cc
+++ b/chrome/browser/google/google_url_tracker.cc
@@ -343,10 +343,10 @@
if (map_entry->has_infobar_delegate()) {
map_entry->infobar_delegate()->Update(search_url);
} else {
- GoogleURLTrackerInfoBarDelegate* infobar_delegate =
+ GoogleURLTrackerInfoBarDelegate* infobar =
infobar_creator_.Run(infobar_service, this, search_url);
- if (infobar_delegate)
- map_entry->SetInfoBarDelegate(infobar_delegate);
+ if (infobar)
+ map_entry->SetInfoBarDelegate(infobar);
else
map_entry->Close(false);
}
@@ -354,14 +354,14 @@
void GoogleURLTracker::OnTabClosed(
content::NavigationController* navigation_controller) {
- // Because InfoBarService tears itself down in on tab destruction, it may
- // or may not be possible to get a non-NULL InfoBarService pointer here,
- // depending on which order notifications fired in. Likewise, the pointer in
- // |entry_map_| (and in its associated MapEntry) may point to deleted memory.
- // Therefore, if we were to access to the InfoBarService* we have for this
- // tab, we'd need to ensure we just looked at the raw pointer value, and never
- // dereferenced it. This function doesn't need to do even that, but others in
- // the call chain from here might (and have comments pointing back here).
+ // Because InfoBarService tears itself down on tab destruction, it's possible
+ // to get a non-NULL InfoBarService pointer here, depending on which order
+ // notifications fired in. Likewise, the pointer in |entry_map_| (and in its
+ // associated MapEntry) may point to deleted memory. Therefore, if we were to
+ // access the InfoBarService* we have for this tab, we'd need to ensure we
+ // just looked at the raw pointer value, and never dereferenced it. This
+ // function doesn't need to do even that, but others in the call chain from
+ // here might (and have comments pointing back here).
for (EntryMap::iterator i(entry_map_.begin()); i != entry_map_.end(); ++i) {
if (i->second->navigation_controller() == navigation_controller) {
i->second->Close(false);
diff --git a/chrome/browser/google/google_url_tracker_infobar_delegate.h b/chrome/browser/google/google_url_tracker_infobar_delegate.h
index 7e01655..b0be8f5 100644
--- a/chrome/browser/google/google_url_tracker_infobar_delegate.h
+++ b/chrome/browser/google/google_url_tracker_infobar_delegate.h
@@ -14,8 +14,8 @@
// changed.
class GoogleURLTrackerInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
- // Creates a Google URL tracker delegate and adds it to |infobar_service|.
- // Returns the delegate if it was successfully added.
+ // Creates a Google URL tracker infobar delegate and adds it to
+ // |infobar_service|. Returns the delegate if it was successfully added.
static GoogleURLTrackerInfoBarDelegate* Create(
InfoBarService* infobar_service,
GoogleURLTracker* google_url_tracker,
diff --git a/chrome/browser/google/google_url_tracker_unittest.cc b/chrome/browser/google/google_url_tracker_unittest.cc
index 3a1d676..88bdc5a 100644
--- a/chrome/browser/google/google_url_tracker_unittest.cc
+++ b/chrome/browser/google/google_url_tracker_unittest.cc
@@ -33,10 +33,10 @@
class TestInfoBarDelegate : public GoogleURLTrackerInfoBarDelegate {
public:
// Creates a test delegate and returns it. Unlike the parent class, this does
- // not create add the infobar to |infobar_service|, since that "pointer" is
- // really just a magic number. Thus there is no InfoBarService ownership of
- // the returned object; and since the caller doesn't own the returned object,
- // we rely on |test_harness| cleaning this up eventually in
+ // not add the infobar to |infobar_service|, since that "pointer" is really
+ // just a magic number. Thus there is no InfoBarService ownership of the
+ // returned object; and since the caller doesn't own the returned object, we
+ // rely on |test_harness| cleaning this up eventually in
// GoogleURLTrackerTest::OnInfoBarClosed() to avoid leaks.
static GoogleURLTrackerInfoBarDelegate* Create(
GoogleURLTrackerTest* test_harness,
@@ -201,7 +201,7 @@
class GoogleURLTrackerTest : public testing::Test {
public:
// Called by TestInfoBarDelegate::Close().
- void OnInfoBarClosed(InfoBarDelegate* infobar,
+ void OnInfoBarClosed(scoped_ptr<InfoBarDelegate> infobar,
InfoBarService* infobar_service);
protected:
@@ -265,10 +265,10 @@
std::set<int> unique_ids_seen_;
};
-void GoogleURLTrackerTest::OnInfoBarClosed(InfoBarDelegate* infobar,
+void GoogleURLTrackerTest::OnInfoBarClosed(scoped_ptr<InfoBarDelegate> infobar,
InfoBarService* infobar_service) {
// First, simulate the InfoBarService firing INFOBAR_REMOVED.
- InfoBarRemovedDetails removed_details(infobar, false);
+ InfoBarRemovedDetails removed_details(infobar.get(), false);
GoogleURLTracker::EntryMap::const_iterator i =
google_url_tracker_->entry_map_.find(infobar_service);
ASSERT_FALSE(i == google_url_tracker_->entry_map_.end());
@@ -279,7 +279,7 @@
content::Details<InfoBarRemovedDetails>(&removed_details));
// Second, simulate the infobar container closing the infobar in response.
- delete infobar;
+ // This happens automatically as |infobar| goes out of scope.
}
GoogleURLTrackerTest::GoogleURLTrackerTest()
@@ -491,7 +491,8 @@
}
void TestInfoBarDelegate::Close(bool redo_search) {
- test_harness_->OnInfoBarClosed(this, infobar_service_);
+ test_harness_->OnInfoBarClosed(scoped_ptr<InfoBarDelegate>(this),
+ infobar_service_);
// WARNING: At this point |this| has been deleted!
}
diff --git a/chrome/browser/google_apis/task_util.h b/chrome/browser/google_apis/task_util.h
index 3c72beb..d186f3d 100644
--- a/chrome/browser/google_apis/task_util.h
+++ b/chrome/browser/google_apis/task_util.h
@@ -19,6 +19,16 @@
// Implementation of the composed callback, whose signature is |Sig|.
template<typename Sig> struct ComposedCallback;
+// ComposedCallback with no argument.
+template<>
+struct ComposedCallback<void()> {
+ static void Run(
+ const base::Callback<void(const base::Closure&)>& runner,
+ const base::Closure& callback) {
+ runner.Run(callback);
+ }
+};
+
// ComposedCallback with one argument.
template<typename T1>
struct ComposedCallback<void(T1)> {
diff --git a/chrome/browser/hang_monitor/hung_plugin_action.cc b/chrome/browser/hang_monitor/hung_plugin_action.cc
index e2133b0..cdb9e59 100644
--- a/chrome/browser/hang_monitor/hung_plugin_action.cc
+++ b/chrome/browser/hang_monitor/hung_plugin_action.cc
@@ -10,11 +10,11 @@
#include "base/version.h"
#include "chrome/browser/ui/simple_message_box.h"
#include "chrome/common/logging_chrome.h"
+#include "content/public/browser/plugin_service.h"
+#include "content/public/common/webplugininfo.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/win/hwnd_util.h"
-#include "webkit/plugins/npapi/plugin_utils.h"
-#include "webkit/plugins/npapi/webplugin_delegate_impl.h"
namespace {
@@ -41,7 +41,7 @@
GTalkPluginLogVersion GetGTalkPluginVersion(const string16& version) {
int gtalk_plugin_version = GTALK_PLUGIN_VERSION_MIN;
Version plugin_version;
- webkit::npapi::CreateVersionFromString(version, &plugin_version);
+ content::WebPluginInfo::CreateVersionFromString(version, &plugin_version);
if (plugin_version.IsValid() && plugin_version.components().size() >= 2) {
gtalk_plugin_version = 10 * plugin_version.components()[0] +
plugin_version.components()[1] - kGTalkPluginLogMinVersion;
@@ -175,10 +175,8 @@
// we have gone too far.
return false;
}
- if (webkit::npapi::WebPluginDelegateImpl::GetPluginNameFromWindow(
- window_to_check, plugin_name)) {
- webkit::npapi::WebPluginDelegateImpl::GetPluginVersionFromWindow(
- window_to_check, plugin_version);
+ if (content::PluginService::GetInstance()->GetPluginInfoFromWindow(
+ window_to_check, plugin_name, plugin_version)) {
return true;
}
window_to_check = GetParent(window_to_check);
diff --git a/chrome/browser/history/archived_database.cc b/chrome/browser/history/archived_database.cc
index ab114d2..468416e 100644
--- a/chrome/browser/history/archived_database.cc
+++ b/chrome/browser/history/archived_database.cc
@@ -74,6 +74,10 @@
return transaction.Commit();
}
+void ArchivedDatabase::TrimMemory(bool aggressively) {
+ db_.TrimMemory(aggressively);
+}
+
void ArchivedDatabase::BeginTransaction() {
db_.BeginTransaction();
}
diff --git a/chrome/browser/history/archived_database.h b/chrome/browser/history/archived_database.h
index 0fe7184..3bf896a 100644
--- a/chrome/browser/history/archived_database.h
+++ b/chrome/browser/history/archived_database.h
@@ -34,6 +34,10 @@
// functions on this class are called.
bool Init(const base::FilePath& file_name);
+ // Try to trim the cache memory used by the database. If |aggressively| is
+ // true try to trim all unused cache, otherwise trim by half.
+ void TrimMemory(bool aggressively);
+
// Transactions on the database. We support nested transactions and only
// commit when the outermost one is committed (sqlite doesn't support true
// nested transactions).
diff --git a/chrome/browser/history/history_backend.cc b/chrome/browser/history/history_backend.cc
index a5a0cca..adaff5a 100644
--- a/chrome/browser/history/history_backend.cc
+++ b/chrome/browser/history/history_backend.cc
@@ -260,6 +260,8 @@
InitImpl(languages);
delegate_->DBLoaded(id_);
typed_url_syncable_service_.reset(new TypedUrlSyncableService(this));
+ memory_pressure_listener_.reset(new base::MemoryPressureListener(
+ base::Bind(&HistoryBackend::OnMemoryPressure, base::Unretained(this))));
#if defined(OS_ANDROID)
PopulateMostVisitedURLMap();
#endif
@@ -766,6 +768,18 @@
TimeTicks::Now() - beginning_time);
}
+void HistoryBackend::OnMemoryPressure(
+ base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
+ bool trim_aggressively = memory_pressure_level ==
+ base::MemoryPressureListener::MEMORY_PRESSURE_CRITICAL;
+ if (db_)
+ db_->TrimMemory(trim_aggressively);
+ if (thumbnail_db_)
+ thumbnail_db_->TrimMemory(trim_aggressively);
+ if (archived_db_)
+ archived_db_->TrimMemory(trim_aggressively);
+}
+
void HistoryBackend::CloseAllDatabases() {
if (db_) {
// Commit the long-running transaction.
diff --git a/chrome/browser/history/history_backend.h b/chrome/browser/history/history_backend.h
index fbc17a9..c4010b7 100644
--- a/chrome/browser/history/history_backend.h
+++ b/chrome/browser/history/history_backend.h
@@ -13,6 +13,7 @@
#include "base/containers/mru_cache.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
+#include "base/memory/memory_pressure_listener.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/history/archived_database.h"
#include "chrome/browser/history/expire_history_backend.h"
@@ -598,6 +599,10 @@
// Does the work of Init.
void InitImpl(const std::string& languages);
+ // Called when the system is under memory pressure.
+ void OnMemoryPressure(
+ base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
+
// Closes all databases managed by HistoryBackend. Commits any pending
// transactions.
void CloseAllDatabases();
@@ -939,6 +944,9 @@
// before Init is called.
scoped_ptr<TypedUrlSyncableService> typed_url_syncable_service_;
+ // Listens for the system being under memory pressure.
+ scoped_ptr<base::MemoryPressureListener> memory_pressure_listener_;
+
DISALLOW_COPY_AND_ASSIGN(HistoryBackend);
};
diff --git a/chrome/browser/history/history_database.cc b/chrome/browser/history/history_database.cc
index 43ce119..3db7acd 100644
--- a/chrome/browser/history/history_database.cc
+++ b/chrome/browser/history/history_database.cc
@@ -237,6 +237,10 @@
ignore_result(db_.Execute("VACUUM"));
}
+void HistoryDatabase::TrimMemory(bool aggressively) {
+ db_.TrimMemory(aggressively);
+}
+
bool HistoryDatabase::Raze() {
return db_.Raze();
}
diff --git a/chrome/browser/history/history_database.h b/chrome/browser/history/history_database.h
index 01df342..5aac5ba 100644
--- a/chrome/browser/history/history_database.h
+++ b/chrome/browser/history/history_database.h
@@ -131,6 +131,10 @@
// unused space in the file. It can be VERY SLOW.
void Vacuum();
+ // Try to trim the cache memory used by the database. If |aggressively| is
+ // true try to trim all unused cache, otherwise trim by half.
+ void TrimMemory(bool aggressively);
+
// Razes the database. Returns true if successful.
bool Raze();
diff --git a/chrome/browser/history/snippet.cc b/chrome/browser/history/snippet.cc
index 90d80d0..e1069a6 100644
--- a/chrome/browser/history/snippet.cc
+++ b/chrome/browser/history/snippet.cc
@@ -11,9 +11,9 @@
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
-#include "third_party/icu/public/common/unicode/brkiter.h"
-#include "third_party/icu/public/common/unicode/utext.h"
-#include "third_party/icu/public/common/unicode/utf8.h"
+#include "third_party/icu/source/common/unicode/brkiter.h"
+#include "third_party/icu/source/common/unicode/utext.h"
+#include "third_party/icu/source/common/unicode/utf8.h"
namespace {
diff --git a/chrome/browser/history/thumbnail_database.cc b/chrome/browser/history/thumbnail_database.cc
index da34646..51cbac1 100644
--- a/chrome/browser/history/thumbnail_database.cc
+++ b/chrome/browser/history/thumbnail_database.cc
@@ -582,6 +582,10 @@
ignore_result(db_.Execute("VACUUM"));
}
+void ThumbnailDatabase::TrimMemory(bool aggressively) {
+ db_.TrimMemory(aggressively);
+}
+
bool ThumbnailDatabase::SetPageThumbnail(
const GURL& url,
URLID id,
diff --git a/chrome/browser/history/thumbnail_database.h b/chrome/browser/history/thumbnail_database.h
index 00931f1..ae4006d 100644
--- a/chrome/browser/history/thumbnail_database.h
+++ b/chrome/browser/history/thumbnail_database.h
@@ -74,6 +74,10 @@
// unused space in the file. It can be VERY SLOW.
void Vacuum();
+ // Try to trim the cache memory used by the database. If |aggressively| is
+ // true try to trim all unused cache, otherwise trim by half.
+ void TrimMemory(bool aggressively);
+
// Thumbnails ----------------------------------------------------------------
// Sets the given data to be the thumbnail for the given URL,
diff --git a/chrome/browser/history/web_history_service.h b/chrome/browser/history/web_history_service.h
index dceb815..3a234a2 100644
--- a/chrome/browser/history/web_history_service.h
+++ b/chrome/browser/history/web_history_service.h
@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_HISTORY_WEB_HISTORY_SERVICE_H_
#define CHROME_BROWSER_HISTORY_WEB_HISTORY_SERVICE_H_
+#include "base/memory/weak_ptr.h"
#include "chrome/browser/history/history_types.h"
#include "chrome/browser/profiles/profile.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
diff --git a/chrome/browser/icon_loader_chromeos.cc b/chrome/browser/icon_loader_chromeos.cc
index db95067..1329845 100644
--- a/chrome/browser/icon_loader_chromeos.cc
+++ b/chrome/browser/icon_loader_chromeos.cc
@@ -12,7 +12,7 @@
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
#include "base/memory/ref_counted_memory.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/strings/string_util.h"
#include "chrome/browser/icon_loader.h"
#include "grit/theme_resources.h"
diff --git a/chrome/browser/icon_loader_linux.cc b/chrome/browser/icon_loader_linux.cc
index b75da17..4d400a9 100644
--- a/chrome/browser/icon_loader_linux.cc
+++ b/chrome/browser/icon_loader_linux.cc
@@ -9,7 +9,7 @@
#include "base/bind.h"
#include "base/file_util.h"
#include "base/logging.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/nix/mime_util_xdg.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/codec/png_codec.h"
diff --git a/chrome/browser/icon_loader_mac.mm b/chrome/browser/icon_loader_mac.mm
index 4a93736..be2eecf 100644
--- a/chrome/browser/icon_loader_mac.mm
+++ b/chrome/browser/icon_loader_mac.mm
@@ -8,9 +8,9 @@
#include "base/bind.h"
#include "base/files/file_path.h"
-#include "base/message_loop.h"
-#include "base/threading/thread.h"
+#include "base/message_loop/message_loop.h"
#include "base/strings/sys_string_conversions.h"
+#include "base/threading/thread.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_util_mac.h"
diff --git a/chrome/browser/icon_loader_win.cc b/chrome/browser/icon_loader_win.cc
index 62cb6f0..fe826f0 100644
--- a/chrome/browser/icon_loader_win.cc
+++ b/chrome/browser/icon_loader_win.cc
@@ -8,7 +8,7 @@
#include <shellapi.h>
#include "base/bind.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/threading/thread.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/icon_util.h"
diff --git a/chrome/browser/importer/external_process_importer_client.cc b/chrome/browser/importer/external_process_importer_client.cc
index 7861c9c..aa7199e 100644
--- a/chrome/browser/importer/external_process_importer_client.cc
+++ b/chrome/browser/importer/external_process_importer_client.cc
@@ -296,6 +296,9 @@
// in the external process.
DictionaryValue localized_strings;
localized_strings.SetString(
+ base::IntToString(IDS_BOOKMARK_GROUP),
+ l10n_util::GetStringUTF8(IDS_BOOKMARK_GROUP));
+ localized_strings.SetString(
base::IntToString(IDS_BOOKMARK_GROUP_FROM_FIREFOX),
l10n_util::GetStringUTF8(IDS_BOOKMARK_GROUP_FROM_FIREFOX));
localized_strings.SetString(
@@ -305,6 +308,9 @@
base::IntToString(IDS_IMPORT_FROM_FIREFOX),
l10n_util::GetStringUTF8(IDS_IMPORT_FROM_FIREFOX));
localized_strings.SetString(
+ base::IntToString(IDS_IMPORT_FROM_ICEWEASEL),
+ l10n_util::GetStringUTF8(IDS_IMPORT_FROM_ICEWEASEL));
+ localized_strings.SetString(
base::IntToString(IDS_IMPORT_FROM_SAFARI),
l10n_util::GetStringUTF8(IDS_IMPORT_FROM_SAFARI));
localized_strings.SetString(
diff --git a/chrome/browser/importer/external_process_importer_host.cc b/chrome/browser/importer/external_process_importer_host.cc
index 2615d00..4a25adc 100644
--- a/chrome/browser/importer/external_process_importer_host.cc
+++ b/chrome/browser/importer/external_process_importer_host.cc
@@ -171,7 +171,7 @@
bool ExternalProcessImporterHost::CheckForFirefoxLock(
const importer::SourceProfile& source_profile) {
- if (source_profile.importer_type != importer::TYPE_FIREFOX3)
+ if (source_profile.importer_type != importer::TYPE_FIREFOX)
return true;
DCHECK(!firefox_lock_.get());
diff --git a/chrome/browser/importer/firefox_importer_browsertest.cc b/chrome/browser/importer/firefox_importer_browsertest.cc
index 0290ba2..8082e76 100644
--- a/chrome/browser/importer/firefox_importer_browsertest.cc
+++ b/chrome/browser/importer/firefox_importer_browsertest.cc
@@ -5,7 +5,7 @@
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/stl_util.h"
#include "base/strings/string16.h"
@@ -50,7 +50,7 @@
const char* url;
};
-const BookmarkInfo kFirefox3Bookmarks[] = {
+const BookmarkInfo kFirefoxBookmarks[] = {
{true, 1, {L"Bookmarks Toolbar"},
L"Toolbar",
"http://site/"},
@@ -59,14 +59,14 @@
"http://www.google.com/"},
};
-const PasswordInfo kFirefox3Passwords[] = {
+const PasswordInfo kFirefoxPasswords[] = {
{"http://localhost:8080/", "http://localhost:8080/", "http://localhost:8080/",
L"loginuser", L"abc", L"loginpass", L"123", false},
{"http://localhost:8080/", "", "http://localhost:8080/localhost",
L"", L"http", L"", L"Http1+1abcdefg", false},
};
-const KeywordInfo kFirefox3Keywords[] = {
+const KeywordInfo kFirefoxKeywords[] = {
{ L"amazon.com",
"http://www.amazon.com/exec/obidos/external-search/?field-keywords="
"{searchTerms}&mode=blended" },
@@ -94,17 +94,17 @@
{ L"\x4E2D\x6587", "http://www.google.com/" },
};
-const int kDefaultFirefox3KeywordIndex = 8;
+const int kDefaultFirefoxKeywordIndex = 8;
-class Firefox3Observer : public ProfileWriter,
- public importer::ImporterProgressObserver {
+class FirefoxObserver : public ProfileWriter,
+ public importer::ImporterProgressObserver {
public:
- Firefox3Observer()
+ FirefoxObserver()
: ProfileWriter(NULL), bookmark_count_(0), history_count_(0),
password_count_(0), keyword_count_(0), import_search_engines_(true) {
}
- explicit Firefox3Observer(bool import_search_engines)
+ explicit FirefoxObserver(bool import_search_engines)
: ProfileWriter(NULL), bookmark_count_(0), history_count_(0),
password_count_(0), keyword_count_(0),
import_search_engines_(import_search_engines) {
@@ -116,11 +116,11 @@
virtual void ImportItemEnded(importer::ImportItem item) OVERRIDE {}
virtual void ImportEnded() OVERRIDE {
base::MessageLoop::current()->Quit();
- EXPECT_EQ(arraysize(kFirefox3Bookmarks), bookmark_count_);
+ EXPECT_EQ(arraysize(kFirefoxBookmarks), bookmark_count_);
EXPECT_EQ(1U, history_count_);
- EXPECT_EQ(arraysize(kFirefox3Passwords), password_count_);
+ EXPECT_EQ(arraysize(kFirefoxPasswords), password_count_);
if (import_search_engines_)
- EXPECT_EQ(arraysize(kFirefox3Keywords), keyword_count_);
+ EXPECT_EQ(arraysize(kFirefoxKeywords), keyword_count_);
}
virtual bool BookmarkModelIsLoaded() const OVERRIDE {
@@ -133,7 +133,7 @@
}
virtual void AddPasswordForm(const content::PasswordForm& form) OVERRIDE {
- PasswordInfo p = kFirefox3Passwords[password_count_];
+ PasswordInfo p = kFirefoxPasswords[password_count_];
EXPECT_EQ(p.origin, form.origin.spec());
EXPECT_EQ(p.realm, form.signon_realm);
EXPECT_EQ(p.action, form.action.spec());
@@ -161,14 +161,13 @@
virtual void AddBookmarks(const std::vector<ImportedBookmarkEntry>& bookmarks,
const string16& top_level_folder_name) OVERRIDE {
- ASSERT_LE(bookmark_count_ + bookmarks.size(),
- arraysize(kFirefox3Bookmarks));
+ ASSERT_LE(bookmark_count_ + bookmarks.size(), arraysize(kFirefoxBookmarks));
// Importer should import the FF favorites the same as the list, in the same
// order.
for (size_t i = 0; i < bookmarks.size(); ++i) {
EXPECT_NO_FATAL_FAILURE(
TestEqualBookmarkEntry(bookmarks[i],
- kFirefox3Bookmarks[bookmark_count_])) << i;
+ kFirefoxBookmarks[bookmark_count_])) << i;
++bookmark_count_;
}
}
@@ -180,10 +179,10 @@
// that template URL.
bool found = false;
string16 keyword = template_urls[i]->keyword();
- for (size_t j = 0; j < arraysize(kFirefox3Keywords); ++j) {
+ for (size_t j = 0; j < arraysize(kFirefoxKeywords); ++j) {
if (template_urls[i]->keyword() ==
- WideToUTF16Hack(kFirefox3Keywords[j].keyword)) {
- EXPECT_EQ(kFirefox3Keywords[j].url, template_urls[i]->url());
+ WideToUTF16Hack(kFirefoxKeywords[j].keyword)) {
+ EXPECT_EQ(kFirefoxKeywords[j].url, template_urls[i]->url());
found = true;
break;
}
@@ -198,7 +197,7 @@
}
private:
- virtual ~Firefox3Observer() {}
+ virtual ~FirefoxObserver() {}
size_t bookmark_count_;
size_t history_count_;
@@ -256,7 +255,7 @@
}
importer::SourceProfile source_profile;
- source_profile.importer_type = importer::TYPE_FIREFOX3;
+ source_profile.importer_type = importer::TYPE_FIREFOX;
source_profile.app_path = app_path_;
source_profile.source_path = profile_path_;
source_profile.locale = "en-US";
@@ -282,7 +281,7 @@
IN_PROC_BROWSER_TEST_F(FirefoxProfileImporterBrowserTest,
MAYBE_IMPORTER(Firefox30Importer)) {
- scoped_refptr<Firefox3Observer> observer(new Firefox3Observer());
+ scoped_refptr<FirefoxObserver> observer(new FirefoxObserver());
Firefox3xImporterBrowserTest("firefox3_profile", observer.get(),
observer.get(), true);
}
@@ -290,8 +289,8 @@
IN_PROC_BROWSER_TEST_F(FirefoxProfileImporterBrowserTest,
MAYBE_IMPORTER(Firefox35Importer)) {
bool import_search_engines = false;
- scoped_refptr<Firefox3Observer> observer(
- new Firefox3Observer(import_search_engines));
+ scoped_refptr<FirefoxObserver> observer(
+ new FirefoxObserver(import_search_engines));
Firefox3xImporterBrowserTest("firefox35_profile", observer.get(),
observer.get(), import_search_engines);
}
diff --git a/chrome/browser/importer/ie_importer_browsertest_win.cc b/chrome/browser/importer/ie_importer_browsertest_win.cc
index 79d849f..5063966 100644
--- a/chrome/browser/importer/ie_importer_browsertest_win.cc
+++ b/chrome/browser/importer/ie_importer_browsertest_win.cc
@@ -18,7 +18,7 @@
#include "base/compiler_specific.h"
#include "base/file_util.h"
#include "base/files/scoped_temp_dir.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/stl_util.h"
#include "base/strings/string16.h"
diff --git a/chrome/browser/importer/importer_list.cc b/chrome/browser/importer/importer_list.cc
index 0e9ff34..1863d4a 100644
--- a/chrome/browser/importer/importer_list.cc
+++ b/chrome/browser/importer/importer_list.cc
@@ -55,7 +55,7 @@
#endif // defined(OS_MACOSX)
// |locale|: The application locale used for lookups in Firefox's
-// locale-specific search engines feature (see firefox3_importer.cc for
+// locale-specific search engines feature (see firefox_importer.cc for
// details).
void DetectFirefoxProfiles(const std::string locale,
std::vector<importer::SourceProfile*>* profiles) {
@@ -74,7 +74,7 @@
GetFirefoxVersionAndPathFromProfile(profile_path, &version, &app_path);
if (version >= 3) {
- firefox_type = importer::TYPE_FIREFOX3;
+ firefox_type = importer::TYPE_FIREFOX;
} else {
// Ignores old versions of firefox.
return;
diff --git a/chrome/browser/importer/importer_uma.cc b/chrome/browser/importer/importer_uma.cc
index 4e62217..839dd6e 100644
--- a/chrome/browser/importer/importer_uma.cc
+++ b/chrome/browser/importer/importer_uma.cc
@@ -42,7 +42,7 @@
metrics_type = IMPORTER_METRICS_IE;
break;
#endif
- case TYPE_FIREFOX3:
+ case TYPE_FIREFOX:
metrics_type = IMPORTER_METRICS_FIREFOX3;
break;
#if defined(OS_MACOSX)
diff --git a/chrome/browser/importer/profile_writer_unittest.cc b/chrome/browser/importer/profile_writer_unittest.cc
index f61b6c8..2f6334b 100644
--- a/chrome/browser/importer/profile_writer_unittest.cc
+++ b/chrome/browser/importer/profile_writer_unittest.cc
@@ -4,7 +4,7 @@
#include <string>
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
diff --git a/chrome/browser/infobars/infobar.cc b/chrome/browser/infobars/infobar.cc
index 079b571..2dc1391 100644
--- a/chrome/browser/infobars/infobar.cc
+++ b/chrome/browser/infobars/infobar.cc
@@ -13,25 +13,19 @@
#include "ui/base/animation/slide_animation.h"
SkColor GetInfoBarTopColor(InfoBarDelegate::Type infobar_type) {
- // Yellow
static const SkColor kWarningBackgroundColorTop =
- SkColorSetRGB(255, 242, 183);
- // Gray
+ SkColorSetRGB(255, 242, 183); // Yellow
static const SkColor kPageActionBackgroundColorTop =
- SkColorSetRGB(237, 237, 237);
-
+ SkColorSetRGB(237, 237, 237); // Gray
return (infobar_type == InfoBarDelegate::WARNING_TYPE) ?
kWarningBackgroundColorTop : kPageActionBackgroundColorTop;
}
SkColor GetInfoBarBottomColor(InfoBarDelegate::Type infobar_type) {
- // Yellow
static const SkColor kWarningBackgroundColorBottom =
- SkColorSetRGB(250, 230, 145);
- // Gray
+ SkColorSetRGB(250, 230, 145); // Yellow
static const SkColor kPageActionBackgroundColorBottom =
- SkColorSetRGB(217, 217, 217);
-
+ SkColorSetRGB(217, 217, 217); // Gray
return (infobar_type == InfoBarDelegate::WARNING_TYPE) ?
kWarningBackgroundColorBottom : kPageActionBackgroundColorBottom;
}
diff --git a/chrome/browser/infobars/infobar_service.cc b/chrome/browser/infobars/infobar_service.cc
index f52304f..f941f22 100644
--- a/chrome/browser/infobars/infobar_service.cc
+++ b/chrome/browser/infobars/infobar_service.cc
@@ -17,23 +17,23 @@
DEFINE_WEB_CONTENTS_USER_DATA_KEY(InfoBarService);
InfoBarDelegate* InfoBarService::AddInfoBar(
- scoped_ptr<InfoBarDelegate> delegate) {
- DCHECK(delegate);
+ scoped_ptr<InfoBarDelegate> infobar) {
+ DCHECK(infobar);
if (!infobars_enabled_)
return NULL;
for (InfoBars::const_iterator i(infobars_.begin()); i != infobars_.end();
++i) {
- if ((*i)->EqualsDelegate(delegate.get())) {
- DCHECK_NE(*i, delegate.get());
+ if ((*i)->EqualsDelegate(infobar.get())) {
+ DCHECK_NE(*i, infobar.get());
return NULL;
}
}
+ InfoBarDelegate* infobar_ptr = infobar.release();
+ infobars_.push_back(infobar_ptr);
// TODO(pkasting): Remove InfoBarService arg from delegate constructors and
// instead use a setter from here.
- InfoBarDelegate* delegate_ptr = delegate.release();
- infobars_.push_back(delegate_ptr);
// Add ourselves as an observer for navigations the first time a delegate is
// added. We use this notification to expire InfoBars that need to expire on
@@ -52,40 +52,40 @@
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED,
content::Source<InfoBarService>(this),
- content::Details<InfoBarAddedDetails>(delegate_ptr));
- return delegate_ptr;
+ content::Details<InfoBarAddedDetails>(infobar_ptr));
+ return infobar_ptr;
}
-void InfoBarService::RemoveInfoBar(InfoBarDelegate* delegate) {
- RemoveInfoBarInternal(delegate, true);
+void InfoBarService::RemoveInfoBar(InfoBarDelegate* infobar) {
+ RemoveInfoBarInternal(infobar, true);
}
InfoBarDelegate* InfoBarService::ReplaceInfoBar(
- InfoBarDelegate* old_delegate,
- scoped_ptr<InfoBarDelegate> new_delegate) {
- DCHECK(old_delegate);
+ InfoBarDelegate* old_infobar,
+ scoped_ptr<InfoBarDelegate> new_infobar) {
+ DCHECK(old_infobar);
if (!infobars_enabled_)
- return AddInfoBar(new_delegate.Pass()); // Deletes the delegate.
- DCHECK(new_delegate);
+ return AddInfoBar(new_infobar.Pass()); // Deletes the delegate.
+ DCHECK(new_infobar);
InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(),
- old_delegate));
+ old_infobar));
DCHECK(i != infobars_.end());
- InfoBarDelegate* new_delegate_ptr = new_delegate.release();
- i = infobars_.insert(i, new_delegate_ptr);
- InfoBarReplacedDetails replaced_details(old_delegate, new_delegate_ptr);
+ InfoBarDelegate* new_infobar_ptr = new_infobar.release();
+ i = infobars_.insert(i, new_infobar_ptr);
+ InfoBarReplacedDetails replaced_details(old_infobar, new_infobar_ptr);
- // Remove the old delegate before notifying, so that if any observers call
- // back to AddInfoBar() or similar, we don't dupe-check against this delegate.
+ // Remove the old infobar before notifying, so that if any observers call
+ // back to AddInfoBar() or similar, we don't dupe-check against this infobar.
infobars_.erase(++i);
- old_delegate->clear_owner();
+ old_infobar->clear_owner();
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REPLACED,
content::Source<InfoBarService>(this),
content::Details<InfoBarReplacedDetails>(&replaced_details));
- return new_delegate_ptr;
+ return new_infobar_ptr;
}
InfoBarService::InfoBarService(content::WebContents* web_contents)
@@ -137,9 +137,9 @@
// use iterators, as the RemoveInfoBar() call synchronously modifies our
// delegate list.
for (size_t i = infobars_.size(); i > 0; --i) {
- InfoBarDelegate* delegate = infobars_[i - 1];
- if (delegate->ShouldExpire(committed_details))
- RemoveInfoBar(delegate);
+ InfoBarDelegate* infobar = infobars_[i - 1];
+ if (infobar->ShouldExpire(committed_details))
+ RemoveInfoBar(infobar);
}
return;
@@ -157,20 +157,20 @@
return;
}
-void InfoBarService::RemoveInfoBarInternal(InfoBarDelegate* delegate,
+void InfoBarService::RemoveInfoBarInternal(InfoBarDelegate* infobar,
bool animate) {
- DCHECK(delegate);
+ DCHECK(infobar);
if (!infobars_enabled_) {
DCHECK(infobars_.empty());
return;
}
- InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(), delegate));
+ InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(), infobar));
DCHECK(i != infobars_.end());
- delegate->clear_owner();
- // Remove the delegate before notifying, so that if any observers call back to
- // AddInfoBar() or similar, we don't dupe-check against this delegate.
+ infobar->clear_owner();
+ // Remove the infobar before notifying, so that if any observers call back to
+ // AddInfoBar() or similar, we don't dupe-check against this infobar.
infobars_.erase(i);
// Remove ourselves as an observer if we are tracking no more InfoBars. We
@@ -186,7 +186,7 @@
&web_contents()->GetController()));
}
- InfoBarRemovedDetails removed_details(delegate, animate);
+ InfoBarRemovedDetails removed_details(infobar, animate);
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
content::Source<InfoBarService>(this),
diff --git a/chrome/browser/infobars/infobar_service.h b/chrome/browser/infobars/infobar_service.h
index e0f40aa..1bc98ed 100644
--- a/chrome/browser/infobars/infobar_service.h
+++ b/chrome/browser/infobars/infobar_service.h
@@ -13,10 +13,6 @@
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
-namespace content {
-class WebContents;
-}
-
class InfoBarDelegate;
// Provides access to creating, removing and enumerating info bars
@@ -35,14 +31,14 @@
// |delegate| is closed immediately without being added.
//
// Returns the delegate if it was successfully added.
- InfoBarDelegate* AddInfoBar(scoped_ptr<InfoBarDelegate> delegate);
+ InfoBarDelegate* AddInfoBar(scoped_ptr<InfoBarDelegate> infobar);
// Removes the InfoBar for the specified |delegate|.
//
// If infobars are disabled for this tab, this will do nothing, on the
// assumption that the matching AddInfoBar() call will have already closed the
// delegate (see above).
- void RemoveInfoBar(InfoBarDelegate* delegate);
+ void RemoveInfoBar(InfoBarDelegate* infobar);
// Replaces one infobar with another, without any animation in between.
//
@@ -52,14 +48,14 @@
// Returns the new delegate if it was successfully added.
//
// NOTE: This does not perform any EqualsDelegate() checks like AddInfoBar().
- InfoBarDelegate* ReplaceInfoBar(InfoBarDelegate* old_delegate,
- scoped_ptr<InfoBarDelegate> new_delegate);
+ InfoBarDelegate* ReplaceInfoBar(InfoBarDelegate* old_infobar,
+ scoped_ptr<InfoBarDelegate> new_infobar);
// Returns the number of infobars for this tab.
size_t infobar_count() const { return infobars_.size(); }
- // Returns the infobar delegate at the given |index|. The InfoBarService
- // retains ownership.
+ // Returns the infobar at the given |index|. The InfoBarService retains
+ // ownership.
//
// Warning: Does not sanity check |index|.
InfoBarDelegate* infobar_at(size_t index) { return infobars_[index]; }
@@ -74,6 +70,10 @@
typedef std::vector<InfoBarDelegate*> InfoBars;
+ // Delegates for InfoBars associated with this InfoBarService. We do not own
+ // these pointers; they own themselves and are deleted in response to being
+ // closed.
+ // TODO(pkasting): These leak if closed while not visible.
explicit InfoBarService(content::WebContents* web_contents);
virtual ~InfoBarService();
@@ -86,14 +86,13 @@
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
- void RemoveInfoBarInternal(InfoBarDelegate* delegate, bool animate);
+ void RemoveInfoBarInternal(InfoBarDelegate* infobar, bool animate);
void RemoveAllInfoBars(bool animate);
// Message handlers.
void OnDidBlockDisplayingInsecureContent();
void OnDidBlockRunningInsecureContent();
- // Delegates for InfoBars associated with this InfoBarService.
InfoBars infobars_;
bool infobars_enabled_;
diff --git a/chrome/browser/infobars/infobars_browsertest.cc b/chrome/browser/infobars/infobars_browsertest.cc
index f95fa56..8286b79 100644
--- a/chrome/browser/infobars/infobars_browsertest.cc
+++ b/chrome/browser/infobars/infobars_browsertest.cc
@@ -19,6 +19,10 @@
#include "content/public/browser/notification_service.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
class InfoBarsTest : public InProcessBrowserTest {
public:
InfoBarsTest() {}
@@ -51,6 +55,12 @@
};
IN_PROC_BROWSER_TEST_F(InfoBarsTest, TestInfoBarsCloseOnNewTheme) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
ui_test_utils::NavigateToURL(
diff --git a/chrome/browser/infobars/insecure_content_infobar_delegate.h b/chrome/browser/infobars/insecure_content_infobar_delegate.h
index e2a78e7..f2be21a 100644
--- a/chrome/browser/infobars/insecure_content_infobar_delegate.h
+++ b/chrome/browser/infobars/insecure_content_infobar_delegate.h
@@ -18,8 +18,8 @@
// Depending on the |type| requested and whether an insecure content infobar
// is already present in |infobar_service|, may do nothing; otherwise, creates
- // an insecure content delegate and either adds it to |infobar_service| or
- // replaces the existing infobar delegate.
+ // an insecure content infobar delegate and either adds it to
+ // |infobar_service| or replaces the existing infobar.
static void Create(InfoBarService* infobar_service, InfoBarType type);
private:
diff --git a/chrome/browser/infobars/simple_alert_infobar_delegate.h b/chrome/browser/infobars/simple_alert_infobar_delegate.h
index 7d783f6..a5cef30 100644
--- a/chrome/browser/infobars/simple_alert_infobar_delegate.h
+++ b/chrome/browser/infobars/simple_alert_infobar_delegate.h
@@ -12,7 +12,7 @@
class SimpleAlertInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
- // Creates a simple alert delegate and adds it to |infobar_service|.
+ // Creates a simple alert infobar delegate and adds it to |infobar_service|.
static void Create(InfoBarService* infobar_service,
int icon_id, // May be |kNoIconID| if no icon is shown.
const string16& message,
diff --git a/chrome/browser/internal_auth_unittest.cc b/chrome/browser/internal_auth_unittest.cc
index c504bd9..415bef2 100644
--- a/chrome/browser/internal_auth_unittest.cc
+++ b/chrome/browser/internal_auth_unittest.cc
@@ -7,7 +7,7 @@
#include <algorithm>
#include "base/lazy_instance.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/invalidation/fake_invalidation_service.cc b/chrome/browser/invalidation/fake_invalidation_service.cc
index a54a581..a19f4fb 100644
--- a/chrome/browser/invalidation/fake_invalidation_service.cc
+++ b/chrome/browser/invalidation/fake_invalidation_service.cc
@@ -47,10 +47,12 @@
void FakeInvalidationService::EmitInvalidationForTest(
const invalidation::ObjectId& object_id,
+ int64 version,
const std::string& payload) {
syncer::ObjectIdInvalidationMap invalidation_map;
syncer::Invalidation inv;
+ inv.version = version;
inv.payload = payload;
inv.ack_handle = syncer::AckHandle::CreateUnique();
diff --git a/chrome/browser/invalidation/fake_invalidation_service.h b/chrome/browser/invalidation/fake_invalidation_service.h
index 50aa619..4b296ae 100644
--- a/chrome/browser/invalidation/fake_invalidation_service.h
+++ b/chrome/browser/invalidation/fake_invalidation_service.h
@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_INVALIDATION_FAKE_INVALIDATION_SERVICE_H_
#define CHROME_BROWSER_INVALIDATION_FAKE_INVALIDATION_SERVICE_H_
+#include "base/basictypes.h"
#include "chrome/browser/invalidation/invalidation_service.h"
#include "sync/notifier/invalidator_registrar.h"
@@ -34,6 +35,7 @@
void EmitInvalidationForTest(
const invalidation::ObjectId& object_id,
+ int64 version,
const std::string& payload);
private:
diff --git a/chrome/browser/invalidation/invalidation_service_android.cc b/chrome/browser/invalidation/invalidation_service_android.cc
index 06cf3e7..b12f123 100644
--- a/chrome/browser/invalidation/invalidation_service_android.cc
+++ b/chrome/browser/invalidation/invalidation_service_android.cc
@@ -72,7 +72,9 @@
const syncer::ObjectIdInvalidationMap& effective_invalidation_map =
object_invalidation_map.empty() ?
ObjectIdSetToInvalidationMap(
- invalidator_registrar_.GetAllRegisteredIds(), std::string()) :
+ invalidator_registrar_.GetAllRegisteredIds(),
+ syncer::Invalidation::kUnknownVersion,
+ std::string()) :
object_invalidation_map;
invalidator_registrar_.DispatchInvalidationsToHandlers(
diff --git a/chrome/browser/invalidation/invalidator_storage_unittest.cc b/chrome/browser/invalidation/invalidator_storage_unittest.cc
index 1bc015a..985ec94 100644
--- a/chrome/browser/invalidation/invalidator_storage_unittest.cc
+++ b/chrome/browser/invalidation/invalidator_storage_unittest.cc
@@ -5,7 +5,7 @@
#include "chrome/browser/invalidation/invalidator_storage.h"
#include "base/bind.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/prefs/pref_service.h"
#include "base/strings/string_number_conversions.h"
diff --git a/chrome/browser/invalidation/ticl_invalidation_service.cc b/chrome/browser/invalidation/ticl_invalidation_service.cc
index f1bd4e7..ee2da37 100644
--- a/chrome/browser/invalidation/ticl_invalidation_service.cc
+++ b/chrome/browser/invalidation/ticl_invalidation_service.cc
@@ -356,6 +356,7 @@
}
void TiclInvalidationService::Logout() {
+ access_token_request_.reset();
request_access_token_retry_timer_.Stop();
if (IsStarted()) {
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 63d5cc9..3688996 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -85,10 +85,6 @@
#include "net/proxy/proxy_resolver_v8.h"
#endif
-#if defined(OS_CHROMEOS)
-#include "chrome/browser/chromeos/proxy_config_service_impl.h"
-#endif // defined(OS_CHROMEOS)
-
using content::BrowserThread;
class SafeBrowsingURLRequestContext;
@@ -514,7 +510,7 @@
}
globals_->http_auth_handler_factory.reset(CreateDefaultAuthHandlerFactory(
globals_->host_resolver.get()));
- globals_->http_server_properties.reset(new net::HttpServerPropertiesImpl);
+ globals_->http_server_properties.reset(new net::HttpServerPropertiesImpl());
// For the ProxyScriptFetcher, we use a direct ProxyService.
globals_->proxy_script_fetcher_proxy_service.reset(
net::ProxyService::CreateDirectWithNetLog(net_log_));
@@ -862,7 +858,8 @@
params->transport_security_state = globals_->transport_security_state.get();
params->ssl_config_service = globals_->ssl_config_service.get();
params->http_auth_handler_factory = globals_->http_auth_handler_factory.get();
- params->http_server_properties = globals_->http_server_properties.get();
+ params->http_server_properties =
+ globals_->http_server_properties->GetWeakPtr();
params->network_delegate = globals_->system_network_delegate.get();
params->host_mapping_rules = globals_->host_mapping_rules.get();
params->ignore_certificate_errors = globals_->ignore_certificate_errors;
@@ -914,10 +911,9 @@
// If we're in unit_tests, IOThread may not be run.
if (!BrowserThread::IsMessageLoopValid(BrowserThread::IO))
return;
- ChromeProxyConfigService* proxy_config_service =
- ProxyServiceFactory::CreateProxyConfigService();
- system_proxy_config_service_.reset(proxy_config_service);
- pref_proxy_config_tracker_->SetChromeProxyConfigService(proxy_config_service);
+ system_proxy_config_service_.reset(
+ ProxyServiceFactory::CreateProxyConfigService(
+ pref_proxy_config_tracker_.get()));
system_url_request_context_getter_ =
new SystemURLRequestContextGetter(this);
// Safe to post an unretained this pointer, since IOThread is
@@ -972,8 +968,7 @@
if (command_line.HasSwitch(switches::kDisableQuic))
return false;
- if (command_line.HasSwitch(switches::kEnableQuic) ||
- command_line.HasSwitch(switches::kEnableQuicHttps)) {
+ if (command_line.HasSwitch(switches::kEnableQuic)) {
return true;
}
diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h
index eed9d17..4b1b9ef 100644
--- a/chrome/browser/io_thread.h
+++ b/chrome/browser/io_thread.h
@@ -22,7 +22,7 @@
class ChromeNetLog;
class CommandLine;
-class PrefProxyConfigTrackerImpl;
+class PrefProxyConfigTracker;
class PrefService;
class PrefRegistrySimple;
class SystemURLRequestContextGetter;
@@ -300,7 +300,7 @@
// which gets posted by calling certain member functions of IOThread.
scoped_ptr<net::ProxyConfigService> system_proxy_config_service_;
- scoped_ptr<PrefProxyConfigTrackerImpl> pref_proxy_config_tracker_;
+ scoped_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_;
scoped_refptr<net::URLRequestContextGetter>
system_url_request_context_getter_;
diff --git a/chrome/browser/jankometer.cc b/chrome/browser/jankometer.cc
index 5fa82c3..4cfbc41 100644
--- a/chrome/browser/jankometer.cc
+++ b/chrome/browser/jankometer.cc
@@ -10,7 +10,7 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/metrics/stats_counters.h"
#include "base/pending_task.h"
diff --git a/chrome/browser/lifetime/application_lifetime.cc b/chrome/browser/lifetime/application_lifetime.cc
index c594d8e..0b67716 100644
--- a/chrome/browser/lifetime/application_lifetime.cc
+++ b/chrome/browser/lifetime/application_lifetime.cc
@@ -8,7 +8,7 @@
#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/prefs/pref_service.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
diff --git a/chrome/browser/local_discovery/privet_constants.cc b/chrome/browser/local_discovery/privet_constants.cc
index d9c3d9f..3998576 100644
--- a/chrome/browser/local_discovery/privet_constants.cc
+++ b/chrome/browser/local_discovery/privet_constants.cc
@@ -21,6 +21,8 @@
const char kPrivetActionGetClaimToken[] = "getClaimToken";
const char kPrivetActionComplete[] = "complete";
+const char kPrivetActionNameInfo[] = "info";
+
extern const char kPrivetDefaultDeviceType[] = "_privet._tcp.local";
extern const char kPrivetSubtypeTemplate[] = "%s._sub._privet._tcp.local";
diff --git a/chrome/browser/local_discovery/privet_constants.h b/chrome/browser/local_discovery/privet_constants.h
index 4c8465d..e1b5971 100644
--- a/chrome/browser/local_discovery/privet_constants.h
+++ b/chrome/browser/local_discovery/privet_constants.h
@@ -22,6 +22,9 @@
extern const char kPrivetActionGetClaimToken[];
extern const char kPrivetActionComplete[];
+// Name for pseudo-action "info", used only to show info stage in errors.
+extern const char kPrivetActionNameInfo[];
+
extern const char kPrivetDefaultDeviceType[];
extern const char kPrivetSubtypeTemplate[];
diff --git a/chrome/browser/local_discovery/privet_http_impl.cc b/chrome/browser/local_discovery/privet_http_impl.cc
index 6c781f1..38eacd7 100644
--- a/chrome/browser/local_discovery/privet_http_impl.cc
+++ b/chrome/browser/local_discovery/privet_http_impl.cc
@@ -5,7 +5,7 @@
#include "chrome/browser/local_discovery/privet_http_impl.h"
#include "base/bind.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/local_discovery/privet_constants.h"
@@ -215,16 +215,26 @@
void PrivetRegisterOperationImpl::OnPrivetInfoDone(
int http_code,
const base::DictionaryValue* value) {
+ // TODO(noamsml): Distinguish between network errors and unparsable JSON in
+ // this case.
+ if (!value) {
+ delegate_->OnPrivetRegisterError(kPrivetActionNameInfo,
+ FAILURE_NETWORK,
+ -1,
+ NULL);
+ return;
+ }
+
// If there is a key in the info response, the InfoOperation
// has stored it in the client.
- if (!value || !value->HasKey(kPrivetInfoKeyToken)) {
+ if (!value->HasKey(kPrivetInfoKeyToken)) {
if (value->HasKey(kPrivetKeyError)) {
- delegate_->OnPrivetRegisterError(current_action_,
+ delegate_->OnPrivetRegisterError(kPrivetActionNameInfo,
FAILURE_JSON_ERROR,
http_code,
value);
} else {
- delegate_->OnPrivetRegisterError(current_action_,
+ delegate_->OnPrivetRegisterError(kPrivetActionNameInfo,
FAILURE_MALFORMED_RESPONSE,
-1,
NULL);
diff --git a/chrome/browser/local_discovery/privet_http_unittest.cc b/chrome/browser/local_discovery/privet_http_unittest.cc
index 97d28e5..05cf2c5 100644
--- a/chrome/browser/local_discovery/privet_http_unittest.cc
+++ b/chrome/browser/local_discovery/privet_http_unittest.cc
@@ -3,7 +3,7 @@
// found in the LICENSE file.
#include "base/bind.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "chrome/browser/local_discovery/privet_http_impl.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_errors.h"
@@ -73,6 +73,8 @@
const char kSampleRegisterErrorPermanent[] =
"{ \"error\": \"user_cancel\" }";
+const char kSampleInfoResponseBadJson[] = "{";
+
class MockTestURLFetcherFactoryDelegate
: public net::TestURLFetcher::DelegateForTests {
public:
@@ -400,7 +402,7 @@
}
TEST_F(PrivetRegisterTest, PermanentFailure) {
- register_operation_->Start();
+ register_operation_->Start();
EXPECT_TRUE(SuccessfulResponseToURL(
GURL("http://10.0.0.8:6006/privet/info"),
@@ -423,6 +425,21 @@
kSampleRegisterErrorPermanent));
}
+TEST_F(PrivetRegisterTest, InfoFailure) {
+ register_operation_->Start();
+
+ EXPECT_CALL(register_delegate_,
+ OnPrivetRegisterErrorInternal(
+ "info",
+ PrivetRegisterOperation::FAILURE_NETWORK,
+ -1));
+
+
+ EXPECT_TRUE(SuccessfulResponseToURL(
+ GURL("http://10.0.0.8:6006/privet/info"),
+ kSampleInfoResponseBadJson));
+}
+
} // namespace
} // namespace local_discovery
diff --git a/chrome/browser/local_discovery/privet_url_fetcher.cc b/chrome/browser/local_discovery/privet_url_fetcher.cc
index d0a74b5..52da787 100644
--- a/chrome/browser/local_discovery/privet_url_fetcher.cc
+++ b/chrome/browser/local_discovery/privet_url_fetcher.cc
@@ -27,6 +27,10 @@
url_fetcher_->SetRequestContext(request_context);
url_fetcher_->AddExtraRequestHeader(std::string(kXPrivetTokenHeaderPrefix) +
token);
+
+ // URLFetcher requires us to set upload data for POST requests.
+ if (request_type == net::URLFetcher::POST)
+ url_fetcher_->SetUploadData(std::string(), std::string());
}
PrivetURLFetcher::~PrivetURLFetcher() {
diff --git a/chrome/browser/local_discovery/service_discovery_host_client.cc b/chrome/browser/local_discovery/service_discovery_host_client.cc
new file mode 100644
index 0000000..42b5a22
--- /dev/null
+++ b/chrome/browser/local_discovery/service_discovery_host_client.cc
@@ -0,0 +1,241 @@
+// Copyright 2013 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/local_discovery/service_discovery_host_client.h"
+
+#include "chrome/common/local_discovery/local_discovery_messages.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/utility_process_host.h"
+
+namespace local_discovery {
+
+using content::BrowserThread;
+using content::UtilityProcessHost;
+
+class ServiceDiscoveryHostClient::ServiceWatcherProxy : public ServiceWatcher {
+ public:
+ ServiceWatcherProxy(ServiceDiscoveryHostClient* host,
+ const std::string& service_type,
+ const ServiceWatcher::UpdatedCallback& callback)
+ : host_(host),
+ service_type_(service_type),
+ id_(host_->RegisterWatcherCallback(callback)),
+ started_(false) {
+ }
+
+ virtual ~ServiceWatcherProxy() {
+ host_->UnregisterWatcherCallback(id_);
+ if (started_)
+ host_->Send(new LocalDiscoveryMsg_DestroyWatcher(id_));
+ }
+
+ virtual void Start() OVERRIDE {
+ DCHECK(!started_);
+ host_->Send(new LocalDiscoveryMsg_StartWatcher(id_, service_type_));
+ started_ = true;
+ }
+
+ virtual void DiscoverNewServices(bool force_update) OVERRIDE {
+ DCHECK(started_);
+ host_->Send(new LocalDiscoveryMsg_DiscoverServices(id_, force_update));
+ }
+
+ virtual std::string GetServiceType() const OVERRIDE {
+ return service_type_;
+ }
+
+ private:
+ scoped_refptr<ServiceDiscoveryHostClient> host_;
+ const std::string service_type_;
+ const uint64 id_;
+ bool started_;
+};
+
+class ServiceDiscoveryHostClient::ServiceResolverProxy
+ : public ServiceResolver {
+ public:
+ ServiceResolverProxy(ServiceDiscoveryHostClient* host,
+ const std::string& service_name,
+ const ServiceResolver::ResolveCompleteCallback& callback)
+ : host_(host),
+ service_name_(service_name),
+ id_(host->RegisterResolverCallback(callback)),
+ started_(false) {
+ }
+
+ virtual ~ServiceResolverProxy() {
+ host_->UnregisterResolverCallback(id_);
+ if (started_)
+ host_->Send(new LocalDiscoveryMsg_DestroyResolver(id_));
+ }
+
+ virtual void StartResolving() OVERRIDE {
+ DCHECK(!started_);
+ host_->Send(new LocalDiscoveryMsg_ResolveService(id_, service_name_));
+ started_ = true;
+ }
+
+ virtual std::string GetName() const OVERRIDE {
+ return service_name_;
+ }
+
+ private:
+ scoped_refptr<ServiceDiscoveryHostClient> host_;
+ const std::string service_name_;
+ const uint64 id_;
+ bool started_;
+};
+
+ServiceDiscoveryHostClient::ServiceDiscoveryHostClient() : current_id_(0) {
+ callback_runner_ = base::MessageLoop::current()->message_loop_proxy();
+}
+
+ServiceDiscoveryHostClient::~ServiceDiscoveryHostClient() {
+ DCHECK(CalledOnValidThread());
+ DCHECK(service_watcher_callbacks_.empty());
+ DCHECK(service_resolver_callbacks_.empty());
+}
+
+scoped_ptr<ServiceWatcher> ServiceDiscoveryHostClient::CreateServiceWatcher(
+ const std::string& service_type,
+ const ServiceWatcher::UpdatedCallback& callback) {
+ DCHECK(CalledOnValidThread());
+ return scoped_ptr<ServiceWatcher>(
+ new ServiceWatcherProxy(this, service_type, callback));
+}
+
+scoped_ptr<ServiceResolver> ServiceDiscoveryHostClient::CreateServiceResolver(
+ const std::string& service_name,
+ const ServiceResolver::ResolveCompleteCallback& callback) {
+ DCHECK(CalledOnValidThread());
+ return scoped_ptr<ServiceResolver>(
+ new ServiceResolverProxy(this, service_name, callback));
+}
+
+uint64 ServiceDiscoveryHostClient::RegisterWatcherCallback(
+ const ServiceWatcher::UpdatedCallback& callback) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(!ContainsKey(service_watcher_callbacks_, current_id_ + 1));
+ service_watcher_callbacks_[++current_id_] = callback;
+ return current_id_;
+}
+
+uint64 ServiceDiscoveryHostClient::RegisterResolverCallback(
+ const ServiceResolver::ResolveCompleteCallback& callback) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(!ContainsKey(service_resolver_callbacks_, current_id_ + 1));
+ service_resolver_callbacks_[++current_id_] = callback;
+ return current_id_;
+}
+
+void ServiceDiscoveryHostClient::UnregisterWatcherCallback(uint64 id) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(ContainsKey(service_watcher_callbacks_, id));
+ service_watcher_callbacks_.erase(id);
+}
+
+void ServiceDiscoveryHostClient::UnregisterResolverCallback(uint64 id) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(ContainsKey(service_resolver_callbacks_, id));
+ service_resolver_callbacks_.erase(id);
+}
+
+void ServiceDiscoveryHostClient::Start() {
+ DCHECK(CalledOnValidThread());
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&ServiceDiscoveryHostClient::StartOnIOThread, this));
+}
+
+void ServiceDiscoveryHostClient::Shutdown() {
+ DCHECK(CalledOnValidThread());
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&ServiceDiscoveryHostClient::ShutdownOnIOThread, this));
+}
+
+void ServiceDiscoveryHostClient::StartOnIOThread() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ utility_host_ = UtilityProcessHost::Create(
+ this, base::MessageLoopProxy::current().get())->AsWeakPtr();
+ if (utility_host_) {
+ utility_host_->EnableZygote();
+ utility_host_->EnableMDns();
+ utility_host_->StartBatchMode();
+ }
+}
+
+void ServiceDiscoveryHostClient::ShutdownOnIOThread() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ if (utility_host_)
+ utility_host_->EndBatchMode();
+}
+
+void ServiceDiscoveryHostClient::Send(IPC::Message* msg) {
+ DCHECK(CalledOnValidThread());
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(base::IgnoreResult(&content::UtilityProcessHost::Send),
+ utility_host_, msg));
+}
+
+bool ServiceDiscoveryHostClient::OnMessageReceived(
+ const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(ServiceDiscoveryHostClient, message)
+ IPC_MESSAGE_HANDLER(LocalDiscoveryHostMsg_WatcherCallback,
+ OnWatcherCallback)
+ IPC_MESSAGE_HANDLER(LocalDiscoveryHostMsg_ResolverCallback,
+ OnResolverCallback)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void ServiceDiscoveryHostClient::OnWatcherCallback(
+ uint64 id,
+ ServiceWatcher::UpdateType update,
+ const std::string& service_name) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ callback_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&ServiceDiscoveryHostClient::RunWatcherCallback, this, id,
+ update, service_name));
+}
+
+void ServiceDiscoveryHostClient::OnResolverCallback(
+ uint64 id,
+ ServiceResolver::RequestStatus status,
+ const ServiceDescription& description) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ callback_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&ServiceDiscoveryHostClient::RunResolverCallback, this, id,
+ status, description));
+}
+
+void ServiceDiscoveryHostClient::RunWatcherCallback(
+ uint64 id,
+ ServiceWatcher::UpdateType update,
+ const std::string& service_name) {
+ DCHECK(CalledOnValidThread());
+ WatcherCallbacks::iterator it = service_watcher_callbacks_.find(id);
+ if (it != service_watcher_callbacks_.end() && !it->second.is_null())
+ it->second.Run(update, service_name);
+}
+
+void ServiceDiscoveryHostClient::RunResolverCallback(
+ uint64 id,
+ ServiceResolver::RequestStatus status,
+ const ServiceDescription& description) {
+ DCHECK(CalledOnValidThread());
+ ResolverCallbacks::iterator it = service_resolver_callbacks_.find(id);
+ if (it != service_resolver_callbacks_.end() && !it->second.is_null())
+ it->second.Run(status, description);
+}
+
+} // namespace local_discovery
diff --git a/chrome/browser/local_discovery/service_discovery_host_client.h b/chrome/browser/local_discovery/service_discovery_host_client.h
new file mode 100644
index 0000000..4bdf08b
--- /dev/null
+++ b/chrome/browser/local_discovery/service_discovery_host_client.h
@@ -0,0 +1,102 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_LOCAL_DISCOVERY_SERVICE_DISCOVERY_HOST_CLIENT_H_
+#define CHROME_BROWSER_LOCAL_DISCOVERY_SERVICE_DISCOVERY_HOST_CLIENT_H_
+
+#include <map>
+
+#include "base/threading/non_thread_safe.h"
+#include "chrome/common/local_discovery/service_discovery_client.h"
+#include "content/public/browser/utility_process_host_client.h"
+
+namespace base {
+class TaskRunner;
+}
+
+namespace content {
+class UtilityProcessHost;
+}
+
+namespace local_discovery {
+
+// Implementation of ServiceDiscoveryClient that delegates all functionality to
+// utility process.
+class ServiceDiscoveryHostClient : public base::NonThreadSafe,
+ public ServiceDiscoveryClient,
+ public content::UtilityProcessHostClient {
+ public:
+ ServiceDiscoveryHostClient();
+
+ // Starts utility process with ServiceDiscoveryClient.
+ void Start();
+
+ // Shutdowns utility process.
+ void Shutdown();
+
+ // ServiceDiscoveryClient implementation.
+ virtual scoped_ptr<ServiceWatcher> CreateServiceWatcher(
+ const std::string& service_type,
+ const ServiceWatcher::UpdatedCallback& callback) OVERRIDE;
+ virtual scoped_ptr<ServiceResolver> CreateServiceResolver(
+ const std::string& service_name,
+ const ServiceResolver::ResolveCompleteCallback& callback) OVERRIDE;
+
+ // UtilityProcessHostClient implementation.
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+
+ protected:
+ virtual ~ServiceDiscoveryHostClient();
+
+ private:
+ class ServiceWatcherProxy;
+ class ServiceResolverProxy;
+
+ typedef std::map<uint64, ServiceWatcher::UpdatedCallback> WatcherCallbacks;
+ typedef std::map<uint64, ServiceResolver::ResolveCompleteCallback>
+ ResolverCallbacks;
+
+ void StartOnIOThread();
+ void ShutdownOnIOThread();
+
+ void Send(IPC::Message* msg);
+
+ uint64 RegisterWatcherCallback(
+ const ServiceWatcher::UpdatedCallback& callback);
+ uint64 RegisterResolverCallback(
+ const ServiceResolver::ResolveCompleteCallback& callback);
+ void UnregisterWatcherCallback(uint64 id);
+ void UnregisterResolverCallback(uint64 id);
+
+ // IPC Message handlers.
+ void OnWatcherCallback(uint64 id,
+ ServiceWatcher::UpdateType update,
+ const std::string& service_name);
+ void OnResolverCallback(uint64 id,
+ ServiceResolver::RequestStatus status,
+ const ServiceDescription& description);
+
+ // Runs watcher callback on owning thread.
+ void RunWatcherCallback(uint64 id,
+ ServiceWatcher::UpdateType update,
+ const std::string& service_name);
+ // Runs resolver callback on owning thread.
+ void RunResolverCallback(uint64 id,
+ ServiceResolver::RequestStatus status,
+ const ServiceDescription& description);
+
+ base::WeakPtr<content::UtilityProcessHost> utility_host_;
+
+ // Incrementing counter to assign ID to watchers and resolvers.
+ uint64 current_id_;
+ WatcherCallbacks service_watcher_callbacks_;
+ ResolverCallbacks service_resolver_callbacks_;
+ scoped_refptr<base::TaskRunner> callback_runner_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceDiscoveryHostClient);
+};
+
+} // namespace local_discovery
+
+#endif // CHROME_BROWSER_LOCAL_DISCOVERY_SERVICE_DISCOVERY_HOST_CLIENT_H_
diff --git a/chrome/browser/managed_mode/managed_mode_url_filter_unittest.cc b/chrome/browser/managed_mode/managed_mode_url_filter_unittest.cc
index 4eaa308..419f6b1 100644
--- a/chrome/browser/managed_mode/managed_mode_url_filter_unittest.cc
+++ b/chrome/browser/managed_mode/managed_mode_url_filter_unittest.cc
@@ -4,7 +4,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "chrome/browser/managed_mode/managed_mode_url_filter.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/managed_mode/managed_user_refresh_token_fetcher_unittest.cc b/chrome/browser/managed_mode/managed_user_refresh_token_fetcher_unittest.cc
index 424ed86..7b7bebf 100644
--- a/chrome/browser/managed_mode/managed_user_refresh_token_fetcher_unittest.cc
+++ b/chrome/browser/managed_mode/managed_user_refresh_token_fetcher_unittest.cc
@@ -4,7 +4,7 @@
#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/managed_mode/managed_user_refresh_token_fetcher.h"
@@ -81,6 +81,9 @@
const OAuth2TokenService::ScopeSet& scopes,
OAuth2TokenService::Consumer* consumer) OVERRIDE;
virtual std::string GetRefreshToken() OVERRIDE;
+ virtual net::URLRequestContextGetter* GetRequestContext() OVERRIDE {
+ return NULL;
+ }
Request* request_;
@@ -110,9 +113,7 @@
consumer_->OnGetTokenFailure(this, GoogleServiceAuthError(error));
}
-MockOAuth2TokenService::MockOAuth2TokenService()
- : OAuth2TokenService(NULL),
- request_(NULL) {}
+MockOAuth2TokenService::MockOAuth2TokenService() : request_(NULL) {}
MockOAuth2TokenService::~MockOAuth2TokenService() {
EXPECT_FALSE(request_);
diff --git a/chrome/browser/managed_mode/managed_user_registration_service_unittest.cc b/chrome/browser/managed_mode/managed_user_registration_service_unittest.cc
index ef188c5..60e4a35 100644
--- a/chrome/browser/managed_mode/managed_user_registration_service_unittest.cc
+++ b/chrome/browser/managed_mode/managed_user_registration_service_unittest.cc
@@ -5,7 +5,7 @@
#include <string>
#include "base/bind.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/sequenced_worker_pool.h"
diff --git a/chrome/browser/media/audio_stream_indicator.cc b/chrome/browser/media/audio_stream_indicator.cc
index 6cd6232..1d3aa72 100644
--- a/chrome/browser/media/audio_stream_indicator.cc
+++ b/chrome/browser/media/audio_stream_indicator.cc
@@ -4,6 +4,8 @@
#include "chrome/browser/media/audio_stream_indicator.h"
+#include <limits>
+
#include "base/bind.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "content/public/browser/browser_thread.h"
@@ -20,58 +22,106 @@
void AudioStreamIndicator::UpdateWebContentsStatus(
int render_process_id, int render_view_id, int stream_id,
- bool is_playing_and_audible) {
+ bool is_playing, float power_dbfs, bool clipped) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&AudioStreamIndicator::UpdateWebContentsStatusOnUIThread, this,
render_process_id, render_view_id, stream_id,
- is_playing_and_audible));
+ is_playing, power_dbfs, clipped));
}
-bool AudioStreamIndicator::IsPlayingAudio(WebContents* contents) {
+bool AudioStreamIndicator::IsPlayingAudio(const WebContents* contents) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- RenderViewId id(contents->GetRenderProcessHost()->GetID(),
- contents->GetRenderViewHost()->GetRoutingID());
- return audio_streams_.find(id) != audio_streams_.end();
+ // TODO(miu): In order to prevent breaking existing uses of this method, the
+ // old semantics of "playing AND not silent" have been retained here. Once
+ // the tab audio indicator UI switches over to using the new
+ // GetAudioSignalPower(), this method should really be just "playing."
+ float level;
+ bool ignored;
+ CurrentAudibleLevel(contents, &level, &ignored);
+ return level > 0.0f;
}
-AudioStreamIndicator::RenderViewId::RenderViewId(int render_process_id,
- int render_view_id)
- : render_process_id(render_process_id),
- render_view_id(render_view_id) {
-}
+void AudioStreamIndicator::CurrentAudibleLevel(
+ const content::WebContents* contents, float* level, bool* clipped) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-bool AudioStreamIndicator::RenderViewId::operator<(
- const RenderViewId& other) const {
- if (render_process_id != other.render_process_id)
- return render_process_id < other.render_process_id;
+ float max_power_dbfs = -std::numeric_limits<float>::infinity();
+ bool has_clipped = false;
- return render_view_id < other.render_view_id;
+ // Since a RenderView can have more than one stream playing back, return the
+ // maximum of the last-reported power levels. For more information about how
+ // the power level is measured, see media/audio/audio_power_monitor.h.
+ const RenderViewId id(contents->GetRenderProcessHost()->GetID(),
+ contents->GetRenderViewHost()->GetRoutingID());
+ RenderViewStreamMap::const_iterator view_it = audio_streams_.find(id);
+ if (view_it != audio_streams_.end()) {
+ const StreamPowerLevels& stream_levels = view_it->second;
+ for (StreamPowerLevels::const_iterator stream_it = stream_levels.begin();
+ stream_it != stream_levels.end(); ++stream_it) {
+ if (stream_it->power_dbfs > max_power_dbfs)
+ max_power_dbfs = stream_it->power_dbfs;
+ has_clipped |= stream_it->clipped;
+ }
+ }
+
+ // Map the power into an "audible level" in the range [0.0,1.0]. dBFS values
+ // are in the range -inf (minimum power) to 0.0 (maximum power).
+ static const float kSilenceThresholdDBFS = -72.24719896f;
+ if (max_power_dbfs < kSilenceThresholdDBFS)
+ *level = 0.0f;
+ else if (max_power_dbfs > 0.0f)
+ *level = 1.0f;
+ else
+ *level = 1.0f - max_power_dbfs / kSilenceThresholdDBFS;
+ *clipped = has_clipped;
}
void AudioStreamIndicator::UpdateWebContentsStatusOnUIThread(
- int render_process_id,
- int render_view_id,
- int stream_id,
- bool is_playing_and_audible) {
+ int render_process_id, int render_view_id, int stream_id,
+ bool is_playing, float power_dbfs, bool clipped) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- RenderViewId id(render_process_id, render_view_id);
- if (is_playing_and_audible) {
- audio_streams_[id].insert(stream_id);
- } else {
- std::map<RenderViewId, std::set<int> >::iterator it =
- audio_streams_.find(id);
- if (it == audio_streams_.end())
- return;
- it->second.erase(stream_id);
- if (it->second.empty())
- audio_streams_.erase(it);
+ const RenderViewId id(render_process_id, render_view_id);
+ if (is_playing) {
+ // Find the StreamPowerLevel instance associated with |stream_id|, or
+ // auto-create a new one.
+ StreamPowerLevels& stream_levels = audio_streams_[id];
+ StreamPowerLevels::iterator stream_it;
+ for (stream_it = stream_levels.begin(); stream_it != stream_levels.end();
+ ++stream_it) {
+ if (stream_it->stream_id == stream_id)
+ break;
+ }
+ if (stream_it == stream_levels.end()) {
+ stream_it = stream_levels.insert(stream_levels.end(), StreamPowerLevel());
+ stream_it->stream_id = stream_id;
+ }
+
+ // Update power and clip values.
+ stream_it->power_dbfs = power_dbfs;
+ stream_it->clipped = clipped;
+ } else {
+ // Find and erase the StreamPowerLevel instance associated with |stream_id|.
+ RenderViewStreamMap::iterator view_it = audio_streams_.find(id);
+ if (view_it != audio_streams_.end()) {
+ StreamPowerLevels& stream_levels = view_it->second;
+ for (StreamPowerLevels::iterator stream_it = stream_levels.begin();
+ stream_it != stream_levels.end(); ++stream_it) {
+ if (stream_it->stream_id == stream_id) {
+ stream_levels.erase(stream_it);
+ if (stream_levels.empty())
+ audio_streams_.erase(view_it);
+ break;
+ }
+ }
+ }
}
+ // Trigger UI update.
WebContents* web_contents = tab_util::GetWebContentsByID(render_process_id,
render_view_id);
if (web_contents)
diff --git a/chrome/browser/media/audio_stream_indicator.h b/chrome/browser/media/audio_stream_indicator.h
index 2ce504e..613dc3c 100644
--- a/chrome/browser/media/audio_stream_indicator.h
+++ b/chrome/browser/media/audio_stream_indicator.h
@@ -6,7 +6,7 @@
#define CHROME_BROWSER_MEDIA_AUDIO_STREAM_INDICATOR_H_
#include <map>
-#include <set>
+#include <vector>
#include "base/memory/ref_counted.h"
@@ -23,22 +23,34 @@
void UpdateWebContentsStatus(int render_process_id,
int render_view_id,
int stream_id,
- bool is_playing_and_audible);
+ bool is_playing,
+ float power_dbfs,
+ bool clipped);
// This method should be called on the UI thread.
- bool IsPlayingAudio(content::WebContents* contents);
+ bool IsPlayingAudio(const content::WebContents* contents);
+
+ // Returns the audible |level| in the range [0.0,1.0], where 0.0 means the
+ // audio signal is imperceivably silent and 1.0 means it is at maximum
+ // volume. |signal_has_clipped| is set to true if any part of the audio
+ // signal has clipped since the last call to this method.
+ //
+ // This method should be called on the UI thread.
+ void CurrentAudibleLevel(const content::WebContents* contents,
+ float* level, bool* signal_has_clipped);
private:
- struct RenderViewId {
- RenderViewId(int render_process_id,
- int render_view_id);
-
- // Required to use this struct in the std::multiset below.
- bool operator<(const RenderViewId& other) const;
-
- int render_process_id;
- int render_view_id;
+ // <render process ID, render view ID>
+ // Note: Using std::pair<> to reduce binary-size bloat.
+ typedef std::pair<int, int> RenderViewId;
+ struct StreamPowerLevel {
+ int stream_id;
+ float power_dbfs;
+ bool clipped;
};
+ typedef std::vector<StreamPowerLevel> StreamPowerLevels;
+ // Container for the power levels of streams playing from each render view.
+ typedef std::map<RenderViewId, StreamPowerLevels> RenderViewStreamMap;
friend class base::RefCountedThreadSafe<AudioStreamIndicator>;
virtual ~AudioStreamIndicator();
@@ -46,11 +58,11 @@
void UpdateWebContentsStatusOnUIThread(int render_process_id,
int render_view_id,
int stream_id,
- bool playing);
+ bool is_playing,
+ float power_dbfs,
+ bool clipped);
- // A map from RenderViews to sets of streams playing in them (each RenderView
- // might have more than one stream).
- std::map<RenderViewId, std::set<int> > audio_streams_;
+ RenderViewStreamMap audio_streams_;
};
#endif // CHROME_BROWSER_MEDIA_AUDIO_STREAM_INDICATOR_H_
diff --git a/chrome/browser/media/chrome_media_stream_infobar_browsertest.cc b/chrome/browser/media/chrome_media_stream_infobar_browsertest.cc
index 24410c2..5396b11 100644
--- a/chrome/browser/media/chrome_media_stream_infobar_browsertest.cc
+++ b/chrome/browser/media/chrome_media_stream_infobar_browsertest.cc
@@ -26,6 +26,10 @@
#include "content/public/test/browser_test_utils.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
static const char kMainWebrtcTestHtmlPage[] =
"files/webrtc/webrtc_jsep01_test.html";
static const char kFailedWithErrorPermissionDenied[] =
@@ -202,6 +206,12 @@
IN_PROC_BROWSER_TEST_F(MediaStreamInfobarTest,
TestAcceptThenDenyWhichShouldBeSticky) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
content::WebContents* tab_contents = LoadTestPageInTab();
TestAcceptOnInfobar(tab_contents);
diff --git a/chrome/browser/media/media_capture_devices_dispatcher.cc b/chrome/browser/media/media_capture_devices_dispatcher.cc
index 6d49f98..ff9418c 100644
--- a/chrome/browser/media/media_capture_devices_dispatcher.cc
+++ b/chrome/browser/media/media_capture_devices_dispatcher.cc
@@ -64,7 +64,8 @@
origin.spec() == "https://plus.google.com/" ||
origin.spec() == "chrome-extension://pkedcjkdefgpdelpbcmbmeomcjbeemfm/" ||
origin.spec() == "chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/" ||
- origin.spec() == "chrome-extension://hfaagokkkhdbgiakmmlclaapfelnkoah/") {
+ origin.spec() == "chrome-extension://hfaagokkkhdbgiakmmlclaapfelnkoah/" ||
+ origin.spec() == "chrome-extension://gfdkimpbcpahaombhbimeihdjnejgicl/") {
return true;
}
// Check against hashed origins.
@@ -175,7 +176,9 @@
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (request.video_type == content::MEDIA_SCREEN_VIDEO_CAPTURE) {
- ProcessScreenCaptureAccessRequest(web_contents, request, callback);
+ ProcessScreenCaptureAccessRequest(
+ web_contents, request, callback,
+ extension && extension->location() == extensions::Manifest::COMPONENT);
} else if (extension) {
// For extensions access is approved based on extension permissions.
ProcessMediaAccessRequestFromExtension(
@@ -188,7 +191,8 @@
void MediaCaptureDevicesDispatcher::ProcessScreenCaptureAccessRequest(
content::WebContents* web_contents,
const content::MediaStreamRequest& request,
- const content::MediaResponseCallback& callback) {
+ const content::MediaResponseCallback& callback,
+ bool component_extension) {
content::MediaStreamDevices devices;
bool screen_capture_enabled =
@@ -209,22 +213,30 @@
// 3. Audio capture was not requested (it's not supported yet).
if (screen_capture_enabled && origin_is_secure &&
request.audio_type == content::MEDIA_NO_SERVICE) {
- string16 application_name = UTF8ToUTF16(request.security_origin.spec());
- chrome::MessageBoxResult result = chrome::ShowMessageBox(
- NULL,
- l10n_util::GetStringFUTF16(IDS_MEDIA_SCREEN_CAPTURE_CONFIRMATION_TITLE,
- application_name),
- l10n_util::GetStringFUTF16(IDS_MEDIA_SCREEN_CAPTURE_CONFIRMATION_TEXT,
- application_name),
- chrome::MESSAGE_BOX_TYPE_QUESTION);
- if (result == chrome::MESSAGE_BOX_RESULT_YES) {
+ // For component extensions, bypass message box.
+ bool user_approved = false;
+ if (!component_extension) {
+ string16 application_name = UTF8ToUTF16(request.security_origin.spec());
+ chrome::MessageBoxResult result = chrome::ShowMessageBox(
+ NULL,
+ l10n_util::GetStringFUTF16(
+ IDS_MEDIA_SCREEN_CAPTURE_CONFIRMATION_TITLE, application_name),
+ l10n_util::GetStringFUTF16(
+ IDS_MEDIA_SCREEN_CAPTURE_CONFIRMATION_TEXT, application_name),
+ chrome::MESSAGE_BOX_TYPE_QUESTION);
+ user_approved = (result == chrome::MESSAGE_BOX_RESULT_YES);
+ }
+
+ if (user_approved || component_extension) {
devices.push_back(content::MediaStreamDevice(
content::MEDIA_SCREEN_VIDEO_CAPTURE, std::string(), "Screen"));
}
}
scoped_ptr<content::MediaStreamUI> ui;
- if (!devices.empty()) {
+ // Unless we're being invoked from a component extension, register to display
+ // the notification for stream capture.
+ if (!devices.empty() && !component_extension) {
ui = media_stream_capture_indicator_->RegisterMediaStream(
web_contents, devices);
}
@@ -468,11 +480,21 @@
void MediaCaptureDevicesDispatcher::OnAudioStreamPlayingChanged(
int render_process_id, int render_view_id, int stream_id,
- bool is_playing_and_audible) {
- audio_stream_indicator_->UpdateWebContentsStatus(render_process_id,
- render_view_id,
- stream_id,
- is_playing_and_audible);
+ bool is_playing, float power_dbfs, bool clipped) {
+ audio_stream_indicator_->UpdateWebContentsStatus(
+ render_process_id, render_view_id, stream_id,
+ is_playing, power_dbfs, clipped);
+}
+
+void MediaCaptureDevicesDispatcher::OnCreatingAudioStream(
+ int render_process_id,
+ int render_view_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(
+ &MediaCaptureDevicesDispatcher::OnCreatingAudioStreamOnUIThread,
+ base::Unretained(this), render_process_id, render_view_id));
}
void MediaCaptureDevicesDispatcher::UpdateAudioDevicesOnUIThread(
@@ -526,3 +548,11 @@
device,
state));
}
+
+void MediaCaptureDevicesDispatcher::OnCreatingAudioStreamOnUIThread(
+ int render_process_id,
+ int render_view_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ FOR_EACH_OBSERVER(Observer, observers_,
+ OnCreatingAudioStream(render_process_id, render_view_id));
+}
diff --git a/chrome/browser/media/media_capture_devices_dispatcher.h b/chrome/browser/media/media_capture_devices_dispatcher.h
index 6054a30..e9dde12 100644
--- a/chrome/browser/media/media_capture_devices_dispatcher.h
+++ b/chrome/browser/media/media_capture_devices_dispatcher.h
@@ -54,6 +54,10 @@
const content::MediaStreamDevice& device,
const content::MediaRequestState state) {}
+ // Handle an information update that a new stream is being created.
+ virtual void OnCreatingAudioStream(int render_process_id,
+ int render_view_id) {}
+
virtual ~Observer() {}
};
@@ -121,7 +125,11 @@
int render_process_id,
int render_view_id,
int stream_id,
- bool is_playing_and_audible) OVERRIDE;
+ bool is_playing,
+ float power_dBFS,
+ bool clipped) OVERRIDE;
+ virtual void OnCreatingAudioStream(int render_process_id,
+ int render_view_id) OVERRIDE;
scoped_refptr<MediaStreamCaptureIndicator> GetMediaStreamCaptureIndicator();
@@ -153,7 +161,8 @@
void ProcessScreenCaptureAccessRequest(
content::WebContents* web_contents,
const content::MediaStreamRequest& request,
- const content::MediaResponseCallback& callback);
+ const content::MediaResponseCallback& callback,
+ bool from_component_extension);
void ProcessMediaAccessRequestFromExtension(
content::WebContents* web_contents,
const content::MediaStreamRequest& request,
@@ -177,6 +186,8 @@
int page_request_id,
const content::MediaStreamDevice& device,
content::MediaRequestState state);
+ void OnCreatingAudioStreamOnUIThread(int render_process_id,
+ int render_view_id);
// A list of cached audio capture devices.
content::MediaStreamDevices audio_devices_;
diff --git a/chrome/browser/media/media_stream_capture_indicator.cc b/chrome/browser/media/media_stream_capture_indicator.cc
index 42598a6..456fc9d 100644
--- a/chrome/browser/media/media_stream_capture_indicator.cc
+++ b/chrome/browser/media/media_stream_capture_indicator.cc
@@ -55,7 +55,7 @@
return NULL;
return extension_service->extensions()->GetExtensionOrAppByURL(
- ExtensionURLInfo(web_contents->GetURL()));
+ web_contents->GetURL());
}
// Gets the security originator of the tab. It returns a string with no '/'
@@ -379,7 +379,8 @@
if (!status_tray)
return;
- status_icon_ = status_tray->CreateStatusIcon();
+ status_icon_ =
+ status_tray->CreateStatusIcon(StatusTray::MEDIA_STREAM_CAPTURE_ICON);
EnsureStatusTrayIconResources();
}
diff --git a/chrome/browser/media/media_stream_infobar_delegate.cc b/chrome/browser/media/media_stream_infobar_delegate.cc
index 3fc8661..5e2aa87 100644
--- a/chrome/browser/media/media_stream_infobar_delegate.cc
+++ b/chrome/browser/media/media_stream_infobar_delegate.cc
@@ -65,6 +65,7 @@
DCHECK(controller_.get());
DCHECK(controller_->has_audio() || controller_->has_video());
}
+
void MediaStreamInfoBarDelegate::InfoBarDismissed() {
// Deny the request if the infobar was closed with the 'x' button, since
// we don't want WebRTC to be waiting for an answer that will never come.
diff --git a/chrome/browser/media/media_stream_infobar_delegate.h b/chrome/browser/media/media_stream_infobar_delegate.h
index 02992e7..b2aaeeb 100644
--- a/chrome/browser/media/media_stream_infobar_delegate.h
+++ b/chrome/browser/media/media_stream_infobar_delegate.h
@@ -22,9 +22,9 @@
virtual ~MediaStreamInfoBarDelegate();
// Handles a permission request (in |request|) for |web_contents|. If this
- // involves prompting the user, creates a media stream delegate, then checks
- // for an existing infobar for |web_contents| and replaces it if found, or
- // just adds the new infobar otherwise. Returns whether an infobar was
+ // involves prompting the user, creates a media stream infobar delegate, then
+ // checks for an existing infobar for |web_contents| and replaces it if found,
+ // or just adds the new infobar otherwise. Returns whether an infobar was
// created.
static bool Create(content::WebContents* web_contents,
const content::MediaStreamRequest& request,
diff --git a/chrome/browser/media/webrtc_log_upload_list.cc b/chrome/browser/media/webrtc_log_upload_list.cc
index fdaaad0..9f9922e 100644
--- a/chrome/browser/media/webrtc_log_upload_list.cc
+++ b/chrome/browser/media/webrtc_log_upload_list.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/media/webrtc_log_upload_list.h"
#include "base/files/file_path.h"
+#include "base/message_loop/message_loop_proxy.h"
#include "base/path_service.h"
#include "chrome/common/chrome_paths.h"
@@ -23,6 +24,8 @@
WebRtcLogUploadList::WebRtcLogUploadList(Delegate* delegate,
const base::FilePath& upload_log_path)
- : UploadList(delegate, upload_log_path) {}
+ : base::UploadList(delegate,
+ upload_log_path,
+ base::MessageLoopProxy::current()) {}
WebRtcLogUploadList::~WebRtcLogUploadList() {}
diff --git a/chrome/browser/media/webrtc_log_upload_list.h b/chrome/browser/media/webrtc_log_upload_list.h
index b829d8e..366a41d 100644
--- a/chrome/browser/media/webrtc_log_upload_list.h
+++ b/chrome/browser/media/webrtc_log_upload_list.h
@@ -5,10 +5,10 @@
#ifndef CHROME_BROWSER_MEDIA_WEBRTC_LOG_UPLOAD_LIST_H_
#define CHROME_BROWSER_MEDIA_WEBRTC_LOG_UPLOAD_LIST_H_
-#include "chrome/browser/upload_list.h"
+#include "base/upload_list.h"
// Loads and parses a text file list of uploaded WebRTC logs.
-class WebRtcLogUploadList : public UploadList {
+class WebRtcLogUploadList : public base::UploadList {
public:
// Creates the WebRTC log upload list with the given callback delegate.
static WebRtcLogUploadList* Create(Delegate* delegate);
diff --git a/chrome/browser/media_galleries/fileapi/itunes_data_provider.h b/chrome/browser/media_galleries/fileapi/itunes_data_provider.h
index 5d8cb4f..c53f552 100644
--- a/chrome/browser/media_galleries/fileapi/itunes_data_provider.h
+++ b/chrome/browser/media_galleries/fileapi/itunes_data_provider.h
@@ -17,6 +17,8 @@
namespace itunes {
+class TestITunesDataProvider;
+
// This class is the holder for iTunes parsed data. Given a path to the iTunes
// library XML file it will read it in, parse the data, and provide convenient
// methods to access it. When the file changes, it will update the data.
@@ -30,7 +32,7 @@
typedef base::Callback<void(bool)> ReadyCallback;
explicit ITunesDataProvider(const base::FilePath& library_path);
- ~ITunesDataProvider();
+ virtual ~ITunesDataProvider();
// Ask the data provider to refresh the data if necessary. |ready_callback|
// will be called with the result; false if unable to parse the XML file.
@@ -61,6 +63,8 @@
Album GetAlbum(const ArtistName& artist, const AlbumName& album) const;
private:
+ friend class TestITunesDataProvider;
+
typedef std::map<AlbumName, Album> Artist;
typedef std::map<ArtistName, Artist> Library;
@@ -79,8 +83,8 @@
// watch.
void OnLibraryWatchStarted(scoped_ptr<base::FilePathWatcher> library_watcher);
- // Called when |library_path_| has changed.
- void OnLibraryChanged(const base::FilePath& path, bool error);
+ // Called when |library_path_| has changed. Virtual for testing.
+ virtual void OnLibraryChanged(const base::FilePath& path, bool error);
// Called when the utility process finishes parsing the library XML file.
void OnLibraryParsed(const ReadyCallback& ready_callback,
diff --git a/chrome/browser/media_galleries/fileapi/itunes_data_provider_browsertest.cc b/chrome/browser/media_galleries/fileapi/itunes_data_provider_browsertest.cc
new file mode 100644
index 0000000..2f1742a
--- /dev/null
+++ b/chrome/browser/media_galleries/fileapi/itunes_data_provider_browsertest.cc
@@ -0,0 +1,412 @@
+// Copyright 2013 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 <string>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/format_macros.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/strings/stringprintf.h"
+#include "chrome/browser/media_galleries/fileapi/itunes_data_provider.h"
+#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
+#include "chrome/browser/media_galleries/imported_media_gallery_registry.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "content/public/browser/browser_thread.h"
+#include "url/gurl.h"
+
+using chrome::MediaFileSystemBackend;
+
+namespace itunes {
+
+namespace {
+
+struct LibraryEntry {
+ LibraryEntry(const std::string& artist, const std::string& album,
+ const base::FilePath& location)
+ : artist(artist),
+ album(album),
+ location(location) {
+ }
+ std::string artist;
+ std::string album;
+ base::FilePath location;
+};
+
+} // namespace
+
+class TestITunesDataProvider : public ITunesDataProvider {
+ public:
+ TestITunesDataProvider(const base::FilePath& xml_library_path,
+ const base::Closure& callback)
+ : ITunesDataProvider(xml_library_path),
+ callback_(callback) {
+ }
+ virtual ~TestITunesDataProvider() {}
+
+ private:
+ virtual void OnLibraryChanged(const base::FilePath& path,
+ bool error) OVERRIDE {
+ ITunesDataProvider::OnLibraryChanged(path, error);
+ callback_.Run();
+ }
+
+ base::Closure callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestITunesDataProvider);
+};
+
+class ITunesDataProviderTest : public InProcessBrowserTest {
+ public:
+ ITunesDataProviderTest() {}
+ virtual ~ITunesDataProviderTest() {}
+
+ protected:
+ virtual void SetUp() OVERRIDE {
+ ASSERT_TRUE(library_dir_.CreateUniqueTempDir());
+ WriteLibraryInternal(SetUpLibrary());
+ // The ImportedMediaGalleryRegistry is created on which ever thread calls
+ // GetInstance() first. It shouldn't matter what thread creates, however
+ // in practice it is always created on the UI thread, so this calls
+ // GetInstance here to mirror those real conditions.
+ chrome::ImportedMediaGalleryRegistry::GetInstance();
+ InProcessBrowserTest::SetUp();
+ }
+
+ void RunTest() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ base::RunLoop loop;
+ quit_closure_ = loop.QuitClosure();
+ MediaFileSystemBackend::MediaTaskRunner()->PostTask(
+ FROM_HERE,
+ base::Bind(&ITunesDataProviderTest::StartTestOnMediaTaskRunner,
+ base::Unretained(this)));
+ loop.Run();
+ }
+
+ void WriteLibrary(const std::vector<LibraryEntry>& entries,
+ const base::Closure& callback) {
+ SetLibraryChangeCallback(callback);
+ WriteLibraryInternal(entries);
+ }
+
+ void SetLibraryChangeCallback(const base::Closure& callback) {
+ EXPECT_TRUE(library_changed_callback_.is_null());
+ library_changed_callback_ = callback;
+ }
+
+ ITunesDataProvider* data_provider() const {
+ return chrome::ImportedMediaGalleryRegistry::ITunesDataProvider();
+ }
+
+ const base::FilePath& library_dir() const {
+ return library_dir_.path();
+ }
+
+ base::FilePath XmlFile() const {
+ return library_dir_.path().AppendASCII("library.xml");
+ }
+
+ void ExpectTrackLocation(const std::string& artist, const std::string& album,
+ const std::string& track_name) {
+ base::FilePath track =
+ library_dir().AppendASCII(track_name).NormalizePathSeparators();
+ EXPECT_EQ(track.value(),
+ data_provider()->GetTrackLocation(
+ artist, album, track_name).NormalizePathSeparators().value());
+ }
+
+ void ExpectNoTrack(const std::string& artist, const std::string& album,
+ const std::string& track_name) {
+ EXPECT_TRUE(data_provider()->GetTrackLocation(
+ artist, album, track_name).empty()) << track_name;
+ }
+
+
+ // Get the initial set of library entries, called by SetUp. If no entries
+ // are returned the xml file is not created.
+ virtual std::vector<LibraryEntry> SetUpLibrary() {
+ return std::vector<LibraryEntry>();
+ }
+
+ // Start the test. The data provider is refreshed before calling StartTest
+ // and the result of the refresh is passed in.
+ virtual void StartTest(bool parse_success) = 0;
+
+ void TestDone() {
+ DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
+ chrome::ImportedMediaGalleryRegistry* imported_registry =
+ chrome::ImportedMediaGalleryRegistry::GetInstance();
+ imported_registry->itunes_data_provider_.reset();
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+ quit_closure_);
+ }
+
+ private:
+ void StartTestOnMediaTaskRunner() {
+ DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
+ chrome::ImportedMediaGalleryRegistry* imported_registry =
+ chrome::ImportedMediaGalleryRegistry::GetInstance();
+ imported_registry->itunes_data_provider_.reset(
+ new TestITunesDataProvider(
+ XmlFile(),
+ base::Bind(&ITunesDataProviderTest::OnLibraryChanged,
+ base::Unretained(this))));
+ data_provider()->RefreshData(base::Bind(&ITunesDataProviderTest::StartTest,
+ base::Unretained(this)));
+ };
+
+ void OnLibraryChanged() {
+ DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
+ if (!library_changed_callback_.is_null()) {
+ library_changed_callback_.Run();
+ library_changed_callback_.Reset();
+ }
+ }
+
+ void WriteLibraryInternal(const std::vector<LibraryEntry>& entries) {
+ if (!entries.size())
+ return;
+ std::string xml = "<plist><dict><key>Tracks</key><dict>\n";
+ for (size_t i = 0; i < entries.size(); ++i) {
+ GURL location("file://localhost/" + entries[i].location.AsUTF8Unsafe());
+ std::string entry_string = base::StringPrintf(
+ "<key>%" PRIuS "</key><dict>\n"
+ " <key>Track ID</key><integer>%" PRIuS "</integer>\n"
+ " <key>Location</key><string>%s</string>\n"
+ " <key>Artist</key><string>%s</string>\n"
+ " <key>Album</key><string>%s</string>\n"
+ "</dict>\n",
+ i + 1, i + 1, location.spec().c_str(), entries[i].artist.c_str(),
+ entries[i].album.c_str());
+ xml += entry_string;
+ }
+ xml += "</dict></dict></plist>\n";
+ ASSERT_EQ(static_cast<int>(xml.size()),
+ file_util::WriteFile(XmlFile(), xml.c_str(), xml.size()));
+ }
+
+ base::ScopedTempDir library_dir_;
+
+ base::Closure library_changed_callback_;
+
+ base::Closure quit_closure_;
+
+ DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderTest);
+};
+
+class ITunesDataProviderBasicTest : public ITunesDataProviderTest {
+ public:
+ ITunesDataProviderBasicTest() {}
+ virtual ~ITunesDataProviderBasicTest() {}
+
+ virtual std::vector<LibraryEntry> SetUpLibrary() OVERRIDE {
+ base::FilePath track = library_dir().AppendASCII("Track.mp3");
+ std::vector<LibraryEntry> entries;
+ entries.push_back(LibraryEntry("Artist", "Album", track));
+ return entries;
+ }
+
+ virtual void StartTest(bool parse_success) OVERRIDE {
+ EXPECT_TRUE(parse_success);
+
+ // KnownArtist
+ EXPECT_TRUE(data_provider()->KnownArtist("Artist"));
+ EXPECT_FALSE(data_provider()->KnownArtist("Artist2"));
+
+ // KnownAlbum
+ EXPECT_TRUE(data_provider()->KnownAlbum("Artist", "Album"));
+ EXPECT_FALSE(data_provider()->KnownAlbum("Artist", "Album2"));
+ EXPECT_FALSE(data_provider()->KnownAlbum("Artist2", "Album"));
+
+ // GetTrackLocation
+ ExpectTrackLocation("Artist", "Album", "Track.mp3");
+ ExpectNoTrack("Artist", "Album", "Track2.mp3");
+ ExpectNoTrack("Artist", "Album2", "Track.mp3");
+ ExpectNoTrack("Artist2", "Album", "Track.mp3");
+
+ // GetArtistNames
+ std::set<ITunesDataProvider::ArtistName> artists =
+ data_provider()->GetArtistNames();
+ ASSERT_EQ(1U, artists.size());
+ EXPECT_EQ("Artist", *artists.begin());
+
+ // GetAlbumNames
+ std::set<ITunesDataProvider::AlbumName> albums =
+ data_provider()->GetAlbumNames("Artist");
+ ASSERT_EQ(1U, albums.size());
+ EXPECT_EQ("Album", *albums.begin());
+
+ albums = data_provider()->GetAlbumNames("Artist2");
+ EXPECT_EQ(0U, albums.size());
+
+ // GetAlbum
+ base::FilePath track =
+ library_dir().AppendASCII("Track.mp3").NormalizePathSeparators();
+ ITunesDataProvider::Album album =
+ data_provider()->GetAlbum("Artist", "Album");
+ ASSERT_EQ(1U, album.size());
+ EXPECT_EQ(track.BaseName().AsUTF8Unsafe(), album.begin()->first);
+ EXPECT_EQ(track.value(),
+ album.begin()->second.NormalizePathSeparators().value());
+
+ album = data_provider()->GetAlbum("Artist", "Album2");
+ EXPECT_EQ(0U, album.size());
+
+ album = data_provider()->GetAlbum("Artist2", "Album");
+ EXPECT_EQ(0U, album.size());
+
+ TestDone();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderBasicTest);
+};
+
+class ITunesDataProviderRefreshTest : public ITunesDataProviderTest {
+ public:
+ ITunesDataProviderRefreshTest() {}
+ virtual ~ITunesDataProviderRefreshTest() {}
+
+ virtual std::vector<LibraryEntry> SetUpLibrary() OVERRIDE {
+ base::FilePath track = library_dir().AppendASCII("Track.mp3");
+ std::vector<LibraryEntry> entries;
+ entries.push_back(LibraryEntry("Artist", "Album", track));
+ return entries;
+ }
+
+ virtual void StartTest(bool parse_success) OVERRIDE {
+ EXPECT_TRUE(parse_success);
+
+ // Initial contents.
+ ExpectTrackLocation("Artist", "Album", "Track.mp3");
+ ExpectNoTrack("Artist2", "Album2", "Track2.mp3");
+
+ // New file.
+ base::FilePath track2 = library_dir().AppendASCII("Track2.mp3");
+ std::vector<LibraryEntry> entries;
+ entries.push_back(LibraryEntry("Artist2", "Album2", track2));
+ WriteLibrary(entries,
+ base::Bind(&ITunesDataProviderRefreshTest::CheckAfterWrite,
+ base::Unretained(this)));
+ }
+
+ void CheckAfterWrite() {
+ // Content the same.
+ ExpectTrackLocation("Artist", "Album", "Track.mp3");
+ ExpectNoTrack("Artist2", "Album2", "Track2.mp3");
+
+ data_provider()->RefreshData(
+ base::Bind(&ITunesDataProviderRefreshTest::CheckRefresh,
+ base::Unretained(this)));
+ }
+
+ void CheckRefresh(bool is_valid) {
+ EXPECT_TRUE(is_valid);
+
+ ExpectTrackLocation("Artist2", "Album2", "Track2.mp3");
+ ExpectNoTrack("Artist", "Album", "Track.mp3");
+ TestDone();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderRefreshTest);
+};
+
+class ITunesDataProviderInvalidTest : public ITunesDataProviderTest {
+ public:
+ ITunesDataProviderInvalidTest() {}
+ virtual ~ITunesDataProviderInvalidTest() {}
+
+ virtual std::vector<LibraryEntry> SetUpLibrary() OVERRIDE {
+ base::FilePath track = library_dir().AppendASCII("Track.mp3");
+ std::vector<LibraryEntry> entries;
+ entries.push_back(LibraryEntry("Artist", "Album", track));
+ return entries;
+ }
+
+ virtual void StartTest(bool parse_success) OVERRIDE {
+ EXPECT_TRUE(parse_success);
+
+ SetLibraryChangeCallback(
+ base::Bind(&ITunesDataProvider::RefreshData,
+ base::Unretained(data_provider()),
+ base::Bind(&ITunesDataProviderInvalidTest::CheckInvalid,
+ base::Unretained(this))));
+ ASSERT_EQ(1L, file_util::WriteFile(XmlFile(), " ", 1));
+ }
+
+ void CheckInvalid(bool is_valid) {
+ EXPECT_FALSE(is_valid);
+ TestDone();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderInvalidTest);
+};
+
+class ITunesDataProviderUniqueNameTest : public ITunesDataProviderTest {
+ public:
+ ITunesDataProviderUniqueNameTest() {}
+ virtual ~ITunesDataProviderUniqueNameTest() {}
+
+ virtual std::vector<LibraryEntry> SetUpLibrary() OVERRIDE {
+ base::FilePath track = library_dir().AppendASCII("Track.mp3");
+ std::vector<LibraryEntry> entries;
+ // Dupe album names should get uniquified with the track id, which in the
+ // test framework is the vector index.
+ entries.push_back(LibraryEntry("Artist", "Album", track));
+ entries.push_back(LibraryEntry("Artist", "Album", track));
+ entries.push_back(LibraryEntry("Artist", "Album2", track));
+ return entries;
+ }
+
+ virtual void StartTest(bool parse_success) OVERRIDE {
+ EXPECT_TRUE(parse_success);
+
+ base::FilePath track =
+ library_dir().AppendASCII("Track.mp3").NormalizePathSeparators();
+ EXPECT_EQ(track.value(),
+ data_provider()->GetTrackLocation(
+ "Artist", "Album",
+ "Track (1).mp3").NormalizePathSeparators().value());
+ EXPECT_EQ(track.value(),
+ data_provider()->GetTrackLocation(
+ "Artist", "Album",
+ "Track (2).mp3").NormalizePathSeparators().value());
+ EXPECT_EQ(track.value(),
+ data_provider()->GetTrackLocation(
+ "Artist", "Album2",
+ "Track.mp3").NormalizePathSeparators().value());
+
+ TestDone();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderUniqueNameTest);
+};
+
+IN_PROC_BROWSER_TEST_F(ITunesDataProviderBasicTest, BasicTest) {
+ RunTest();
+}
+
+IN_PROC_BROWSER_TEST_F(ITunesDataProviderRefreshTest, RefreshTest) {
+ RunTest();
+}
+
+IN_PROC_BROWSER_TEST_F(ITunesDataProviderInvalidTest, InvalidTest) {
+ RunTest();
+}
+
+IN_PROC_BROWSER_TEST_F(ITunesDataProviderUniqueNameTest, UniqueNameTest) {
+ RunTest();
+}
+
+} // namespace itunes
diff --git a/chrome/browser/media_galleries/fileapi/itunes_finder_win_browsertest.cc b/chrome/browser/media_galleries/fileapi/itunes_finder_win_browsertest.cc
index 6182ede..9aeb450 100644
--- a/chrome/browser/media_galleries/fileapi/itunes_finder_win_browsertest.cc
+++ b/chrome/browser/media_galleries/fileapi/itunes_finder_win_browsertest.cc
@@ -9,7 +9,7 @@
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
@@ -38,6 +38,8 @@
public:
ITunesFinderWinTest() : test_finder_callback_called_(false) {}
+ virtual ~ITunesFinderWinTest() {}
+
virtual void SetUp() OVERRIDE {
ASSERT_TRUE(app_data_dir_.CreateUniqueTempDir());
ASSERT_TRUE(music_dir_.CreateUniqueTempDir());
diff --git a/chrome/browser/media_galleries/imported_media_gallery_registry.h b/chrome/browser/media_galleries/imported_media_gallery_registry.h
index f90e7c1..b9bff98 100644
--- a/chrome/browser/media_galleries/imported_media_gallery_registry.h
+++ b/chrome/browser/media_galleries/imported_media_gallery_registry.h
@@ -15,6 +15,7 @@
namespace itunes {
class ITunesDataProvider;
+class ITunesDataProviderTest;
}
namespace picasa {
@@ -49,6 +50,7 @@
private:
friend struct base::DefaultLazyInstanceTraits<ImportedMediaGalleryRegistry>;
+ friend class itunes::ITunesDataProviderTest;
ImportedMediaGalleryRegistry();
virtual ~ImportedMediaGalleryRegistry();
diff --git a/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac_unittest.mm b/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac_unittest.mm
index 7e71717..3543759 100644
--- a/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac_unittest.mm
+++ b/chrome/browser/media_galleries/mac/mtp_device_delegate_impl_mac_unittest.mm
@@ -10,7 +10,7 @@
#include "base/mac/cocoa_protocols.h"
#include "base/mac/foundation_util.h"
#include "base/mac/scoped_nsobject.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/sys_string_conversions.h"
#include "base/synchronization/waitable_event.h"
@@ -184,7 +184,9 @@
content::BrowserThread::IO));
ASSERT_TRUE(io_thread_->Start());
- manager_.SetNotifications(monitor_.receiver());
+ chrome::test::TestStorageMonitor* monitor =
+ chrome::test::TestStorageMonitor::CreateAndInstall();
+ manager_.SetNotifications(monitor->receiver());
camera_ = [MockMTPICCameraDevice alloc];
id<ICDeviceBrowserDelegate> delegate = manager_.device_browser();
@@ -304,7 +306,6 @@
scoped_ptr<content::TestBrowserThread> file_thread_;
scoped_ptr<content::TestBrowserThread> io_thread_;
base::ScopedTempDir temp_dir_;
- chrome::test::TestStorageMonitor monitor_;
chrome::ImageCaptureDeviceManager manager_;
MockMTPICCameraDevice* camera_;
diff --git a/chrome/browser/media_galleries/media_file_system_registry_unittest.cc b/chrome/browser/media_galleries/media_file_system_registry_unittest.cc
index 59a411b..cab5d3c 100644
--- a/chrome/browser/media_galleries/media_file_system_registry_unittest.cc
+++ b/chrome/browser/media_galleries/media_file_system_registry_unittest.cc
@@ -14,7 +14,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
diff --git a/chrome/browser/media_galleries/media_galleries_preferences_unittest.cc b/chrome/browser/media_galleries/media_galleries_preferences_unittest.cc
index e4c208c..aa3b47d 100644
--- a/chrome/browser/media_galleries/media_galleries_preferences_unittest.cc
+++ b/chrome/browser/media_galleries/media_galleries_preferences_unittest.cc
@@ -9,7 +9,7 @@
#include "base/command_line.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/extensions/extension_system.h"
diff --git a/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win_unittest.cc b/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win_unittest.cc
index 8f7d042..93fd983 100644
--- a/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win_unittest.cc
+++ b/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win_unittest.cc
@@ -6,7 +6,7 @@
#include "base/command_line.h"
#include "base/files/file_path.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "chrome/browser/browser_process.h"
@@ -18,9 +18,11 @@
#include "chrome/browser/storage_monitor/storage_info.h"
#include "chrome/browser/storage_monitor/storage_monitor.h"
#include "chrome/browser/storage_monitor/test_portable_device_watcher_win.h"
+#include "chrome/browser/storage_monitor/test_storage_monitor.h"
#include "chrome/browser/storage_monitor/test_storage_monitor_win.h"
#include "chrome/browser/storage_monitor/test_volume_mount_watcher_win.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
@@ -60,8 +62,8 @@
bool removable,
bool media_device);
- // Note: need to make this weak ptr once ownership moves to g_browser_process
- scoped_ptr<test::TestStorageMonitorWin> monitor_;
+ // Pointer to the storage monitor. Owned by TestingBrowserProcess.
+ test::TestStorageMonitorWin* monitor_;
scoped_refptr<extensions::Extension> extension_;
EnsureMediaDirectoriesExists media_directories_;
@@ -69,13 +71,21 @@
void MTPDeviceDelegateImplWinTest::SetUp() {
ChromeRenderViewHostTestHarness::SetUp();
+
+ test::TestStorageMonitor::RemoveSingleton();
test::TestPortableDeviceWatcherWin* portable_device_watcher =
new test::TestPortableDeviceWatcherWin;
test::TestVolumeMountWatcherWin* mount_watcher =
new test::TestVolumeMountWatcherWin;
portable_device_watcher->set_use_dummy_mtp_storage_info(true);
- monitor_.reset(new test::TestStorageMonitorWin(
- mount_watcher, portable_device_watcher));
+ scoped_ptr<test::TestStorageMonitorWin> monitor(
+ new test::TestStorageMonitorWin(
+ mount_watcher, portable_device_watcher));
+ TestingBrowserProcess* browser_process = TestingBrowserProcess::GetGlobal();
+ DCHECK(browser_process);
+ monitor_ = monitor.get();
+ browser_process->SetStorageMonitor(monitor.Pass());
+
base::RunLoop runloop;
monitor_->EnsureInitialized(runloop.QuitClosure());
runloop.Run();
@@ -93,7 +103,9 @@
}
void MTPDeviceDelegateImplWinTest::TearDown() {
- monitor_.reset();
+ // Windows storage monitor must be destroyed on the same thread
+ // as construction.
+ test::TestStorageMonitor::RemoveSingleton();
ChromeRenderViewHostTestHarness::TearDown();
}
diff --git a/chrome/browser/memory_details.cc b/chrome/browser/memory_details.cc
index ef07356..1dad6f9 100644
--- a/chrome/browser/memory_details.cc
+++ b/chrome/browser/memory_details.cc
@@ -497,6 +497,12 @@
#if defined(OS_CHROMEOS)
void MemoryDetails::UpdateSwapHistograms() {
+ UMA_HISTOGRAM_BOOLEAN("Memory.Swap.HaveSwapped", swap_data_.num_writes > 0);
+ if (swap_data_.num_writes == 0)
+ return;
+
+ // Only record swap info when any swaps have happened, to give us more
+ // detail in the histograms.
const ProcessData& browser = *ChromeBrowser();
size_t aggregate_memory = 0;
for (size_t index = 0; index < browser.processes.size(); index++) {
@@ -563,6 +569,25 @@
int total_sample = static_cast<int>(aggregate_memory / 1000);
UMA_HISTOGRAM_MEMORY_MB("Memory.Swap.Total", total_sample);
+
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Memory.Swap.CompressedDataSize",
+ swap_data_.compr_data_size / (1024 * 1024),
+ 1, 4096, 50);
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Memory.Swap.OriginalDataSize",
+ swap_data_.orig_data_size / (1024 * 1024),
+ 1, 4096, 50);
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Memory.Swap.MemUsedTotal",
+ swap_data_.mem_used_total / (1024 * 1024),
+ 1, 4096, 50);
+ UMA_HISTOGRAM_COUNTS("Memory.Swap.NumReads", swap_data_.num_reads);
+ UMA_HISTOGRAM_COUNTS("Memory.Swap.NumWrites", swap_data_.num_writes);
+
+ if (swap_data_.orig_data_size > 0 && swap_data_.compr_data_size > 0) {
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "Memory.Swap.CompressionRatio",
+ swap_data_.orig_data_size / swap_data_.compr_data_size,
+ 1, 20, 20);
+ }
}
#endif
diff --git a/chrome/browser/memory_details.h b/chrome/browser/memory_details.h
index 24abeb9..be4d51f 100644
--- a/chrome/browser/memory_details.h
+++ b/chrome/browser/memory_details.h
@@ -87,6 +87,24 @@
class ProcessInfoSnapshot;
#endif
+#if defined(OS_CHROMEOS)
+struct SwapData {
+ SwapData()
+ : num_reads(0),
+ num_writes(0),
+ compr_data_size(0),
+ orig_data_size(0),
+ mem_used_total(0) {
+ }
+
+ uint64 num_reads;
+ uint64 num_writes;
+ uint64 compr_data_size;
+ uint64 orig_data_size;
+ uint64 mem_used_total;
+};
+#endif
+
// MemoryDetails fetches memory details about current running browsers.
// Because this data can only be fetched asynchronously, callers use
// this class via a callback.
@@ -187,6 +205,10 @@
UserMetricsMode user_metrics_mode_;
+#if defined(OS_CHROMEOS)
+ SwapData swap_data_;
+#endif
+
DISALLOW_COPY_AND_ASSIGN(MemoryDetails);
};
diff --git a/chrome/browser/memory_details_linux.cc b/chrome/browser/memory_details_linux.cc
index 6c2a55c..31bed8d 100644
--- a/chrome/browser/memory_details_linux.cc
+++ b/chrome/browser/memory_details_linux.cc
@@ -11,7 +11,9 @@
#include <set>
#include "base/bind.h"
+#include "base/file_util.h"
#include "base/process_util.h"
+#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/common/chrome_constants.h"
@@ -160,6 +162,40 @@
return children;
}
+#if defined(OS_CHROMEOS)
+static uint64 ReadFileToUint64(const base::FilePath file) {
+ std::string file_as_string;
+ if (!file_util::ReadFileToString(file, &file_as_string))
+ return 0;
+ uint64 file_as_uint64;
+ if (!base::StringToUint64(file_as_string, &file_as_uint64))
+ return 0;
+ return file_as_uint64;
+}
+
+static void GetSwapData(SwapData* swap_data) {
+ base::FilePath zram_path("/sys/block/zram0");
+ uint64 orig_data_size = ReadFileToUint64(zram_path.Append("orig_data_size"));
+ if (orig_data_size <= 4096) {
+ // A single page is compressed at startup, and has a high compression
+ // ratio. We ignore this as it doesn't indicate any real swapping.
+ swap_data->orig_data_size = 0;
+ swap_data->num_reads = 0;
+ swap_data->num_writes = 0;
+ swap_data->compr_data_size = 0;
+ swap_data->mem_used_total = 0;
+ return;
+ }
+ swap_data->orig_data_size = orig_data_size;
+ swap_data->num_reads = ReadFileToUint64(zram_path.Append("num_reads"));
+ swap_data->num_writes = ReadFileToUint64(zram_path.Append("num_writes"));
+ swap_data->compr_data_size =
+ ReadFileToUint64(zram_path.Append("compr_data_size"));
+ swap_data->mem_used_total =
+ ReadFileToUint64(zram_path.Append("mem_used_total"));
+}
+#endif
+
void MemoryDetails::CollectProcessData(
const std::vector<ProcessMemoryInformation>& child_info) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
@@ -230,6 +266,10 @@
process_data_.push_back(browser);
}
+#if defined(OS_CHROMEOS)
+ GetSwapData(&swap_data_);
+#endif
+
// Finally return to the browser thread.
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
diff --git a/chrome/browser/metrics/metrics_log.cc b/chrome/browser/metrics/metrics_log.cc
index 76563f59..af2613f 100644
--- a/chrome/browser/metrics/metrics_log.cc
+++ b/chrome/browser/metrics/metrics_log.cc
@@ -10,6 +10,7 @@
#include "base/basictypes.h"
#include "base/bind.h"
+#include "base/cpu.h"
#include "base/lazy_instance.h"
#include "base/memory/scoped_ptr.h"
#include "base/perftimer.h"
@@ -43,13 +44,13 @@
#include "components/nacl/common/nacl_process_type.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/common/content_client.h"
+#include "content/public/common/webplugininfo.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/bluetooth_device.h"
#include "gpu/config/gpu_info.h"
#include "ui/gfx/screen.h"
#include "url/gurl.h"
-#include "webkit/plugins/webplugininfo.h"
#if defined(OS_ANDROID)
#include "base/android/build_info.h"
@@ -192,7 +193,7 @@
}
// Fills |plugin| with the info contained in |plugin_info| and |plugin_prefs|.
-void SetPluginInfo(const webkit::WebPluginInfo& plugin_info,
+void SetPluginInfo(const content::WebPluginInfo& plugin_info,
const PluginPrefs* plugin_prefs,
SystemProfileProto::Plugin* plugin) {
plugin->set_name(UTF16ToUTF8(plugin_info.name));
@@ -219,27 +220,17 @@
for (std::vector<tracked_objects::TaskSnapshot>::const_iterator it =
profiler_data.tasks.begin();
it != profiler_data.tasks.end(); ++it) {
- std::string ignored;
- uint64 birth_thread_name_hash;
- uint64 exec_thread_name_hash;
- uint64 source_file_name_hash;
- uint64 source_function_name_hash;
- MetricsLogBase::CreateHashes(it->birth.thread_name,
- &ignored, &birth_thread_name_hash);
- MetricsLogBase::CreateHashes(it->death_thread_name,
- &ignored, &exec_thread_name_hash);
- MetricsLogBase::CreateHashes(it->birth.location.file_name,
- &ignored, &source_file_name_hash);
- MetricsLogBase::CreateHashes(it->birth.location.function_name,
- &ignored, &source_function_name_hash);
-
const tracked_objects::DeathDataSnapshot& death_data = it->death_data;
ProfilerEventProto::TrackedObject* tracked_object =
performance_profile->add_tracked_object();
- tracked_object->set_birth_thread_name_hash(birth_thread_name_hash);
- tracked_object->set_exec_thread_name_hash(exec_thread_name_hash);
- tracked_object->set_source_file_name_hash(source_file_name_hash);
- tracked_object->set_source_function_name_hash(source_function_name_hash);
+ tracked_object->set_birth_thread_name_hash(
+ MetricsLogBase::Hash(it->birth.thread_name));
+ tracked_object->set_exec_thread_name_hash(
+ MetricsLogBase::Hash(it->death_thread_name));
+ tracked_object->set_source_file_name_hash(
+ MetricsLogBase::Hash(it->birth.location.file_name));
+ tracked_object->set_source_function_name_hash(
+ MetricsLogBase::Hash(it->birth.location.function_name));
tracked_object->set_source_line_number(it->birth.location.line_number);
tracked_object->set_exec_count(death_data.count);
tracked_object->set_exec_time_total(death_data.run_duration_sum);
@@ -414,7 +405,7 @@
}
void MetricsLog::RecordIncrementalStabilityElements(
- const std::vector<webkit::WebPluginInfo>& plugin_list) {
+ const std::vector<content::WebPluginInfo>& plugin_list) {
DCHECK(!locked());
PrefService* pref = GetPrefService();
@@ -449,7 +440,7 @@
}
void MetricsLog::WriteStabilityElement(
- const std::vector<webkit::WebPluginInfo>& plugin_list,
+ const std::vector<content::WebPluginInfo>& plugin_list,
PrefService* pref) {
DCHECK(!locked());
@@ -492,7 +483,7 @@
}
void MetricsLog::WritePluginStabilityElements(
- const std::vector<webkit::WebPluginInfo>& plugin_list,
+ const std::vector<content::WebPluginInfo>& plugin_list,
PrefService* pref) {
// Now log plugin stability info.
const ListValue* plugin_stats_list = pref->GetList(
@@ -518,11 +509,11 @@
// fine.
// TODO(isherman): Verify that this does not show up as a hotspot in
// profiler runs.
- const webkit::WebPluginInfo* plugin_info = NULL;
+ const content::WebPluginInfo* plugin_info = NULL;
std::string plugin_name;
plugin_dict->GetString(prefs::kStabilityPluginName, &plugin_name);
const string16 plugin_name_utf16 = UTF8ToUTF16(plugin_name);
- for (std::vector<webkit::WebPluginInfo>::const_iterator iter =
+ for (std::vector<content::WebPluginInfo>::const_iterator iter =
plugin_list.begin();
iter != plugin_list.end(); ++iter) {
if (iter->name == plugin_name_utf16) {
@@ -646,13 +637,13 @@
}
void MetricsLog::WritePluginList(
- const std::vector<webkit::WebPluginInfo>& plugin_list) {
+ const std::vector<content::WebPluginInfo>& plugin_list) {
DCHECK(!locked());
#if defined(ENABLE_PLUGINS)
PluginPrefs* plugin_prefs = GetPluginPrefs();
SystemProfileProto* system_profile = uma_proto()->mutable_system_profile();
- for (std::vector<webkit::WebPluginInfo>::const_iterator iter =
+ for (std::vector<content::WebPluginInfo>::const_iterator iter =
plugin_list.begin();
iter != plugin_list.end(); ++iter) {
SystemProfileProto::Plugin* plugin = system_profile->add_plugin();
@@ -662,7 +653,7 @@
}
void MetricsLog::RecordEnvironment(
- const std::vector<webkit::WebPluginInfo>& plugin_list,
+ const std::vector<content::WebPluginInfo>& plugin_list,
const GoogleUpdateMetrics& google_update_metrics) {
DCHECK(!locked());
@@ -673,7 +664,7 @@
}
void MetricsLog::RecordEnvironmentProto(
- const std::vector<webkit::WebPluginInfo>& plugin_list,
+ const std::vector<content::WebPluginInfo>& plugin_list,
const GoogleUpdateMetrics& google_update_metrics) {
SystemProfileProto* system_profile = uma_proto()->mutable_system_profile();
@@ -732,6 +723,11 @@
base::android::BuildInfo::GetInstance()->android_build_fp());
#endif
+ base::CPU cpu_info;
+ SystemProfileProto::Hardware::CPU* cpu = hardware->mutable_cpu();
+ cpu->set_vendor_name(cpu_info.vendor_name());
+ cpu->set_signature(cpu_info.signature());
+
const gpu::GPUInfo& gpu_info =
GpuDataManager::GetInstance()->GetGPUInfo();
SystemProfileProto::Hardware::Graphics* gpu = hardware->mutable_gpu();
diff --git a/chrome/browser/metrics/metrics_log.h b/chrome/browser/metrics/metrics_log.h
index abc0847..fe06b61 100644
--- a/chrome/browser/metrics/metrics_log.h
+++ b/chrome/browser/metrics/metrics_log.h
@@ -30,6 +30,10 @@
class DictionaryValue;
}
+namespace content {
+struct WebPluginInfo;
+}
+
namespace device {
class BluetoothAdapter;
}
@@ -42,10 +46,6 @@
struct ActiveGroupId;
}
-namespace webkit {
-struct WebPluginInfo;
-}
-
// This is a small helper struct to pass Google Update metrics in a single
// reference argument to MetricsLog::RecordEnvironment().
struct GoogleUpdateMetrics {
@@ -94,7 +94,7 @@
// that are to be recorded. Each value in profile_metrics should be a
// dictionary giving the metrics for the profile.
void RecordEnvironment(
- const std::vector<webkit::WebPluginInfo>& plugin_list,
+ const std::vector<content::WebPluginInfo>& plugin_list,
const GoogleUpdateMetrics& google_update_metrics);
// Records the current operating environment. Takes the list of installed
@@ -104,7 +104,7 @@
// environment with *each* protobuf upload, but only with the initial XML
// upload.
void RecordEnvironmentProto(
- const std::vector<webkit::WebPluginInfo>& plugin_list,
+ const std::vector<content::WebPluginInfo>& plugin_list,
const GoogleUpdateMetrics& google_update_metrics);
// Records the input text, available choices, and selected entry when the
@@ -124,7 +124,7 @@
// installed plugins as a parameter because that can't be obtained
// synchronously from the UI thread.
void RecordIncrementalStabilityElements(
- const std::vector<webkit::WebPluginInfo>& plugin_list);
+ const std::vector<content::WebPluginInfo>& plugin_list);
protected:
// Exposed for the sake of mocking in test code.
@@ -152,12 +152,12 @@
// Writes application stability metrics (as part of the profile log).
// NOTE: Has the side-effect of clearing those counts.
void WriteStabilityElement(
- const std::vector<webkit::WebPluginInfo>& plugin_list,
+ const std::vector<content::WebPluginInfo>& plugin_list,
PrefService* pref);
// Within stability group, write plugin crash stats.
void WritePluginStabilityElements(
- const std::vector<webkit::WebPluginInfo>& plugin_list,
+ const std::vector<content::WebPluginInfo>& plugin_list,
PrefService* pref);
// Within the stability group, write required attributes.
@@ -170,7 +170,7 @@
void WriteRealtimeStabilityAttributes(PrefService* pref);
// Writes the list of installed plugins.
- void WritePluginList(const std::vector<webkit::WebPluginInfo>& plugin_list);
+ void WritePluginList(const std::vector<content::WebPluginInfo>& plugin_list);
// Writes info about the Google Update install that is managing this client.
// This is a no-op if called on a non-Windows platform.
diff --git a/chrome/browser/metrics/metrics_log_unittest.cc b/chrome/browser/metrics/metrics_log_unittest.cc
index 3f3506f..f102a86 100644
--- a/chrome/browser/metrics/metrics_log_unittest.cc
+++ b/chrome/browser/metrics/metrics_log_unittest.cc
@@ -5,7 +5,7 @@
#include <string>
#include "base/basictypes.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/port.h"
#include "base/prefs/pref_service.h"
#include "base/prefs/testing_pref_service.h"
@@ -25,11 +25,11 @@
#include "chrome/installer/util/google_update_settings.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/process_type.h"
+#include "content/public/common/webplugininfo.h"
#include "content/public/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/size.h"
#include "url/gurl.h"
-#include "webkit/plugins/webplugininfo.h"
#if defined(OS_CHROMEOS)
#include "chromeos/dbus/mock_dbus_thread_manager_without_gmock.h"
@@ -128,7 +128,7 @@
void TestRecordEnvironment(bool proto_only) {
TestMetricsLog log(kClientId, kSessionId);
- std::vector<webkit::WebPluginInfo> plugins;
+ std::vector<content::WebPluginInfo> plugins;
GoogleUpdateMetrics google_update_metrics;
if (proto_only)
log.RecordEnvironmentProto(plugins, google_update_metrics);
@@ -160,6 +160,10 @@
EXPECT_EQ(kScreenScaleFactor, hardware.primary_screen_scale_factor());
EXPECT_EQ(kScreenCount, hardware.screen_count());
+ EXPECT_TRUE(hardware.has_cpu());
+ EXPECT_TRUE(hardware.cpu().has_vendor_name());
+ EXPECT_TRUE(hardware.cpu().has_signature());
+
// TODO(isherman): Verify other data written into the protobuf as a result
// of this call.
}
diff --git a/chrome/browser/metrics/metrics_service.cc b/chrome/browser/metrics/metrics_service.cc
index af6e5e2..d48eb7b 100644
--- a/chrome/browser/metrics/metrics_service.cc
+++ b/chrome/browser/metrics/metrics_service.cc
@@ -208,9 +208,9 @@
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/process_type.h"
+#include "content/public/common/webplugininfo.h"
#include "net/base/load_flags.h"
#include "net/url_request/url_fetcher.h"
-#include "webkit/plugins/webplugininfo.h"
// TODO(port): port browser_distribution.h.
#if !defined(OS_POSIX)
@@ -909,13 +909,13 @@
base::Bind(&MetricsService::OnInitTaskGotPluginInfo,
self_ptr_factory_.GetWeakPtr()));
#else
- std::vector<webkit::WebPluginInfo> plugin_list_empty;
+ std::vector<content::WebPluginInfo> plugin_list_empty;
OnInitTaskGotPluginInfo(plugin_list_empty);
#endif // defined(ENABLE_PLUGINS)
}
void MetricsService::OnInitTaskGotPluginInfo(
- const std::vector<webkit::WebPluginInfo>& plugins) {
+ const std::vector<content::WebPluginInfo>& plugins) {
DCHECK_EQ(INIT_TASK_SCHEDULED, state_);
plugins_ = plugins;
@@ -1595,7 +1595,7 @@
#endif // OS_CHROMEOS
void MetricsService::LogPluginLoadingError(const base::FilePath& plugin_path) {
- webkit::WebPluginInfo plugin;
+ content::WebPluginInfo plugin;
bool success =
content::PluginService::GetInstance()->GetPluginInfoByPath(plugin_path,
&plugin);
diff --git a/chrome/browser/metrics/metrics_service.h b/chrome/browser/metrics/metrics_service.h
index d9e274b..b84172a 100644
--- a/chrome/browser/metrics/metrics_service.h
+++ b/chrome/browser/metrics/metrics_service.h
@@ -46,6 +46,7 @@
namespace content {
class RenderProcessHost;
class WebContents;
+struct WebPluginInfo;
}
namespace extensions {
@@ -65,10 +66,6 @@
struct ProcessDataSnapshot;
}
-namespace webkit {
-struct WebPluginInfo;
-}
-
class MetricsService
: public chrome_browser_metrics::TrackingSynchronizerObserver,
public content::BrowserChildProcessObserver,
@@ -236,7 +233,7 @@
// Callback from PluginService::GetPlugins() that continues the init task by
// launching a task to gather Google Update statistics.
void OnInitTaskGotPluginInfo(
- const std::vector<webkit::WebPluginInfo>& plugins);
+ const std::vector<content::WebPluginInfo>& plugins);
// Task launched by OnInitTaskGotPluginInfo() that continues the init task by
// loading Google Update statistics. Called on a blocking pool thread.
@@ -418,7 +415,7 @@
std::string hardware_class_;
// The list of plugins which was retrieved on the file thread.
- std::vector<webkit::WebPluginInfo> plugins_;
+ std::vector<content::WebPluginInfo> plugins_;
// Google Update statistics, which were retrieved on a blocking pool thread.
GoogleUpdateMetrics google_update_metrics_;
diff --git a/chrome/browser/metrics/metrics_service_unittest.cc b/chrome/browser/metrics/metrics_service_unittest.cc
index 51d4e34..3e13221 100644
--- a/chrome/browser/metrics/metrics_service_unittest.cc
+++ b/chrome/browser/metrics/metrics_service_unittest.cc
@@ -6,7 +6,7 @@
#include <string>
#include "base/command_line.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
diff --git a/chrome/browser/metrics/thread_watcher.cc b/chrome/browser/metrics/thread_watcher.cc
index 39dc136..c8ee4cf 100644
--- a/chrome/browser/metrics/thread_watcher.cc
+++ b/chrome/browser/metrics/thread_watcher.cc
@@ -63,10 +63,6 @@
NullPointerCrash(__LINE__);
}
-NOINLINE void ThreadUnresponsive_WEBKIT() {
- NullPointerCrash(__LINE__);
-}
-
NOINLINE void ThreadUnresponsive_FILE() {
NullPointerCrash(__LINE__);
}
@@ -98,8 +94,6 @@
return ThreadUnresponsive_UI();
case BrowserThread::DB:
return ThreadUnresponsive_DB();
- case BrowserThread::WEBKIT_DEPRECATED:
- return ThreadUnresponsive_WEBKIT();
case BrowserThread::FILE:
return ThreadUnresponsive_FILE();
case BrowserThread::FILE_USER_BLOCKING:
diff --git a/chrome/browser/metrics/thread_watcher.h b/chrome/browser/metrics/thread_watcher.h
index 487d6de..c1706fc 100644
--- a/chrome/browser/metrics/thread_watcher.h
+++ b/chrome/browser/metrics/thread_watcher.h
@@ -51,7 +51,7 @@
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/synchronization/lock.h"
#include "base/threading/platform_thread.h"
diff --git a/chrome/browser/metrics/thread_watcher_unittest.cc b/chrome/browser/metrics/thread_watcher_unittest.cc
index 6670722..f8cc88e 100644
--- a/chrome/browser/metrics/thread_watcher_unittest.cc
+++ b/chrome/browser/metrics/thread_watcher_unittest.cc
@@ -8,7 +8,7 @@
#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
@@ -238,24 +238,23 @@
static const TimeDelta kUnresponsiveTime;
static const BrowserThread::ID io_thread_id;
static const std::string io_thread_name;
- static const BrowserThread::ID webkit_thread_id;
- static const std::string webkit_thread_name;
+ static const BrowserThread::ID db_thread_id;
+ static const std::string db_thread_name;
static const std::string crash_on_hang_seconds;
static const std::string crash_on_hang_thread_names;
static const std::string thread_names_and_live_threshold;
static const std::string crash_on_hang_thread_data;
CustomThreadWatcher* io_watcher_;
- CustomThreadWatcher* webkit_watcher_;
+ CustomThreadWatcher* db_watcher_;
ThreadWatcherList* thread_watcher_list_;
ThreadWatcherTest()
: setup_complete_(&lock_),
initialized_(false) {
- webkit_thread_.reset(new content::TestBrowserThread(
- BrowserThread::WEBKIT_DEPRECATED));
+ db_thread_.reset(new content::TestBrowserThread(BrowserThread::DB));
io_thread_.reset(new content::TestBrowserThread(BrowserThread::IO));
watchdog_thread_.reset(new WatchDogThread());
- webkit_thread_->Start();
+ db_thread_->Start();
io_thread_->Start();
watchdog_thread_->Start();
@@ -277,10 +276,10 @@
kSleepTime, kUnresponsiveTime);
EXPECT_EQ(io_watcher_, thread_watcher_list_->Find(io_thread_id));
- // Create thread watcher object for the WEBKIT thread.
- webkit_watcher_ = new CustomThreadWatcher(
- webkit_thread_id, webkit_thread_name, kSleepTime, kUnresponsiveTime);
- EXPECT_EQ(webkit_watcher_, thread_watcher_list_->Find(webkit_thread_id));
+ // Create thread watcher object for the DB thread.
+ db_watcher_ = new CustomThreadWatcher(
+ db_thread_id, db_thread_name, kSleepTime, kUnresponsiveTime);
+ EXPECT_EQ(db_watcher_, thread_watcher_list_->Find(db_thread_id));
{
base::AutoLock lock(lock_);
@@ -302,9 +301,9 @@
virtual ~ThreadWatcherTest() {
ThreadWatcherList::DeleteAll();
io_watcher_ = NULL;
- webkit_watcher_ = NULL;
+ db_watcher_ = NULL;
io_thread_.reset();
- webkit_thread_.reset();
+ db_thread_.reset();
watchdog_thread_.reset();
thread_watcher_list_ = NULL;
}
@@ -313,7 +312,7 @@
base::Lock lock_;
base::ConditionVariable setup_complete_;
bool initialized_;
- scoped_ptr<content::TestBrowserThread> webkit_thread_;
+ scoped_ptr<content::TestBrowserThread> db_thread_;
scoped_ptr<content::TestBrowserThread> io_thread_;
scoped_ptr<WatchDogThread> watchdog_thread_;
};
@@ -325,9 +324,8 @@
TimeDelta::FromMilliseconds(500);
const BrowserThread::ID ThreadWatcherTest::io_thread_id = BrowserThread::IO;
const std::string ThreadWatcherTest::io_thread_name = "IO";
-const BrowserThread::ID ThreadWatcherTest::webkit_thread_id =
- BrowserThread::WEBKIT_DEPRECATED;
-const std::string ThreadWatcherTest::webkit_thread_name = "WEBKIT";
+const BrowserThread::ID ThreadWatcherTest::db_thread_id = BrowserThread::DB;
+const std::string ThreadWatcherTest::db_thread_name = "DB";
const std::string ThreadWatcherTest::crash_on_hang_thread_names = "UI,IO";
const std::string ThreadWatcherTest::thread_names_and_live_threshold =
"UI:4,IO:4";
@@ -441,12 +439,12 @@
EXPECT_EQ(kUnresponsiveTime, io_watcher_->unresponsive_time());
EXPECT_FALSE(io_watcher_->active());
- // Check ThreadWatcher object of watched WEBKIT thread has correct data.
- EXPECT_EQ(webkit_thread_id, webkit_watcher_->thread_id());
- EXPECT_EQ(webkit_thread_name, webkit_watcher_->thread_name());
- EXPECT_EQ(kSleepTime, webkit_watcher_->sleep_time());
- EXPECT_EQ(kUnresponsiveTime, webkit_watcher_->unresponsive_time());
- EXPECT_FALSE(webkit_watcher_->active());
+ // Check ThreadWatcher object of watched DB thread has correct data.
+ EXPECT_EQ(db_thread_id, db_watcher_->thread_id());
+ EXPECT_EQ(db_thread_name, db_watcher_->thread_name());
+ EXPECT_EQ(kSleepTime, db_watcher_->sleep_time());
+ EXPECT_EQ(kUnresponsiveTime, db_watcher_->unresponsive_time());
+ EXPECT_FALSE(db_watcher_->active());
}
// Test ActivateThreadWatching and DeActivateThreadWatching of IO thread. This
@@ -525,11 +523,11 @@
// Test watching of multiple threads with all threads not responding.
TEST_F(ThreadWatcherTest, MultipleThreadsResponding) {
- // Check for WEBKIT thread to perform ping/pong messaging.
+ // Check for DB thread to perform ping/pong messaging.
WatchDogThread::PostTask(
FROM_HERE,
base::Bind(&ThreadWatcher::ActivateThreadWatching,
- base::Unretained(webkit_watcher_)));
+ base::Unretained(db_watcher_)));
// Check for IO thread to perform ping/pong messaging.
WatchDogThread::PostTask(
@@ -537,14 +535,14 @@
base::Bind(&ThreadWatcher::ActivateThreadWatching,
base::Unretained(io_watcher_)));
- // Verify WEBKIT thread is responding with ping/pong messaging.
- webkit_watcher_->WaitForCheckResponse(
+ // Verify DB thread is responding with ping/pong messaging.
+ db_watcher_->WaitForCheckResponse(
kUnresponsiveTime + TimeDelta::FromMinutes(1), SUCCESSFUL);
- EXPECT_GT(webkit_watcher_->ping_sent_, static_cast<uint64>(0));
- EXPECT_GT(webkit_watcher_->pong_received_, static_cast<uint64>(0));
- EXPECT_GE(webkit_watcher_->ping_sequence_number_, static_cast<uint64>(0));
- EXPECT_GT(webkit_watcher_->success_response_, static_cast<uint64>(0));
- EXPECT_EQ(webkit_watcher_->failed_response_, static_cast<uint64>(0));
+ EXPECT_GT(db_watcher_->ping_sent_, static_cast<uint64>(0));
+ EXPECT_GT(db_watcher_->pong_received_, static_cast<uint64>(0));
+ EXPECT_GE(db_watcher_->ping_sequence_number_, static_cast<uint64>(0));
+ EXPECT_GT(db_watcher_->success_response_, static_cast<uint64>(0));
+ EXPECT_EQ(db_watcher_->failed_response_, static_cast<uint64>(0));
// Verify IO thread is responding with ping/pong messaging.
io_watcher_->WaitForCheckResponse(
@@ -564,7 +562,7 @@
WatchDogThread::PostTask(
FROM_HERE,
base::Bind(&ThreadWatcher::DeActivateThreadWatching,
- base::Unretained(webkit_watcher_)));
+ base::Unretained(db_watcher_)));
}
// Test watching of multiple threads with one of the threads not responding.
@@ -580,11 +578,11 @@
base::Unretained(io_watcher_),
kUnresponsiveTime * 10));
- // Activate watching of WEBKIT thread.
+ // Activate watching of DB thread.
WatchDogThread::PostTask(
FROM_HERE,
base::Bind(&ThreadWatcher::ActivateThreadWatching,
- base::Unretained(webkit_watcher_)));
+ base::Unretained(db_watcher_)));
// Activate watching of IO thread.
WatchDogThread::PostTask(
@@ -592,11 +590,11 @@
base::Bind(&ThreadWatcher::ActivateThreadWatching,
base::Unretained(io_watcher_)));
- // Verify WEBKIT thread is responding with ping/pong messaging.
- webkit_watcher_->WaitForCheckResponse(
+ // Verify DB thread is responding with ping/pong messaging.
+ db_watcher_->WaitForCheckResponse(
kUnresponsiveTime + TimeDelta::FromMinutes(1), SUCCESSFUL);
- EXPECT_GT(webkit_watcher_->success_response_, static_cast<uint64>(0));
- EXPECT_EQ(webkit_watcher_->failed_response_, static_cast<uint64>(0));
+ EXPECT_GT(db_watcher_->success_response_, static_cast<uint64>(0));
+ EXPECT_EQ(db_watcher_->failed_response_, static_cast<uint64>(0));
// Verify IO thread is not responding for ping messages.
io_watcher_->WaitForCheckResponse(
@@ -612,7 +610,7 @@
WatchDogThread::PostTask(
FROM_HERE,
base::Bind(&ThreadWatcher::DeActivateThreadWatching,
- base::Unretained(webkit_watcher_)));
+ base::Unretained(db_watcher_)));
// Wait for the io_watcher_'s VeryLongMethod to finish.
io_watcher_->WaitForWaitStateChange(kUnresponsiveTime * 10, ALL_DONE);
diff --git a/chrome/browser/metrics/variations/variations_request_scheduler_unittest.cc b/chrome/browser/metrics/variations/variations_request_scheduler_unittest.cc
index f69a0b8..493275b 100644
--- a/chrome/browser/metrics/variations/variations_request_scheduler_unittest.cc
+++ b/chrome/browser/metrics/variations/variations_request_scheduler_unittest.cc
@@ -5,7 +5,7 @@
#include "chrome/browser/metrics/variations/variations_request_scheduler.h"
#include "base/bind.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chrome_variations {
diff --git a/chrome/browser/nacl_host/nacl_broker_host_win.cc b/chrome/browser/nacl_host/nacl_broker_host_win.cc
index f0eca4d..bcb250b 100644
--- a/chrome/browser/nacl_host/nacl_broker_host_win.cc
+++ b/chrome/browser/nacl_host/nacl_broker_host_win.cc
@@ -10,8 +10,8 @@
#include "ipc/ipc_switches.h"
#include "chrome/browser/nacl_host/nacl_broker_service_win.h"
#include "chrome/browser/nacl_host/nacl_browser.h"
-#include "chrome/common/nacl_cmd_line.h"
#include "chrome/common/nacl_messages.h"
+#include "components/nacl/common/nacl_cmd_line.h"
#include "components/nacl/common/nacl_process_type.h"
#include "components/nacl/common/nacl_switches.h"
#include "content/public/browser/browser_child_process_host.h"
diff --git a/chrome/browser/nacl_host/nacl_browser.cc b/chrome/browser/nacl_host/nacl_browser.cc
index ea9ea0f..8460124 100644
--- a/chrome/browser/nacl_host/nacl_browser.cc
+++ b/chrome/browser/nacl_host/nacl_browser.cc
@@ -6,7 +6,7 @@
#include "base/command_line.h"
#include "base/file_util.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/path_service.h"
#include "base/pickle.h"
diff --git a/chrome/browser/nacl_host/nacl_file_host.cc b/chrome/browser/nacl_host/nacl_file_host.cc
index 18efee9..ca1feb9 100644
--- a/chrome/browser/nacl_host/nacl_file_host.cc
+++ b/chrome/browser/nacl_host/nacl_file_host.cc
@@ -145,38 +145,6 @@
nacl_host_message_filter->Send(reply_msg);
}
-IPC::PlatformFileForTransit GetTemporaryFile(
- scoped_refptr<NaClHostMessageFilter> nacl_host_message_filter) {
- DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
-
- base::FilePath file_path;
- if (!file_util::CreateTemporaryFile(&file_path))
- return IPC::InvalidPlatformFileForTransit();
-
- base::PlatformFileError error;
- base::PlatformFile file_handle = base::CreatePlatformFile(
- file_path,
- base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_READ |
- base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_TEMPORARY |
- base::PLATFORM_FILE_DELETE_ON_CLOSE,
- NULL, &error);
-
- if (error != base::PLATFORM_FILE_OK)
- return IPC::InvalidPlatformFileForTransit();
-
- // Do any DuplicateHandle magic that is necessary first.
- return IPC::GetFileHandleForProcess(file_handle,
- nacl_host_message_filter->PeerHandle(),
- true);
-}
-
-void ReturnTemporaryFileOnIOThread(
- nacl_file_host::TempFileCallback cb,
- IPC::PlatformFileForTransit fd) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- cb.Run(fd);
-}
-
void DoRegisterOpenedNaClExecutableFile(
scoped_refptr<NaClHostMessageFilter> nacl_host_message_filter,
base::PlatformFile file,
@@ -209,8 +177,7 @@
base::FilePath* file_path) {
// Check that the URL is recognized by the extension system.
const extensions::Extension* extension =
- extension_info_map->extensions().GetExtensionOrAppByURL(
- ExtensionURLInfo(file_url));
+ extension_info_map->extensions().GetExtensionOrAppByURL(file_url);
if (!extension)
return false;
@@ -334,19 +301,6 @@
return true;
}
-void CreateTemporaryFile(
- scoped_refptr<NaClHostMessageFilter> nacl_host_message_filter,
- TempFileCallback cb) {
- if (!base::PostTaskAndReplyWithResult(
- BrowserThread::GetBlockingPool(),
- FROM_HERE,
- base::Bind(&GetTemporaryFile, nacl_host_message_filter),
- base::Bind(&ReturnTemporaryFileOnIOThread, cb))) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- cb.Run(IPC::InvalidPlatformFileForTransit());
- }
-}
-
void OpenNaClExecutable(
scoped_refptr<NaClHostMessageFilter> nacl_host_message_filter,
scoped_refptr<ExtensionInfoMap> extension_info_map,
diff --git a/chrome/browser/nacl_host/nacl_file_host.h b/chrome/browser/nacl_host/nacl_file_host.h
index b27a87e..ee473cc 100644
--- a/chrome/browser/nacl_host/nacl_file_host.h
+++ b/chrome/browser/nacl_host/nacl_file_host.h
@@ -7,9 +7,8 @@
#include <string>
-#include "base/callback.h"
+#include "base/callback_forward.h"
#include "base/memory/ref_counted.h"
-#include "ipc/ipc_platform_file.h"
class ExtensionInfoMap;
class GURL;
@@ -26,7 +25,6 @@
// Opens NaCl Files in the Browser process, on behalf of the NaCl plugin.
namespace nacl_file_host {
-typedef base::Callback<void(IPC::PlatformFileForTransit)> TempFileCallback;
// Open a Pnacl file (readonly) on behalf of the NaCl plugin.
void GetReadonlyPnaclFd(
@@ -39,12 +37,6 @@
bool PnaclCanOpenFile(const std::string& filename,
base::FilePath* file_to_open);
-// Creates a temporary file that will be deleted when the last handle
-// is closed, or earlier.
-void CreateTemporaryFile(
- scoped_refptr<NaClHostMessageFilter> nacl_host_message_filter,
- TempFileCallback cb);
-
// Opens a NaCl executable file for reading and executing.
void OpenNaClExecutable(
scoped_refptr<NaClHostMessageFilter> nacl_host_message_filter,
diff --git a/chrome/browser/nacl_host/nacl_host_message_filter.cc b/chrome/browser/nacl_host/nacl_host_message_filter.cc
index 01cc5f8..ceecc2a 100644
--- a/chrome/browser/nacl_host/nacl_host_message_filter.cc
+++ b/chrome/browser/nacl_host/nacl_host_message_filter.cc
@@ -8,6 +8,7 @@
#include "chrome/browser/nacl_host/nacl_browser.h"
#include "chrome/browser/nacl_host/nacl_file_host.h"
#include "chrome/browser/nacl_host/nacl_process_host.h"
+#include "chrome/browser/nacl_host/pnacl_host.h"
#include "chrome/common/nacl_host_messages.h"
#include "extensions/common/constants.h"
#include "net/url_request/url_request_context.h"
@@ -17,7 +18,7 @@
ExtensionInfoMap* extension_info_map, const std::string& manifest) {
GURL manifest_url(manifest);
const extensions::Extension* extension = extension_info_map->extensions()
- .GetExtensionOrAppByURL(ExtensionURLInfo(manifest_url));
+ .GetExtensionOrAppByURL(manifest_url);
if (extension != NULL &&
manifest_url.SchemeIs(extensions::kExtensionScheme)) {
std::string path = manifest_url.path();
@@ -44,6 +45,11 @@
NaClHostMessageFilter::~NaClHostMessageFilter() {
}
+void NaClHostMessageFilter::OnChannelClosing() {
+ PnaclHost::GetInstance()->RendererClosing(render_process_id_);
+ BrowserMessageFilter::OnChannelClosing();
+}
+
bool NaClHostMessageFilter::OnMessageReceived(const IPC::Message& message,
bool* message_was_ok) {
bool handled = true;
@@ -95,6 +101,10 @@
// This posts a task to another thread, but the renderer will
// block until the reply is sent.
nacl_file_host::GetReadonlyPnaclFd(this, filename, reply_msg);
+
+ // This is the first message we receive from the renderer once it knows we
+ // want to use PNaCl, so start the translation cache initialization here.
+ PnaclHost::GetInstance()->Init();
}
// Return the temporary file via a reply to the
@@ -113,8 +123,8 @@
void NaClHostMessageFilter::OnNaClCreateTemporaryFile(
IPC::Message* reply_msg) {
- nacl_file_host::CreateTemporaryFile(
- this,
+ PnaclHost::GetInstance()->CreateTemporaryFile(
+ PeerHandle(),
base::Bind(&NaClHostMessageFilter::SyncReturnTemporaryFile,
this,
reply_msg));
@@ -122,28 +132,40 @@
// For now, GetNexeFd cache requests always set is_hit to false and returns
// a new temporary file via a NaClViewMsg_NexeTempFileReply message.
-// A future CL will implement the cache lookup logic.
+// A future CL will implement the cache lookup logic (and use the currently-
+// unused parameters)
// See also https://code.google.com/p/nativeclient/issues/detail?id=3372
void NaClHostMessageFilter::AsyncReturnTemporaryFile(
- int render_view_id,
- IPC::PlatformFileForTransit fd) {
- Send(new NaClViewMsg_NexeTempFileReply(render_view_id, false, fd));
+ int pp_instance,
+ IPC::PlatformFileForTransit fd,
+ bool is_hit) {
+ Send(new NaClViewMsg_NexeTempFileReply(pp_instance, is_hit, fd));
}
void NaClHostMessageFilter::OnGetNexeFd(
int render_view_id,
+ int pp_instance,
const nacl::PnaclCacheInfo& cache_info) {
- nacl_file_host::CreateTemporaryFile(
- this,
+ if (!cache_info.pexe_url.is_valid()) {
+ LOG(ERROR) << "Bad URL received from GetNexeFd: " <<
+ cache_info.pexe_url.possibly_invalid_spec();
+ BadMessageReceived();
+ return;
+ }
+ PnaclHost::GetInstance()->GetNexeFd(
+ render_process_id_,
+ PeerHandle(),
+ render_view_id,
+ pp_instance,
+ cache_info,
base::Bind(&NaClHostMessageFilter::AsyncReturnTemporaryFile,
this,
- render_view_id));
+ pp_instance));
}
-// For now, ignore translation finished messages. A future CL will implement
-// the logic of reading the nexe from the temp file and storing it in the cache.
-// See also https://code.google.com/p/nativeclient/issues/detail?id=3372
-void NaClHostMessageFilter::OnTranslationFinished(int render_view_id) {
+void NaClHostMessageFilter::OnTranslationFinished(int instance) {
+ PnaclHost::GetInstance()->TranslationFinished(
+ render_process_id_, instance);
}
void NaClHostMessageFilter::OnNaClErrorStatus(int render_view_id,
diff --git a/chrome/browser/nacl_host/nacl_host_message_filter.h b/chrome/browser/nacl_host/nacl_host_message_filter.h
index 8c99c55..66af82d 100644
--- a/chrome/browser/nacl_host/nacl_host_message_filter.h
+++ b/chrome/browser/nacl_host/nacl_host_message_filter.h
@@ -36,6 +36,7 @@
// content::BrowserMessageFilter methods:
virtual bool OnMessageReceived(const IPC::Message& message,
bool* message_was_ok) OVERRIDE;
+ virtual void OnChannelClosing() OVERRIDE;
int render_process_id() { return render_process_id_; }
bool off_the_record() { return off_the_record_; }
@@ -53,8 +54,10 @@
void OnGetReadonlyPnaclFd(const std::string& filename,
IPC::Message* reply_msg);
void OnNaClCreateTemporaryFile(IPC::Message* reply_msg);
- void OnGetNexeFd(int render_view_id, const nacl::PnaclCacheInfo& cache_info);
- void OnTranslationFinished(int render_view_id);
+ void OnGetNexeFd(int render_view_id,
+ int pp_instance,
+ const nacl::PnaclCacheInfo& cache_info);
+ void OnTranslationFinished(int instance);
void OnNaClErrorStatus(int render_view_id, int error_id);
void OnOpenNaClExecutable(int render_view_id,
const GURL& file_url,
@@ -62,8 +65,9 @@
void SyncReturnTemporaryFile(IPC::Message* reply_msg,
IPC::PlatformFileForTransit fd);
- void AsyncReturnTemporaryFile(int render_view_id,
- IPC::PlatformFileForTransit fd);
+ void AsyncReturnTemporaryFile(int pp_instance,
+ IPC::PlatformFileForTransit fd,
+ bool is_hit);
#endif
int render_process_id_;
diff --git a/chrome/browser/nacl_host/nacl_infobar_delegate.cc b/chrome/browser/nacl_host/nacl_infobar_delegate.cc
index b9e08b8..fecad03 100644
--- a/chrome/browser/nacl_host/nacl_infobar_delegate.cc
+++ b/chrome/browser/nacl_host/nacl_infobar_delegate.cc
@@ -24,9 +24,10 @@
return;
InfoBarService* infobar_service =
InfoBarService::FromWebContents(web_contents);
- if (infobar_service)
+ if (infobar_service) {
infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
new NaClInfoBarDelegate(infobar_service)));
+ }
}
NaClInfoBarDelegate::NaClInfoBarDelegate(InfoBarService* infobar_service)
diff --git a/chrome/browser/nacl_host/nacl_infobar_delegate.h b/chrome/browser/nacl_host/nacl_infobar_delegate.h
index c3da4d4..2b3b4e9 100644
--- a/chrome/browser/nacl_host/nacl_infobar_delegate.h
+++ b/chrome/browser/nacl_host/nacl_infobar_delegate.h
@@ -9,8 +9,8 @@
class NaClInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
- // Creates a NaCl delegate and adds it to the infobar service corresponding to
- // the given render process and view IDs.
+ // Creates a NaCl infobar delegate and adds it to the infobar service
+ // corresponding to the given render process and view IDs.
static void Create(int render_process_id, int render_view_id);
private:
diff --git a/chrome/browser/nacl_host/nacl_process_host.cc b/chrome/browser/nacl_host/nacl_process_host.cc
index df54445..ee67c58 100644
--- a/chrome/browser/nacl_host/nacl_process_host.cc
+++ b/chrome/browser/nacl_host/nacl_process_host.cc
@@ -12,7 +12,7 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/file_util.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/path_service.h"
#include "base/process_util.h"
@@ -25,10 +25,10 @@
#include "build/build_config.h"
#include "chrome/browser/nacl_host/nacl_browser.h"
#include "chrome/browser/nacl_host/nacl_host_message_filter.h"
-#include "chrome/common/nacl_cmd_line.h"
#include "chrome/common/nacl_host_messages.h"
#include "chrome/common/nacl_messages.h"
#include "components/nacl/common/nacl_browser_delegate.h"
+#include "components/nacl/common/nacl_cmd_line.h"
#include "components/nacl/common/nacl_process_type.h"
#include "components/nacl/common/nacl_switches.h"
#include "content/public/browser/browser_child_process_host.h"
@@ -289,8 +289,8 @@
NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
nacl_browser->EnsureAllResourcesAvailable();
if (!nacl_browser->IsOk()) {
- LOG(ERROR) << "NaCl process launch failed: could not find all the "
- "resources needed to launch the process";
+ SendErrorToRenderer("could not find all the resources needed"
+ " to launch the process");
delete this;
return;
}
@@ -307,7 +307,7 @@
NaClHandle pair[2];
// Create a connected socket
if (NaClSocketPair(pair) == -1) {
- LOG(ERROR) << "NaCl process launch failed: could not create a socket pair";
+ SendErrorToRenderer("NaClSocketPair() failed");
delete this;
return;
}
@@ -393,7 +393,7 @@
bool NaClProcessHost::LaunchSelLdr() {
std::string channel_id = process_->GetHost()->CreateChannel();
if (channel_id.empty()) {
- LOG(ERROR) << "NaCl process launch failed: could not create channel";
+ SendErrorToRenderer("CreateChannel() failed");
return false;
}
@@ -428,6 +428,7 @@
// On Windows 64-bit NaCl loader is called nacl64.exe instead of chrome.exe
if (RunningOnWOW64()) {
if (!NaClBrowser::GetInstance()->GetNaCl64ExePath(&exe_path)) {
+ SendErrorToRenderer("could not get path to nacl64.exe");
return false;
}
}
@@ -450,8 +451,7 @@
if (RunningOnWOW64()) {
if (!NaClBrokerService::GetInstance()->LaunchLoader(
weak_factory_.GetWeakPtr(), channel_id)) {
- LOG(ERROR) << "NaCl process launch failed: broker service did not launch "
- "process";
+ SendErrorToRenderer("broker service did not launch process");
return false;
}
} else {
@@ -496,8 +496,7 @@
void NaClProcessHost::OnResourcesReady() {
NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
if (!nacl_browser->IsReady()) {
- LOG(ERROR) << "NaCl process launch failed: could not acquire shared "
- "resources needed by NaCl";
+ SendErrorToRenderer("could not acquire shared resources needed by NaCl");
delete this;
} else if (!SendStart()) {
delete this;
@@ -514,7 +513,7 @@
// BrokerDuplicateHandle().
if (RunningOnWOW64()) {
if (!content::BrokerAddTargetPeer(process_->GetData().handle)) {
- LOG(ERROR) << "Failed to add NaCl process PID";
+ SendErrorToRenderer("BrokerAddTargetPeer() failed");
return false;
}
}
@@ -532,7 +531,7 @@
0, // Unused given DUPLICATE_SAME_ACCESS.
FALSE,
DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
- LOG(ERROR) << "DuplicateHandle() failed";
+ SendErrorToRenderer("DuplicateHandle() failed");
return false;
}
handle_for_renderer = reinterpret_cast<nacl::FileDescriptor>(
@@ -547,16 +546,35 @@
#endif
const ChildProcessData& data = process_->GetData();
- NaClHostMsg_LaunchNaCl::WriteReplyParams(
- reply_msg_, handle_for_renderer,
- channel_handle, base::GetProcId(data.handle), data.id);
- nacl_host_message_filter_->Send(reply_msg_);
- nacl_host_message_filter_ = NULL;
- reply_msg_ = NULL;
+ SendMessageToRenderer(
+ nacl::NaClLaunchResult(handle_for_renderer,
+ channel_handle,
+ base::GetProcId(data.handle),
+ data.id),
+ std::string() /* error_message */);
internal_->socket_for_renderer = NACL_INVALID_HANDLE;
return true;
}
+void NaClProcessHost::SendErrorToRenderer(const std::string& error_message) {
+ LOG(ERROR) << "NaCl process launch failed: " << error_message;
+ SendMessageToRenderer(nacl::NaClLaunchResult(), error_message);
+}
+
+void NaClProcessHost::SendMessageToRenderer(
+ const nacl::NaClLaunchResult& result,
+ const std::string& error_message) {
+ DCHECK(nacl_host_message_filter_);
+ DCHECK(reply_msg_);
+ if (nacl_host_message_filter_ != NULL && reply_msg_ != NULL) {
+ NaClHostMsg_LaunchNaCl::WriteReplyParams(
+ reply_msg_, result, error_message);
+ nacl_host_message_filter_->Send(reply_msg_);
+ nacl_host_message_filter_ = NULL;
+ reply_msg_ = NULL;
+ }
+}
+
// TCP port we chose for NaCl debug stub. It can be any other number.
static const int kDebugStubPort = 4014;
@@ -755,8 +773,7 @@
weak_factory_.GetWeakPtr()));
return true;
} else {
- LOG(ERROR) << "NaCl process failed to launch: previously failed to acquire "
- "shared resources";
+ SendErrorToRenderer("previously failed to acquire shared resources");
return false;
}
}
diff --git a/chrome/browser/nacl_host/nacl_process_host.h b/chrome/browser/nacl_host/nacl_process_host.h
index d68693d..1250b3c 100644
--- a/chrome/browser/nacl_host/nacl_process_host.h
+++ b/chrome/browser/nacl_host/nacl_process_host.h
@@ -11,7 +11,7 @@
#include "base/files/file_util_proxy.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/process.h"
#include "chrome/common/nacl_types.h"
#include "content/public/browser/browser_child_process_host_delegate.h"
@@ -123,6 +123,14 @@
// to load. Returns true on success.
bool ReplyToRenderer(const IPC::ChannelHandle& channel_handle);
+ // Sends the reply with error message to the renderer.
+ void SendErrorToRenderer(const std::string& error_message);
+
+ // Sends the reply message to the renderer. Either result or
+ // error message must be empty.
+ void SendMessageToRenderer(const nacl::NaClLaunchResult& result,
+ const std::string& error_message);
+
// Sends the message to the NaCl process to load the plugin. Returns true
// on success.
bool StartNaClExecution();
diff --git a/chrome/browser/nacl_host/pnacl_host.cc b/chrome/browser/nacl_host/pnacl_host.cc
new file mode 100644
index 0000000..f3b7de2
--- /dev/null
+++ b/chrome/browser/nacl_host/pnacl_host.cc
@@ -0,0 +1,208 @@
+// Copyright 2013 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/nacl_host/pnacl_host.h"
+
+#include "base/bind.h"
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/logging.h"
+#include "base/task_runner_util.h"
+#include "base/threading/sequenced_worker_pool.h"
+#include "chrome/browser/nacl_host/nacl_browser.h"
+#include "chrome/browser/nacl_host/pnacl_translation_cache.h"
+#include "content/public/browser/browser_thread.h"
+#include "net/base/net_errors.h"
+
+using content::BrowserThread;
+
+namespace {
+static const base::FilePath::CharType kTranslationCacheDirectoryName[] =
+ FILE_PATH_LITERAL("PnaclTranslationCache");
+}
+
+PnaclHost::PnaclHost()
+ : cache_state_(CacheUninitialized), weak_factory_(this) {}
+
+PnaclHost::~PnaclHost() {}
+
+PnaclHost* PnaclHost::GetInstance() { return Singleton<PnaclHost>::get(); }
+
+PnaclHost::PendingTranslation::PendingTranslation() {}
+PnaclHost::PendingTranslation::~PendingTranslation() {}
+
+/////////////////////////////////////// Initialization
+
+static base::FilePath GetCachePath() {
+ NaClBrowserDelegate* browser_delegate = NaClBrowser::GetDelegate();
+ // Determine where the translation cache resides in the file system. It
+ // exists in Chrome's cache directory and is not tied to any specific
+ // profile. If we fail, return an empty path.
+ // Start by finding the user data directory.
+ base::FilePath user_data_dir;
+ if (!browser_delegate ||
+ !browser_delegate->GetUserDirectory(&user_data_dir)) {
+ return base::FilePath();
+ }
+ // The cache directory may or may not be the user data directory.
+ base::FilePath cache_file_path;
+ browser_delegate->GetCacheDirectory(&cache_file_path);
+
+ // Append the base file name to the cache directory.
+ return cache_file_path.Append(kTranslationCacheDirectoryName);
+}
+
+void PnaclHost::OnCacheInitialized(int error) {
+ // If the cache was cleared before the load completed, ignore.
+ if (cache_state_ == CacheReady)
+ return;
+ if (error != net::OK) {
+ LOG(ERROR) << "PNaCl translation cache initalization failure: " << error
+ << "\n";
+ } else {
+ cache_state_ = CacheReady;
+ }
+}
+
+void PnaclHost::Init() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ base::FilePath cache_path(GetCachePath());
+ if (cache_path.empty() || cache_state_ != CacheUninitialized)
+ return;
+ disk_cache_.reset(new pnacl::PnaclTranslationCache());
+ cache_state_ = CacheInitializing;
+ disk_cache_->InitCache(
+ cache_path,
+ true,
+ base::Bind(&PnaclHost::OnCacheInitialized, weak_factory_.GetWeakPtr()));
+}
+
+// Initialize using the in-memory backend, and manually set the temporary file
+// directory instead of using the system directory.
+void PnaclHost::InitForTest(base::FilePath temp_dir) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ disk_cache_.reset(new pnacl::PnaclTranslationCache());
+ cache_state_ = CacheInitializing;
+ temp_dir_ = temp_dir;
+ disk_cache_->InitCache(
+ temp_dir,
+ true, // Use in-memory backend
+ base::Bind(&PnaclHost::OnCacheInitialized, weak_factory_.GetWeakPtr()));
+}
+
+///////////////////////////////////////// Temp files
+
+// Create a temporary file on the blocking pool
+IPC::PlatformFileForTransit PnaclHost::DoCreateTemporaryFile(
+ base::ProcessHandle process_handle,
+ base::FilePath temp_dir) {
+ DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
+
+ base::FilePath file_path;
+ bool rv = temp_dir.empty()
+ ? file_util::CreateTemporaryFileInDir(temp_dir, &file_path)
+ : file_util::CreateTemporaryFile(&file_path);
+ if (!rv)
+ return IPC::InvalidPlatformFileForTransit();
+
+ base::PlatformFileError error;
+ base::PlatformFile file_handle(base::CreatePlatformFile(
+ file_path,
+ base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_READ |
+ base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_TEMPORARY |
+ base::PLATFORM_FILE_DELETE_ON_CLOSE,
+ NULL,
+ &error));
+
+ if (error != base::PLATFORM_FILE_OK)
+ return IPC::InvalidPlatformFileForTransit();
+
+ // Do any DuplicateHandle magic that is necessary first.
+ return IPC::GetFileHandleForProcess(file_handle, process_handle, true);
+}
+
+void PnaclHost::CreateTemporaryFile(base::ProcessHandle process_handle,
+ TempFileCallback cb) {
+ if (!base::PostTaskAndReplyWithResult(
+ BrowserThread::GetBlockingPool(),
+ FROM_HERE,
+ base::Bind(
+ &PnaclHost::DoCreateTemporaryFile, process_handle, temp_dir_),
+ cb)) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ cb.Run(IPC::InvalidPlatformFileForTransit());
+ }
+}
+
+///////////////////////////////////////// GetNexeFd implementation
+
+void PnaclHost::ReturnMiss(TranslationID id, IPC::PlatformFileForTransit fd) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ PendingTranslationMap::iterator entry(pending_translations_.find(id));
+ if (entry == pending_translations_.end()) {
+ LOG(ERROR) << "PnaclHost::ReturnMiss: Failed to find TranslationID "
+ << id.first << "," << id.second;
+ return;
+ }
+ NexeFdCallback cb(entry->second.callback);
+ if (fd == IPC::InvalidPlatformFileForTransit()) {
+ pending_translations_.erase(entry);
+ } else {
+ entry->second.nexe_fd = fd;
+ }
+ cb.Run(fd, false);
+}
+
+void PnaclHost::GetNexeFd(int render_process_id,
+ base::ProcessHandle process_handle,
+ int render_view_id,
+ int pp_instance,
+ const nacl::PnaclCacheInfo& cache_info,
+ const NexeFdCallback& cb) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (cache_state_ != CacheReady)
+ return;
+ PendingTranslation pt;
+ pt.render_view_id = render_view_id;
+ pt.callback = cb;
+ pt.cache_info = cache_info;
+
+ pending_translations_[TranslationID(render_process_id, pp_instance)] = pt;
+
+ CreateTemporaryFile(
+ process_handle,
+ base::Bind(&PnaclHost::ReturnMiss,
+ weak_factory_.GetWeakPtr(),
+ TranslationID(render_process_id, pp_instance)));
+}
+
+/////////////////// Cleanup
+
+void PnaclHost::TranslationFinished(int render_process_id, int pp_instance) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (cache_state_ != CacheReady)
+ return;
+ PendingTranslationMap::iterator it(pending_translations_.find(
+ TranslationID(render_process_id, pp_instance)));
+ if (it == pending_translations_.end()) {
+ LOG(ERROR) << "TranslationFinished: TranslationID " << render_process_id
+ << "," << pp_instance << " not found.";
+ } else {
+ pending_translations_.erase(it);
+ }
+}
+
+void PnaclHost::RendererClosing(int render_process_id) {
+ if (cache_state_ != CacheReady)
+ return;
+ DCHECK(thread_checker_.CalledOnValidThread());
+ for (PendingTranslationMap::iterator it = pending_translations_.begin();
+ it != pending_translations_.end();) {
+ PendingTranslationMap::iterator to_erase(it++);
+ if (to_erase->first.first == render_process_id) {
+ // clean up the open files
+ pending_translations_.erase(to_erase);
+ }
+ }
+}
diff --git a/chrome/browser/nacl_host/pnacl_host.h b/chrome/browser/nacl_host/pnacl_host.h
new file mode 100644
index 0000000..b55c9a6
--- /dev/null
+++ b/chrome/browser/nacl_host/pnacl_host.h
@@ -0,0 +1,114 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_NACL_HOST_PNACL_HOST_H_
+#define CHROME_BROWSER_NACL_HOST_PNACL_HOST_H_
+
+#include <map>
+
+#include "base/callback_forward.h"
+#include "base/memory/singleton.h"
+#include "base/memory/weak_ptr.h"
+#include "base/threading/thread_checker.h"
+#include "chrome/browser/nacl_host/nacl_file_host.h"
+#include "chrome/common/pnacl_types.h"
+#include "ipc/ipc_platform_file.h"
+
+namespace pnacl {
+class PnaclHostTest;
+class PnaclTranslationCache;
+}
+
+// Shared state (translation cache) and common utilities (temp file creation)
+// for all PNaCl translations. Unless otherwise specified, all methods should be
+// called on the IO thread.
+class PnaclHost {
+ public:
+ typedef base::Callback<void(IPC::PlatformFileForTransit)> TempFileCallback;
+ typedef base::Callback<void(IPC::PlatformFileForTransit, bool is_hit)>
+ NexeFdCallback;
+
+ static PnaclHost* GetInstance();
+
+ PnaclHost();
+ ~PnaclHost();
+ void Init();
+
+ // Creates a temporary file that will be deleted when the last handle
+ // is closed, or earlier. Returns a PlatformFileForTransit usable by the
+ // process identified by |process_handle|.
+ void CreateTemporaryFile(base::ProcessHandle process_handle,
+ TempFileCallback cb);
+
+ // Create a temporary file, which will be deleted by the time the last
+ // handle is closed (or earlier on POSIX systems), to use for the nexe
+ // with the cache information given in |cache_info|. The specific instance
+ // is identified by the combination of |render_process_id| and |pp_instance|.
+ // Returns by calling |cb| with a PlatformFileForTransit usable by the process
+ // identified by |process_handle|. If the nexe is already present
+ // in the cache, |is_hit| is set to true and the contents of the nexe
+ // have been copied into the temporary file. Otherwise |is_hit| is set to
+ // false and the temporary file will be writeable.
+ // Currently the implementation is a stub, which always sets is_hit to false
+ // and calls the implementation of CreateTemporaryFile.
+ // If the cache request was a miss, the caller is expected to call
+ // TranslationFinished after it finishes translation to allow the nexe to be
+ // stored in the cache.
+ void GetNexeFd(int render_process_id,
+ base::ProcessHandle process_handle,
+ int render_view_id,
+ int pp_instance,
+ const nacl::PnaclCacheInfo& cache_info,
+ const NexeFdCallback& cb);
+
+ // Called after the translation of a pexe instance identified by
+ // |render_process_id| and |pp_instance| finishes. Store the nexe translated
+ // for the instance in the cache.
+ void TranslationFinished(int render_process_id, int pp_instance);
+
+ // Called when the renderer identified by |render_process_id| is closing.
+ // Clean up any outstanding translations for that renderer.
+ void RendererClosing(int render_process_id);
+
+ private:
+ // PnaclHost is a singleton because there is only one translation cache, and
+ // so that the BrowsingDataRemover can clear it even if no translation has
+ // ever been started.
+ friend struct DefaultSingletonTraits<PnaclHost>;
+ friend class pnacl::PnaclHostTest;
+ enum CacheState {
+ CacheUninitialized,
+ CacheInitializing,
+ CacheReady
+ };
+ struct PendingTranslation {
+ public:
+ PendingTranslation();
+ ~PendingTranslation();
+ int render_view_id;
+ IPC::PlatformFileForTransit nexe_fd;
+ NexeFdCallback callback;
+ nacl::PnaclCacheInfo cache_info;
+ };
+
+ typedef std::pair<int, int> TranslationID;
+ typedef std::map<TranslationID, PendingTranslation> PendingTranslationMap;
+
+ void InitForTest(base::FilePath temp_dir);
+ void OnCacheInitialized(int error);
+ static IPC::PlatformFileForTransit DoCreateTemporaryFile(
+ base::ProcessHandle process_handle,
+ base::FilePath temp_dir_);
+ void ReturnMiss(TranslationID id, IPC::PlatformFileForTransit fd);
+
+ CacheState cache_state_;
+ base::FilePath temp_dir_;
+ scoped_ptr<pnacl::PnaclTranslationCache> disk_cache_;
+ PendingTranslationMap pending_translations_;
+ base::ThreadChecker thread_checker_;
+ base::WeakPtrFactory<PnaclHost> weak_factory_;
+ DISALLOW_COPY_AND_ASSIGN(PnaclHost);
+};
+
+#endif // CHROME_BROWSER_NACL_HOST_PNACL_HOST_H_
diff --git a/chrome/browser/nacl_host/pnacl_host_unittest.cc b/chrome/browser/nacl_host/pnacl_host_unittest.cc
new file mode 100644
index 0000000..7796aa6
--- /dev/null
+++ b/chrome/browser/nacl_host/pnacl_host_unittest.cc
@@ -0,0 +1,103 @@
+// Copyright 2013 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/nacl_host/pnacl_host.h"
+
+#include "base/bind.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/run_loop.h"
+#include "base/threading/sequenced_worker_pool.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace pnacl {
+
+class PnaclHostTest : public testing::Test {
+ protected:
+ PnaclHostTest()
+ : temp_callback_count_(0),
+ thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
+ virtual void SetUp() {
+ host_ = new PnaclHost();
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ host_->InitForTest(temp_dir_.path());
+ EXPECT_EQ(host_->cache_state_, PnaclHost::CacheReady);
+ }
+ virtual void TearDown() {
+ ExpectPendingTranslations(0);
+ delete host_;
+ }
+ // Utilities for inspecting internal state of the pnacl host
+ void ExpectPendingTranslations(size_t count) {
+ EXPECT_EQ(count, host_->pending_translations_.size());
+ }
+ void ExpectCallbackCount(int count) {
+ EXPECT_EQ(count, temp_callback_count_);
+ }
+
+ public: // Required for derived classes to bind this method
+ void CallbackExpectMiss(IPC::PlatformFileForTransit fd, bool is_hit) {
+ temp_callback_count_++;
+ EXPECT_FALSE(is_hit);
+ EXPECT_FALSE(fd == IPC::InvalidPlatformFileForTransit());
+ }
+
+ protected:
+ PnaclHost* host_;
+ int temp_callback_count_;
+ content::TestBrowserThreadBundle thread_bundle_;
+ base::ScopedTempDir temp_dir_;
+};
+
+#define EXPECT_PENDING_TRANSLATIONS(n) \
+ do { \
+ SCOPED_TRACE(""); \
+ ExpectPendingTranslations(n); \
+ } while (0)
+
+// We don't do actual caching yet, but just return a new temp file with a miss
+TEST_F(PnaclHostTest, BasicMiss) {
+ nacl::PnaclCacheInfo info;
+ host_->GetNexeFd(
+ 0,
+ base::ProcessHandle(),
+ 0,
+ 0,
+ info,
+ base::Bind(&PnaclHostTest::CallbackExpectMiss, base::Unretained(this)));
+
+ EXPECT_PENDING_TRANSLATIONS(1);
+ content::BrowserThread::GetBlockingPool()->FlushForTesting();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_PENDING_TRANSLATIONS(1);
+ ExpectCallbackCount(1);
+ host_->TranslationFinished(0, 0);
+ EXPECT_PENDING_TRANSLATIONS(0);
+ host_->RendererClosing(0);
+}
+
+TEST_F(PnaclHostTest, BadArguments) {
+ nacl::PnaclCacheInfo info;
+ host_->GetNexeFd(
+ 0,
+ base::ProcessHandle(),
+ 0,
+ 0,
+ info,
+ base::Bind(&PnaclHostTest::CallbackExpectMiss, base::Unretained(this)));
+
+ EXPECT_PENDING_TRANSLATIONS(1);
+ host_->TranslationFinished(0, 1); // nonexistent translation
+ EXPECT_PENDING_TRANSLATIONS(1);
+ host_->RendererClosing(1); // nonexistent renderer
+ EXPECT_PENDING_TRANSLATIONS(1);
+ content::BrowserThread::GetBlockingPool()->FlushForTesting();
+ base::RunLoop().RunUntilIdle();
+ ExpectCallbackCount(1);
+ host_->RendererClosing(0); // close without finishing
+ EXPECT_PENDING_TRANSLATIONS(0);
+}
+
+} // namespace pnacl
diff --git a/chrome/browser/nacl_host/pnacl_translation_cache.cc b/chrome/browser/nacl_host/pnacl_translation_cache.cc
index 155258b..6492e36 100644
--- a/chrome/browser/nacl_host/pnacl_translation_cache.cc
+++ b/chrome/browser/nacl_host/pnacl_translation_cache.cc
@@ -16,16 +16,13 @@
using content::BrowserThread;
-static const base::FilePath::CharType kDiskCacheDirectoryName[] =
- FILE_PATH_LITERAL("PnaclTranslationCache");
-
namespace {
void CloseDiskCacheEntry(disk_cache::Entry* entry) { entry->Close(); }
} // namespace
-namespace pnacl_cache {
+namespace pnacl {
// These are in pnacl_cache namespace instead of static so they can be used
// by the unit test.
const int kMaxDiskCacheSize = 1000 * 1024 * 1024;
@@ -367,7 +364,7 @@
if (in_memory_) {
rv = InitWithMemBackend(kMaxMemCacheSize, callback);
} else {
- rv = InitWithDiskBackend(cache_directory.Append(kDiskCacheDirectoryName),
+ rv = InitWithDiskBackend(cache_directory,
kMaxDiskCacheSize,
callback);
}
@@ -381,4 +378,4 @@
return disk_cache_->GetEntryCount();
}
-} // namespace pnacl_cache
+} // namespace pnacl
diff --git a/chrome/browser/nacl_host/pnacl_translation_cache.h b/chrome/browser/nacl_host/pnacl_translation_cache.h
index 6af0ddc..96f03c0 100644
--- a/chrome/browser/nacl_host/pnacl_translation_cache.h
+++ b/chrome/browser/nacl_host/pnacl_translation_cache.h
@@ -20,7 +20,7 @@
class Backend;
}
-namespace pnacl_cache {
+namespace pnacl {
typedef base::Callback<void(int)> CompletionCallback;
class PnaclTranslationCacheEntry;
extern const int kMaxMemCacheSize;
@@ -85,6 +85,6 @@
DISALLOW_COPY_AND_ASSIGN(PnaclTranslationCache);
};
-} // namespace pnacl_cache
+} // namespace pnacl
#endif // CHROME_BROWSER_NACL_HOST_PNACL_TRANSLATION_CACHE_H_
diff --git a/chrome/browser/nacl_host/pnacl_translation_cache_unittest.cc b/chrome/browser/nacl_host/pnacl_translation_cache_unittest.cc
index a22db45..b2e8061 100644
--- a/chrome/browser/nacl_host/pnacl_translation_cache_unittest.cc
+++ b/chrome/browser/nacl_host/pnacl_translation_cache_unittest.cc
@@ -6,7 +6,7 @@
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
@@ -16,7 +16,7 @@
using content::BrowserThread;
using base::FilePath;
-namespace pnacl_cache {
+namespace pnacl {
class PnaclTranslationCacheTest : public testing::Test {
protected:
@@ -155,4 +155,4 @@
EXPECT_EQ(net::ERR_FAILED, load_cb.GetResult(net::ERR_IO_PENDING));
}
-} // namespace pnacl_cache
+} // namespace pnacl
diff --git a/chrome/browser/net/connection_tester.cc b/chrome/browser/net/connection_tester.cc
index 347761c..5127d55 100644
--- a/chrome/browser/net/connection_tester.cc
+++ b/chrome/browser/net/connection_tester.cc
@@ -113,7 +113,9 @@
storage_.set_ssl_config_service(new net::SSLConfigServiceDefaults);
storage_.set_http_auth_handler_factory(
net::HttpAuthHandlerFactory::CreateDefault(host_resolver()));
- storage_.set_http_server_properties(new net::HttpServerPropertiesImpl);
+ storage_.set_http_server_properties(
+ scoped_ptr<net::HttpServerProperties>(
+ new net::HttpServerPropertiesImpl()));
net::HttpNetworkSession::Params session_params;
session_params.host_resolver = host_resolver();
diff --git a/chrome/browser/net/connection_tester_unittest.cc b/chrome/browser/net/connection_tester_unittest.cc
index 5d87aa1..f5ecb59 100644
--- a/chrome/browser/net/connection_tester_unittest.cc
+++ b/chrome/browser/net/connection_tester_unittest.cc
@@ -138,7 +138,8 @@
session_params.http_auth_handler_factory = &http_auth_handler_factory_;
session_params.ssl_config_service = ssl_config_service_.get();
session_params.proxy_service = proxy_service_.get();
- session_params.http_server_properties = &http_server_properties_impl_;
+ session_params.http_server_properties =
+ http_server_properties_impl_.GetWeakPtr();
scoped_refptr<net::HttpNetworkSession> network_session(
new net::HttpNetworkSession(session_params));
http_transaction_factory_.reset(
diff --git a/chrome/browser/net/dns_probe_browsertest.cc b/chrome/browser/net/dns_probe_browsertest.cc
index 5c3dfaf..3e11252 100644
--- a/chrome/browser/net/dns_probe_browsertest.cc
+++ b/chrome/browser/net/dns_probe_browsertest.cc
@@ -467,8 +467,7 @@
// Double-check to make sure sync failures don't explode.
IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, SyncFailureWithBrokenLinkDoctor) {
SetLinkDoctorBroken(true);
- SetMockDnsClientRules(MockDnsClientRule::FAIL_SYNC,
- MockDnsClientRule::FAIL_SYNC);
+ SetMockDnsClientRules(MockDnsClientRule::FAIL, MockDnsClientRule::FAIL);
NavigateToDnsError();
diff --git a/chrome/browser/net/dns_probe_runner.cc b/chrome/browser/net/dns_probe_runner.cc
index d2b3a5d..ce5aed5 100644
--- a/chrome/browser/net/dns_probe_runner.cc
+++ b/chrome/browser/net/dns_probe_runner.cc
@@ -24,6 +24,7 @@
using net::DnsClient;
using net::DnsResponse;
using net::DnsTransaction;
+using net::DnsTransactionFactory;
using net::IPAddressNumber;
using net::IPEndPoint;
using net::NetLog;
@@ -44,7 +45,7 @@
break;
// ERR_NAME_NOT_RESOLVED maps to NXDOMAIN, which means the server is working
- // but gave us a wrong answer.
+ // but returned a wrong answer.
case net::ERR_NAME_NOT_RESOLVED:
return DnsProbeRunner::INCORRECT;
@@ -68,15 +69,12 @@
TimeDelta ttl;
DnsResponse::Result result = response->ParseToAddressList(&addr_list, &ttl);
- if (result != DnsResponse::DNS_PARSE_OK) {
+ if (result != DnsResponse::DNS_PARSE_OK)
return DnsProbeRunner::FAILING;
- }
-
- if (addr_list.empty()) {
+ else if (addr_list.empty())
return DnsProbeRunner::INCORRECT;
- }
-
- return DnsProbeRunner::CORRECT;
+ else
+ return DnsProbeRunner::CORRECT;
}
} // namespace
@@ -96,16 +94,27 @@
DCHECK(!transaction_.get());
callback_ = callback;
- transaction_ = client_->GetTransactionFactory()->CreateTransaction(
+ DnsTransactionFactory* factory = client_->GetTransactionFactory();
+ if (!factory) {
+ // If the DnsTransactionFactory is NULL, then the DnsConfig is invalid, so
+ // the runner can't run a transaction. Return UNKNOWN asynchronously.
+ result_ = UNKNOWN;
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&DnsProbeRunner::CallCallback,
+ weak_factory_.GetWeakPtr()));
+ return;
+ }
+
+ transaction_ = factory->CreateTransaction(
kKnownGoodHostname,
net::dns_protocol::kTypeA,
base::Bind(&DnsProbeRunner::OnTransactionComplete,
weak_factory_.GetWeakPtr()),
BoundNetLog());
- int rv = transaction_->Start();
- if (rv != net::ERR_IO_PENDING)
- OnTransactionComplete(transaction_.get(), rv, NULL);
+ transaction_->Start();
}
bool DnsProbeRunner::IsRunning() const {
diff --git a/chrome/browser/net/dns_probe_runner_unittest.cc b/chrome/browser/net/dns_probe_runner_unittest.cc
index e8568cc..5020afc 100644
--- a/chrome/browser/net/dns_probe_runner_unittest.cc
+++ b/chrome/browser/net/dns_probe_runner_unittest.cc
@@ -15,6 +15,8 @@
using base::MessageLoopForIO;
using base::RunLoop;
using content::TestBrowserThreadBundle;
+using net::DnsClient;
+using net::DnsConfig;
using net::MockDnsClientRule;
namespace chrome_browser_net {
@@ -77,12 +79,8 @@
RunTest(MockDnsClientRule::TIMEOUT, DnsProbeRunner::UNREACHABLE);
}
-TEST_F(DnsProbeRunnerTest, Probe_FAIL_ASYNC) {
- RunTest(MockDnsClientRule::FAIL_ASYNC, DnsProbeRunner::INCORRECT);
-}
-
-TEST_F(DnsProbeRunnerTest, Probe_FAIL_SYNC) {
- RunTest(MockDnsClientRule::FAIL_SYNC, DnsProbeRunner::INCORRECT);
+TEST_F(DnsProbeRunnerTest, Probe_FAIL) {
+ RunTest(MockDnsClientRule::FAIL, DnsProbeRunner::INCORRECT);
}
TEST_F(DnsProbeRunnerTest, TwoProbes) {
@@ -90,6 +88,24 @@
RunTest(MockDnsClientRule::EMPTY, DnsProbeRunner::INCORRECT);
}
+TEST_F(DnsProbeRunnerTest, InvalidDnsConfig) {
+ scoped_ptr<DnsClient> dns_client(DnsClient::CreateClient(NULL));
+ DnsConfig empty_config;
+ dns_client->SetConfig(empty_config);
+ ASSERT_EQ(NULL, dns_client->GetTransactionFactory());
+ runner_.SetClient(dns_client.Pass());
+
+ TestDnsProbeRunnerCallback callback;
+
+ runner_.RunProbe(callback.callback());
+ EXPECT_TRUE(runner_.IsRunning());
+
+ RunLoop().RunUntilIdle();
+ EXPECT_FALSE(runner_.IsRunning());
+ EXPECT_TRUE(callback.called());
+ EXPECT_EQ(DnsProbeRunner::UNKNOWN, runner_.result());
+}
+
} // namespace
} // namespace chrome_browser_net
diff --git a/chrome/browser/net/dns_probe_service_unittest.cc b/chrome/browser/net/dns_probe_service_unittest.cc
index 450426b..946bf9a 100644
--- a/chrome/browser/net/dns_probe_service_unittest.cc
+++ b/chrome/browser/net/dns_probe_service_unittest.cc
@@ -95,18 +95,18 @@
chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET);
}
-TEST_F(DnsProbeServiceTest, Probe_OK_FAIL_SYNC) {
- RunTest(MockDnsClientRule::OK, MockDnsClientRule::FAIL_SYNC,
+TEST_F(DnsProbeServiceTest, Probe_OK_FAIL) {
+ RunTest(MockDnsClientRule::OK, MockDnsClientRule::FAIL,
chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN);
}
-TEST_F(DnsProbeServiceTest, Probe_FAIL_SYNC_OK) {
- RunTest(MockDnsClientRule::FAIL_SYNC, MockDnsClientRule::OK,
+TEST_F(DnsProbeServiceTest, Probe_FAIL_OK) {
+ RunTest(MockDnsClientRule::FAIL, MockDnsClientRule::OK,
chrome_common_net::DNS_PROBE_FINISHED_BAD_CONFIG);
}
-TEST_F(DnsProbeServiceTest, Probe_FAIL_SYNC_FAIL_SYNC) {
- RunTest(MockDnsClientRule::FAIL_SYNC, MockDnsClientRule::FAIL_SYNC,
+TEST_F(DnsProbeServiceTest, Probe_FAIL_FAIL) {
+ RunTest(MockDnsClientRule::FAIL, MockDnsClientRule::FAIL,
chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE);
}
diff --git a/chrome/browser/net/http_server_properties_manager.cc b/chrome/browser/net/http_server_properties_manager.cc
index 7da72f4..c77f624 100644
--- a/chrome/browser/net/http_server_properties_manager.cc
+++ b/chrome/browser/net/http_server_properties_manager.cc
@@ -67,10 +67,14 @@
}
HttpServerPropertiesManager::~HttpServerPropertiesManager() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ io_weak_ptr_factory_.reset();
}
void HttpServerPropertiesManager::InitializeOnIOThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ io_weak_ptr_factory_.reset(
+ new base::WeakPtrFactory<HttpServerPropertiesManager>(this));
http_server_properties_impl_.reset(new net::HttpServerPropertiesImpl());
io_prefs_update_timer_.reset(
@@ -111,6 +115,12 @@
}
// This is required for conformance with the HttpServerProperties interface.
+base::WeakPtr<net::HttpServerProperties>
+ HttpServerPropertiesManager::GetWeakPtr() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ return io_weak_ptr_factory_->GetWeakPtr();
+}
+
void HttpServerPropertiesManager::Clear() {
Clear(base::Closure());
}
diff --git a/chrome/browser/net/http_server_properties_manager.h b/chrome/browser/net/http_server_properties_manager.h
index 756b119..a2a52a7 100644
--- a/chrome/browser/net/http_server_properties_manager.h
+++ b/chrome/browser/net/http_server_properties_manager.h
@@ -81,6 +81,9 @@
// net::HttpServerProperties methods:
// ----------------------------------
+ // Gets a weak pointer for this object.
+ virtual base::WeakPtr<net::HttpServerProperties> GetWeakPtr() OVERRIDE;
+
// Deletes all data. Works asynchronously.
virtual void Clear() OVERRIDE;
@@ -229,6 +232,10 @@
// IO thread
// ---------
+ // Used to get |weak_ptr_| to self on the IO thread.
+ scoped_ptr<base::WeakPtrFactory<HttpServerPropertiesManager> >
+ io_weak_ptr_factory_;
+
// Used to post |prefs::kHttpServerProperties| pref update tasks.
scoped_ptr<base::OneShotTimer<HttpServerPropertiesManager> >
io_prefs_update_timer_;
diff --git a/chrome/browser/net/pref_proxy_config_tracker.cc b/chrome/browser/net/pref_proxy_config_tracker.cc
new file mode 100644
index 0000000..f71f841
--- /dev/null
+++ b/chrome/browser/net/pref_proxy_config_tracker.cc
@@ -0,0 +1,11 @@
+// Copyright 2013 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/net/pref_proxy_config_tracker.h"
+
+PrefProxyConfigTracker::PrefProxyConfigTracker() {
+}
+
+PrefProxyConfigTracker::~PrefProxyConfigTracker() {
+}
diff --git a/chrome/browser/net/pref_proxy_config_tracker.h b/chrome/browser/net/pref_proxy_config_tracker.h
index 97dc70e..7ce43e0 100644
--- a/chrome/browser/net/pref_proxy_config_tracker.h
+++ b/chrome/browser/net/pref_proxy_config_tracker.h
@@ -5,18 +5,39 @@
#ifndef CHROME_BROWSER_NET_PREF_PROXY_CONFIG_TRACKER_H_
#define CHROME_BROWSER_NET_PREF_PROXY_CONFIG_TRACKER_H_
-#include "chrome/browser/net/pref_proxy_config_tracker_impl.h"
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
-#if defined(OS_CHROMEOS)
-namespace chromeos {
-class ProxyConfigServiceImpl;
+namespace net {
+class ProxyConfigService;
}
-#endif // defined(OS_CHROMEOS)
-#if defined(OS_CHROMEOS)
-typedef chromeos::ProxyConfigServiceImpl PrefProxyConfigTracker;
-#else
-typedef PrefProxyConfigTrackerImpl PrefProxyConfigTracker;
-#endif // defined(OS_CHROMEOS)
+// Interface for a class that tracks proxy preferences. The purpose of the
+// concrete class is to track changes in the Preferences, to translates the
+// preferences to net::ProxyConfig and to push the result over to a
+// net::ProxyConfigService onto the IO thread.
+class PrefProxyConfigTracker {
+ public:
+ PrefProxyConfigTracker();
+ virtual ~PrefProxyConfigTracker();
+
+ // Creates a net::ProxyConfigService and keeps a pointer to it. After this
+ // call, this tracker forwards any changes of proxy preferences to the created
+ // ProxyConfigService. The returned ProxyConfigService must not be deleted
+ // before DetachFromPrefService was called. Takes ownership of the passed
+ // |base_service|, which can be NULL. This |base_service| provides the proxy
+ // settings of the OS (except of ChromeOS). This must be called on the
+ // UI thread.
+ virtual scoped_ptr<net::ProxyConfigService> CreateTrackingProxyConfigService(
+ scoped_ptr<net::ProxyConfigService> base_service) = 0;
+
+ // Releases the PrefService passed upon construction and the |base_service|
+ // passed to CreateTrackingProxyConfigService. This must be called on the UI
+ // thread.
+ virtual void DetachFromPrefService() = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PrefProxyConfigTracker);
+};
#endif // CHROME_BROWSER_NET_PREF_PROXY_CONFIG_TRACKER_H_
diff --git a/chrome/browser/net/pref_proxy_config_tracker_impl.cc b/chrome/browser/net/pref_proxy_config_tracker_impl.cc
index 2c6318c..5dd3e5d 100644
--- a/chrome/browser/net/pref_proxy_config_tracker_impl.cc
+++ b/chrome/browser/net/pref_proxy_config_tracker_impl.cc
@@ -140,13 +140,17 @@
DCHECK(pref_service_ == NULL);
}
-void PrefProxyConfigTrackerImpl::SetChromeProxyConfigService(
- ChromeProxyConfigService* chrome_proxy_config_service) {
+scoped_ptr<net::ProxyConfigService>
+PrefProxyConfigTrackerImpl::CreateTrackingProxyConfigService(
+ scoped_ptr<net::ProxyConfigService> base_service) {
+ chrome_proxy_config_service_ =
+ new ChromeProxyConfigService(base_service.release());
VLOG(1) << this << ": set chrome proxy config service to "
- << chrome_proxy_config_service;
- chrome_proxy_config_service_ = chrome_proxy_config_service;
+ << chrome_proxy_config_service_;
if (chrome_proxy_config_service_ && update_pending_)
OnProxyConfigChanged(config_state_, pref_config_);
+
+ return scoped_ptr<net::ProxyConfigService>(chrome_proxy_config_service_);
}
void PrefProxyConfigTrackerImpl::DetachFromPrefService() {
@@ -154,7 +158,7 @@
// Stop notifications.
proxy_prefs_.RemoveAll();
pref_service_ = NULL;
- SetChromeProxyConfigService(NULL);
+ chrome_proxy_config_service_ = NULL;
}
// static
diff --git a/chrome/browser/net/pref_proxy_config_tracker_impl.h b/chrome/browser/net/pref_proxy_config_tracker_impl.h
index 0abbc99..4e1aa00 100644
--- a/chrome/browser/net/pref_proxy_config_tracker_impl.h
+++ b/chrome/browser/net/pref_proxy_config_tracker_impl.h
@@ -10,6 +10,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "base/prefs/pref_change_registrar.h"
+#include "chrome/browser/net/pref_proxy_config_tracker.h"
#include "chrome/browser/prefs/proxy_config_dictionary.h"
#include "net/proxy/proxy_config.h"
#include "net/proxy/proxy_config_service.h"
@@ -81,18 +82,18 @@
// A class that tracks proxy preferences. It translates the configuration
// to net::ProxyConfig and pushes the result over to the IO thread for
// ChromeProxyConfigService::UpdateProxyConfig to use.
-class PrefProxyConfigTrackerImpl {
+class PrefProxyConfigTrackerImpl : public PrefProxyConfigTracker {
public:
explicit PrefProxyConfigTrackerImpl(PrefService* pref_service);
virtual ~PrefProxyConfigTrackerImpl();
- // Sets the proxy config service to push the preference proxy to.
- void SetChromeProxyConfigService(
- ChromeProxyConfigService* proxy_config_service);
+ // PrefProxyConfigTracker implementation:
+ virtual scoped_ptr<net::ProxyConfigService> CreateTrackingProxyConfigService(
+ scoped_ptr<net::ProxyConfigService> base_service) OVERRIDE;
// Notifies the tracker that the pref service passed upon construction is
// about to go away. This must be called from the UI thread.
- void DetachFromPrefService();
+ virtual void DetachFromPrefService() OVERRIDE;
// Determines if |config_state| takes precedence regardless, which happens if
// config is from policy or extension or other-precede.
diff --git a/chrome/browser/net/pref_proxy_config_tracker_impl_unittest.cc b/chrome/browser/net/pref_proxy_config_tracker_impl_unittest.cc
index 1313731..40a9647 100644
--- a/chrome/browser/net/pref_proxy_config_tracker_impl_unittest.cc
+++ b/chrome/browser/net/pref_proxy_config_tracker_impl_unittest.cc
@@ -87,11 +87,10 @@
delegate_service_ =
new TestProxyConfigService(fixed_config_,
net::ProxyConfigService::CONFIG_VALID);
- proxy_config_service_.reset(
- new ChromeProxyConfigService(delegate_service_));
proxy_config_tracker_.reset(new PrefProxyConfigTrackerImpl(pref_service));
- proxy_config_tracker_->SetChromeProxyConfigService(
- proxy_config_service_.get());
+ proxy_config_service_ =
+ proxy_config_tracker_->CreateTrackingProxyConfigService(
+ scoped_ptr<net::ProxyConfigService>(delegate_service_));
// SetChromeProxyConfigService triggers update of initial prefs proxy
// config by tracker to chrome proxy config service, so flush all pending
// tasks so that tests start fresh.
@@ -107,7 +106,7 @@
base::MessageLoop loop_;
TestProxyConfigService* delegate_service_; // weak
- scoped_ptr<ChromeProxyConfigService> proxy_config_service_;
+ scoped_ptr<net::ProxyConfigService> proxy_config_service_;
net::ProxyConfig fixed_config_;
private:
diff --git a/chrome/browser/net/proxy_service_factory.cc b/chrome/browser/net/proxy_service_factory.cc
index 0c83d0e..ab66107 100644
--- a/chrome/browser/net/proxy_service_factory.cc
+++ b/chrome/browser/net/proxy_service_factory.cc
@@ -9,7 +9,7 @@
#include "base/threading/thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/io_thread.h"
-#include "chrome/browser/net/pref_proxy_config_tracker.h"
+#include "chrome/browser/net/pref_proxy_config_tracker_impl.h"
#include "chrome/common/chrome_switches.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/net_log.h"
@@ -27,12 +27,13 @@
using content::BrowserThread;
// static
-ChromeProxyConfigService* ProxyServiceFactory::CreateProxyConfigService() {
+net::ProxyConfigService* ProxyServiceFactory::CreateProxyConfigService(
+ PrefProxyConfigTracker* tracker) {
// The linux gconf-based proxy settings getter relies on being initialized
// from the UI thread.
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- net::ProxyConfigService* base_service = NULL;
+ scoped_ptr<net::ProxyConfigService> base_service;
#if !defined(OS_CHROMEOS)
// On ChromeOS, base service is NULL; chromeos::ProxyConfigServiceImpl
@@ -46,12 +47,13 @@
// TODO(port): the IO and FILE message loops are only used by Linux. Can
// that code be moved to chrome/browser instead of being in net, so that it
// can use BrowserThread instead of raw MessageLoop pointers? See bug 25354.
- base_service = net::ProxyService::CreateSystemProxyConfigService(
+ base_service.reset(net::ProxyService::CreateSystemProxyConfigService(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get(),
- BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE));
+ BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE)));
#endif // !defined(OS_CHROMEOS)
- return new ChromeProxyConfigService(base_service);
+ return tracker->CreateTrackingProxyConfigService(base_service.Pass())
+ .release();
}
// static
diff --git a/chrome/browser/net/proxy_service_factory.h b/chrome/browser/net/proxy_service_factory.h
index 154f5e9..f16e226 100644
--- a/chrome/browser/net/proxy_service_factory.h
+++ b/chrome/browser/net/proxy_service_factory.h
@@ -7,38 +7,24 @@
#include "base/basictypes.h"
-class ChromeProxyConfigService;
class CommandLine;
-class PrefProxyConfigTrackerImpl;
+class PrefProxyConfigTracker;
class PrefService;
-#if defined(OS_CHROMEOS)
-namespace chromeos {
-class ProxyConfigServiceImpl;
-}
-#endif // defined(OS_CHROMEOS)
-
-#if defined(OS_CHROMEOS)
-typedef chromeos::ProxyConfigServiceImpl PrefProxyConfigTracker;
-#else
-typedef PrefProxyConfigTrackerImpl PrefProxyConfigTracker;
-#endif // defined(OS_CHROMEOS)
-
namespace net {
class NetLog;
class NetworkDelegate;
class ProxyConfigService;
class ProxyService;
class URLRequestContext;
-} // namespace net
+}
class ProxyServiceFactory {
public:
// Creates a ProxyConfigService that delivers the system preferences
// (or the respective ChromeOS equivalent).
- // The ChromeProxyConfigService returns "pending" until it has been informed
- // about the proxy configuration by calling its UpdateProxyConfig method.
- static ChromeProxyConfigService* CreateProxyConfigService();
+ static net::ProxyConfigService* CreateProxyConfigService(
+ PrefProxyConfigTracker* tracker);
// Creates a PrefProxyConfigTracker that tracks preferences of a
// profile. On ChromeOS it additionaly tracks local state for shared proxy
diff --git a/chrome/browser/net/resource_prefetch_predictor_observer.h b/chrome/browser/net/resource_prefetch_predictor_observer.h
index 5ffb27b..3790f0a 100644
--- a/chrome/browser/net/resource_prefetch_predictor_observer.h
+++ b/chrome/browser/net/resource_prefetch_predictor_observer.h
@@ -8,7 +8,7 @@
#include "base/basictypes.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/predictors/resource_prefetch_predictor.h"
-#include "webkit/glue/resource_type.h"
+#include "webkit/common/resource_type.h"
namespace net {
class URLRequest;
diff --git a/chrome/browser/notifications/balloon.cc b/chrome/browser/notifications/balloon.cc
index 2a73c05..0997212 100644
--- a/chrome/browser/notifications/balloon.cc
+++ b/chrome/browser/notifications/balloon.cc
@@ -82,9 +82,9 @@
}
std::string Balloon::GetExtensionId() {
- const ExtensionURLInfo url(notification().origin_url());
const ExtensionService* service = profile()->GetExtensionService();
const extensions::Extension* extension =
- service->extensions()->GetExtensionOrAppByURL(url);
+ service->extensions()->GetExtensionOrAppByURL(
+ notification().origin_url());
return extension ? extension->id() : std::string();
}
diff --git a/chrome/browser/notifications/balloon_collection_impl.h b/chrome/browser/notifications/balloon_collection_impl.h
index 07b223d..45b26d0 100644
--- a/chrome/browser/notifications/balloon_collection_impl.h
+++ b/chrome/browser/notifications/balloon_collection_impl.h
@@ -12,7 +12,7 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/weak_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "chrome/browser/notifications/balloon_collection.h"
#include "chrome/browser/notifications/balloon_collection_base.h"
#include "content/public/browser/notification_observer.h"
diff --git a/chrome/browser/notifications/desktop_notification_service.cc b/chrome/browser/notifications/desktop_notification_service.cc
index e81a2b1..90c827b 100644
--- a/chrome/browser/notifications/desktop_notification_service.cc
+++ b/chrome/browser/notifications/desktop_notification_service.cc
@@ -42,7 +42,6 @@
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "net/base/escape.h"
-#include "third_party/WebKit/public/web/WebSecurityOrigin.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/message_center/message_center_util.h"
@@ -55,7 +54,6 @@
using message_center::NotifierId;
using WebKit::WebNotificationPresenter;
using WebKit::WebTextDirection;
-using WebKit::WebSecurityOrigin;
// NotificationPermissionInfoBarDelegate --------------------------------------
@@ -64,7 +62,7 @@
// permissions.
class NotificationPermissionInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
- // Creates a notification permission delegate and adds it to
+ // Creates a notification permission infobar delegate and adds it to
// |infobar_service|.
static void Create(InfoBarService* infobar_service,
DesktopNotificationService* notification_service,
diff --git a/chrome/browser/notifications/desktop_notification_service_unittest.cc b/chrome/browser/notifications/desktop_notification_service_unittest.cc
index a4ec7b1..5b48097 100644
--- a/chrome/browser/notifications/desktop_notification_service_unittest.cc
+++ b/chrome/browser/notifications/desktop_notification_service_unittest.cc
@@ -6,7 +6,7 @@
#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "chrome/browser/notifications/desktop_notification_service_factory.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
diff --git a/chrome/browser/notifications/desktop_notifications_unittest.cc b/chrome/browser/notifications/desktop_notifications_unittest.cc
index 7b969f3..9d07c8b 100644
--- a/chrome/browser/notifications/desktop_notifications_unittest.cc
+++ b/chrome/browser/notifications/desktop_notifications_unittest.cc
@@ -21,7 +21,6 @@
#if defined(USE_ASH)
#include "ash/shell.h"
#include "ash/test/test_shell_delegate.h"
-#include "third_party/WebKit/public/web/WebKit.h"
#include "ui/aura/env.h"
#include "ui/aura/root_window.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
@@ -103,7 +102,6 @@
void DesktopNotificationsTest::SetUp() {
ui::InitializeInputMethodForTesting();
#if defined(USE_ASH)
- WebKit::initialize(webkit_platform_support_.Get());
ui::ScopedAnimationDurationScaleMode normal_duration_mode(
ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
// The message center is notmally initialized on |g_browser_process| which
@@ -133,7 +131,6 @@
// is not created for these tests.
message_center::MessageCenter::Shutdown();
aura::Env::DeleteInstance();
- WebKit::shutdown();
#endif
ui::ShutdownInputMethodForTesting();
}
diff --git a/chrome/browser/notifications/desktop_notifications_unittest.h b/chrome/browser/notifications/desktop_notifications_unittest.h
index ad8d0d8..935710f 100644
--- a/chrome/browser/notifications/desktop_notifications_unittest.h
+++ b/chrome/browser/notifications/desktop_notifications_unittest.h
@@ -8,7 +8,7 @@
#include <deque>
#include <string>
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/prefs/testing_pref_service.h"
#include "chrome/browser/notifications/balloon_collection_impl.h"
#include "chrome/browser/notifications/balloon_notification_ui_manager.h"
@@ -114,11 +114,6 @@
// Real DesktopNotificationService
scoped_ptr<DesktopNotificationService> service_;
-#if defined(USE_ASH)
- content::RenderViewTest::RendererWebKitPlatformSupportImplNoSandbox
- webkit_platform_support_;
-#endif
-
// Contains the cumulative output of the unit test.
static std::string log_output_;
};
diff --git a/chrome/browser/notifications/message_center_notifications_browsertest.cc b/chrome/browser/notifications/message_center_notifications_browsertest.cc
index 4cd7ce7..455f514 100644
--- a/chrome/browser/notifications/message_center_notifications_browsertest.cc
+++ b/chrome/browser/notifications/message_center_notifications_browsertest.cc
@@ -5,7 +5,7 @@
#include <string>
#include "base/command_line.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
@@ -21,6 +21,10 @@
#include "ui/message_center/message_center_switches.h"
#include "ui/message_center/message_center_util.h"
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
class TestAddObserver : public message_center::MessageCenterObserver {
public:
TestAddObserver(const std::string& id,
@@ -177,6 +181,12 @@
#endif
IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest, MAYBE_BasicDelegate) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
EXPECT_TRUE(NotificationUIManager::DelegatesToMessageCenter());
TestDelegate* delegate;
manager()->Add(CreateTestNotification("hey", &delegate), profile());
@@ -197,6 +207,12 @@
IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest,
MAYBE_ButtonClickedDelegate) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
EXPECT_TRUE(NotificationUIManager::DelegatesToMessageCenter());
TestDelegate* delegate;
manager()->Add(CreateTestNotification("n", &delegate), profile());
@@ -215,6 +231,12 @@
IN_PROC_BROWSER_TEST_F(MessageCenterNotificationsTest,
MAYBE_UpdateExistingNotification) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
EXPECT_TRUE(NotificationUIManager::DelegatesToMessageCenter());
TestDelegate* delegate;
manager()->Add(CreateTestNotification("n", &delegate), profile());
diff --git a/chrome/browser/notifications/notification_options_menu_model.cc b/chrome/browser/notifications/notification_options_menu_model.cc
index 3d2cbea..7a11a1a 100644
--- a/chrome/browser/notifications/notification_options_menu_model.cc
+++ b/chrome/browser/notifications/notification_options_menu_model.cc
@@ -140,8 +140,7 @@
ExtensionService* extension_service =
balloon_->profile()->GetExtensionService();
const extensions::Extension* extension =
- extension_service->extensions()->GetExtensionOrAppByURL(
- ExtensionURLInfo(origin));
+ extension_service->extensions()->GetExtensionOrAppByURL(origin);
// We get back no extension here when we show the notification after
// the extension has crashed.
if (extension) {
@@ -192,8 +191,7 @@
ExtensionService* extension_service =
balloon_->profile()->GetExtensionService();
const extensions::Extension* extension =
- extension_service->extensions()->GetExtensionOrAppByURL(
- ExtensionURLInfo(origin));
+ extension_service->extensions()->GetExtensionOrAppByURL(origin);
if (extension) {
return l10n_util::GetStringUTF16(
extension_service->IsExtensionEnabled(extension->id()) ?
@@ -251,8 +249,7 @@
break;
case kToggleExtensionCommand: {
const extensions::Extension* extension =
- extension_service->extensions()->GetExtensionOrAppByURL(
- ExtensionURLInfo(origin));
+ extension_service->extensions()->GetExtensionOrAppByURL(origin);
if (extension) {
const std::string& id = extension->id();
if (extension_service->IsExtensionEnabled(id))
diff --git a/chrome/browser/notifications/sync_notifier/synced_notification_unittest.cc b/chrome/browser/notifications/sync_notifier/synced_notification_unittest.cc
index abb60a2..ccd6b4f 100644
--- a/chrome/browser/notifications/sync_notifier/synced_notification_unittest.cc
+++ b/chrome/browser/notifications/sync_notifier/synced_notification_unittest.cc
@@ -5,7 +5,7 @@
#include <string>
#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/notifications/notification.h"
#include "chrome/browser/notifications/notification_test_util.h"
diff --git a/chrome/browser/page_cycler/page_cycler.cc b/chrome/browser/page_cycler/page_cycler.cc
index 1f1c47e..7fcf078 100644
--- a/chrome/browser/page_cycler/page_cycler.cc
+++ b/chrome/browser/page_cycler/page_cycler.cc
@@ -7,7 +7,7 @@
#include "base/bind.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
-#include "base/message_loop.h"
+#include "base/message_loop/message_loop.h"
#include "base/process_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
diff --git a/chrome/browser/password_manager/login_database.cc b/chrome/browser/password_manager/login_database.cc
index 9b0ebda..7204385 100644
--- a/chrome/browser/password_manager/login_database.cc
+++ b/chrome/browser/password_manager/login_database.cc
@@ -83,6 +83,22 @@
return found_port == form_port;
}
+bool IsPublicSuffixDomainMatchingEnabled() {
+#if defined(OS_ANDROID)
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnablePasswordAutofillPublicSuffixDomainMatching)) {
+ return true;
+ }
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisablePasswordAutofillPublicSuffixDomainMatching)) {
+ return false;
+ }
+ return true;
+#else
+ return false;
+#endif
+}
+
} // namespace
LoginDatabase::LoginDatabase() : public_suffix_domain_matching_(false) {
@@ -140,8 +156,7 @@
return false;
}
- public_suffix_domain_matching_ = CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnablePasswordAutofillPublicSuffixDomainMatching);
+ public_suffix_domain_matching_ = IsPublicSuffixDomainMatchingEnabled();
return true;
}
diff --git a/chrome/browser/password_manager/password_manager.cc b/chrome/browser/password_manager/password_manager.cc
index 15bfb8c..e1390aa 100644
--- a/chrome/browser/password_manager/password_manager.cc
+++ b/chrome/browser/password_manager/password_manager.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/password_manager/password_manager.h"
+#include "base/command_line.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/prefs/pref_service.h"
@@ -13,6 +14,7 @@
#include "chrome/browser/password_manager/password_form_manager.h"
#include "chrome/browser/password_manager/password_manager_delegate.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/pref_names.h"
#include "components/autofill/core/common/autofill_messages.h"
@@ -308,12 +310,16 @@
provisional_save_manager_->SubmitPassed();
if (provisional_save_manager_->HasGeneratedPassword())
UMA_HISTOGRAM_COUNTS("PasswordGeneration.Submitted", 1);
- if (ShouldShowSavePasswordInfoBar()) {
- delegate_->AddSavePasswordInfoBarIfPermitted(
- provisional_save_manager_.release());
- } else {
- provisional_save_manager_->Save();
- provisional_save_manager_.reset();
+
+ if(!CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableSavePasswordBubble)){
+ if (ShouldShowSavePasswordInfoBar()) {
+ delegate_->AddSavePasswordInfoBarIfPermitted(
+ provisional_save_manager_.release());
+ } else {
+ provisional_save_manager_->Save();
+ provisional_save_manager_.reset();
+ }
}
}
diff --git a/chrome/browser/password_manager/password_manager_delegate_impl.cc b/chrome/browser/password_manager/password_manager_delegate_impl.cc
index edf7a23..95ce6b8 100644
--- a/chrome/browser/password_manager/password_manager_delegate_impl.cc
+++ b/chrome/browser/password_manager/password_manager_delegate_impl.cc
@@ -40,7 +40,8 @@
class SavePasswordInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
// If we won't be showing the one-click signin infobar, creates a save
- // password delegate and adds it to the InfoBarService for |web_contents|.
+ // password infobar delegate and adds it to the InfoBarService for
+ // |web_contents|.
static void Create(content::WebContents* web_contents,
PasswordFormManager* form_to_save);
diff --git a/chrome/browser/password_manager/password_store_unittest.cc b/chrome/browser/password_manager/password_store_unittest.cc
index 0c179b6..25d177e 100644
--- a/chrome/browser/password_manager/password_store_unittest.cc
+++ b/chrome/browser/password_manager/password_store_unittest.cc
@@ -152,7 +152,7 @@
true, true, cutoff - 1 },
// A form on https://www.google.com/ older than the cutoff. Will be ignored.
{ PasswordForm::SCHEME_HTML,
- "https://www.google.com/",
+ "https://www.google.com",
"https://www.google.com/origin",
"https://www.google.com/action",
L"submit_element",
diff --git a/chrome/browser/pepper_broker_infobar_delegate.cc b/chrome/browser/pepper_broker_infobar_delegate.cc
index 66624ec..9ca7068 100644
--- a/chrome/browser/pepper_broker_infobar_delegate.cc
+++ b/chrome/browser/pepper_broker_infobar_delegate.cc
@@ -17,11 +17,11 @@
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/referrer.h"
+#include "content/public/common/webplugininfo.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "net/base/net_util.h"
#include "ui/base/l10n/l10n_util.h"
-#include "webkit/plugins/webplugininfo.h"
#if defined(GOOGLE_TV)
#include "base/android/context_types.h"
@@ -48,11 +48,12 @@
#if defined(OS_CHROMEOS)
// On ChromeOS, we're ok with granting broker access to the Netflix and
// Widevine plugins, since they can only come installed with the OS.
- const char kNetflixPluginFileName[] = "libnetflixplugin2.so";
const char kWidevinePluginFileName[] = "libwidevinecdmadapter.so";
+ const char kNetflixDomain[] = "netflix.com";
+
base::FilePath plugin_file_name = plugin_path.BaseName();
- if (plugin_file_name.value() == FILE_PATH_LITERAL(kNetflixPluginFileName) ||
- plugin_file_name.value() == FILE_PATH_LITERAL(kWidevinePluginFileName)) {
+ if (plugin_file_name.value() == FILE_PATH_LITERAL(kWidevinePluginFileName) &&
+ url.DomainIs(kNetflixDomain)) {
tab_content_settings->SetPepperBrokerAllowed(true);
callback.Run(true);
return;
@@ -139,7 +140,7 @@
string16 PepperBrokerInfoBarDelegate::GetMessageText() const {
content::PluginService* plugin_service =
content::PluginService::GetInstance();
- webkit::WebPluginInfo plugin;
+ content::WebPluginInfo plugin;
bool success = plugin_service->GetPluginInfoByPath(plugin_path_, &plugin);
DCHECK(success);
scoped_ptr<PluginMetadata> plugin_metadata(
diff --git a/chrome/browser/pepper_broker_infobar_delegate.h b/chrome/browser/pepper_broker_infobar_delegate.h
index 33574d1..220297c 100644
--- a/chrome/browser/pepper_broker_infobar_delegate.h
+++ b/chrome/browser/pepper_broker_infobar_delegate.h
@@ -25,7 +25,7 @@
public:
// Determines whether the broker setting is allow, deny, or ask. In the first
// two cases, runs the callback directly. In the third, creates a pepper
- // broker delegate and adds it to the InfoBarService associated with
+ // broker infobar delegate and adds it to the InfoBarService associated with
// |web_contents|.
static void Create(content::WebContents* web_contents,
const GURL& url,
diff --git a/chrome/browser/pepper_flash_settings_manager.cc b/chrome/browser/pepper_flash_settings_manager.cc
index 2886b4e..243ea84 100644
--- a/chrome/browser/pepper_flash_settings_manager.cc
+++ b/chrome/browser/pepper_flash_settings_manager.cc
@@ -24,12 +24,12 @@
#include "content/public/browser/pepper_flash_settings_helper.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/common/content_constants.h"
+#include "content/public/common/webplugininfo.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_listener.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "url/gurl.h"
#include "webkit/plugins/plugin_constants.h"
-#include "webkit/plugins/webplugininfo.h"
using content::BrowserThread;
@@ -401,7 +401,7 @@
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DCHECK_EQ(STATE_UNINITIALIZED, state_);
- webkit::WebPluginInfo plugin_info;
+ content::WebPluginInfo plugin_info;
if (!PepperFlashSettingsManager::IsPepperFlashInUse(plugin_prefs_.get(),
&plugin_info)) {
NotifyErrorFromIOThread();
@@ -947,19 +947,19 @@
// static
bool PepperFlashSettingsManager::IsPepperFlashInUse(
PluginPrefs* plugin_prefs,
- webkit::WebPluginInfo* plugin_info) {
+ content::WebPluginInfo* plugin_info) {
if (!plugin_prefs)
return false;
content::PluginService* plugin_service =
content::PluginService::GetInstance();
- std::vector<webkit::WebPluginInfo> plugins;
+ std::vector<content::WebPluginInfo> plugins;
plugin_service->GetPluginInfoArray(
GURL(), kFlashPluginSwfMimeType, false, &plugins, NULL);
- for (std::vector<webkit::WebPluginInfo>::iterator iter = plugins.begin();
+ for (std::vector<content::WebPluginInfo>::iterator iter = plugins.begin();
iter != plugins.end(); ++iter) {
- if (webkit::IsPepperPlugin(*iter) && plugin_prefs->IsPluginEnabled(*iter)) {
+ if (iter->is_pepper_plugin() && plugin_prefs->IsPluginEnabled(*iter)) {
if (plugin_info)
*plugin_info = *iter;
return true;
diff --git a/chrome/browser/pepper_flash_settings_manager.h b/chrome/browser/pepper_flash_settings_manager.h
index cefb9c5..6aef457 100644
--- a/chrome/browser/pepper_flash_settings_manager.h
+++ b/chrome/browser/pepper_flash_settings_manager.h
@@ -16,16 +16,13 @@
namespace content {
class BrowserContext;
+struct WebPluginInfo;
}
namespace user_prefs {
class PrefRegistrySyncable;
}
-namespace webkit {
-struct WebPluginInfo;
-}
-
// PepperFlashSettingsManager communicates with a PPAPI broker process to
// read/write Pepper Flash settings.
class PepperFlashSettingsManager {
@@ -64,7 +61,7 @@
// |plugin_info| will be updated if it is not NULL and the method returns
// true.
static bool IsPepperFlashInUse(PluginPrefs* plugin_prefs,
- webkit::WebPluginInfo* plugin_info);
+ content::WebPluginInfo* plugin_info);
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
diff --git a/chrome/browser/plugins/chrome_plugin_service_filter.cc b/chrome/browser/plugins/chrome_plugin_service_filter.cc
index 633d758..c466380 100644
--- a/chrome/browser/plugins/chrome_plugin_service_filter.cc
+++ b/chrome/browser/plugins/chrome_plugin_service_filter.cc
@@ -42,7 +42,7 @@
int render_process_id,
int render_view_id,
const GURL& url,
- const webkit::WebPluginInfo& plugin) {
+ const content::WebPluginInfo& plugin) {
base::AutoLock auto_lock(lock_);
ProcessDetails* details = GetOrRegisterProcess(render_process_id);
OverriddenPlugin overridden_plugin;
@@ -73,7 +73,7 @@
const void* context,
const GURL& url,
const GURL& policy_url,
- webkit::WebPluginInfo* plugin) {
+ content::WebPluginInfo* plugin) {
base::AutoLock auto_lock(lock_);
const ProcessDetails* details = GetProcess(render_process_id);
diff --git a/chrome/browser/plugins/chrome_plugin_service_filter.h b/chrome/browser/plugins/chrome_plugin_service_filter.h
index 5b61c3a..513b1ff 100644
--- a/chrome/browser/plugins/chrome_plugin_service_filter.h
+++ b/chrome/browser/plugins/chrome_plugin_service_filter.h
@@ -17,8 +17,8 @@
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/plugin_service_filter.h"
+#include "content/public/common/webplugininfo.h"
#include "url/gurl.h"
-#include "webkit/plugins/webplugininfo.h"
class PluginPrefs;
class Profile;
@@ -40,7 +40,7 @@
void OverridePluginForTab(int render_process_id,
int render_view_id,
const GURL& url,
- const webkit::WebPluginInfo& plugin);
+ const content::WebPluginInfo& plugin);
// Restricts the given plugin to the given profile and origin of the given
// URL.
@@ -65,7 +65,7 @@
const void* context,
const GURL& url,
const GURL& policy_url,
- webkit::WebPluginInfo* plugin) OVERRIDE;
+ content::WebPluginInfo* plugin) OVERRIDE;
// CanLoadPlugin always grants permission to the browser
// (render_process_id == 0)
@@ -82,7 +82,7 @@
int render_view_id;
GURL url; // If empty, the override applies to all urls in render_view.
- webkit::WebPluginInfo plugin;
+ content::WebPluginInfo plugin;
};
struct ProcessDetails {
diff --git a/chrome/browser/plugins/plugin_data_remover_helper.cc b/chrome/browser/plugins/plugin_data_remover_helper.cc
index f9e19ae..0f7d6b7 100644
--- a/chrome/browser/plugins/plugin_data_remover_helper.cc
+++ b/chrome/browser/plugins/plugin_data_remover_helper.cc
@@ -6,13 +6,13 @@
#include "chrome/browser/plugins/plugin_prefs.h"
#include "content/public/browser/plugin_data_remover.h"
-#include "webkit/plugins/webplugininfo.h"
+#include "content/public/common/webplugininfo.h"
// static
bool PluginDataRemoverHelper::IsSupported(PluginPrefs* plugin_prefs) {
- std::vector<webkit::WebPluginInfo> plugins;
+ std::vector<content::WebPluginInfo> plugins;
content::PluginDataRemover::GetSupportedPlugins(&plugins);
- for (std::vector<webkit::WebPluginInfo>::const_iterator it = plugins.begin();
+ for (std::vector<content::WebPluginInfo>::const_iterator it = plugins.begin();
it != plugins.end(); ++it) {
if (plugin_prefs->IsPluginEnabled(*it))
return true;
diff --git a/chrome/browser/plugins/plugin_finder.cc b/chrome/browser/plugins/plugin_finder.cc
index 5cf9378..9f7b799 100644
--- a/chrome/browser/plugins/plugin_finder.cc
+++ b/chrome/browser/plugins/plugin_finder.cc
@@ -34,18 +34,18 @@
typedef std::map<std::string, PluginMetadata*> PluginMap;
// Gets the full path of the plug-in file as the identifier.
-std::string GetLongIdentifier(const webkit::WebPluginInfo& plugin) {
+std::string GetLongIdentifier(const content::WebPluginInfo& plugin) {
return plugin.path.AsUTF8Unsafe();
}
// Gets the base name of the file path as the identifier.
-std::string GetIdentifier(const webkit::WebPluginInfo& plugin) {
+std::string GetIdentifier(const content::WebPluginInfo& plugin) {
return plugin.path.BaseName().AsUTF8Unsafe();
}
// Gets the plug-in group name as the plug-in name if it is not empty or
// the filename without extension if the name is empty.
-static string16 GetGroupName(const webkit::WebPluginInfo& plugin) {
+static string16 GetGroupName(const content::WebPluginInfo& plugin) {
if (!plugin.name.empty())
return plugin.name;
@@ -277,7 +277,7 @@
}
scoped_ptr<PluginMetadata> PluginFinder::GetPluginMetadata(
- const webkit::WebPluginInfo& plugin) {
+ const content::WebPluginInfo& plugin) {
base::AutoLock lock(mutex_);
for (PluginMap::const_iterator it = identifier_plugin_.begin();
it != identifier_plugin_.end(); ++it) {
diff --git a/chrome/browser/plugins/plugin_finder.h b/chrome/browser/plugins/plugin_finder.h
index 25e1eee..d7f8cb0 100644
--- a/chrome/browser/plugins/plugin_finder.h
+++ b/chrome/browser/plugins/plugin_finder.h
@@ -14,7 +14,7 @@
#include "base/memory/singleton.h"
#include "base/strings/string16.h"
#include "base/synchronization/lock.h"
-#include "webkit/plugins/webplugininfo.h"
+#include "content/public/common/webplugininfo.h"
namespace base {
class DictionaryValue;
@@ -65,7 +65,7 @@
// Gets plug-in metadata using |plugin|.
scoped_ptr<PluginMetadata> GetPluginMetadata(
- const webkit::WebPluginInfo& plugin);
+ const content::WebPluginInfo& plugin);
private:
friend struct DefaultSingletonTraits<PluginFinder>;
diff --git a/chrome/browser/plugins/plugin_info_message_filter.cc b/chrome/browser/plugins/plugin_info_message_filter.cc
index 399a01f..f2260e4 100644
--- a/chrome/browser/plugins/plugin_info_message_filter.cc
+++ b/chrome/browser/plugins/plugin_info_message_filter.cc
@@ -31,7 +31,7 @@
#endif
using content::PluginService;
-using webkit::WebPluginInfo;
+using content::WebPluginInfo;
namespace {
diff --git a/chrome/browser/plugins/plugin_info_message_filter.h b/chrome/browser/plugins/plugin_info_message_filter.h
index 9eaafe1..d57427e 100644
--- a/chrome/browser/plugins/plugin_info_message_filter.h
+++ b/chrome/browser/plugins/plugin_info_message_filter.h
@@ -25,9 +25,6 @@
namespace content {
class ResourceContext;
-}
-
-namespace webkit {
struct WebPluginInfo;
}
@@ -46,7 +43,7 @@
void DecidePluginStatus(
const GetPluginInfo_Params& params,
- const webkit::WebPluginInfo& plugin,
+ const content::WebPluginInfo& plugin,
const PluginMetadata* plugin_metadata,
ChromeViewHostMsg_GetPluginInfo_Status* status) const;
bool FindEnabledPlugin(int render_view_id,
@@ -54,10 +51,10 @@
const GURL& top_origin_url,
const std::string& mime_type,
ChromeViewHostMsg_GetPluginInfo_Status* status,
- webkit::WebPluginInfo* plugin,
+ content::WebPluginInfo* plugin,
std::string* actual_mime_type,
scoped_ptr<PluginMetadata>* plugin_metadata) const;
- void GetPluginContentSetting(const webkit::WebPluginInfo& plugin,
+ void GetPluginContentSetting(const content::WebPluginInfo& plugin,
const GURL& policy_url,
const GURL& plugin_url,
const std::string& resource,
@@ -99,7 +96,7 @@
// |base::Bind| doesn't support the required arity <http://crbug.com/98542>.
void PluginsLoaded(const GetPluginInfo_Params& params,
IPC::Message* reply_msg,
- const std::vector<webkit::WebPluginInfo>& plugins);
+ const std::vector<content::WebPluginInfo>& plugins);
Context context_;
diff --git a/chrome/browser/plugins/plugin_infobar_delegates.cc b/chrome/browser/plugins/plugin_infobar_delegates.cc
index 2ad36c7..e4a2651 100644
--- a/chrome/browser/plugins/plugin_infobar_delegates.cc
+++ b/chrome/browser/plugins/plugin_infobar_delegates.cc
@@ -172,6 +172,8 @@
InfoBarService* infobar_service,
PluginInstaller* installer,
scoped_ptr<PluginMetadata> plugin_metadata) {
+ // Copy the name out of |plugin_metadata| now, since the Pass() call below
+ // will make it impossible to get at.
string16 name(plugin_metadata->name());
infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
new OutdatedPluginInfoBarDelegate(
@@ -293,9 +295,7 @@
// Return early if the message doesn't change. This is important in case the
// PluginInstaller is still iterating over its observers (otherwise we would
// keep replacing infobar delegates infinitely).
- if (message_ == message)
- return;
- if (!owner())
+ if ((message_ == message) || !owner())
return;
PluginInstallerInfoBarDelegate::Replace(
this, installer(), plugin_metadata_->Clone(), false, message);
@@ -396,7 +396,6 @@
url = google_util::AppendGoogleLocaleParam(GURL(
"https://www.google.com/support/chrome/bin/answer.py?answer=142064"));
}
-
web_contents()->OpenURL(content::OpenURLParams(
url, content::Referrer(),
(disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
@@ -436,9 +435,7 @@
// Return early if the message doesn't change. This is important in case the
// PluginInstaller is still iterating over its observers (otherwise we would
// keep replacing infobar delegates infinitely).
- if (message_ == message)
- return;
- if (!owner())
+ if ((message_ == message) || !owner())
return;
Replace(this, installer(), plugin_metadata_->Clone(), new_install_, message);
}
diff --git a/chrome/browser/plugins/plugin_infobar_delegates.h b/chrome/browser/plugins/plugin_infobar_delegates.h
index 72ab27c..35a064c 100644
--- a/chrome/browser/plugins/plugin_infobar_delegates.h
+++ b/chrome/browser/plugins/plugin_infobar_delegates.h
@@ -23,11 +23,9 @@
// Base class for blocked plug-in infobars.
class PluginInfoBarDelegate : public ConfirmInfoBarDelegate {
- public:
+ protected:
PluginInfoBarDelegate(InfoBarService* infobar_service,
const std::string& identifier);
-
- protected:
virtual ~PluginInfoBarDelegate();
// ConfirmInfoBarDelegate:
@@ -50,7 +48,8 @@
// Infobar that's shown when a plug-in requires user authorization to run.
class UnauthorizedPluginInfoBarDelegate : public PluginInfoBarDelegate {
public:
- // Creates an unauthorized plugin delegate and adds it to |infobar_service|.
+ // Creates an unauthorized plugin infobar delegate and adds it to
+ // |infobar_service|.
static void Create(InfoBarService* infobar_service,
HostContentSettingsMap* content_settings,
const string16& name,
@@ -83,7 +82,8 @@
class OutdatedPluginInfoBarDelegate : public PluginInfoBarDelegate,
public WeakPluginInstallerObserver {
public:
- // Creates an outdated plugin delegate and adds it to |infobar_service|.
+ // Creates an outdated plugin infobar delegate and adds it to
+ // |infobar_service|.
static void Create(InfoBarService* infobar_service,
PluginInstaller* installer,
scoped_ptr<PluginMetadata> metadata);
@@ -144,7 +144,7 @@
// the user to install or update a particular plugin.
static void Replace(InfoBarDelegate* infobar,
PluginInstaller* installer,
- scoped_ptr<PluginMetadata> metadata,
+ scoped_ptr<PluginMetadata> plugin_metadata,
bool new_install,
const string16& message);
diff --git a/chrome/browser/plugins/plugin_installer.h b/chrome/browser/plugins/plugin_installer.h
index 36a4261..978fe1a 100644
--- a/chrome/browser/plugins/plugin_installer.h
+++ b/chrome/browser/plugins/plugin_installer.h
@@ -18,9 +18,6 @@
namespace content {
class WebContents;
-}
-
-namespace webkit {
struct WebPluginInfo;
}
diff --git a/chrome/browser/plugins/plugin_installer_unittest.cc b/chrome/browser/plugins/plugin_installer_unittest.cc
index 9fd2e41..bceecc4 100644
--- a/chrome/browser/plugins/plugin_installer_unittest.cc
+++ b/chrome/browser/plugins/plugin_installer_unittest.cc
@@ -5,19 +5,18 @@
#include "chrome/browser/plugins/plugin_installer.h"
#include "base/strings/utf_string_conversions.h"
+#include "content/public/common/webplugininfo.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "webkit/plugins/webplugininfo.h"
-
-using webkit::WebPluginInfo;
namespace {
PluginInstaller::SecurityStatus GetSecurityStatus(PluginInstaller* installer,
const char* version) {
- WebPluginInfo plugin(ASCIIToUTF16("Foo plug-in"),
- base::FilePath(FILE_PATH_LITERAL("/tmp/plugin.so")),
- ASCIIToUTF16(version),
- ASCIIToUTF16("Foo plug-in."));
+ content:: WebPluginInfo plugin(
+ ASCIIToUTF16("Foo plug-in"),
+ base::FilePath(FILE_PATH_LITERAL("/tmp/plugin.so")),
+ ASCIIToUTF16(version),
+ ASCIIToUTF16("Foo plug-in."));
return installer->GetSecurityStatus(plugin);
}
diff --git a/chrome/browser/plugins/plugin_metadata.cc b/chrome/browser/plugins/plugin_metadata.cc
index ce64531..5f2fc50 100644
--- a/chrome/browser/plugins/plugin_metadata.cc
+++ b/chrome/browser/plugins/plugin_metadata.cc
@@ -8,8 +8,7 @@
#include "base/logging.h"
#include "base/strings/string_util.h"
-#include "webkit/plugins/npapi/plugin_utils.h"
-#include "webkit/plugins/webplugininfo.h"
+#include "content/public/common/webplugininfo.h"
// static
const char PluginMetadata::kAdobeReaderGroupName[] = "Adobe Reader";
@@ -59,7 +58,7 @@
all_mime_types_.end();
}
-bool PluginMetadata::MatchesPlugin(const webkit::WebPluginInfo& plugin) {
+bool PluginMetadata::MatchesPlugin(const content::WebPluginInfo& plugin) {
for (size_t i = 0; i < matching_mime_types_.size(); ++i) {
// To have a match, every one of the |matching_mime_types_|
// must be handled by the plug-in.
@@ -92,7 +91,7 @@
}
PluginMetadata::SecurityStatus PluginMetadata::GetSecurityStatus(
- const webkit::WebPluginInfo& plugin) const {
+ const content::WebPluginInfo& plugin) const {
if (versions_.empty()) {
#if defined(OS_LINUX)
// On Linux, unknown plugins require authorization.
@@ -103,7 +102,7 @@
}
Version version;
- webkit::npapi::CreateVersionFromString(plugin.version, &version);
+ content::WebPluginInfo::CreateVersionFromString(plugin.version, &version);
if (!version.IsValid())
version = Version("0");
diff --git a/chrome/browser/plugins/plugin_metadata.h b/chrome/browser/plugins/plugin_metadata.h
index 69019a7..98d1925 100644
--- a/chrome/browser/plugins/plugin_metadata.h
+++ b/chrome/browser/plugins/plugin_metadata.h
@@ -12,7 +12,7 @@
#include "base/version.h"
#include "url/gurl.h"
-namespace webkit {
+namespace content {
struct WebPluginInfo;
}
@@ -72,7 +72,7 @@
// Checks if |plugin| mime types match all |matching_mime_types_|.
// If there is no |matching_mime_types_|, |group_name_matcher_| is used
// for matching.
- bool MatchesPlugin(const webkit::WebPluginInfo& plugin);
+ bool MatchesPlugin(const content::WebPluginInfo& plugin);
// If |status_str| describes a valid security status, writes it to |status|
// and returns true, else returns false and leaves |status| unchanged.
@@ -81,7 +81,7 @@
// Returns the security status for the given plug-in (i.e. whether it is
// considered out-of-date, etc.)
- SecurityStatus GetSecurityStatus(const webkit::WebPluginInfo& plugin) const;
+ SecurityStatus GetSecurityStatus(const content::WebPluginInfo& plugin) const;
scoped_ptr<PluginMetadata> Clone() const;
diff --git a/chrome/browser/plugins/plugin_metadata_unittest.cc b/chrome/browser/plugins/plugin_metadata_unittest.cc
index 0ff692c..bb69ee7 100644
--- a/chrome/browser/plugins/plugin_metadata_unittest.cc
+++ b/chrome/browser/plugins/plugin_metadata_unittest.cc
@@ -5,20 +5,19 @@
#include "chrome/browser/plugins/plugin_metadata.h"
#include "base/strings/utf_string_conversions.h"
+#include "content/public/common/webplugininfo.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "webkit/plugins/webplugininfo.h"
-
-using webkit::WebPluginInfo;
namespace {
PluginMetadata::SecurityStatus GetSecurityStatus(
PluginMetadata* plugin_metadata,
const char* version) {
- WebPluginInfo plugin(ASCIIToUTF16("Foo plug-in"),
- base::FilePath(FILE_PATH_LITERAL("/tmp/plugin.so")),
- ASCIIToUTF16(version),
- ASCIIToUTF16("Foo plug-in."));
+ content::WebPluginInfo plugin(
+ ASCIIToUTF16("Foo plug-in"),
+ base::FilePath(FILE_PATH_LITERAL("/tmp/plugin.so")),
+ ASCIIToUTF16(version),
+ ASCIIToUTF16("Foo plug-in."));
return plugin_metadata->GetSecurityStatus(plugin);
}
diff --git a/chrome/browser/plugins/plugin_observer.cc b/chrome/browser/plugins/plugin_observer.cc
index a6a64a2..7c9cd67 100644
--- a/chrome/browser/plugins/plugin_observer.cc
+++ b/chrome/browser/plugins/plugin_observer.cc
@@ -29,10 +29,10 @@
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_view.h"
+#include "content/public/common/webplugininfo.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
-#include "webkit/plugins/webplugininfo.h"
#if defined(ENABLE_PLUGIN_INSTALLATION)
#if defined(OS_WIN)
@@ -83,8 +83,7 @@
content::WebContents* web_contents,
PluginInstaller* installer,
scoped_ptr<PluginMetadata> plugin_metadata)
- : TabModalConfirmDialogDelegate(web_contents),
- WeakPluginInstallerObserver(installer),
+ : WeakPluginInstallerObserver(installer),
web_contents_(web_contents),
plugin_metadata_(plugin_metadata.Pass()) {
}
@@ -404,7 +403,7 @@
scoped_ptr<PluginMetadata> plugin;
bool ret = PluginFinder::GetInstance()->FindPluginWithIdentifier(
- identifier, NULL, &plugin);
+ identifier, NULL, &plugin);
DCHECK(ret);
PluginMetroModeInfoBarDelegate::Create(
diff --git a/chrome/browser/plugins/plugin_prefs.cc b/chrome/browser/plugins/plugin_prefs.cc
index 37841ca..a88e151 100644
--- a/chrome/browser/plugins/plugin_prefs.cc
+++ b/chrome/browser/plugins/plugin_prefs.cc
@@ -31,7 +31,7 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/plugin_service.h"
-#include "webkit/plugins/webplugininfo.h"
+#include "content/public/common/webplugininfo.h"
using content::BrowserThread;
using content::PluginService;
@@ -110,7 +110,7 @@
void PluginPrefs::EnablePluginGroupInternal(
bool enabled,
const string16& group_name,
- const std::vector<webkit::WebPluginInfo>& plugins) {
+ const std::vector<content::WebPluginInfo>& plugins) {
base::AutoLock auto_lock(lock_);
PluginFinder* finder = PluginFinder::GetInstance();
@@ -135,7 +135,7 @@
bool enabled, const base::FilePath& path,
const base::Callback<void(bool)>& callback) {
PluginFinder* finder = PluginFinder::GetInstance();
- webkit::WebPluginInfo plugin;
+ content::WebPluginInfo plugin;
bool can_enable = true;
if (PluginService::GetInstance()->GetPluginInfoByPath(path, &plugin)) {
scoped_ptr<PluginMetadata> plugin_metadata(
@@ -169,7 +169,7 @@
const base::FilePath& path,
PluginFinder* plugin_finder,
const base::Callback<void(bool)>& callback,
- const std::vector<webkit::WebPluginInfo>& plugins) {
+ const std::vector<content::WebPluginInfo>& plugins) {
{
// Set the desired state for the plug-in.
base::AutoLock auto_lock(lock_);
@@ -225,7 +225,7 @@
}
}
-bool PluginPrefs::IsPluginEnabled(const webkit::WebPluginInfo& plugin) const {
+bool PluginPrefs::IsPluginEnabled(const content::WebPluginInfo& plugin) const {
scoped_ptr<PluginMetadata> plugin_metadata(
PluginFinder::GetInstance()->GetPluginMetadata(plugin));
string16 group_name = plugin_metadata->name();
@@ -522,7 +522,7 @@
}
void PluginPrefs::OnUpdatePreferences(
- const std::vector<webkit::WebPluginInfo>& plugins) {
+ const std::vector<content::WebPluginInfo>& plugins) {
if (!prefs_)
return;
diff --git a/chrome/browser/plugins/plugin_prefs.h b/chrome/browser/plugins/plugin_prefs.h
index fd0e403..bfcaa06 100644
--- a/chrome/browser/plugins/plugin_prefs.h
+++ b/chrome/browser/plugins/plugin_prefs.h
@@ -23,7 +23,7 @@
class ListValue;
}
-namespace webkit {
+namespace content {
struct WebPluginInfo;
}
@@ -70,7 +70,7 @@
PolicyStatus PolicyStatusForPlugin(const string16& name) const;
// Returns whether the plugin is enabled or not.
- bool IsPluginEnabled(const webkit::WebPluginInfo& plugin) const;
+ bool IsPluginEnabled(const content::WebPluginInfo& plugin) const;
void set_profile(Profile* profile) { profile_ = profile; }
@@ -117,16 +117,16 @@
void EnablePluginGroupInternal(
bool enabled,
const string16& group_name,
- const std::vector<webkit::WebPluginInfo>& plugins);
+ const std::vector<content::WebPluginInfo>& plugins);
void EnablePluginInternal(
bool enabled,
const base::FilePath& path,
PluginFinder* plugin_finder,
const base::Callback<void(bool)>& callback,
- const std::vector<webkit::WebPluginInfo>& plugins);
+ const std::vector<content::WebPluginInfo>& plugins);
// Called on the UI thread with the plugin data to save the preferences.
- void OnUpdatePreferences(const std::vector<webkit::WebPluginInfo>& plugins);
+ void OnUpdatePreferences(const std::vector<content::WebPluginInfo>& plugins);
// Sends the notification that plugin data has changed.
void NotifyPluginStatusChanged();
diff --git a/chrome/browser/plugins/plugin_prefs_unittest.cc b/chrome/browser/plugins/plugin_prefs_unittest.cc
index 18863c8..53e148d 100644
--- a/chrome/browser/plugins/plugin_prefs_unittest.cc
+++ b/chrome/browser/plugins/plugin_prefs_unittest.cc
@@ -13,10 +13,11 @@
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "content/public/browser/plugin_service.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/common/webplugininfo.h"
#include "content/public/test/test_browser_thread.h"
+#include "content/public/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "webkit/plugins/npapi/mock_plugin_list.h"
-#include "webkit/plugins/webplugininfo.h"
using content::BrowserThread;
using content::PluginService;
@@ -46,6 +47,11 @@
return path;
}
+void GotPlugins(const base::Closure& quit_closure,
+ const std::vector<content::WebPluginInfo>& plugins) {
+ quit_closure.Run();
+}
+
} // namespace
class PluginPrefsTest : public ::testing::Test {
@@ -177,35 +183,52 @@
plugin_prefs_->PolicyStatusForPlugin(k42));
}
+// Linux Aura doesn't support NPAPI.
+#if !(defined(OS_LINUX) && defined(USE_AURA))
+
TEST_F(PluginPrefsTest, UnifiedPepperFlashState) {
base::ShadowingAtExitManager at_exit_manager_; // Destroys the PluginService.
base::MessageLoop message_loop;
content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
- webkit::npapi::MockPluginList plugin_list;
- PluginService::GetInstance()->SetPluginListForTesting(&plugin_list);
PluginService::GetInstance()->Init();
+ PluginService::GetInstance()->DisablePluginsDiscoveryForTesting();
string16 component_updated_plugin_name(
ASCIIToUTF16("Component-updated Pepper Flash"));
- webkit::WebPluginInfo component_updated_plugin_1(
+ content::WebPluginInfo component_updated_plugin_1(
component_updated_plugin_name,
GetComponentUpdatedPepperFlashPath(FILE_PATH_LITERAL("11.3.31.227")),
ASCIIToUTF16("11.3.31.227"),
ASCIIToUTF16(""));
- webkit::WebPluginInfo component_updated_plugin_2(
+ content::WebPluginInfo component_updated_plugin_2(
component_updated_plugin_name,
GetComponentUpdatedPepperFlashPath(FILE_PATH_LITERAL("11.3.31.228")),
ASCIIToUTF16("11.3.31.228"),
ASCIIToUTF16(""));
- webkit::WebPluginInfo bundled_plugin(ASCIIToUTF16("Pepper Flash"),
- GetBundledPepperFlashPath(),
- ASCIIToUTF16("11.3.31.229"),
- ASCIIToUTF16(""));
+ content::WebPluginInfo bundled_plugin(ASCIIToUTF16("Pepper Flash"),
+ GetBundledPepperFlashPath(),
+ ASCIIToUTF16("11.3.31.229"),
+ ASCIIToUTF16(""));
- plugin_list.AddPluginToLoad(component_updated_plugin_1);
- plugin_list.AddPluginToLoad(component_updated_plugin_2);
- plugin_list.AddPluginToLoad(bundled_plugin);
+ PluginService::GetInstance()->RegisterInternalPlugin(
+ component_updated_plugin_1, false);
+ PluginService::GetInstance()->RegisterInternalPlugin(
+ component_updated_plugin_2, false);
+ PluginService::GetInstance()->RegisterInternalPlugin(bundled_plugin, false);
+
+#if !defined(OS_WIN)
+ // Can't go out of process in unit tests.
+ content::RenderProcessHost::SetRunRendererInProcess(true);
+#endif
+ scoped_refptr<content::MessageLoopRunner> runner =
+ new content::MessageLoopRunner;
+ PluginService::GetInstance()->GetPlugins(
+ base::Bind(&GotPlugins, runner->QuitClosure()));
+ runner->Run();
+#if !defined(OS_WIN)
+ content::RenderProcessHost::SetRunRendererInProcess(false);
+#endif
// Set the state of any of the three plugins will affect the others.
EnablePluginSynchronously(true, component_updated_plugin_1.path, true);
@@ -249,6 +272,6 @@
EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_1));
EXPECT_FALSE(plugin_prefs_->IsPluginEnabled(component_updated_plugin_2));
EXPECT_TRUE(plugin_prefs_->IsPluginEnabled(bundled_plugin));
-
- PluginService::GetInstance()->SetPluginListForTesting(NULL);
}
+
+#endif
diff --git a/chrome/browser/plugins/plugin_status_pref_setter.cc b/chrome/browser/plugins/plugin_status_pref_setter.cc
index 09bf546..f2b4e7f 100644
--- a/chrome/browser/plugins/plugin_status_pref_setter.cc
+++ b/chrome/browser/plugins/plugin_status_pref_setter.cc
@@ -15,7 +15,7 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/plugin_service.h"
-#include "webkit/plugins/webplugininfo.h"
+#include "content/public/common/webplugininfo.h"
using content::BrowserThread;
using content::PluginService;
@@ -59,7 +59,7 @@
void PluginStatusPrefSetter::GotPlugins(
scoped_refptr<PluginPrefs> plugin_prefs,
- const std::vector<webkit::WebPluginInfo>& /* plugins */) {
+ const std::vector<content::WebPluginInfo>& plugins) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// Set the values on the PrefService instead of through the PrefMembers to
// notify observers if they changed.
diff --git a/chrome/browser/plugins/plugin_status_pref_setter.h b/chrome/browser/plugins/plugin_status_pref_setter.h
index 034b74a..e77c94a 100644
--- a/chrome/browser/plugins/plugin_status_pref_setter.h
+++ b/chrome/browser/plugins/plugin_status_pref_setter.h
@@ -17,7 +17,7 @@
class PrefService;
class Profile;
-namespace webkit {
+namespace content {
struct WebPluginInfo;
}
@@ -53,7 +53,7 @@
private:
void StartUpdate();
void GotPlugins(scoped_refptr<PluginPrefs> plugin_prefs,
- const std::vector<webkit::WebPluginInfo>& plugins);
+ const std::vector<content::WebPluginInfo>& plugins);
content::NotificationRegistrar registrar_;
// Weak pointer.
diff --git a/chrome/browser/policy/browser_policy_connector.cc b/chrome/browser/policy/browser_policy_connector.cc
index 718e572..2a1d1cf 100644
--- a/chrome/browser/policy/browser_policy_connector.cc
+++ b/chrome/browser/policy/browser_policy_connector.cc
@@ -37,7 +37,7 @@
#include "grit/generated_resources.h"
#include "net/url_request/url_request_context_getter.h"
#include "policy/policy_constants.h"
-#include "third_party/icu/public/i18n/unicode/regex.h"
+#include "third_party/icu/source/i18n/unicode/regex.h"
#if defined(OS_WIN)
#include "chrome/browser/policy/policy_loader_win.h"
diff --git a/chrome/browser/policy/cloud/cloud_policy_client.cc b/chrome/browser/policy/cloud/cloud_policy_client.cc
index 3581d31..a9b30c3 100644
--- a/chrome/browser/policy/cloud/cloud_policy_client.cc
+++ b/chrome/browser/policy/cloud/cloud_policy_client.cc
@@ -34,7 +34,7 @@
bool IsChromePolicy(const std::string& type) {
return type == dm_protocol::kChromeDevicePolicyType ||
- type == dm_protocol::kChromeUserPolicyType;
+ type == GetChromeUserPolicyType();
}
} // namespace
diff --git a/chrome/browser/policy/cloud/cloud_policy_constants.cc b/chrome/browser/policy/cloud/cloud_policy_constants.cc
index 905ddab..83f05f4 100644
--- a/chrome/browser/policy/cloud/cloud_policy_constants.cc
+++ b/chrome/browser/policy/cloud/cloud_policy_constants.cc
@@ -4,6 +4,9 @@
#include "chrome/browser/policy/cloud/cloud_policy_constants.h"
+#include "base/command_line.h"
+#include "chrome/common/chrome_switches.h"
+
namespace policy {
// Constants related to the device management protocol.
@@ -32,10 +35,10 @@
const char kValueUserAffiliationNone[] = "none";
const char kChromeDevicePolicyType[] = "google/chromeos/device";
-// TODO(joaodasilva): add a new constant for Android here.
-// http://crbug.com/248527
#if defined(OS_CHROMEOS)
const char kChromeUserPolicyType[] = "google/chromeos/user";
+#elif defined(OS_ANDROID)
+const char kChromeUserPolicyType[] = "google/android/user";
#else
const char kChromeUserPolicyType[] = "google/chrome/user";
#endif
@@ -44,4 +47,13 @@
} // namespace dm_protocol
+const char* GetChromeUserPolicyType() {
+#if defined(OS_ANDROID)
+ CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kFakeCloudPolicyType))
+ return "google/chrome/user";
+#endif
+ return dm_protocol::kChromeUserPolicyType;
+}
+
} // namespace policy
diff --git a/chrome/browser/policy/cloud/cloud_policy_constants.h b/chrome/browser/policy/cloud/cloud_policy_constants.h
index 028d9c9..a0fb70b 100644
--- a/chrome/browser/policy/cloud/cloud_policy_constants.h
+++ b/chrome/browser/policy/cloud/cloud_policy_constants.h
@@ -104,6 +104,12 @@
// A pair that combines a policy fetch type and entity ID.
typedef std::pair<std::string, std::string> PolicyNamespaceKey;
+// Returns the Chrome user policy type to use. This allows overridding the
+// default user policy type on Android for testing purposes.
+// TODO(joaodasilva): remove this once the server is ready.
+// http://crbug.com/248527
+const char* GetChromeUserPolicyType();
+
} // namespace policy
#endif // CHROME_BROWSER_POLICY_CLOUD_CLOUD_POLICY_CONSTANTS_H_
diff --git a/chrome/browser/policy/cloud/user_cloud_policy_manager.cc b/chrome/browser/policy/cloud/user_cloud_policy_manager.cc
index edaf8be..09db701 100644
--- a/chrome/browser/policy/cloud/user_cloud_policy_manager.cc
+++ b/chrome/browser/policy/cloud/user_cloud_policy_manager.cc
@@ -21,7 +21,7 @@
Profile* profile,
scoped_ptr<UserCloudPolicyStore> store)
: CloudPolicyManager(
- PolicyNamespaceKey(dm_protocol::kChromeUserPolicyType, std::string()),
+ PolicyNamespaceKey(GetChromeUserPolicyType(), std::string()),
store.get()),
profile_(profile),
store_(store.Pass()) {
diff --git a/chrome/browser/policy/cloud/user_cloud_policy_store_base.cc b/chrome/browser/policy/cloud/user_cloud_policy_store_base.cc
index c875bc7..5d88574 100644
--- a/chrome/browser/policy/cloud/user_cloud_policy_store_base.cc
+++ b/chrome/browser/policy/cloud/user_cloud_policy_store_base.cc
@@ -25,7 +25,7 @@
// Configure the validator.
UserCloudPolicyValidator* validator =
UserCloudPolicyValidator::Create(policy.Pass());
- validator->ValidatePolicyType(dm_protocol::kChromeUserPolicyType);
+ validator->ValidatePolicyType(GetChromeUserPolicyType());
validator->ValidateAgainstCurrentPolicy(
policy_.get(),
CloudPolicyValidatorBase::TIMESTAMP_REQUIRED,
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_android.cc b/chrome/browser/policy/cloud/user_policy_signin_service_android.cc
index 93564e7..f165796 100644
--- a/chrome/browser/policy/cloud/user_policy_signin_service_android.cc
+++ b/chrome/browser/policy/cloud/user_policy_signin_service_android.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
+#include "base/command_line.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/prefs/pref_service.h"
@@ -18,11 +19,23 @@
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager.h"
#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "net/base/network_change_notifier.h"
namespace policy {
+namespace {
+
+enterprise_management::DeviceRegisterRequest::Type GetRegistrationType() {
+ CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kFakeCloudPolicyType))
+ return enterprise_management::DeviceRegisterRequest::BROWSER;
+ return enterprise_management::DeviceRegisterRequest::ANDROID_BROWSER;
+}
+
+} // namespace
+
UserPolicySigninService::UserPolicySigninService(Profile* profile)
: UserPolicySigninServiceBase(profile),
weak_factory_(this) {}
@@ -43,14 +56,12 @@
// Fire off the registration process. Callback keeps the CloudPolicyClient
// alive for the length of the registration process.
- // TODO(joaodasilva): use DeviceRegisterRequest::ANDROID_BROWSER here once
- // the server is ready. http://crbug.com/248527
const bool force_load_policy = false;
registration_helper_.reset(new CloudPolicyClientRegistrationHelper(
profile()->GetRequestContext(),
policy_client.get(),
force_load_policy,
- enterprise_management::DeviceRegisterRequest::BROWSER));
+ GetRegistrationType()));
registration_helper_->StartRegistration(
ProfileOAuth2TokenServiceFactory::GetForProfile(profile()),
username,
@@ -132,14 +143,12 @@
profile()->GetPrefs()->SetInt64(prefs::kLastPolicyCheckTime,
base::Time::Now().ToInternalValue());
- // TODO(joaodasilva): use DeviceRegisterRequest::ANDROID_BROWSER here once
- // the server is ready. http://crbug.com/248527
const bool force_load_policy = false;
registration_helper_.reset(new CloudPolicyClientRegistrationHelper(
profile()->GetRequestContext(),
GetManager()->core()->client(),
force_load_policy,
- enterprise_management::DeviceRegisterRequest::BROWSER));
+ GetRegistrationType()));
registration_helper_->StartRegistration(
ProfileOAuth2TokenServiceFactory::GetForProfile(profile()),
username,
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc b/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
index b9402b3..82539a3 100644
--- a/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
+++ b/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
@@ -98,8 +98,7 @@
class FakeProfileOAuth2TokenService : public AndroidProfileOAuth2TokenService {
public:
- explicit FakeProfileOAuth2TokenService(Profile* profile)
- : AndroidProfileOAuth2TokenService(profile->GetRequestContext()) {
+ explicit FakeProfileOAuth2TokenService(Profile* profile) {
Initialize(profile);
}
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc
index 87f9f7e..869c9bf 100644
--- a/chrome/browser/policy/policy_browsertest.cc
+++ b/chrome/browser/policy/policy_browsertest.cc
@@ -95,6 +95,7 @@
#include "content/public/common/page_transition_types.h"
#include "content/public/common/process_type.h"
#include "content/public/common/url_constants.h"
+#include "content/public/common/webplugininfo.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/download_test_observer.h"
#include "content/public/test/mock_notification_observer.h"
@@ -116,9 +117,7 @@
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "url/gurl.h"
-#include "webkit/plugins/npapi/plugin_utils.h"
#include "webkit/plugins/plugin_constants.h"
-#include "webkit/plugins/webplugininfo.h"
#if defined(OS_CHROMEOS)
#include "ash/accelerators/accelerator_controller.h"
@@ -132,6 +131,10 @@
#include "chromeos/audio/audio_pref_handler.h"
#endif
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
using content::BrowserThread;
using content::URLRequestMockHTTPJob;
using testing::AnyNumber;
@@ -335,8 +338,8 @@
return result == 123;
}
-void CopyPluginListAndQuit(std::vector<webkit::WebPluginInfo>* out,
- const std::vector<webkit::WebPluginInfo>& in) {
+void CopyPluginListAndQuit(std::vector<content::WebPluginInfo>* out,
+ const std::vector<content::WebPluginInfo>& in) {
*out = in;
base::MessageLoop::current()->QuitWhenIdle();
}
@@ -347,15 +350,15 @@
base::MessageLoop::current()->QuitWhenIdle();
}
-void GetPluginList(std::vector<webkit::WebPluginInfo>* plugins) {
+void GetPluginList(std::vector<content::WebPluginInfo>* plugins) {
content::PluginService* service = content::PluginService::GetInstance();
service->GetPlugins(base::Bind(CopyPluginListAndQuit, plugins));
content::RunMessageLoop();
}
-const webkit::WebPluginInfo* GetFlashPlugin(
- const std::vector<webkit::WebPluginInfo>& plugins) {
- const webkit::WebPluginInfo* flash = NULL;
+const content::WebPluginInfo* GetFlashPlugin(
+ const std::vector<content::WebPluginInfo>& plugins) {
+ const content::WebPluginInfo* flash = NULL;
for (size_t i = 0; i < plugins.size(); ++i) {
if (plugins[i].name == ASCIIToUTF16(kFlashPluginName)) {
flash = &plugins[i];
@@ -373,7 +376,7 @@
}
bool SetPluginEnabled(PluginPrefs* plugin_prefs,
- const webkit::WebPluginInfo* plugin,
+ const content::WebPluginInfo* plugin,
bool enabled) {
bool ok = false;
plugin_prefs->EnablePlugin(enabled, plugin->path,
@@ -657,6 +660,12 @@
#endif
IN_PROC_BROWSER_TEST_F(PolicyTest, BookmarkBarEnabled) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
// Verifies that the bookmarks bar can be forced to always or never show up.
// Test starts in about:blank.
@@ -927,7 +936,7 @@
ui_test_utils::SendToOmniboxAndSubmit(location_bar,
"https://www.google.com/?espv=1#q=foobar");
EXPECT_TRUE(
- browser()->toolbar_model()->WouldReplaceSearchURLWithSearchTerms());
+ browser()->toolbar_model()->WouldReplaceSearchURLWithSearchTerms(false));
EXPECT_EQ(ASCIIToUTF16("foobar"),
location_bar->GetLocationEntry()->GetText());
@@ -937,7 +946,7 @@
ui_test_utils::SendToOmniboxAndSubmit(location_bar,
"https://www.google.com/?q=foobar");
EXPECT_FALSE(
- browser()->toolbar_model()->WouldReplaceSearchURLWithSearchTerms());
+ browser()->toolbar_model()->WouldReplaceSearchURLWithSearchTerms(false));
EXPECT_EQ(ASCIIToUTF16("https://www.google.com/?q=foobar"),
location_bar->GetLocationEntry()->GetText());
@@ -947,7 +956,7 @@
ui_test_utils::SendToOmniboxAndSubmit(location_bar,
"https://www.google.com/search?espv=1#q=banana");
EXPECT_TRUE(
- browser()->toolbar_model()->WouldReplaceSearchURLWithSearchTerms());
+ browser()->toolbar_model()->WouldReplaceSearchURLWithSearchTerms(false));
EXPECT_EQ(ASCIIToUTF16("banana"),
location_bar->GetLocationEntry()->GetText());
@@ -957,7 +966,7 @@
ui_test_utils::SendToOmniboxAndSubmit(location_bar,
"https://www.google.com/search?q=tractor+parts&espv=1");
EXPECT_TRUE(
- browser()->toolbar_model()->WouldReplaceSearchURLWithSearchTerms());
+ browser()->toolbar_model()->WouldReplaceSearchURLWithSearchTerms(false));
EXPECT_EQ(ASCIIToUTF16("tractor parts"),
location_bar->GetLocationEntry()->GetText());
@@ -966,7 +975,7 @@
ui_test_utils::SendToOmniboxAndSubmit(location_bar,
"https://www.google.com/search?q=tractor+parts&espv=1#q=foobar");
EXPECT_TRUE(
- browser()->toolbar_model()->WouldReplaceSearchURLWithSearchTerms());
+ browser()->toolbar_model()->WouldReplaceSearchURLWithSearchTerms(false));
EXPECT_EQ(ASCIIToUTF16("foobar"),
location_bar->GetLocationEntry()->GetText());
}
@@ -1021,9 +1030,9 @@
// Verify that the Flash plugin exists and that it can be enabled and disabled
// by the user.
- std::vector<webkit::WebPluginInfo> plugins;
+ std::vector<content::WebPluginInfo> plugins;
GetPluginList(&plugins);
- const webkit::WebPluginInfo* flash = GetFlashPlugin(plugins);
+ const content::WebPluginInfo* flash = GetFlashPlugin(plugins);
if (!flash)
return;
PluginPrefs* plugin_prefs =
@@ -1052,9 +1061,9 @@
// Verify that the Flash plugin exists and that it can be enabled and disabled
// by the user.
- std::vector<webkit::WebPluginInfo> plugins;
+ std::vector<content::WebPluginInfo> plugins;
GetPluginList(&plugins);
- const webkit::WebPluginInfo* flash = GetFlashPlugin(plugins);
+ const content::WebPluginInfo* flash = GetFlashPlugin(plugins);
if (!flash)
return;
PluginPrefs* plugin_prefs =
@@ -1091,9 +1100,9 @@
IN_PROC_BROWSER_TEST_F(PolicyTest, EnabledPlugins) {
// Verifies that a plugin can be force-installed with a policy.
- std::vector<webkit::WebPluginInfo> plugins;
+ std::vector<content::WebPluginInfo> plugins;
GetPluginList(&plugins);
- const webkit::WebPluginInfo* flash = GetFlashPlugin(plugins);
+ const content::WebPluginInfo* flash = GetFlashPlugin(plugins);
if (!flash)
return;
PluginPrefs* plugin_prefs =
@@ -1190,6 +1199,12 @@
}
IN_PROC_BROWSER_TEST_F(PolicyTest, WebStoreIconHidden) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
// Verifies that the web store icons can be hidden from the new tab page.
// Open new tab page and look for the web store icons.
@@ -1473,6 +1488,12 @@
}
IN_PROC_BROWSER_TEST_F(PolicyTest, HomepageLocation) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
// Verifies that the homepage can be configured with policies.
// Set a default, and check that the home button navigates there.
browser()->profile()->GetPrefs()->SetString(
@@ -1636,16 +1657,16 @@
// Verify that the translate infobar showed up.
ASSERT_EQ(1u, infobar_service->infobar_count());
- InfoBarDelegate* infobar_delegate = infobar_service->infobar_at(0);
- TranslateInfoBarDelegate* delegate =
- infobar_delegate->AsTranslateInfoBarDelegate();
- ASSERT_TRUE(delegate);
+ InfoBarDelegate* infobar = infobar_service->infobar_at(0);
+ TranslateInfoBarDelegate* translate_infobar_delegate =
+ infobar->AsTranslateInfoBarDelegate();
+ ASSERT_TRUE(translate_infobar_delegate);
EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE,
- delegate->infobar_type());
- EXPECT_EQ("fr", delegate->original_language_code());
+ translate_infobar_delegate->infobar_type());
+ EXPECT_EQ("fr", translate_infobar_delegate->original_language_code());
// Now force disable translate.
- infobar_service->RemoveInfoBar(infobar_delegate);
+ infobar_service->RemoveInfoBar(infobar);
EXPECT_EQ(0u, infobar_service->infobar_count());
policies.Set(key::kTranslateEnabled, POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER, base::Value::CreateBooleanValue(false), NULL);
diff --git a/chrome/browser/predictors/autocomplete_action_predictor.cc b/chrome/browser/predictors/autocomplete_action_predictor.cc
index 5a1e75b..2b9e732 100644
--- a/chrome/browser/predictors/autocomplete_action_predictor.cc
+++ b/chrome/browser/predictors/autocomplete_action_predictor.cc
@@ -138,7 +138,7 @@
void AutocompleteActionPredictor::StartPrerendering(
const GURL& url,
- content::SessionStorageNamespace* session_storage_namespace,
+ const content::SessionStorageNamespaceMap& session_storage_namespace_map,
const gfx::Size& size) {
// Only cancel the old prerender after starting the new one, so if the URLs
// are the same, the underlying prerender will be reused.
@@ -146,6 +146,11 @@
prerender_handle_.release());
if (prerender::PrerenderManager* prerender_manager =
prerender::PrerenderManagerFactory::GetForProfile(profile_)) {
+ content::SessionStorageNamespace* session_storage_namespace = NULL;
+ content::SessionStorageNamespaceMap::const_iterator it =
+ session_storage_namespace_map.find(std::string());
+ if (it != session_storage_namespace_map.end())
+ session_storage_namespace = it->second.get();
prerender_handle_.reset(prerender_manager->AddPrerenderFromOmnibox(
url, session_storage_namespace, size));
}
diff --git a/chrome/browser/predictors/autocomplete_action_predictor.h b/chrome/browser/predictors/autocomplete_action_predictor.h
index 762d31a..b1c4f97 100644
--- a/chrome/browser/predictors/autocomplete_action_predictor.h
+++ b/chrome/browser/predictors/autocomplete_action_predictor.h
@@ -98,7 +98,7 @@
// prerenders (if any).
void StartPrerendering(
const GURL& url,
- content::SessionStorageNamespace* session_storage_namespace,
+ const content::SessionStorageNamespaceMap& session_storage_namespace_map,
const gfx::Size& size);
// Return true if the suggestion type warrants a TCP/IP preconnection.
diff --git a/chrome/browser/predictors/resource_prefetch_predictor.h b/chrome/browser/predictors/resource_prefetch_predictor.h
index 3776241..ed177e4 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor.h
+++ b/chrome/browser/predictors/resource_prefetch_predictor.h
@@ -23,7 +23,7 @@
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "url/gurl.h"
-#include "webkit/glue/resource_type.h"
+#include "webkit/common/resource_type.h"
class PredictorsHandler;
class Profile;
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_tables.h b/chrome/browser/predictors/resource_prefetch_predictor_tables.h
index f8a965e..6995388 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor_tables.h
+++ b/chrome/browser/predictors/resource_prefetch_predictor_tables.h
@@ -14,7 +14,7 @@
#include "chrome/browser/predictors/predictor_table_base.h"
#include "chrome/browser/predictors/resource_prefetch_common.h"
#include "url/gurl.h"
-#include "webkit/glue/resource_type.h"
+#include "webkit/common/resource_type.h"
namespace sql {
class Statement;
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index b606a80..14cc6a7 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -42,6 +42,7 @@
#include "chrome/browser/net/http_server_properties_manager.h"
#include "chrome/browser/net/net_pref_observer.h"
#include "chrome/browser/net/predictor.h"
+#include "chrome/browser/net/pref_proxy_config_tracker_impl.h"
#include "chrome/browser/net/ssl_config_service_manager.h"
#include "chrome/browser/notifications/desktop_notification_service.h"
#include "chrome/browser/notifications/notification_prefs_manager.h"
@@ -258,6 +259,7 @@
chromeos::KioskAppManager::RegisterPrefs(registry);
chromeos::LoginUtils::RegisterPrefs(registry);
chromeos::Preferences::RegisterPrefs(registry);
+ chromeos::proxy_config::RegisterPrefs(registry);
chromeos::RegisterDisplayLocalStatePrefs(registry);
chromeos::ServicesCustomizationDocument::RegisterPrefs(registry);
chromeos::system::AutomaticRebootManager::RegisterPrefs(registry);
diff --git a/chrome/browser/prefs/pref_service_browsertest.cc b/chrome/browser/prefs/pref_service_browsertest.cc
index fc1ba42..c3c0856 100644
--- a/chrome/browser/prefs/pref_service_browsertest.cc
+++ b/chrome/browser/prefs/pref_service_browsertest.cc
@@ -23,6 +23,10 @@
#include "chrome/test/base/ui_test_utils.h"
#include "ui/gfx/rect.h"
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
// On GTK, resizing happens asynchronously and we currently don't have a way to
// get called back (it's probably possible, but we don't have that code). Since
// the GTK code is going away, not spending more time on this.
@@ -42,6 +46,12 @@
#define MAYBE_Test Test
#endif
IN_PROC_BROWSER_TEST_F(PreservedWindowPlacement, MAYBE_Test) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
gfx::Rect bounds = browser()->window()->GetBounds();
gfx::Rect expected_bounds(gfx::Rect(20, 30, 400, 500));
ASSERT_EQ(expected_bounds.ToString(), bounds.ToString());
@@ -112,6 +122,12 @@
};
IN_PROC_BROWSER_TEST_F(PreservedWindowPlacementIsLoaded, Test) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
// The window should open with the new reference profile, with window
// placement values stored in the user data directory.
JSONFileValueSerializer deserializer(tmp_pref_file_);
@@ -165,6 +181,12 @@
};
IN_PROC_BROWSER_TEST_F(PreservedWindowPlacementIsMigrated, Test) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
// The window should open with the old reference profile, with window
// placement values stored in Local State.
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc
index cfaf608..41c3423 100644
--- a/chrome/browser/prerender/prerender_browsertest.cc
+++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -54,6 +54,7 @@
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
+#include "extensions/common/switches.h"
#include "grit/generated_resources.h"
#include "net/dns/mock_host_resolver.h"
#include "net/url_request/url_request_context.h"
@@ -63,6 +64,10 @@
#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
using content::BrowserThread;
using content::DevToolsAgentHost;
using content::DevToolsClientHost;
@@ -126,6 +131,7 @@
case FINAL_STATUS_RENDERER_CRASHED:
case FINAL_STATUS_CANCELLED:
case FINAL_STATUS_DEVTOOLS_ATTACHED:
+ case FINAL_STATUS_PAGE_BEING_CAPTURED:
return true;
default:
return false;
@@ -639,7 +645,7 @@
current_browser()->tab_strip_model()->GetActiveWebContents();
if (!web_contents)
return NULL;
- return web_contents->GetController().GetSessionStorageNamespace();
+ return web_contents->GetController().GetDefaultSessionStorageNamespace();
}
virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
@@ -1158,10 +1164,6 @@
current_browser(), dest_url, disposition,
ui_test_utils::BROWSER_TEST_NONE);
- // Make sure the PrerenderContents found earlier was used or removed,
- // unless we expect the swap in to fail.
- EXPECT_EQ(expect_swap_to_succeed, !GetPrerenderContents());
-
if (call_javascript_ && web_contents && expect_swap_to_succeed) {
if (page_load_observer.get())
page_load_observer->Wait();
@@ -2697,6 +2699,12 @@
// Check that NaCl plugins work when enabled, with prerendering.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithNaCl,
PrerenderNaClPluginEnabled) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
PrerenderTestURL("files/prerender/prerender_plugin_nacl_enabled.html",
FINAL_STATUS_USED,
1);
@@ -2764,7 +2772,7 @@
extensions::FrameNavigationState::set_allow_extension_scheme(true);
CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kAllowLegacyExtensionManifests);
+ extensions::switches::kAllowLegacyExtensionManifests);
// Wait for the extension to set itself up and return control to us.
ASSERT_TRUE(
@@ -2899,4 +2907,23 @@
NavigateToDestUrlAndWaitForPassTitle();
}
+// Checks that a prerender that creates an audio stream (via a WebAudioDevice)
+// is cancelled.
+// http://crbug.com/261489
+IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderWebAudioDevice) {
+ PrerenderTestURL("files/prerender/prerender_web_audio_device.html",
+ FINAL_STATUS_CREATING_AUDIO_STREAM, 1);
+}
+
+// Checks that prerenders do not swap in to WebContents being captured.
+IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCapturedWebContents) {
+ PrerenderTestURL("files/prerender/prerender_page.html",
+ FINAL_STATUS_PAGE_BEING_CAPTURED, 1);
+ WebContents* web_contents =
+ current_browser()->tab_strip_model()->GetActiveWebContents();
+ web_contents->IncrementCapturerCount();
+ NavigateToDestURLWithDisposition(CURRENT_TAB, false);
+ web_contents->DecrementCapturerCount();
+}
+
} // namespace prerender
diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc
index 6f7caf4..957809f 100644
--- a/chrome/browser/prerender/prerender_contents.cc
+++ b/chrome/browser/prerender/prerender_contents.cc
@@ -180,8 +180,9 @@
SessionStorageNamespace* session_storage_namespace = NULL;
if (prerender_contents_) {
+ // TODO(ajwong): This does not correctly handle storage for isolated apps.
session_storage_namespace = prerender_contents_->
- GetController().GetSessionStorageNamespace();
+ GetController().GetDefaultSessionStorageNamespace();
}
prerender_manager_->StartPendingPrerenders(
child_id_, &pending_prerenders_, session_storage_namespace);
@@ -473,8 +474,12 @@
WebContents* PrerenderContents::CreateWebContents(
SessionStorageNamespace* session_storage_namespace) {
+ // TODO(ajwong): Remove the temporary map once prerendering is aware of
+ // multiple session storage namespaces per tab.
+ content::SessionStorageNamespaceMap session_storage_namespace_map;
+ session_storage_namespace_map[std::string()] = session_storage_namespace;
return WebContents::CreateWithSessionStorage(
- WebContents::CreateParams(profile_), session_storage_namespace);
+ WebContents::CreateParams(profile_), session_storage_namespace_map);
}
void PrerenderContents::NotifyPrerenderStart() {
diff --git a/chrome/browser/prerender/prerender_final_status.cc b/chrome/browser/prerender/prerender_final_status.cc
index f3f2cfe..6455dcf 100644
--- a/chrome/browser/prerender/prerender_final_status.cc
+++ b/chrome/browser/prerender/prerender_final_status.cc
@@ -54,12 +54,14 @@
"OpenURL",
"WouldHaveBeenUsed",
"Register Protocol Handler",
+ "Creating Audio Stream",
+ "Page Being Captured",
"Max",
};
COMPILE_ASSERT(arraysize(kFinalStatusNames) == FINAL_STATUS_MAX + 1,
PrerenderFinalStatus_name_count_mismatch);
-}
+} // namespace
const char* NameFromFinalStatus(FinalStatus final_status) {
DCHECK_LT(static_cast<unsigned int>(final_status),
diff --git a/chrome/browser/prerender/prerender_final_status.h b/chrome/browser/prerender/prerender_final_status.h
index 87922f8..8e989c6 100644
--- a/chrome/browser/prerender/prerender_final_status.h
+++ b/chrome/browser/prerender/prerender_final_status.h
@@ -55,6 +55,8 @@
FINAL_STATUS_OPEN_URL = 40,
FINAL_STATUS_WOULD_HAVE_BEEN_USED = 41,
FINAL_STATUS_REGISTER_PROTOCOL_HANDLER = 42,
+ FINAL_STATUS_CREATING_AUDIO_STREAM = 43,
+ FINAL_STATUS_PAGE_BEING_CAPTURED = 44,
FINAL_STATUS_MAX,
};
diff --git a/chrome/browser/prerender/prerender_local_predictor.cc b/chrome/browser/prerender/prerender_local_predictor.cc
index 398a06f..93525f6 100644
--- a/chrome/browser/prerender/prerender_local_predictor.cc
+++ b/chrome/browser/prerender/prerender_local_predictor.cc
@@ -536,7 +536,7 @@
scoped_refptr<SessionStorageNamespace> session_storage_namespace =
- source_web_contents->GetController().GetSessionStorageNamespace();
+ source_web_contents->GetController().GetDefaultSessionStorageNamespace();
gfx::Rect container_bounds;
source_web_contents->GetView()->GetContainerBounds(&container_bounds);
@@ -883,7 +883,7 @@
p->prerender_handle->Matches(
url,
web_contents->GetController().
- GetSessionStorageNamespace());
+ GetDefaultSessionStorageNamespace());
}
}
if (best_matched_prerender) {
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc
index e93ccc9..b955695 100644
--- a/chrome/browser/prerender/prerender_manager.cc
+++ b/chrome/browser/prerender/prerender_manager.cc
@@ -39,6 +39,7 @@
#include "chrome/browser/prerender/prerender_tracker.h"
#include "chrome/browser/prerender/prerender_util.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/browser/ui/tab_contents/core_tab_helper.h"
#include "chrome/browser/ui/tab_contents/core_tab_helper_delegate.h"
#include "chrome/common/chrome_switches.h"
@@ -111,7 +112,8 @@
final_status != FINAL_STATUS_CACHE_OR_HISTORY_CLEARED &&
final_status != FINAL_STATUS_CANCELLED &&
final_status != FINAL_STATUS_DEVTOOLS_ATTACHED &&
- final_status != FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING;
+ final_status != FINAL_STATUS_CROSS_SITE_NAVIGATION_PENDING &&
+ final_status != FINAL_STATUS_PAGE_BEING_CAPTURED;
}
void CheckIfCookiesExistForDomainResultOnUIThread(
@@ -275,9 +277,13 @@
notification_registrar_.Add(
this, chrome::NOTIFICATION_COOKIE_CHANGED,
content::NotificationService::AllBrowserContextsAndSources());
+
+ MediaCaptureDevicesDispatcher::GetInstance()->AddObserver(this);
}
PrerenderManager::~PrerenderManager() {
+ MediaCaptureDevicesDispatcher::GetInstance()->RemoveObserver(this);
+
// The earlier call to BrowserContextKeyedService::Shutdown() should have
// emptied these vectors already.
DCHECK(active_prerenders_.empty());
@@ -323,8 +329,10 @@
return NULL;
if (source_web_contents->GetURL().host() == url.host())
origin = ORIGIN_LINK_REL_PRERENDER_SAMEDOMAIN;
+ // TODO(ajwong): This does not correctly handle storage for isolated apps.
session_storage_namespace =
- source_web_contents->GetController().GetSessionStorageNamespace();
+ source_web_contents->GetController()
+ .GetDefaultSessionStorageNamespace();
}
// If the prerender request comes from a recently cancelled prerender that
@@ -406,8 +414,10 @@
DeleteOldEntries();
to_delete_prerenders_.clear();
+ // TODO(ajwong): This doesn't handle isolated apps correctly.
PrerenderData* prerender_data = FindPrerenderData(
- url, web_contents->GetController().GetSessionStorageNamespace());
+ url,
+ web_contents->GetController().GetDefaultSessionStorageNamespace());
if (!prerender_data)
return false;
DCHECK(prerender_data->contents());
@@ -434,6 +444,12 @@
return false;
}
+ // Do not swap in the prerender if the current WebContents is being captured.
+ if (web_contents->GetCapturerCount() > 0) {
+ prerender_data->contents()->Destroy(FINAL_STATUS_PAGE_BEING_CAPTURED);
+ return false;
+ }
+
// If we are just in the control group (which can be detected by noticing
// that prerendering hasn't even started yet), record that |web_contents| now
// would be showing a prerendered contents, but otherwise, don't do anything.
@@ -1432,6 +1448,21 @@
CookieChanged(content::Details<ChromeCookieDetails>(details).ptr());
}
+void PrerenderManager::OnCreatingAudioStream(int render_process_id,
+ int render_view_id) {
+ WebContents* tab = tab_util::GetWebContentsByID(
+ render_process_id, render_view_id);
+ if (!tab)
+ return;
+
+ if (!IsWebContentsPrerendering(tab, NULL))
+ return;
+
+ prerender_tracker()->TryCancel(
+ render_process_id, render_view_id,
+ prerender::FINAL_STATUS_CREATING_AUDIO_STREAM);
+}
+
void PrerenderManager::RecordLikelyLoginOnURL(const GURL& url) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (!IsWebURL(url))
diff --git a/chrome/browser/prerender/prerender_manager.h b/chrome/browser/prerender/prerender_manager.h
index 67ff3f3..8789699 100644
--- a/chrome/browser/prerender/prerender_manager.h
+++ b/chrome/browser/prerender/prerender_manager.h
@@ -19,6 +19,7 @@
#include "base/threading/non_thread_safe.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
+#include "chrome/browser/media/media_capture_devices_dispatcher.h"
#include "chrome/browser/predictors/logged_in_predictor_table.h"
#include "chrome/browser/prerender/prerender_config.h"
#include "chrome/browser/prerender/prerender_contents.h"
@@ -78,7 +79,8 @@
class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
public base::NonThreadSafe,
public content::NotificationObserver,
- public BrowserContextKeyedService {
+ public BrowserContextKeyedService,
+ public MediaCaptureDevicesDispatcher::Observer {
public:
// NOTE: New values need to be appended, since they are used in histograms.
enum PrerenderManagerMode {
@@ -274,6 +276,10 @@
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
+ // MediaCaptureDevicesDispatcher::Observer
+ virtual void OnCreatingAudioStream(int render_process_id,
+ int render_view_id) OVERRIDE;
+
const Config& config() const { return config_; }
Config& mutable_config() { return config_; }
diff --git a/chrome/browser/printing/background_printing_manager.cc b/chrome/browser/printing/background_printing_manager.cc
index 4db8f15..f0aa96a 100644
--- a/chrome/browser/printing/background_printing_manager.cc
+++ b/chrome/browser/printing/background_printing_manager.cc
@@ -63,16 +63,15 @@
rph_source);
}
- // Activate the initiator tab.
+ // Activate the initiator.
PrintPreviewDialogController* dialog_controller =
PrintPreviewDialogController::GetInstance();
if (!dialog_controller)
return;
- WebContents* initiator_tab =
- dialog_controller->GetInitiatorTab(preview_dialog);
- if (!initiator_tab)
+ WebContents* initiator = dialog_controller->GetInitiator(preview_dialog);
+ if (!initiator)
return;
- initiator_tab->GetDelegate()->ActivateContents(initiator_tab);
+ initiator->GetDelegate()->ActivateContents(initiator);
}
void BackgroundPrintingManager::Observe(
diff --git a/chrome/browser/printing/cloud_print/test/cloud_print_policy_browsertest.cc b/chrome/browser/printing/cloud_print/test/cloud_print_policy_browsertest.cc
index 6433df6..eb238e5 100644
--- a/chrome/browser/printing/cloud_print/test/cloud_print_policy_browsertest.cc
+++ b/chrome/browser/printing/cloud_print/test/cloud_print_policy_browsertest.cc
@@ -14,6 +14,10 @@
#include "content/public/browser/notification_service.h"
#include "content/public/common/result_codes.h"
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
// These tests don't apply to the Mac version; see GetCommandLineForRelaunch
// for details.
#if defined(OS_MACOSX)
@@ -28,6 +32,12 @@
};
IN_PROC_BROWSER_TEST_F(CloudPrintPolicyTest, NormalPassedFlag) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
base::FilePath test_file_path = ui_test_utils::GetTestFilePath(
base::FilePath(), base::FilePath().AppendASCII("empty.html"));
CommandLine new_command_line(GetCommandLineForRelaunch());
diff --git a/chrome/browser/printing/print_preview_dialog_controller.cc b/chrome/browser/printing/print_preview_dialog_controller.cc
index 5088ffb..6d96eb3 100644
--- a/chrome/browser/printing/print_preview_dialog_controller.cc
+++ b/chrome/browser/printing/print_preview_dialog_controller.cc
@@ -40,9 +40,9 @@
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_view.h"
+#include "content/public/common/webplugininfo.h"
#include "ui/web_dialogs/web_dialog_delegate.h"
#include "ui/web_dialogs/web_dialog_web_contents_delegate.h"
-#include "webkit/plugins/webplugininfo.h"
using content::NativeWebKeyboardEvent;
using content::NavigationController;
@@ -59,7 +59,7 @@
if (!PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_plugin_path))
return;
- webkit::WebPluginInfo pdf_plugin;
+ content::WebPluginInfo pdf_plugin;
if (!content::PluginService::GetInstance()->GetPluginInfoByPath(
pdf_plugin_path, &pdf_plugin))
return;
@@ -74,7 +74,7 @@
// will look like.
class PrintPreviewDialogDelegate : public WebDialogDelegate {
public:
- explicit PrintPreviewDialogDelegate(WebContents* initiator_tab);
+ explicit PrintPreviewDialogDelegate(WebContents* initiator);
virtual ~PrintPreviewDialogDelegate();
virtual ui::ModalType GetDialogModalType() const OVERRIDE;
@@ -90,14 +90,13 @@
virtual bool ShouldShowDialogTitle() const OVERRIDE;
private:
- WebContents* initiator_tab_;
+ WebContents* initiator_;
DISALLOW_COPY_AND_ASSIGN(PrintPreviewDialogDelegate);
};
-PrintPreviewDialogDelegate::PrintPreviewDialogDelegate(
- WebContents* initiator_tab) {
- initiator_tab_ = initiator_tab;
+PrintPreviewDialogDelegate::PrintPreviewDialogDelegate(WebContents* initiator)
+ : initiator_(initiator) {
}
PrintPreviewDialogDelegate::~PrintPreviewDialogDelegate() {
@@ -129,7 +128,7 @@
const int kBorder = 25;
const int kConstrainedWindowOverlap = 3;
gfx::Rect rect;
- initiator_tab_->GetView()->GetContainerBounds(&rect);
+ initiator_->GetView()->GetContainerBounds(&rect);
size->set_width(std::max(rect.width(), kMinDialogSize.width()) - 2 * kBorder);
size->set_height(std::max(rect.height(), kMinDialogSize.height()) - kBorder +
kConstrainedWindowOverlap);
@@ -165,7 +164,7 @@
// renderer to the browser.
class PrintPreviewWebContentDelegate : public WebDialogWebContentsDelegate {
public:
- PrintPreviewWebContentDelegate(Profile* profile, WebContents* initiator_tab);
+ PrintPreviewWebContentDelegate(Profile* profile, WebContents* initiator);
virtual ~PrintPreviewWebContentDelegate();
// Overridden from WebDialogWebContentsDelegate:
@@ -181,9 +180,9 @@
PrintPreviewWebContentDelegate::PrintPreviewWebContentDelegate(
Profile* profile,
- WebContents* initiator_tab)
+ WebContents* initiator)
: WebDialogWebContentsDelegate(profile, new ChromeWebContentsHandler),
- tab_(initiator_tab) {}
+ tab_(initiator) {}
PrintPreviewWebContentDelegate::~PrintPreviewWebContentDelegate() {}
@@ -216,28 +215,28 @@
}
// static
-void PrintPreviewDialogController::PrintPreview(WebContents* initiator_tab) {
- if (initiator_tab->ShowingInterstitialPage())
+void PrintPreviewDialogController::PrintPreview(WebContents* initiator) {
+ if (initiator->ShowingInterstitialPage())
return;
PrintPreviewDialogController* dialog_controller = GetInstance();
if (!dialog_controller)
return;
- if (!dialog_controller->GetOrCreatePreviewDialog(initiator_tab))
- PrintViewManager::FromWebContents(initiator_tab)->PrintPreviewDone();
+ if (!dialog_controller->GetOrCreatePreviewDialog(initiator))
+ PrintViewManager::FromWebContents(initiator)->PrintPreviewDone();
}
WebContents* PrintPreviewDialogController::GetOrCreatePreviewDialog(
- WebContents* initiator_tab) {
- DCHECK(initiator_tab);
+ WebContents* initiator) {
+ DCHECK(initiator);
- // Get the print preview dialog for |initiator_tab|.
- WebContents* preview_dialog = GetPrintPreviewForContents(initiator_tab);
+ // Get the print preview dialog for |initiator|.
+ WebContents* preview_dialog = GetPrintPreviewForContents(initiator);
if (!preview_dialog)
- return CreatePrintPreviewDialog(initiator_tab);
+ return CreatePrintPreviewDialog(initiator);
- // Show the initiator tab holding the existing preview dialog.
- initiator_tab->GetDelegate()->ActivateContents(initiator_tab);
+ // Show the initiator holding the existing preview dialog.
+ initiator->GetDelegate()->ActivateContents(initiator);
return preview_dialog;
}
@@ -252,7 +251,7 @@
for (it = preview_dialog_map_.begin();
it != preview_dialog_map_.end();
++it) {
- // If |contents| is an initiator tab.
+ // If |contents| is an initiator.
if (contents == it->second) {
// Return the associated preview dialog.
return it->first;
@@ -261,7 +260,7 @@
return NULL;
}
-WebContents* PrintPreviewDialogController::GetInitiatorTab(
+WebContents* PrintPreviewDialogController::GetInitiator(
WebContents* preview_dialog) {
PrintPreviewDialogMap::iterator it = preview_dialog_map_.find(preview_dialog);
return (it != preview_dialog_map_.end()) ? it->second : NULL;
@@ -297,13 +296,13 @@
url.host() == chrome::kChromeUIPrintHost);
}
-void PrintPreviewDialogController::EraseInitiatorTabInfo(
+void PrintPreviewDialogController::EraseInitiatorInfo(
WebContents* preview_dialog) {
PrintPreviewDialogMap::iterator it = preview_dialog_map_.find(preview_dialog);
if (it == preview_dialog_map_.end())
return;
- RemoveObservers(it->second);
+ RemoveObservers(it->second, INITIATOR);
preview_dialog_map_[preview_dialog] = NULL;
}
@@ -313,17 +312,17 @@
content::RenderProcessHost* rph) {
// Store contents in a vector and deal with them after iterating through
// |preview_dialog_map_| because RemoveFoo() can change |preview_dialog_map_|.
- std::vector<WebContents*> closed_initiator_tabs;
+ std::vector<WebContents*> closed_initiators;
std::vector<WebContents*> closed_preview_dialogs;
for (PrintPreviewDialogMap::iterator iter = preview_dialog_map_.begin();
iter != preview_dialog_map_.end(); ++iter) {
WebContents* preview_dialog = iter->first;
- WebContents* initiator_tab = iter->second;
+ WebContents* initiator = iter->second;
if (preview_dialog->GetRenderProcessHost() == rph) {
closed_preview_dialogs.push_back(preview_dialog);
- } else if (initiator_tab &&
- initiator_tab->GetRenderProcessHost() == rph) {
- closed_initiator_tabs.push_back(initiator_tab);
+ } else if (initiator &&
+ initiator->GetRenderProcessHost() == rph) {
+ closed_initiators.push_back(initiator);
}
}
@@ -335,8 +334,8 @@
print_preview_ui->OnPrintPreviewDialogClosed();
}
- for (size_t i = 0; i < closed_initiator_tabs.size(); ++i)
- RemoveInitiatorTab(closed_initiator_tabs[i]);
+ for (size_t i = 0; i < closed_initiators.size(); ++i)
+ RemoveInitiator(closed_initiators[i]);
}
void PrintPreviewDialogController::OnWebContentsDestroyed(
@@ -350,7 +349,7 @@
if (contents == preview_dialog)
RemovePreviewDialog(contents);
else
- RemoveInitiatorTab(contents);
+ RemoveInitiator(contents);
}
void PrintPreviewDialogController::OnNavEntryCommitted(
@@ -361,42 +360,40 @@
return;
}
- if (contents == preview_dialog) {
- // Preview dialog navigated.
- if (details) {
- content::PageTransition transition_type =
- details->entry->GetTransitionType();
- content::NavigationType nav_type = details->type;
+ DCHECK_EQ(contents, preview_dialog);
- // New |preview_dialog| is created. Don't update/erase map entry.
- if (waiting_for_new_preview_page_ &&
- transition_type == content::PAGE_TRANSITION_AUTO_TOPLEVEL &&
- nav_type == content::NAVIGATION_TYPE_NEW_PAGE) {
- waiting_for_new_preview_page_ = false;
- SaveInitiatorTabTitle(preview_dialog);
- return;
- }
+ // Preview dialog navigated.
+ if (details) {
+ content::PageTransition transition_type =
+ details->entry->GetTransitionType();
+ content::NavigationType nav_type = details->type;
- // Cloud print sign-in causes a reload.
- if (!waiting_for_new_preview_page_ &&
- transition_type == content::PAGE_TRANSITION_RELOAD &&
- nav_type == content::NAVIGATION_TYPE_EXISTING_PAGE &&
- IsPrintPreviewURL(details->previous_url)) {
- return;
- }
+ // New |preview_dialog| is created. Don't update/erase map entry.
+ if (waiting_for_new_preview_page_ &&
+ transition_type == content::PAGE_TRANSITION_AUTO_TOPLEVEL &&
+ nav_type == content::NAVIGATION_TYPE_NEW_PAGE) {
+ waiting_for_new_preview_page_ = false;
+ SaveInitiatorTitle(preview_dialog);
+ return;
}
- NOTREACHED();
- return;
+
+ // Cloud print sign-in causes a reload.
+ if (!waiting_for_new_preview_page_ &&
+ transition_type == content::PAGE_TRANSITION_RELOAD &&
+ nav_type == content::NAVIGATION_TYPE_EXISTING_PAGE &&
+ IsPrintPreviewURL(details->previous_url)) {
+ return;
+ }
}
- RemoveInitiatorTab(contents);
+ NOTREACHED();
}
WebContents* PrintPreviewDialogController::CreatePrintPreviewDialog(
- WebContents* initiator_tab) {
+ WebContents* initiator) {
base::AutoReset<bool> auto_reset(&is_creating_print_preview_dialog_, true);
Profile* profile =
- Profile::FromBrowserContext(initiator_tab->GetBrowserContext());
+ Profile::FromBrowserContext(initiator->GetBrowserContext());
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kChromeFrame)) {
// Chrome Frame only ever runs on the native desktop, so it is safe to
// create the popup on the native desktop.
@@ -412,45 +409,48 @@
// |web_dialog_ui_delegate| deletes itself in
// PrintPreviewDialogDelegate::OnDialogClosed().
WebDialogDelegate* web_dialog_delegate =
- new PrintPreviewDialogDelegate(initiator_tab);
+ new PrintPreviewDialogDelegate(initiator);
// |web_dialog_delegate|'s owner is |constrained_delegate|.
PrintPreviewWebContentDelegate* pp_wcd =
- new PrintPreviewWebContentDelegate(profile, initiator_tab);
+ new PrintPreviewWebContentDelegate(profile, initiator);
ConstrainedWebDialogDelegate* constrained_delegate =
CreateConstrainedWebDialog(profile,
web_dialog_delegate,
pp_wcd,
- initiator_tab);
+ initiator);
WebContents* preview_dialog = constrained_delegate->GetWebContents();
EnableInternalPDFPluginForContents(preview_dialog);
PrintViewManager::CreateForWebContents(preview_dialog);
// Add an entry to the map.
- preview_dialog_map_[preview_dialog] = initiator_tab;
+ preview_dialog_map_[preview_dialog] = initiator;
waiting_for_new_preview_page_ = true;
- AddObservers(initiator_tab);
- AddObservers(preview_dialog);
+ AddObservers(initiator, INITIATOR);
+ AddObservers(preview_dialog, PREVIEW_DIALOG);
return preview_dialog;
}
-void PrintPreviewDialogController::SaveInitiatorTabTitle(
+void PrintPreviewDialogController::SaveInitiatorTitle(
WebContents* preview_dialog) {
- WebContents* initiator_tab = GetInitiatorTab(preview_dialog);
- if (initiator_tab && preview_dialog->GetWebUI()) {
+ WebContents* initiator = GetInitiator(preview_dialog);
+ if (initiator && preview_dialog->GetWebUI()) {
PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>(
preview_dialog->GetWebUI()->GetController());
- print_preview_ui->SetInitiatorTabTitle(
- PrintViewManager::FromWebContents(initiator_tab)->RenderSourceName());
+ print_preview_ui->SetInitiatorTitle(
+ PrintViewManager::FromWebContents(initiator)->RenderSourceName());
}
}
-void PrintPreviewDialogController::AddObservers(WebContents* contents) {
+void PrintPreviewDialogController::AddObservers(WebContents* contents,
+ ContentsType contents_type) {
registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
content::Source<WebContents>(contents));
- registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
- content::Source<NavigationController>(&contents->GetController()));
+ if (contents_type == PREVIEW_DIALOG) {
+ registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
+ content::Source<NavigationController>(&contents->GetController()));
+ }
// Multiple sites may share the same RenderProcessHost, so check if this
// notification has already been added.
@@ -463,11 +463,14 @@
}
}
-void PrintPreviewDialogController::RemoveObservers(WebContents* contents) {
+void PrintPreviewDialogController::RemoveObservers(WebContents* contents,
+ ContentsType contents_type) {
registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
content::Source<WebContents>(contents));
- registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
- content::Source<NavigationController>(&contents->GetController()));
+ if (contents_type == PREVIEW_DIALOG) {
+ registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
+ content::Source<NavigationController>(&contents->GetController()));
+ }
// Multiple sites may share the same RenderProcessHost, so check if this
// notification has already been added.
@@ -480,43 +483,43 @@
}
}
-void PrintPreviewDialogController::RemoveInitiatorTab(
- WebContents* initiator_tab) {
- WebContents* preview_dialog = GetPrintPreviewForContents(initiator_tab);
+void PrintPreviewDialogController::RemoveInitiator(
+ WebContents* initiator) {
+ WebContents* preview_dialog = GetPrintPreviewForContents(initiator);
DCHECK(preview_dialog);
// Update the map entry first, so when the print preview dialog gets destroyed
// and reaches RemovePreviewDialog(), it does not attempt to also remove the
- // initiator tab's observers.
+ // initiator's observers.
preview_dialog_map_[preview_dialog] = NULL;
- RemoveObservers(initiator_tab);
+ RemoveObservers(initiator, INITIATOR);
- PrintViewManager::FromWebContents(initiator_tab)->PrintPreviewDone();
+ PrintViewManager::FromWebContents(initiator)->PrintPreviewDone();
- // Initiator tab is closed. Close the print preview dialog too.
+ // initiator is closed. Close the print preview dialog too.
PrintPreviewUI* print_preview_ui =
static_cast<PrintPreviewUI*>(preview_dialog->GetWebUI()->GetController());
if (print_preview_ui)
- print_preview_ui->OnInitiatorTabClosed();
+ print_preview_ui->OnInitiatorClosed();
}
void PrintPreviewDialogController::RemovePreviewDialog(
WebContents* preview_dialog) {
- // Remove the initiator tab's observers before erasing the mapping.
- WebContents* initiator_tab = GetInitiatorTab(preview_dialog);
- if (initiator_tab) {
- RemoveObservers(initiator_tab);
- PrintViewManager::FromWebContents(initiator_tab)->PrintPreviewDone();
+ // Remove the initiator's observers before erasing the mapping.
+ WebContents* initiator = GetInitiator(preview_dialog);
+ if (initiator) {
+ RemoveObservers(initiator, INITIATOR);
+ PrintViewManager::FromWebContents(initiator)->PrintPreviewDone();
}
// Print preview WebContents is destroyed. Notify |PrintPreviewUI| to abort
- // the initiator tab preview request.
+ // the initiator preview request.
PrintPreviewUI* print_preview_ui =
static_cast<PrintPreviewUI*>(preview_dialog->GetWebUI()->GetController());
if (print_preview_ui)
print_preview_ui->OnPrintPreviewDialogDestroyed();
preview_dialog_map_.erase(preview_dialog);
- RemoveObservers(preview_dialog);
+ RemoveObservers(preview_dialog, PREVIEW_DIALOG);
}
} // namespace printing
diff --git a/chrome/browser/printing/print_preview_dialog_controller.h b/chrome/browser/printing/print_preview_dialog_controller.h
index 0ce70db..da5d385 100644
--- a/chrome/browser/printing/print_preview_dialog_controller.h
+++ b/chrome/browser/printing/print_preview_dialog_controller.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+ // 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.
@@ -22,9 +22,9 @@
namespace printing {
-// For print preview, the tab that initiates the printing operation is the
-// initiator tab, and the constrained dialog that shows the print preview is
-// the print preview dialog.
+// For print preview, the WebContents that initiates the printing operation is
+// the initiator, and the constrained dialog that shows the print preview is the
+// print preview dialog.
// This class manages print preview dialog creation and destruction, and keeps
// track of the 1:1 relationship between initiatora tabs and print preview
// dialogs.
@@ -36,14 +36,14 @@
static PrintPreviewDialogController* GetInstance();
- // Initiate print preview for |initiator_tab|.
+ // Initiate print preview for |initiator|.
// Call this instead of GetOrCreatePreviewDialog().
- static void PrintPreview(content::WebContents* initiator_tab);
+ static void PrintPreview(content::WebContents* initiator);
- // Get/Create the print preview dialog for |initiator_tab|.
+ // Get/Create the print preview dialog for |initiator|.
// Exposed for unit tests.
content::WebContents* GetOrCreatePreviewDialog(
- content::WebContents* initiator_tab);
+ content::WebContents* initiator);
// Returns the preview dialog for |contents|.
// Returns |contents| if |contents| is a preview dialog.
@@ -51,9 +51,9 @@
content::WebContents* GetPrintPreviewForContents(
content::WebContents* contents) const;
- // Returns the initiator tab for |preview_dialog|.
- // Returns NULL if no initiator tab exists for |preview_dialog|.
- content::WebContents* GetInitiatorTab(content::WebContents* preview_dialog);
+ // Returns the initiator for |preview_dialog|.
+ // Returns NULL if no initiator exists for |preview_dialog|.
+ content::WebContents* GetInitiator(content::WebContents* preview_dialog);
// content::NotificationObserver implementation.
virtual void Observe(int type,
@@ -66,8 +66,8 @@
// Returns true if |url| is a print preview url.
static bool IsPrintPreviewURL(const GURL& url);
- // Erase the initiator tab info associated with |preview_tab|.
- void EraseInitiatorTabInfo(content::WebContents* preview_tab);
+ // Erase the initiator info associated with |preview_dialog|.
+ void EraseInitiatorInfo(content::WebContents* preview_dialog);
bool is_creating_print_preview_dialog() const {
return is_creating_print_preview_dialog_;
@@ -76,9 +76,16 @@
private:
friend class base::RefCounted<PrintPreviewDialogController>;
- // 1:1 relationship between a print preview dialog and its initiator tab.
+ // Used to distinguish between the two varieties of WebContents dealt with by
+ // this class.
+ enum ContentsType {
+ INITIATOR,
+ PREVIEW_DIALOG
+ };
+
+ // 1:1 relationship between a print preview dialog and its initiator.
// Key: Print preview dialog.
- // Value: Initiator tab.
+ // Value: Initiator.
typedef std::map<content::WebContents*, content::WebContents*>
PrintPreviewDialogMap;
@@ -99,21 +106,22 @@
// Creates a new print preview dialog.
content::WebContents* CreatePrintPreviewDialog(
- content::WebContents* initiator_tab);
+ content::WebContents* initiator);
- // Helper function to store the title of the initiator tab associated with
+ // Helper function to store the title of the initiator associated with
// |preview_dialog| in |preview_dialog|'s PrintPreviewUI.
- void SaveInitiatorTabTitle(content::WebContents* preview_dialog);
+ void SaveInitiatorTitle(content::WebContents* preview_dialog);
// Adds/Removes observers for notifications from |contents|.
- void AddObservers(content::WebContents* contents);
- void RemoveObservers(content::WebContents* contents);
+ void AddObservers(content::WebContents* contents, ContentsType contents_type);
+ void RemoveObservers(content::WebContents* contents,
+ ContentsType contents_type);
// Removes WebContents when they close/crash/navigate.
- void RemoveInitiatorTab(content::WebContents* initiator_tab);
+ void RemoveInitiator(content::WebContents* initiator);
void RemovePreviewDialog(content::WebContents* preview_dialog);
- // Mapping between print preview dialog and the corresponding initiator tab.
+ // Mapping between print preview dialog and the corresponding initiator.
PrintPreviewDialogMap preview_dialog_map_;
// A registrar for listening notifications.
diff --git a/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc b/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
index b9bcb4e..c64c3bf 100644
--- a/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
+++ b/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
@@ -103,11 +103,11 @@
class PrintPreviewDialogControllerBrowserTest : public InProcessBrowserTest {
public:
- PrintPreviewDialogControllerBrowserTest() : initiator_tab_(NULL) {}
+ PrintPreviewDialogControllerBrowserTest() : initiator_(NULL) {}
virtual ~PrintPreviewDialogControllerBrowserTest() {}
- WebContents* initiator_tab() {
- return initiator_tab_;
+ WebContents* initiator() {
+ return initiator_;
}
void PrintPreview() {
@@ -120,7 +120,7 @@
WebContents* GetPrintPreviewDialog() {
printing::PrintPreviewDialogController* dialog_controller =
printing::PrintPreviewDialogController::GetInstance();
- return dialog_controller->GetPrintPreviewForContents(initiator_tab_);
+ return dialog_controller->GetPrintPreviewForContents(initiator_);
}
private:
@@ -143,14 +143,14 @@
cloned_tab_observer_.reset(new PrintPreviewDialogClonedObserver(first_tab));
chrome::DuplicateTab(browser());
- initiator_tab_ = browser()->tab_strip_model()->GetActiveWebContents();
- ASSERT_TRUE(initiator_tab_);
- ASSERT_NE(first_tab, initiator_tab_);
+ initiator_ = browser()->tab_strip_model()->GetActiveWebContents();
+ ASSERT_TRUE(initiator_);
+ ASSERT_NE(first_tab, initiator_);
}
virtual void CleanUpOnMainThread() OVERRIDE {
cloned_tab_observer_.reset();
- initiator_tab_ = NULL;
+ initiator_ = NULL;
}
RequestPrintPreviewObserver* request_preview_tab_observer() {
@@ -158,13 +158,13 @@
}
scoped_ptr<PrintPreviewDialogClonedObserver> cloned_tab_observer_;
- WebContents* initiator_tab_;
+ WebContents* initiator_;
DISALLOW_COPY_AND_ASSIGN(PrintPreviewDialogControllerBrowserTest);
};
-// Test to verify that when a initiator tab navigates, we can create a new
-// preview dialog for the new tab contents.
+// Test to verify that when a initiator navigates, we can create a new preview
+// dialog for the new tab contents.
IN_PROC_BROWSER_TEST_F(PrintPreviewDialogControllerBrowserTest,
NavigateFromInitiatorTab) {
// print for the first time.
@@ -175,7 +175,7 @@
// Check a new print preview dialog got created.
ASSERT_TRUE(preview_dialog);
- ASSERT_NE(initiator_tab(), preview_dialog);
+ ASSERT_NE(initiator(), preview_dialog);
// Navigate in the initiator tab. Make sure navigating destroys the print
// preview dialog.
@@ -193,8 +193,8 @@
EXPECT_TRUE(new_preview_dialog);
}
-// Test to verify that after reloading the initiator tab, it creates a new
-// print preview dialog.
+// Test to verify that after reloading the initiator, it creates a new print
+// preview dialog.
IN_PROC_BROWSER_TEST_F(PrintPreviewDialogControllerBrowserTest,
ReloadInitiatorTab) {
// print for the first time.
@@ -204,9 +204,9 @@
// Check a new print preview dialog got created.
ASSERT_TRUE(preview_dialog);
- ASSERT_NE(initiator_tab(), preview_dialog);
+ ASSERT_NE(initiator(), preview_dialog);
- // Reload the initiator tab. Make sure reloading destroys the print preview
+ // Reload the initiator. Make sure reloading destroys the print preview
// dialog.
PrintPreviewDialogDestroyedObserver dialog_destroyed_observer(preview_dialog);
content::WindowedNotificationObserver notification_observer(
diff --git a/chrome/browser/printing/print_preview_dialog_controller_unittest.cc b/chrome/browser/printing/print_preview_dialog_controller_unittest.cc
index a336631..6ec20ba 100644
--- a/chrome/browser/printing/print_preview_dialog_controller_unittest.cc
+++ b/chrome/browser/printing/print_preview_dialog_controller_unittest.cc
@@ -16,23 +16,23 @@
using content::WebContents;
-// Test crashes on Aura due to initiator tab's native view having no parent.
+// Test crashes on Aura due to initiator's native view having no parent.
// http://crbug.com/104284
#if defined(USE_AURA)
#define MAYBE_GetOrCreatePreviewDialog DISABLED_GetOrCreatePreviewDialog
#define MAYBE_MultiplePreviewDialogs DISABLED_MultiplePreviewDialogs
-#define MAYBE_ClearInitiatorTabDetails DISABLED_ClearInitiatorTabDetails
+#define MAYBE_ClearInitiatorDetails DISABLED_ClearInitiatorDetails
#else
#define MAYBE_GetOrCreatePreviewDialog GetOrCreatePreviewDialog
#define MAYBE_MultiplePreviewDialogs MultiplePreviewDialogs
-#define MAYBE_ClearInitiatorTabDetails ClearInitiatorTabDetails
+#define MAYBE_ClearInitiatorDetails ClearInitiatorDetails
#endif
namespace printing {
typedef PrintPreviewTest PrintPreviewDialogControllerUnitTest;
-// Create/Get a preview dialog for initiator tab.
+// Create/Get a preview dialog for initiator.
TEST_F(PrintPreviewDialogControllerUnitTest, MAYBE_GetOrCreatePreviewDialog) {
// Lets start with one window with one tab.
EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
@@ -40,38 +40,37 @@
chrome::NewTab(browser());
EXPECT_EQ(1, browser()->tab_strip_model()->count());
- // Create a reference to initiator tab contents.
- WebContents* initiator_tab =
- browser()->tab_strip_model()->GetActiveWebContents();
+ // Create a reference to initiator contents.
+ WebContents* initiator = browser()->tab_strip_model()->GetActiveWebContents();
PrintPreviewDialogController* dialog_controller =
PrintPreviewDialogController::GetInstance();
ASSERT_TRUE(dialog_controller);
- // Get the preview dialog for initiator tab.
- PrintViewManager::FromWebContents(initiator_tab)->PrintPreviewNow(false);
+ // Get the preview dialog for initiator.
+ PrintViewManager::FromWebContents(initiator)->PrintPreviewNow(false);
WebContents* preview_dialog =
- dialog_controller->GetOrCreatePreviewDialog(initiator_tab);
+ dialog_controller->GetOrCreatePreviewDialog(initiator);
// New print preview dialog is a constrained window, so the number of tabs is
// still 1.
EXPECT_EQ(1, browser()->tab_strip_model()->count());
- EXPECT_NE(initiator_tab, preview_dialog);
+ EXPECT_NE(initiator, preview_dialog);
- // Get the print preview dialog for the same initiator tab.
+ // Get the print preview dialog for the same initiator.
WebContents* new_preview_dialog =
- dialog_controller->GetOrCreatePreviewDialog(initiator_tab);
+ dialog_controller->GetOrCreatePreviewDialog(initiator);
// Preview dialog already exists. Tab count remains the same.
EXPECT_EQ(1, browser()->tab_strip_model()->count());
- // 1:1 relationship between initiator tab and preview dialog.
+ // 1:1 relationship between initiator and preview dialog.
EXPECT_EQ(new_preview_dialog, preview_dialog);
}
-// Tests multiple print preview dialogs exist in the same browser for
-// different initiator tabs. If a preview dialog already exists for an
-// initiator tab, that initiator tab gets focused.
+// Tests multiple print preview dialogs exist in the same browser for different
+// initiators. If a preview dialog already exists for an initiator, that
+// initiator gets focused.
TEST_F(PrintPreviewDialogControllerUnitTest, MAYBE_MultiplePreviewDialogs) {
// Lets start with one window and two tabs.
EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
@@ -80,7 +79,7 @@
EXPECT_EQ(0, tab_strip_model->count());
- // Create some new initiator tabs.
+ // Create some new initiators.
chrome::NewTab(browser());
WebContents* web_contents_1 = tab_strip_model->GetActiveWebContents();
ASSERT_TRUE(web_contents_1);
@@ -109,8 +108,8 @@
EXPECT_NE(web_contents_2, preview_dialog_2);
EXPECT_NE(preview_dialog_1, preview_dialog_2);
- // 2 initiator tabs and 2 preview dialogs exist in the same browser.
- // The preview dialogs are constrained in their respective initiator tabs.
+ // 2 initiators and 2 preview dialogs exist in the same browser. The preview
+ // dialogs are constrained in their respective initiators.
EXPECT_EQ(2, tab_strip_model->count());
int tab_1_index = tab_strip_model->GetIndexOfWebContents(web_contents_1);
@@ -125,7 +124,7 @@
EXPECT_EQ(-1, preview_dialog_2_index);
// Since |preview_dialog_2_index| was the most recently created dialog, its
- // initiator tab should have focus.
+ // initiator should have focus.
EXPECT_EQ(tab_2_index, tab_strip_model->active_index());
// When we get the preview dialog for |web_contents_1|,
@@ -134,39 +133,38 @@
EXPECT_EQ(tab_1_index, tab_strip_model->active_index());
}
-// Check clearing the initiator tab details associated with a print preview
-// dialog allows the initiator tab to create another print preview dialog.
-TEST_F(PrintPreviewDialogControllerUnitTest, MAYBE_ClearInitiatorTabDetails) {
+// Check clearing the initiator details associated with a print preview dialog
+// allows the initiator to create another print preview dialog.
+TEST_F(PrintPreviewDialogControllerUnitTest, MAYBE_ClearInitiatorDetails) {
// Lets start with one window with one tab.
EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
EXPECT_EQ(0, browser()->tab_strip_model()->count());
chrome::NewTab(browser());
EXPECT_EQ(1, browser()->tab_strip_model()->count());
- // Create a reference to initiator tab contents.
- WebContents* initiator_tab =
- browser()->tab_strip_model()->GetActiveWebContents();
+ // Create a reference to initiator contents.
+ WebContents* initiator = browser()->tab_strip_model()->GetActiveWebContents();
PrintPreviewDialogController* dialog_controller =
PrintPreviewDialogController::GetInstance();
ASSERT_TRUE(dialog_controller);
- // Get the preview dialog for the initiator tab.
- PrintViewManager::FromWebContents(initiator_tab)->PrintPreviewNow(false);
+ // Get the preview dialog for the initiator.
+ PrintViewManager::FromWebContents(initiator)->PrintPreviewNow(false);
WebContents* preview_dialog =
- dialog_controller->GetOrCreatePreviewDialog(initiator_tab);
+ dialog_controller->GetOrCreatePreviewDialog(initiator);
// New print preview dialog is a constrained window, so the number of tabs is
// still 1.
EXPECT_EQ(1, browser()->tab_strip_model()->count());
- EXPECT_NE(initiator_tab, preview_dialog);
+ EXPECT_NE(initiator, preview_dialog);
- // Clear the initiator tab details associated with the preview dialog.
- dialog_controller->EraseInitiatorTabInfo(preview_dialog);
+ // Clear the initiator details associated with the preview dialog.
+ dialog_controller->EraseInitiatorInfo(preview_dialog);
- // Get a new print preview dialog for the initiator tab.
+ // Get a new print preview dialog for the initiator.
WebContents* new_preview_dialog =
- dialog_controller->GetOrCreatePreviewDialog(initiator_tab);
+ dialog_controller->GetOrCreatePreviewDialog(initiator);
// New print preview dialog is a constrained window, so the number of tabs is
// still 1.
diff --git a/chrome/browser/printing/print_preview_test.cc b/chrome/browser/printing/print_preview_test.cc
index 4733668..e6136a1 100644
--- a/chrome/browser/printing/print_preview_test.cc
+++ b/chrome/browser/printing/print_preview_test.cc
@@ -76,8 +76,8 @@
// The PluginService will be destroyed at the end of the test (due to the
// ShadowingAtExitManager in our base class).
- content::PluginService::GetInstance()->SetPluginListForTesting(
- &plugin_list_);
+ content::PluginService::GetInstance()->Init();
+ content::PluginService::GetInstance()->DisablePluginsDiscoveryForTesting();
profile()->GetPrefs()->SetBoolean(prefs::kPrintPreviewDisabled, false);
}
diff --git a/chrome/browser/printing/print_preview_test.h b/chrome/browser/printing/print_preview_test.h
index f1c6ab5..ddfee0e 100644
--- a/chrome/browser/printing/print_preview_test.h
+++ b/chrome/browser/printing/print_preview_test.h
@@ -6,7 +6,6 @@
#define CHROME_BROWSER_PRINTING_PRINT_PREVIEW_TEST_H_
#include "chrome/test/base/browser_with_test_window_test.h"
-#include "webkit/plugins/npapi/mock_plugin_list.h"
class PrintPreviewTest : public BrowserWithTestWindowTest {
public:
@@ -20,8 +19,6 @@
virtual BrowserWindow* CreateBrowserWindow() OVERRIDE;
private:
- webkit::npapi::MockPluginList plugin_list_;
-
DISALLOW_COPY_AND_ASSIGN(PrintPreviewTest);
};
diff --git a/chrome/browser/printing/print_view_manager.h b/chrome/browser/printing/print_view_manager.h
index 55b4708..616ff00 100644
--- a/chrome/browser/printing/print_view_manager.h
+++ b/chrome/browser/printing/print_view_manager.h
@@ -46,7 +46,7 @@
bool PrintForSystemDialogNow();
// Same as PrintNow(), but for the case where a user press "ctrl+shift+p" to
- // show the native system dialog. This can happen from both initiator tab and
+ // show the native system dialog. This can happen from both initiator and
// preview dialog.
bool AdvancedPrintNow();
diff --git a/chrome/browser/profile_resetter/profile_resetter.cc b/chrome/browser/profile_resetter/profile_resetter.cc
index 297e359..3c797a7 100644
--- a/chrome/browser/profile_resetter/profile_resetter.cc
+++ b/chrome/browser/profile_resetter/profile_resetter.cc
@@ -123,7 +123,8 @@
ListPrefUpdate update(prefs, prefs::kSearchProviderOverrides);
update->Swap(search_engines.get());
}
- template_url_service_->ResetNonExtensionURLs();
+
+ template_url_service_->ResetURLs();
// Reset Google search URL.
prefs->ClearPref(prefs::kLastPromptedGoogleURL);
diff --git a/chrome/browser/profile_resetter/profile_resetter_test_base.cc b/chrome/browser/profile_resetter/profile_resetter_test_base.cc
index a4c4cf4..85b4ef7 100644
--- a/chrome/browser/profile_resetter/profile_resetter_test_base.cc
+++ b/chrome/browser/profile_resetter/profile_resetter_test_base.cc
@@ -14,6 +14,7 @@
EXPECT_CALL(*this, Callback());
runner_ = new content::MessageLoopRunner;
runner_->Run();
+ runner_ = NULL;
}
void ProfileResetterMockObject::StopLoop() {
diff --git a/chrome/browser/profile_resetter/profile_resetter_unittest.cc b/chrome/browser/profile_resetter/profile_resetter_unittest.cc
index 32442f9..f1caa33 100644
--- a/chrome/browser/profile_resetter/profile_resetter_unittest.cc
+++ b/chrome/browser/profile_resetter/profile_resetter_unittest.cc
@@ -15,7 +15,7 @@
#include "chrome/browser/profile_resetter/brandcode_config_fetcher.h"
#include "chrome/browser/profile_resetter/profile_resetter_test_base.h"
#include "chrome/browser/search_engines/template_url_service.h"
-#include "chrome/browser/search_engines/template_url_service_test_util.h"
+#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/themes/theme_service.h"
#include "chrome/browser/themes/theme_service_factory.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -72,36 +72,33 @@
using extensions::Extension;
using extensions::Manifest;
-class ProfileResetterTest : public testing::Test,
+// ProfileResetterTest sets up the extension, WebData and TemplateURL services.
+class ProfileResetterTest : public ExtensionServiceTestBase,
public ProfileResetterTestBase {
protected:
- // testing::Test:
virtual void SetUp() OVERRIDE;
- virtual void TearDown() OVERRIDE;
- TemplateURLServiceTestUtil test_util_;
+ TestingProfile* profile() { return profile_.get(); }
+
+ static BrowserContextKeyedService* CreateTemplateURLService(
+ content::BrowserContext* context);
};
void ProfileResetterTest::SetUp() {
- test_util_.SetUp();
- resetter_.reset(new ProfileResetter(test_util_.profile()));
-}
-
-void ProfileResetterTest::TearDown() {
- test_util_.TearDown();
-}
-
-// ExtensionsResetTest sets up the extension service.
-class ExtensionsResetTest : public ExtensionServiceTestBase,
- public ProfileResetterTestBase {
- protected:
- virtual void SetUp() OVERRIDE;
-};
-
-void ExtensionsResetTest::SetUp() {
ExtensionServiceTestBase::SetUp();
InitializeEmptyExtensionService();
- resetter_.reset(new ProfileResetter(profile_.get()));
+
+ profile()->CreateWebDataService();
+ TemplateURLServiceFactory::GetInstance()->SetTestingFactory(
+ profile(),
+ &ProfileResetterTest::CreateTemplateURLService);
+ resetter_.reset(new ProfileResetter(profile()));
+}
+
+// static
+BrowserContextKeyedService* ProfileResetterTest::CreateTemplateURLService(
+ content::BrowserContext* context) {
+ return new TemplateURLService(static_cast<Profile*>(context));
}
scoped_refptr<Extension> CreateExtension(const std::string& name,
@@ -113,7 +110,8 @@
manifest.SetString(extension_manifest_keys::kName, name);
manifest.SetString("app.launch.web_url", "http://www.google.com");
if (theme)
- manifest.Set(extension_manifest_keys::kTheme, new DictionaryValue());
+ manifest.Set(extension_manifest_keys::kTheme, new DictionaryValue);
+ manifest.SetString(extension_manifest_keys::kOmniboxKeyword, name);
std::string error;
scoped_refptr<Extension> extension = Extension::Create(
path,
@@ -211,25 +209,42 @@
TEST_F(ProfileResetterTest, ResetDefaultSearchEngine) {
// Search engine's logic is tested by
- // TemplateURLServiceTest.ResetNonExtensionURLs.
- PrefService* prefs = test_util_.profile()->GetPrefs();
+ // TemplateURLServiceTest.ResetURLs.
+ PrefService* prefs = profile()->GetPrefs();
DCHECK(prefs);
prefs->SetString(prefs::kLastPromptedGoogleURL, "http://www.foo.com/");
+ scoped_refptr<Extension> extension = CreateExtension(
+ "xxx",
+ base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
+ Manifest::COMPONENT,
+ false);
+ service_->AddExtension(extension.get());
+
ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE);
+ // TemplateURLService should reset extension search engines.
+ TemplateURLService* model =
+ TemplateURLServiceFactory::GetForProfile(profile());
+ TemplateURL* ext_url = model->GetTemplateURLForKeyword(ASCIIToUTF16("xxx"));
+ ASSERT_TRUE(ext_url);
+ EXPECT_TRUE(ext_url->IsExtensionKeyword());
+ EXPECT_EQ(ASCIIToUTF16("xxx"), ext_url->keyword());
+ EXPECT_EQ(ASCIIToUTF16("xxx"), ext_url->short_name());
EXPECT_EQ("", prefs->GetString(prefs::kLastPromptedGoogleURL));
}
TEST_F(ProfileResetterTest, ResetDefaultSearchEngineNonOrganic) {
- PrefService* prefs = test_util_.profile()->GetPrefs();
+ PrefService* prefs = profile()->GetPrefs();
DCHECK(prefs);
prefs->SetString(prefs::kLastPromptedGoogleURL, "http://www.foo.com/");
ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE, kDistributionConfig);
- EXPECT_EQ(1u, test_util_.model()->GetTemplateURLs().size());
- TemplateURL* default_engine = test_util_.model()->GetDefaultSearchProvider();
+ TemplateURLService* model =
+ TemplateURLServiceFactory::GetForProfile(profile());
+ EXPECT_EQ(1u, model->GetTemplateURLs().size());
+ TemplateURL* default_engine = model->GetDefaultSearchProvider();
ASSERT_NE(static_cast<TemplateURL*>(NULL), default_engine);
EXPECT_EQ(ASCIIToUTF16("first"), default_engine->short_name());
EXPECT_EQ(ASCIIToUTF16("firstkey"), default_engine->keyword());
@@ -239,7 +254,7 @@
}
TEST_F(ProfileResetterTest, ResetHomepage) {
- PrefService* prefs = test_util_.profile()->GetPrefs();
+ PrefService* prefs = profile()->GetPrefs();
DCHECK(prefs);
prefs->SetBoolean(prefs::kHomePageIsNewTabPage, false);
prefs->SetString(prefs::kHomePage, "http://google.com");
@@ -253,7 +268,7 @@
}
TEST_F(ProfileResetterTest, ResetHomepageNonOrganic) {
- PrefService* prefs = test_util_.profile()->GetPrefs();
+ PrefService* prefs = profile()->GetPrefs();
DCHECK(prefs);
prefs->SetBoolean(prefs::kHomePageIsNewTabPage, true);
prefs->SetString(prefs::kHomePage, "http://google.com");
@@ -268,9 +283,9 @@
TEST_F(ProfileResetterTest, ResetContentSettings) {
HostContentSettingsMap* host_content_settings_map =
- test_util_.profile()->GetHostContentSettingsMap();
+ profile()->GetHostContentSettingsMap();
DesktopNotificationService* notification_service =
- DesktopNotificationServiceFactory::GetForProfile(test_util_.profile());
+ DesktopNotificationServiceFactory::GetForProfile(profile());
ContentSettingsPattern pattern =
ContentSettingsPattern::FromString("[*.]example.org");
std::map<ContentSettingsType, ContentSetting> default_settings;
@@ -297,7 +312,7 @@
default_setting == CONTENT_SETTING_ALLOW ? CONTENT_SETTING_ALLOW
: CONTENT_SETTING_BLOCK;
if (HostContentSettingsMap::IsSettingAllowedForType(
- test_util_.profile()->GetPrefs(),
+ profile()->GetPrefs(),
wildcard_setting,
content_type)) {
host_content_settings_map->SetDefaultContentSetting(
@@ -306,7 +321,7 @@
}
if (!HostContentSettingsMap::ContentTypeHasCompoundValue(content_type) &&
HostContentSettingsMap::IsSettingAllowedForType(
- test_util_.profile()->GetPrefs(),
+ profile()->GetPrefs(),
site_setting,
content_type)) {
host_content_settings_map->SetContentSetting(
@@ -361,7 +376,7 @@
}
}
-TEST_F(ExtensionsResetTest, ResetExtensionsByDisabling) {
+TEST_F(ProfileResetterTest, ResetExtensionsByDisabling) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
@@ -374,7 +389,7 @@
// ThemeService isn't compiled for Android.
ThemeService* theme_service =
- ThemeServiceFactory::GetForProfile(profile_.get());
+ ThemeServiceFactory::GetForProfile(profile());
EXPECT_FALSE(theme_service->UsingDefaultTheme());
scoped_refptr<Extension> ext2 = CreateExtension(
@@ -406,7 +421,7 @@
EXPECT_TRUE(theme_service->UsingDefaultTheme());
}
-TEST_F(ExtensionsResetTest, ResetExtensionsByDisablingNonOrganic) {
+TEST_F(ProfileResetterTest, ResetExtensionsByDisablingNonOrganic) {
scoped_refptr<Extension> ext2 = CreateExtension(
"example2",
base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
@@ -432,7 +447,7 @@
}
TEST_F(ProfileResetterTest, ResetStartPage) {
- PrefService* prefs = test_util_.profile()->GetPrefs();
+ PrefService* prefs = profile()->GetPrefs();
DCHECK(prefs);
SessionStartupPref startup_pref(SessionStartupPref::URLS);
@@ -448,7 +463,7 @@
}
TEST_F(ProfileResetterTest, ResetStartPageNonOrganic) {
- PrefService* prefs = test_util_.profile()->GetPrefs();
+ PrefService* prefs = profile()->GetPrefs();
DCHECK(prefs);
SessionStartupPref startup_pref(SessionStartupPref::LAST);
@@ -502,7 +517,8 @@
TEST_F(ProfileResetterTest, ResetFewFlags) {
// mock_object_ is a StrictMock, so we verify that it is called only once.
ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE |
- ProfileResetter::HOMEPAGE);
+ ProfileResetter::HOMEPAGE |
+ ProfileResetter::CONTENT_SETTINGS);
}
// Tries to load unavailable config file.
diff --git a/chrome/browser/profiles/avatar_menu_model.cc b/chrome/browser/profiles/avatar_menu_model.cc
index 55e2b89..de6b904 100644
--- a/chrome/browser/profiles/avatar_menu_model.cc
+++ b/chrome/browser/profiles/avatar_menu_model.cc
@@ -12,6 +12,7 @@
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/profiles/avatar_menu_model_observer.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_info_cache.h"
@@ -62,6 +63,16 @@
}
}
+void OnGuestProfileCreated(bool always_create,
+ chrome::HostDesktopType desktop_type,
+ Profile* profile,
+ Profile::CreateStatus status) {
+ IncognitoModePrefs::SetAvailability(
+ profile->GetPrefs(),
+ IncognitoModePrefs::FORCED);
+ OnProfileCreated(always_create, desktop_type, profile, status);
+}
+
// Constants for the show profile switcher experiment
const char kShowProfileSwitcherFieldTrialName[] = "ShowProfileSwitcher";
const char kAlwaysShowSwitcherGroupName[] = "AlwaysShow";
@@ -152,15 +163,7 @@
if (browser_)
desktop_type = browser_->host_desktop_type();
- g_browser_process->profile_manager()->CreateProfileAsync(
- path,
- base::Bind(&OnProfileCreated,
- always_create,
- desktop_type),
- string16(),
- string16(),
- false);
-
+ profiles::SwitchToProfile(path, desktop_type, always_create);
ProfileMetrics::LogProfileSwitchUser(ProfileMetrics::SWITCH_PROFILE_ICON);
}
@@ -198,7 +201,7 @@
void AvatarMenuModel::SwitchToGuestProfileWindow(Browser* browser) {
ProfileManager* profile_manager = g_browser_process->profile_manager();
profile_manager->CreateProfileAsync(ProfileManager::GetGuestProfilePath(),
- base::Bind(&OnProfileCreated,
+ base::Bind(&OnGuestProfileCreated,
false,
browser->host_desktop_type()),
string16(),
diff --git a/chrome/browser/profiles/avatar_menu_model_browsertest.cc b/chrome/browser/profiles/avatar_menu_model_browsertest.cc
index b980ef3..f7bed7b 100644
--- a/chrome/browser/profiles/avatar_menu_model_browsertest.cc
+++ b/chrome/browser/profiles/avatar_menu_model_browsertest.cc
@@ -17,6 +17,14 @@
namespace {
+// An observer that returns back to test code after a new profile is
+// initialized.
+void OnUnblockOnProfileCreation(Profile* profile,
+ Profile::CreateStatus status) {
+ if (status == Profile::CREATE_STATUS_INITIALIZED)
+ base::MessageLoop::current()->Quit();
+}
+
typedef InProcessBrowserTest AvatarMenuModelTest;
IN_PROC_BROWSER_TEST_F(AvatarMenuModelTest, SignOut) {
@@ -46,4 +54,48 @@
EXPECT_EQ(0U, browser_list->size());
}
+IN_PROC_BROWSER_TEST_F(AvatarMenuModelTest, SwitchToProfile) {
+ if (!profiles::IsMultipleProfilesEnabled())
+ return;
+
+ ProfileManager* profile_manager = g_browser_process->profile_manager();
+ Profile* current_profile = browser()->profile();
+ ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
+ base::FilePath path_profile1 = current_profile->GetPath();
+ base::FilePath user_dir = cache.GetUserDataDir();
+
+ // Create an additional profile.
+ base::FilePath path_profile2 = user_dir.Append(
+ FILE_PATH_LITERAL("New Profile 2"));
+ profile_manager->CreateProfileAsync(path_profile2,
+ base::Bind(&OnUnblockOnProfileCreation),
+ string16(), string16(), false);
+
+ // Spin to allow profile creation to take place, loop is terminated
+ // by OnUnblockOnProfileCreation when the profile is created.
+ content::RunMessageLoop();
+ ASSERT_EQ(cache.GetNumberOfProfiles(), 2U);
+
+ AvatarMenuModel model(&cache, NULL, browser());
+ BrowserList* browser_list =
+ BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_NATIVE);
+ EXPECT_EQ(1U, browser_list->size());
+ EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
+
+ // Open a browser window for the first profile.
+ model.SwitchToProfile(cache.GetIndexOfProfileWithPath(path_profile1), false);
+ EXPECT_EQ(1U, browser_list->size());
+ EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
+
+ // Open a browser window for the second profile.
+ model.SwitchToProfile(cache.GetIndexOfProfileWithPath(path_profile2), false);
+ EXPECT_EQ(2U, browser_list->size());
+
+ // Switch to the first profile without opening a new window.
+ model.SwitchToProfile(cache.GetIndexOfProfileWithPath(path_profile1), false);
+ EXPECT_EQ(2U, browser_list->size());
+ EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
+ EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
+
+}
} // namespace
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
index bd26711..38b80e9 100644
--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
+++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -39,6 +39,7 @@
#include "chrome/browser/extensions/api/management/management_api.h"
#include "chrome/browser/extensions/api/media_galleries_private/media_galleries_private_api.h"
#include "chrome/browser/extensions/api/omnibox/omnibox_api.h"
+#include "chrome/browser/extensions/api/preference/chrome_direct_setting_api.h"
#include "chrome/browser/extensions/api/preference/preference_api.h"
#include "chrome/browser/extensions/api/processes/processes_api.h"
#include "chrome/browser/extensions/api/push_messaging/push_messaging_api.h"
@@ -198,6 +199,7 @@
extensions::AudioAPI::GetFactoryInstance();
extensions::BookmarksAPI::GetFactoryInstance();
extensions::BluetoothAPIFactory::GetInstance();
+ extensions::chromedirectsetting::ChromeDirectSettingAPI::GetFactoryInstance();
extensions::CommandService::GetFactoryInstance();
extensions::CookiesAPI::GetFactoryInstance();
extensions::DeveloperPrivateAPIFactory::GetInstance();
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc
index 931ed9a..3228c41 100644
--- a/chrome/browser/profiles/off_the_record_profile_impl.cc
+++ b/chrome/browser/profiles/off_the_record_profile_impl.cc
@@ -28,6 +28,7 @@
#include "chrome/browser/geolocation/chrome_geolocation_permission_context.h"
#include "chrome/browser/geolocation/chrome_geolocation_permission_context_factory.h"
#include "chrome/browser/io_thread.h"
+#include "chrome/browser/net/pref_proxy_config_tracker.h"
#include "chrome/browser/net/proxy_service_factory.h"
#include "chrome/browser/plugins/chrome_plugin_service_filter.h"
#include "chrome/browser/plugins/plugin_prefs.h"
@@ -54,13 +55,13 @@
#include "webkit/browser/database/database_tracker.h"
#if defined(OS_ANDROID) || defined(OS_IOS)
+#include "chrome/browser/prefs/proxy_prefs.h"
#include "chrome/browser/prefs/scoped_user_pref_update.h"
#endif // defined(OS_ANDROID) || defined(OS_IOS)
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/preferences.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
-#include "chrome/browser/chromeos/proxy_config_service_impl.h"
#endif
using content::BrowserThread;
diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.cc b/chrome/browser/profiles/off_the_record_profile_io_data.cc
index d6f546a..842204e 100644
--- a/chrome/browser/profiles/off_the_record_profile_io_data.cc
+++ b/chrome/browser/profiles/off_the_record_profile_io_data.cc
@@ -190,7 +190,9 @@
io_thread_globals->throttler_manager.get());
// For incognito, we use the default non-persistent HttpServerPropertiesImpl.
- set_http_server_properties(new net::HttpServerPropertiesImpl);
+ set_http_server_properties(
+ scoped_ptr<net::HttpServerProperties>(
+ new net::HttpServerPropertiesImpl()));
main_context->set_http_server_properties(http_server_properties());
// For incognito, we use a non-persistent server bound cert store.
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc
index 93415c7..c8690ee 100644
--- a/chrome/browser/profiles/profile.cc
+++ b/chrome/browser/profiles/profile.cc
@@ -116,6 +116,10 @@
prefs::kSpeechRecognitionFilterProfanities,
true,
user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
+ registry->RegisterIntegerPref(
+ prefs::kProfileIconVersion,
+ 0,
+ user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
#if defined(OS_CHROMEOS)
// TODO(dilmah): For OS_CHROMEOS we maintain kApplicationLocale in both
// local state and user's profile. For other platforms we maintain
diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h
index 19a232a..1e5270b 100644
--- a/chrome/browser/profiles/profile.h
+++ b/chrome/browser/profiles/profile.h
@@ -12,7 +12,6 @@
#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/logging.h"
-#include "chrome/browser/net/pref_proxy_config_tracker.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/content_browser_client.h"
#include "net/url_request/url_request_job_factory.h"
@@ -23,6 +22,8 @@
class FaviconService;
class HostContentSettingsMap;
class PasswordStore;
+class PrefProxyConfigTracker;
+class PrefService;
class PromoCounter;
class ProtocolHandlerRegistry;
class TestingProfile;
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index b4ef81e..57ffb8f 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -48,6 +48,7 @@
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/net/net_pref_observer.h"
#include "chrome/browser/net/predictor.h"
+#include "chrome/browser/net/pref_proxy_config_tracker.h"
#include "chrome/browser/net/proxy_service_factory.h"
#include "chrome/browser/net/ssl_config_service_manager.h"
#include "chrome/browser/net/url_fixer_upper.h"
@@ -104,7 +105,6 @@
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/preferences.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
-#include "chrome/browser/chromeos/proxy_config_service_impl.h"
#endif
#if defined(ENABLE_CONFIGURATION_POLICY)
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc
index ee68a4d..bbe1142 100644
--- a/chrome/browser/profiles/profile_impl_io_data.cc
+++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -291,7 +291,8 @@
io_data_->http_server_properties_manager_ =
new chrome_browser_net::HttpServerPropertiesManager(pref_service);
io_data_->set_http_server_properties(
- io_data_->http_server_properties_manager_);
+ scoped_ptr<net::HttpServerProperties>(
+ io_data_->http_server_properties_manager_));
io_data_->session_startup_pref()->Init(
prefs::kRestoreOnStartup, pref_service);
io_data_->session_startup_pref()->MoveToThread(
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index 8335fa5..e7b2cfb 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.cc
@@ -11,6 +11,7 @@
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
+#include "base/debug/alias.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/prefs/pref_service.h"
@@ -85,7 +86,6 @@
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/drive/drive_protocol_handler.h"
#include "chrome/browser/chromeos/policy/policy_cert_verifier.h"
-#include "chrome/browser/chromeos/proxy_config_service_impl.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/cros_settings_names.h"
#include "chrome/browser/policy/browser_policy_connector.h"
@@ -260,11 +260,9 @@
params->protocol_handler_interceptor =
protocol_handler_registry->CreateJobInterceptorFactory();
- ChromeProxyConfigService* proxy_config_service =
- ProxyServiceFactory::CreateProxyConfigService();
- params->proxy_config_service.reset(proxy_config_service);
- profile->GetProxyConfigTracker()->SetChromeProxyConfigService(
- proxy_config_service);
+ params->proxy_config_service
+ .reset(ProxyServiceFactory::CreateProxyConfigService(
+ profile->GetProxyConfigTracker()));
#if defined(ENABLE_MANAGED_USERS)
ManagedUserService* managed_user_service =
ManagedUserServiceFactory::GetForProfile(profile);
@@ -409,20 +407,80 @@
if (BrowserThread::IsMessageLoopValid(BrowserThread::IO))
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ // Pull the contents of the request context maps onto the stack for sanity
+ // checking of values in a minidump. http://crbug.com/260425
+ size_t num_app_contexts = app_request_context_map_.size();
+ size_t num_media_contexts = isolated_media_request_context_map_.size();
+ size_t current_context = 0;
+ static const size_t kMaxCachedContexts = 20;
+ ChromeURLRequestContext* app_context_cache[kMaxCachedContexts] = {0};
+ void* app_context_vtable_cache[kMaxCachedContexts] = {0};
+ ChromeURLRequestContext* media_context_cache[kMaxCachedContexts] = {0};
+ void* media_context_vtable_cache[kMaxCachedContexts] = {0};
+ void* tmp_vtable = NULL;
+ base::debug::Alias(&num_app_contexts);
+ base::debug::Alias(&num_media_contexts);
+ base::debug::Alias(¤t_context);
+ base::debug::Alias(app_context_cache);
+ base::debug::Alias(app_context_vtable_cache);
+ base::debug::Alias(media_context_cache);
+ base::debug::Alias(media_context_vtable_cache);
+ base::debug::Alias(&tmp_vtable);
+
+ current_context = 0;
+ for (URLRequestContextMap::const_iterator it =
+ app_request_context_map_.begin();
+ current_context < kMaxCachedContexts &&
+ it != app_request_context_map_.end();
+ ++it, ++current_context) {
+ app_context_cache[current_context] = it->second;
+ memcpy(&app_context_vtable_cache[current_context],
+ static_cast<void*>(it->second), sizeof(void*));
+ }
+
+ current_context = 0;
+ for (URLRequestContextMap::const_iterator it =
+ isolated_media_request_context_map_.begin();
+ current_context < kMaxCachedContexts &&
+ it != isolated_media_request_context_map_.end();
+ ++it, ++current_context) {
+ media_context_cache[current_context] = it->second;
+ memcpy(&media_context_vtable_cache[current_context],
+ static_cast<void*>(it->second), sizeof(void*));
+ }
+
+ // TODO(ajwong): These AssertNoURLRequests() calls are unnecessary since they
+ // are already done in the URLRequestContext destructor.
if (main_request_context_)
main_request_context_->AssertNoURLRequests();
if (extensions_request_context_)
extensions_request_context_->AssertNoURLRequests();
+
+ current_context = 0;
for (URLRequestContextMap::iterator it = app_request_context_map_.begin();
it != app_request_context_map_.end(); ++it) {
+ if (current_context < kMaxCachedContexts) {
+ CHECK_EQ(app_context_cache[current_context], it->second);
+ memcpy(&tmp_vtable, static_cast<void*>(it->second), sizeof(void*));
+ CHECK_EQ(app_context_vtable_cache[current_context], tmp_vtable);
+ }
it->second->AssertNoURLRequests();
delete it->second;
+ current_context++;
}
+
+ current_context = 0;
for (URLRequestContextMap::iterator it =
isolated_media_request_context_map_.begin();
it != isolated_media_request_context_map_.end(); ++it) {
+ if (current_context < kMaxCachedContexts) {
+ CHECK_EQ(media_context_cache[current_context], it->second);
+ memcpy(&tmp_vtable, static_cast<void*>(it->second), sizeof(void*));
+ CHECK_EQ(media_context_vtable_cache[current_context], tmp_vtable);
+ }
it->second->AssertNoURLRequests();
delete it->second;
+ current_context++;
}
}
@@ -596,13 +654,14 @@
#endif // defined(OS_CHROMEOS)
}
-net::HttpServerProperties* ProfileIOData::http_server_properties() const {
- return http_server_properties_.get();
+base::WeakPtr<net::HttpServerProperties>
+ProfileIOData::http_server_properties() const {
+ return http_server_properties_->GetWeakPtr();
}
void ProfileIOData::set_http_server_properties(
- net::HttpServerProperties* http_server_properties) const {
- http_server_properties_.reset(http_server_properties);
+ scoped_ptr<net::HttpServerProperties> http_server_properties) const {
+ http_server_properties_ = http_server_properties.Pass();
}
ProfileIOData::ResourceContext::ResourceContext(ProfileIOData* io_data)
diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h
index c472b3f..1bb562b 100644
--- a/chrome/browser/profiles/profile_io_data.h
+++ b/chrome/browser/profiles/profile_io_data.h
@@ -319,10 +319,10 @@
return proxy_service_.get();
}
- net::HttpServerProperties* http_server_properties() const;
+ base::WeakPtr<net::HttpServerProperties> http_server_properties() const;
void set_http_server_properties(
- net::HttpServerProperties* http_server_properties) const;
+ scoped_ptr<net::HttpServerProperties> http_server_properties) const;
ChromeURLRequestContext* main_request_context() const {
return main_request_context_.get();
diff --git a/chrome/browser/profiles/profile_manager.h b/chrome/browser/profiles/profile_manager.h
index dea43de..4068c88 100644
--- a/chrome/browser/profiles/profile_manager.h
+++ b/chrome/browser/profiles/profile_manager.h
@@ -234,6 +234,7 @@
private:
friend class TestingProfileManager;
FRIEND_TEST_ALL_PREFIXES(ProfileManagerBrowserTest, DeleteAllProfiles);
+ FRIEND_TEST_ALL_PREFIXES(ProfileManagerBrowserTest, SwitchToProfile);
// This struct contains information about profiles which are being loaded or
// were loaded.
diff --git a/chrome/browser/profiles/profile_manager_browsertest.cc b/chrome/browser/profiles/profile_manager_browsertest.cc
index 7b96cc4..5243d66 100644
--- a/chrome/browser/profiles/profile_manager_browsertest.cc
+++ b/chrome/browser/profiles/profile_manager_browsertest.cc
@@ -8,6 +8,8 @@
#include "chrome/browser/profiles/profile_info_cache.h"
#include "chrome/browser/profiles/profile_info_cache_observer.h"
#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/profiles/profile_window.h"
+#include "chrome/browser/profiles/profiles_state.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/host_desktop.h"
@@ -181,3 +183,55 @@
BrowserList::CloseAllBrowsersWithProfile(*it);
}
}
+
+IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest,
+ SwitchToProfile) {
+ // If multiprofile mode is not enabled, you can't switch between profiles.
+ if (!profiles::IsMultipleProfilesEnabled())
+ return;
+
+
+ ProfileManager* profile_manager = g_browser_process->profile_manager();
+ ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
+ base::FilePath path_profile1 = cache.GetPathOfProfileAtIndex(0);
+
+ ASSERT_EQ(profile_manager->GetNumberOfProfiles(), 1U);
+ EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
+
+ // Create an additional profile.
+ base::FilePath path_profile2 =
+ profile_manager->GenerateNextProfileDirectoryPath();
+ profile_manager->CreateProfileAsync(path_profile2,
+ base::Bind(&OnUnblockOnProfileCreation),
+ string16(), string16(), false);
+
+ // Spin to allow profile creation to take place, loop is terminated
+ // by OnUnblockOnProfileCreation when the profile is created.
+ content::RunMessageLoop();
+
+ chrome::HostDesktopType desktop_type = chrome::HOST_DESKTOP_TYPE_NATIVE;
+ BrowserList* browser_list = BrowserList::GetInstance(desktop_type);
+ ASSERT_EQ(cache.GetNumberOfProfiles(), 2U);
+ EXPECT_EQ(1U, browser_list->size());
+
+ // Open a browser window for the first profile.
+ profiles::SwitchToProfile(path_profile1, desktop_type, false);
+ EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
+ EXPECT_EQ(1U, browser_list->size());
+ EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
+
+ // Open a browser window for the second profile.
+ profiles::SwitchToProfile(path_profile2, desktop_type, false);
+ EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
+ EXPECT_EQ(2U, browser_list->size());
+ EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
+
+ // Switch to the first profile without opening a new window.
+ profiles::SwitchToProfile(path_profile1, desktop_type, false);
+ EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
+ EXPECT_EQ(2U, browser_list->size());
+
+ EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
+ EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
+
+}
diff --git a/chrome/browser/profiles/profile_shortcut_manager.h b/chrome/browser/profiles/profile_shortcut_manager.h
index 9091ad6..602757d 100644
--- a/chrome/browser/profiles/profile_shortcut_manager.h
+++ b/chrome/browser/profiles/profile_shortcut_manager.h
@@ -16,6 +16,12 @@
public:
virtual ~ProfileShortcutManager();
+ // Create a profile icon for the profile with path |profile_path|.
+ // |callback| is called only on creation success.
+ virtual void CreateOrUpdateProfileIcon(
+ const base::FilePath& profile_path,
+ const base::Closure& callback) = 0;
+
// Create a profile shortcut for the profile with path |profile_path|, plus
// update the original profile shortcut if |profile_path| is the second
// profile created.
diff --git a/chrome/browser/profiles/profile_shortcut_manager_unittest_win.cc b/chrome/browser/profiles/profile_shortcut_manager_unittest_win.cc
index 5e3cf5f..4afb347 100644
--- a/chrome/browser/profiles/profile_shortcut_manager_unittest_win.cc
+++ b/chrome/browser/profiles/profile_shortcut_manager_unittest_win.cc
@@ -71,16 +71,17 @@
profile_info_cache_->DeleteProfileFromCache(profile_path);
RunPendingTasks();
ASSERT_FALSE(ProfileShortcutExistsAtDefaultPath(profile_name));
+ // The icon file is not deleted until the profile directory is deleted.
const base::FilePath icon_path =
- profile_path.AppendASCII(profiles::internal::kProfileIconFileName);
- ASSERT_FALSE(base::PathExists(icon_path));
+ profiles::internal::GetProfileIconPath(profile_path);
+ ASSERT_TRUE(base::PathExists(icon_path));
}
}
base::FilePath CreateProfileDirectory(const string16& profile_name) {
const base::FilePath profile_path =
profile_info_cache_->GetUserDataDir().Append(profile_name);
- file_util::CreateDirectoryW(profile_path);
+ file_util::CreateDirectory(profile_path);
return profile_path;
}
@@ -134,7 +135,7 @@
// Ensure that the corresponding icon exists.
const base::FilePath icon_path =
- profile_path.AppendASCII(profiles::internal::kProfileIconFileName);
+ profiles::internal::GetProfileIconPath(profile_path);
EXPECT_TRUE(base::PathExists(icon_path)) << location.ToString();
base::win::ShortcutProperties expected_properties;
@@ -760,7 +761,7 @@
CreateRegularSystemLevelShortcut(FROM_HERE);
// Delete the profile that has a shortcut, which will exercise the non-profile
- // shortcut creation path in |DeleteDesktopShortcutsAndIconFile()|, which is
+ // shortcut creation path in |DeleteDesktopShortcuts()|, which is
// not covered by the |DeleteSecondToLastProfileWithSystemLevelShortcut| test.
profile_info_cache_->DeleteProfileFromCache(profile_2_path_);
RunPendingTasks();
@@ -772,3 +773,95 @@
EXPECT_FALSE(base::PathExists(profile_1_shortcut_path));
EXPECT_FALSE(base::PathExists(profile_2_shortcut_path));
}
+
+TEST_F(ProfileShortcutManagerTest, CreateProfileIcon) {
+ SetupDefaultProfileShortcut(FROM_HERE);
+
+ const base::FilePath icon_path =
+ profiles::internal::GetProfileIconPath(profile_1_path_);
+
+ EXPECT_TRUE(base::PathExists(icon_path));
+ EXPECT_TRUE(base::DeleteFile(icon_path, false));
+ EXPECT_FALSE(base::PathExists(icon_path));
+
+ profile_shortcut_manager_->CreateOrUpdateProfileIcon(profile_1_path_,
+ base::Closure());
+ RunPendingTasks();
+ EXPECT_TRUE(base::PathExists(icon_path));
+}
+
+TEST_F(ProfileShortcutManagerTest, UnbadgeProfileIconOnDeletion) {
+ SetupDefaultProfileShortcut(FROM_HERE);
+ const base::FilePath icon_path_1 =
+ profiles::internal::GetProfileIconPath(profile_1_path_);
+ const base::FilePath icon_path_2 =
+ profiles::internal::GetProfileIconPath(profile_2_path_);
+
+ // Default profile has unbadged icon to start.
+ std::string unbadged_icon_1;
+ EXPECT_TRUE(file_util::ReadFileToString(icon_path_1, &unbadged_icon_1));
+
+ // Creating a new profile adds a badge to both the new profile icon and the
+ // default profile icon. Since they use the same icon index, the icon files
+ // should be the same.
+ CreateProfileWithShortcut(FROM_HERE, profile_2_name_, profile_2_path_);
+
+ std::string badged_icon_1;
+ EXPECT_TRUE(file_util::ReadFileToString(icon_path_1, &badged_icon_1));
+ std::string badged_icon_2;
+ EXPECT_TRUE(file_util::ReadFileToString(icon_path_2, &badged_icon_2));
+
+ EXPECT_NE(badged_icon_1, unbadged_icon_1);
+ EXPECT_EQ(badged_icon_1, badged_icon_2);
+
+ // Deleting the default profile will unbadge the new profile's icon and should
+ // result in an icon that is identical to the unbadged default profile icon.
+ profile_info_cache_->DeleteProfileFromCache(profile_1_path_);
+ RunPendingTasks();
+
+ std::string unbadged_icon_2;
+ EXPECT_TRUE(file_util::ReadFileToString(icon_path_2, &unbadged_icon_2));
+ EXPECT_EQ(unbadged_icon_1, unbadged_icon_2);
+}
+
+TEST_F(ProfileShortcutManagerTest, ProfileIconOnAvatarChange) {
+ SetupAndCreateTwoShortcuts(FROM_HERE);
+ const base::FilePath icon_path_1 =
+ profiles::internal::GetProfileIconPath(profile_1_path_);
+ const base::FilePath icon_path_2 =
+ profiles::internal::GetProfileIconPath(profile_2_path_);
+ const size_t profile_index_1 =
+ profile_info_cache_->GetIndexOfProfileWithPath(profile_1_path_);
+
+ std::string badged_icon_1;
+ EXPECT_TRUE(file_util::ReadFileToString(icon_path_1, &badged_icon_1));
+ std::string badged_icon_2;
+ EXPECT_TRUE(file_util::ReadFileToString(icon_path_2, &badged_icon_2));
+
+ // Profile 1 and 2 are created with the same icon.
+ EXPECT_EQ(badged_icon_1, badged_icon_2);
+
+ // Change profile 1's icon.
+ profile_info_cache_->SetAvatarIconOfProfileAtIndex(profile_index_1, 1);
+ RunPendingTasks();
+
+ std::string new_badged_icon_1;
+ EXPECT_TRUE(file_util::ReadFileToString(icon_path_1, &new_badged_icon_1));
+ EXPECT_NE(new_badged_icon_1, badged_icon_1);
+
+ // Ensure the new icon is not the unbadged icon.
+ profile_info_cache_->DeleteProfileFromCache(profile_2_path_);
+ RunPendingTasks();
+
+ std::string unbadged_icon_1;
+ EXPECT_TRUE(file_util::ReadFileToString(icon_path_1, &unbadged_icon_1));
+ EXPECT_NE(unbadged_icon_1, new_badged_icon_1);
+
+ // Ensure the icon doesn't change on avatar change without 2 profiles.
+ profile_info_cache_->SetAvatarIconOfProfileAtIndex(profile_index_1, 1);
+ RunPendingTasks();
+
+ std::string unbadged_icon_1_a;
+ EXPECT_TRUE(file_util::ReadFileToString(icon_path_1, &unbadged_icon_1_a));
+ EXPECT_EQ(unbadged_icon_1, unbadged_icon_1_a);
+}
diff --git a/chrome/browser/profiles/profile_shortcut_manager_win.cc b/chrome/browser/profiles/profile_shortcut_manager_win.cc
index cc8c250..7ce8ca2 100644
--- a/chrome/browser/profiles/profile_shortcut_manager_win.cc
+++ b/chrome/browser/profiles/profile_shortcut_manager_win.cc
@@ -14,6 +14,7 @@
#include "base/file_util.h"
#include "base/files/file_enumerator.h"
#include "base/path_service.h"
+#include "base/prefs/pref_service.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
@@ -21,15 +22,18 @@
#include "base/win/shortcut.h"
#include "chrome/browser/app_icon_win.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/profiles/profile_info_cache_observer.h"
#include "chrome/browser/profiles/profile_info_util.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/common/pref_names.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/product.h"
#include "chrome/installer/util/shell_util.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/notification_service.h"
#include "grit/chrome_unscaled_resources.h"
#include "grit/chromium_strings.h"
#include "skia/ext/image_operations.h"
@@ -46,6 +50,9 @@
namespace {
+// Name of the badged icon file generated for a given profile.
+const char kProfileIconFileName[] = "Google Profile.ico";
+
// Characters that are not allowed in Windows filenames. Taken from
// http://msdn.microsoft.com/en-us/library/aa365247.aspx
const char16 kReservedCharacters[] = L"<>:\"/\\|?*\x01\x02\x03\x04\x05\x06\x07"
@@ -61,6 +68,8 @@
const int kProfileAvatarBadgeSize = 28;
const int kShortcutIconSize = 48;
+const int kCurrentProfileIconVersion = 1;
+
// 2x sized profile avatar icons. Mirrors |kDefaultAvatarIconResources| in
// profile_info_cache.cc.
const int kProfileAvatarIconResources2x[] = {
@@ -141,35 +150,92 @@
// Creates a desktop shortcut icon file (.ico) on the disk for a given profile,
// badging the browser distribution icon with the profile avatar.
// Returns a path to the shortcut icon file on disk, which is empty if this
-// fails. Use index 0 when assigning the resulting file as the icon.
-base::FilePath CreateChromeDesktopShortcutIconForProfile(
+// fails. Use index 0 when assigning the resulting file as the icon. If both
+// given bitmaps are empty, an unbadged icon is created.
+// |callback| will be run on successful icon creation.
+// Returns the path to the created icon on success and an empty base::FilePath
+// on failure.
+// TODO(calamity): Ideally we'd just copy the app icon verbatim from the exe's
+// resources in the case of an unbadged icon.
+base::FilePath CreateOrUpdateShortcutIconForProfile(
const base::FilePath& profile_path,
const SkBitmap& avatar_bitmap_1x,
- const SkBitmap& avatar_bitmap_2x) {
+ const SkBitmap& avatar_bitmap_2x,
+ const base::Closure& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+
+ if (!base::PathExists(profile_path)) {
+ LOG(ERROR) << "Profile directory " << profile_path.value()
+ << " did not exist when trying to create profile icon";
+ return base::FilePath();
+ }
+
scoped_ptr<SkBitmap> app_icon_bitmap(GetAppIconForSize(kShortcutIconSize));
if (!app_icon_bitmap)
return base::FilePath();
gfx::ImageFamily badged_bitmaps;
- badged_bitmaps.Add(gfx::Image::CreateFrom1xBitmap(
- BadgeIcon(*app_icon_bitmap, avatar_bitmap_1x, 1)));
-
- app_icon_bitmap = GetAppIconForSize(IconUtil::kLargeIconSize);
- if (app_icon_bitmap) {
+ if (!avatar_bitmap_1x.empty()) {
badged_bitmaps.Add(gfx::Image::CreateFrom1xBitmap(
- BadgeIcon(*app_icon_bitmap, avatar_bitmap_2x, 2)));
+ BadgeIcon(*app_icon_bitmap, avatar_bitmap_1x, 1)));
}
+ scoped_ptr<SkBitmap> large_app_icon_bitmap(
+ GetAppIconForSize(IconUtil::kLargeIconSize));
+ if (large_app_icon_bitmap && !avatar_bitmap_2x.empty()) {
+ badged_bitmaps.Add(gfx::Image::CreateFrom1xBitmap(
+ BadgeIcon(*large_app_icon_bitmap, avatar_bitmap_2x, 2)));
+ }
+
+ // If we have no badged bitmaps, we should just use the default chrome icon.
+ if (badged_bitmaps.empty()) {
+ badged_bitmaps.Add(gfx::Image::CreateFrom1xBitmap(*app_icon_bitmap));
+ if (large_app_icon_bitmap) {
+ badged_bitmaps.Add(
+ gfx::Image::CreateFrom1xBitmap(*large_app_icon_bitmap));
+ }
+ }
// Finally, write the .ico file containing this new bitmap.
const base::FilePath icon_path =
- profile_path.AppendASCII(profiles::internal::kProfileIconFileName);
- if (!IconUtil::CreateIconFileFromImageFamily(badged_bitmaps, icon_path))
- return base::FilePath();
+ profiles::internal::GetProfileIconPath(profile_path);
+ const bool had_icon = base::PathExists(icon_path);
+ if (!IconUtil::CreateIconFileFromImageFamily(badged_bitmaps, icon_path)) {
+ // This can happen in theory if the profile directory is deleted between the
+ // beginning of this function and here; however this is extremely unlikely
+ // and this check will help catch any regression where this call would start
+ // failing constantly.
+ NOTREACHED();
+ return base::FilePath();
+ }
+
+ if (had_icon) {
+ // This invalidates the Windows icon cache and causes the icon changes to
+ // register with the taskbar and desktop. SHCNE_ASSOCCHANGED will cause a
+ // desktop flash and we would like to avoid that if possible.
+ SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
+ } else {
+ SHChangeNotify(SHCNE_CREATE, SHCNF_PATH, icon_path.value().c_str(), NULL);
+ }
+ if (!callback.is_null())
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
return icon_path;
}
+// Updates the preferences with the current icon version on icon creation
+// success.
+void OnProfileIconCreateSuccess(base::FilePath profile_path) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (!g_browser_process->profile_manager())
+ return;
+ Profile* profile =
+ g_browser_process->profile_manager()->GetProfileByPath(profile_path);
+ if (profile) {
+ profile->GetPrefs()->SetInteger(prefs::kProfileIconVersion,
+ kCurrentProfileIconVersion);
+ }
+}
+
// Gets the user and system directories for desktop shortcuts. Parameters may
// be NULL if a directory type is not needed. Returns true on success.
bool GetDesktopShortcutsDirectories(
@@ -301,7 +367,8 @@
// It's also possible that a system-level shortcut exists instead - this
// should only be the case for the original Chrome shortcut from an
// installation. If that's the case, copy that one over - it will get its
- // properties updated by |CreateOrUpdateDesktopShortcutsForProfile()|.
+ // properties updated by
+ // |CreateOrUpdateDesktopShortcutsAndIconForProfile()|.
const base::FilePath possible_old_system_shortcut =
system_shortcuts_directory.Append(old_shortcut_filename);
if (base::PathExists(possible_old_system_shortcut))
@@ -309,20 +376,49 @@
}
}
+struct CreateOrUpdateShortcutsParams {
+ CreateOrUpdateShortcutsParams(
+ base::FilePath profile_path,
+ ProfileShortcutManagerWin::CreateOrUpdateMode create_mode,
+ ProfileShortcutManagerWin::NonProfileShortcutAction action)
+ : profile_path(profile_path), create_mode(create_mode), action(action) {}
+ ~CreateOrUpdateShortcutsParams() {}
+
+ ProfileShortcutManagerWin::CreateOrUpdateMode create_mode;
+ ProfileShortcutManagerWin::NonProfileShortcutAction action;
+
+ // The path for this profile.
+ base::FilePath profile_path;
+ // The profile name before this update. Empty on create.
+ string16 old_profile_name;
+ // The new profile name.
+ string16 profile_name;
+ // Avatar images for this profile.
+ SkBitmap avatar_image_1x;
+ SkBitmap avatar_image_2x;
+};
+
// Updates all desktop shortcuts for the given profile to have the specified
-// parameters. If |create_mode| is CREATE_WHEN_NONE_FOUND, a new shortcut is
-// created if no existing ones were found. Whether non-profile shortcuts should
-// be updated is specified by |action|. Must be called on the FILE thread.
-void CreateOrUpdateDesktopShortcutsForProfile(
- const base::FilePath& profile_path,
- const string16& old_profile_name,
- const string16& profile_name,
- const SkBitmap& avatar_image_1x,
- const SkBitmap& avatar_image_2x,
- ProfileShortcutManagerWin::CreateOrUpdateMode create_mode,
- ProfileShortcutManagerWin::NonProfileShortcutAction action) {
+// parameters. If |params.create_mode| is CREATE_WHEN_NONE_FOUND, a new shortcut
+// is created if no existing ones were found. Whether non-profile shortcuts
+// should be updated is specified by |params.action|. Must be called on the FILE
+// thread. |callback| is called on successful icon creation.
+void CreateOrUpdateDesktopShortcutsAndIconForProfile(
+ const CreateOrUpdateShortcutsParams& params,
+ const base::Closure& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ const base::FilePath shortcut_icon =
+ CreateOrUpdateShortcutIconForProfile(params.profile_path,
+ params.avatar_image_1x,
+ params.avatar_image_2x,
+ callback);
+ if (shortcut_icon.empty() ||
+ params.create_mode ==
+ ProfileShortcutManagerWin::CREATE_OR_UPDATE_ICON_ONLY) {
+ return;
+ }
+
base::FilePath chrome_exe;
if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
NOTREACHED();
@@ -334,12 +430,13 @@
// the following code may result in NOTREACHED() being hit.
DCHECK(distribution->CanCreateDesktopShortcuts());
- if (old_profile_name != profile_name) {
+ if (params.old_profile_name != params.profile_name) {
const string16 old_shortcut_filename =
- profiles::internal::GetShortcutFilenameForProfile(old_profile_name,
- distribution);
+ profiles::internal::GetShortcutFilenameForProfile(
+ params.old_profile_name,
+ distribution);
const string16 new_shortcut_filename =
- profiles::internal::GetShortcutFilenameForProfile(profile_name,
+ profiles::internal::GetShortcutFilenameForProfile(params.profile_name,
distribution);
RenameChromeDesktopShortcutForProfile(old_shortcut_filename,
new_shortcut_filename);
@@ -350,19 +447,14 @@
product.AddDefaultShortcutProperties(chrome_exe, &properties);
const string16 command_line =
- profiles::internal::CreateProfileShortcutFlags(profile_path);
+ profiles::internal::CreateProfileShortcutFlags(params.profile_path);
// Only set the profile-specific properties when |profile_name| is non empty.
// If it is empty, it means the shortcut being created should be a regular,
// non-profile Chrome shortcut.
- if (!profile_name.empty()) {
- const base::FilePath shortcut_icon =
- CreateChromeDesktopShortcutIconForProfile(profile_path,
- avatar_image_1x,
- avatar_image_2x);
- if (!shortcut_icon.empty())
- properties.set_icon(shortcut_icon, 0);
+ if (!params.profile_name.empty()) {
properties.set_arguments(command_line);
+ properties.set_icon(shortcut_icon, 0);
} else {
// Set the arguments explicitly to the empty string to ensure that
// |ShellUtil::CreateOrUpdateShortcut| updates that part of the shortcut.
@@ -370,19 +462,19 @@
}
properties.set_app_id(
- ShellIntegration::GetChromiumModelIdForProfile(profile_path));
+ ShellIntegration::GetChromiumModelIdForProfile(params.profile_path));
ShellUtil::ShortcutOperation operation =
ShellUtil::SHELL_SHORTCUT_REPLACE_EXISTING;
std::vector<base::FilePath> shortcuts;
ListDesktopShortcutsWithCommandLine(chrome_exe, command_line,
- action == ProfileShortcutManagerWin::UPDATE_NON_PROFILE_SHORTCUTS,
+ params.action == ProfileShortcutManagerWin::UPDATE_NON_PROFILE_SHORTCUTS,
&shortcuts);
- if (create_mode == ProfileShortcutManagerWin::CREATE_WHEN_NONE_FOUND &&
+ if (params.create_mode == ProfileShortcutManagerWin::CREATE_WHEN_NONE_FOUND &&
shortcuts.empty()) {
const string16 shortcut_name =
- profiles::internal::GetShortcutFilenameForProfile(profile_name,
+ profiles::internal::GetShortcutFilenameForProfile(params.profile_name,
distribution);
shortcuts.push_back(base::FilePath(shortcut_name));
operation = ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL;
@@ -415,12 +507,12 @@
return false;
}
-// Deletes all desktop shortcuts for the specified profile and also removes the
-// corresponding icon file. If |ensure_shortcuts_remain| is true, then a regular
-// non-profile shortcut will be created if this function would otherwise delete
-// the last Chrome desktop shortcut(s). Must be called on the FILE thread.
-void DeleteDesktopShortcutsAndIconFile(const base::FilePath& profile_path,
- bool ensure_shortcuts_remain) {
+// Deletes all desktop shortcuts for the specified profile. If
+// |ensure_shortcuts_remain| is true, then a regular non-profile shortcut will
+// be created if this function would otherwise delete the last Chrome desktop
+// shortcut(s). Must be called on the FILE thread.
+void DeleteDesktopShortcuts(const base::FilePath& profile_path,
+ bool ensure_shortcuts_remain) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
base::FilePath chrome_exe;
@@ -445,10 +537,6 @@
NULL);
}
- const base::FilePath icon_path =
- profile_path.AppendASCII(profiles::internal::kProfileIconFileName);
- base::DeleteFile(icon_path, false);
-
// If |ensure_shortcuts_remain| is true and deleting this profile caused the
// last shortcuts to be removed, re-create a regular non-profile shortcut.
const bool had_shortcuts = !shortcuts.empty();
@@ -530,7 +618,9 @@
namespace profiles {
namespace internal {
-const char kProfileIconFileName[] = "Google Profile.ico";
+base::FilePath GetProfileIconPath(const base::FilePath& profile_path) {
+ return profile_path.AppendASCII(kProfileIconFileName);
+}
string16 GetShortcutFilenameForProfile(const string16& profile_name,
BrowserDistribution* distribution) {
@@ -572,6 +662,9 @@
arraysize(kProfileAvatarIconResources2x),
profile_manager_->GetProfileInfoCache().GetDefaultAvatarIconCount());
+ registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
+ content::NotificationService::AllSources());
+
profile_manager_->GetProfileInfoCache().AddObserver(this);
}
@@ -579,17 +672,27 @@
profile_manager_->GetProfileInfoCache().RemoveObserver(this);
}
+void ProfileShortcutManagerWin::CreateOrUpdateProfileIcon(
+ const base::FilePath& profile_path,
+ const base::Closure& callback) {
+ CreateOrUpdateShortcutsForProfileAtPath(profile_path,
+ CREATE_OR_UPDATE_ICON_ONLY,
+ IGNORE_NON_PROFILE_SHORTCUTS,
+ callback);
+}
+
void ProfileShortcutManagerWin::CreateProfileShortcut(
const base::FilePath& profile_path) {
CreateOrUpdateShortcutsForProfileAtPath(profile_path, CREATE_WHEN_NONE_FOUND,
- IGNORE_NON_PROFILE_SHORTCUTS);
+ IGNORE_NON_PROFILE_SHORTCUTS,
+ base::Closure());
}
void ProfileShortcutManagerWin::RemoveProfileShortcuts(
const base::FilePath& profile_path) {
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
- base::Bind(&DeleteDesktopShortcutsAndIconFile, profile_path, false));
+ base::Bind(&DeleteDesktopShortcuts, profile_path, false));
}
void ProfileShortcutManagerWin::HasProfileShortcuts(
@@ -602,12 +705,14 @@
void ProfileShortcutManagerWin::OnProfileAdded(
const base::FilePath& profile_path) {
+ CreateOrUpdateProfileIcon(profile_path, base::Closure());
if (profile_manager_->GetProfileInfoCache().GetNumberOfProfiles() == 2) {
// When the second profile is added, make existing non-profile shortcuts
// point to the first profile and be badged/named appropriately.
CreateOrUpdateShortcutsForProfileAtPath(GetOtherProfilePath(profile_path),
UPDATE_EXISTING_ONLY,
- UPDATE_NON_PROFILE_SHORTCUTS);
+ UPDATE_NON_PROFILE_SHORTCUTS,
+ base::Closure());
}
}
@@ -619,13 +724,15 @@
// from an existing shortcut.
const bool deleting_down_to_last_profile = (cache.GetNumberOfProfiles() == 1);
if (deleting_down_to_last_profile) {
+ // This is needed to unbadge the icon.
CreateOrUpdateShortcutsForProfileAtPath(cache.GetPathOfProfileAtIndex(0),
UPDATE_EXISTING_ONLY,
- IGNORE_NON_PROFILE_SHORTCUTS);
+ IGNORE_NON_PROFILE_SHORTCUTS,
+ base::Closure());
}
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
- base::Bind(&DeleteDesktopShortcutsAndIconFile,
+ base::Bind(&DeleteDesktopShortcuts,
profile_path,
deleting_down_to_last_profile));
}
@@ -634,13 +741,13 @@
const base::FilePath& profile_path,
const string16& old_profile_name) {
CreateOrUpdateShortcutsForProfileAtPath(profile_path, UPDATE_EXISTING_ONLY,
- IGNORE_NON_PROFILE_SHORTCUTS);
+ IGNORE_NON_PROFILE_SHORTCUTS,
+ base::Closure());
}
void ProfileShortcutManagerWin::OnProfileAvatarChanged(
const base::FilePath& profile_path) {
- CreateOrUpdateShortcutsForProfileAtPath(profile_path, UPDATE_EXISTING_ONLY,
- IGNORE_NON_PROFILE_SHORTCUTS);
+ CreateOrUpdateProfileIcon(profile_path, base::Closure());
}
base::FilePath ProfileShortcutManagerWin::GetOtherProfilePath(
@@ -657,32 +764,33 @@
void ProfileShortcutManagerWin::CreateOrUpdateShortcutsForProfileAtPath(
const base::FilePath& profile_path,
CreateOrUpdateMode create_mode,
- NonProfileShortcutAction action) {
+ NonProfileShortcutAction action,
+ const base::Closure& callback) {
+ DCHECK(!BrowserThread::IsWellKnownThread(BrowserThread::UI) ||
+ BrowserThread::CurrentlyOn(BrowserThread::UI));
+ CreateOrUpdateShortcutsParams params(profile_path, create_mode, action);
+
ProfileInfoCache* cache = &profile_manager_->GetProfileInfoCache();
size_t profile_index = cache->GetIndexOfProfileWithPath(profile_path);
if (profile_index == std::string::npos)
return;
bool remove_badging = cache->GetNumberOfProfiles() == 1;
- string16 old_shortcut_appended_name =
+ params.old_profile_name =
cache->GetShortcutNameOfProfileAtIndex(profile_index);
// Exit early if the mode is to update existing profile shortcuts only and
// none were ever created for this profile, per the shortcut name not being
// set in the profile info cache.
- if (old_shortcut_appended_name.empty() &&
+ if (params.old_profile_name.empty() &&
create_mode == UPDATE_EXISTING_ONLY &&
action == IGNORE_NON_PROFILE_SHORTCUTS) {
return;
}
- string16 new_shortcut_appended_name;
- if (!remove_badging)
- new_shortcut_appended_name = cache->GetNameOfProfileAtIndex(profile_index);
-
- SkBitmap avatar_bitmap_copy_1x;
- SkBitmap avatar_bitmap_copy_2x;
if (!remove_badging) {
+ params.profile_name = cache->GetNameOfProfileAtIndex(profile_index);
+
const size_t icon_index =
cache->GetAvatarIconIndexOfProfileAtIndex(profile_index);
const int resource_id_1x =
@@ -690,16 +798,38 @@
const int resource_id_2x = kProfileAvatarIconResources2x[icon_index];
// Make a copy of the SkBitmaps to ensure that we can safely use the image
// data on the FILE thread.
- avatar_bitmap_copy_1x = GetImageResourceSkBitmapCopy(resource_id_1x);
- avatar_bitmap_copy_2x = GetImageResourceSkBitmapCopy(resource_id_2x);
+ params.avatar_image_1x = GetImageResourceSkBitmapCopy(resource_id_1x);
+ params.avatar_image_2x = GetImageResourceSkBitmapCopy(resource_id_2x);
}
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
- base::Bind(&CreateOrUpdateDesktopShortcutsForProfile, profile_path,
- old_shortcut_appended_name, new_shortcut_appended_name,
- avatar_bitmap_copy_1x, avatar_bitmap_copy_2x, create_mode,
- action));
+ base::Bind(&CreateOrUpdateDesktopShortcutsAndIconForProfile, params,
+ callback));
cache->SetShortcutNameOfProfileAtIndex(profile_index,
- new_shortcut_appended_name);
+ params.profile_name);
+}
+
+void ProfileShortcutManagerWin::Observe(
+ int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ switch (type) {
+ // This notification is triggered when a profile is loaded.
+ case chrome::NOTIFICATION_PROFILE_CREATED: {
+ Profile* profile =
+ content::Source<Profile>(source).ptr()->GetOriginalProfile();
+ if (profile->GetPrefs()->GetInteger(prefs::kProfileIconVersion) <
+ kCurrentProfileIconVersion) {
+ // Ensure the profile's icon file has been created.
+ CreateOrUpdateProfileIcon(
+ profile->GetPath(),
+ base::Bind(&OnProfileIconCreateSuccess, profile->GetPath()));
+ }
+ break;
+ }
+ default:
+ NOTREACHED();
+ break;
+ }
}
diff --git a/chrome/browser/profiles/profile_shortcut_manager_win.h b/chrome/browser/profiles/profile_shortcut_manager_win.h
index fa627a4..4ecbfec 100644
--- a/chrome/browser/profiles/profile_shortcut_manager_win.h
+++ b/chrome/browser/profiles/profile_shortcut_manager_win.h
@@ -5,7 +5,10 @@
#ifndef CHROME_BROWSER_PROFILES_PROFILE_SHORTCUT_MANAGER_WIN_H_
#define CHROME_BROWSER_PROFILES_PROFILE_SHORTCUT_MANAGER_WIN_H_
+#include "base/callback.h"
#include "chrome/browser/profiles/profile_shortcut_manager.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
class BrowserDistribution;
@@ -13,8 +16,8 @@
namespace profiles {
namespace internal {
-// Name of the badged icon file generated for a given profile.
-extern const char kProfileIconFileName[];
+// Returns the full path to the profile icon file.
+base::FilePath GetProfileIconPath(const base::FilePath& profile_path);
// Returns the default shortcut filename for the given profile name,
// given |distribution|. Returns a filename appropriate for a
@@ -29,12 +32,16 @@
} // namespace profiles
class ProfileShortcutManagerWin : public ProfileShortcutManager,
- public ProfileInfoCacheObserver {
+ public ProfileInfoCacheObserver,
+ public content::NotificationObserver {
public:
- // Specifies whether a new shortcut should be created if none exist.
+ // Specifies whether only the existing shortcut should be updated, a new
+ // shortcut should be created if none exist, or only the icon for this profile
+ // should be created in the profile directory.
enum CreateOrUpdateMode {
UPDATE_EXISTING_ONLY,
CREATE_WHEN_NONE_FOUND,
+ CREATE_OR_UPDATE_ICON_ONLY,
};
// Specifies whether non-profile shortcuts should be updated.
enum NonProfileShortcutAction {
@@ -46,6 +53,9 @@
virtual ~ProfileShortcutManagerWin();
// ProfileShortcutManager implementation:
+ virtual void CreateOrUpdateProfileIcon(
+ const base::FilePath& profile_path,
+ const base::Closure& callback) OVERRIDE;
virtual void CreateProfileShortcut(
const base::FilePath& profile_path) OVERRIDE;
virtual void RemoveProfileShortcuts(
@@ -63,18 +73,30 @@
virtual void OnProfileAvatarChanged(
const base::FilePath& profile_path) OVERRIDE;
+ // content::NotificationObserver implementation:
+ virtual void Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) OVERRIDE;
+
private:
// Gives the profile path of an alternate profile than |profile_path|.
// Must only be called when the number profiles is 2.
base::FilePath GetOtherProfilePath(const base::FilePath& profile_path);
+ // Creates or updates shortcuts for the profile at |profile_path| according
+ // to the specified |create_mode| and |action|. This will always involve
+ // creating or updating the icon file for this profile.
+ // Calls |callback| on successful icon creation.
void CreateOrUpdateShortcutsForProfileAtPath(
const base::FilePath& profile_path,
CreateOrUpdateMode create_mode,
- NonProfileShortcutAction action);
+ NonProfileShortcutAction action,
+ const base::Closure& callback);
ProfileManager* profile_manager_;
+ content::NotificationRegistrar registrar_;
+
DISALLOW_COPY_AND_ASSIGN(ProfileShortcutManagerWin);
};
diff --git a/chrome/browser/profiles/profile_window.cc b/chrome/browser/profiles/profile_window.cc
index fb3276f..5523087 100644
--- a/chrome/browser/profiles/profile_window.cc
+++ b/chrome/browser/profiles/profile_window.cc
@@ -6,8 +6,11 @@
#include "base/command_line.h"
#include "base/files/file_path.h"
+#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/user_metrics.h"
#if !defined(OS_IOS)
@@ -16,8 +19,29 @@
#include "chrome/browser/ui/startup/startup_browser_creator.h"
#endif // !defined (OS_IOS)
+using content::BrowserThread;
using content::UserMetricsAction;
+namespace {
+
+void OpenBrowserWindowForProfile(bool always_create,
+ chrome::HostDesktopType desktop_type,
+ Profile* profile,
+ Profile::CreateStatus status) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (status == Profile::CREATE_STATUS_INITIALIZED) {
+ profiles::FindOrCreateNewWindowForProfile(
+ profile,
+ chrome::startup::IS_NOT_PROCESS_STARTUP,
+ chrome::startup::IS_NOT_FIRST_RUN,
+ desktop_type,
+ always_create);
+ }
+}
+
+} // namespace
+
namespace profiles {
void FindOrCreateNewWindowForProfile(
@@ -48,4 +72,18 @@
#endif // defined(OS_IOS)
}
+void SwitchToProfile(
+ const base::FilePath& path,
+ chrome::HostDesktopType desktop_type,
+ bool always_create) {
+ g_browser_process->profile_manager()->CreateProfileAsync(
+ path,
+ base::Bind(&OpenBrowserWindowForProfile,
+ always_create,
+ desktop_type),
+ string16(),
+ string16(),
+ false);
+}
+
} // namespace profiles
diff --git a/chrome/browser/profiles/profile_window.h b/chrome/browser/profiles/profile_window.h
index bf98403..f66b776 100644
--- a/chrome/browser/profiles/profile_window.h
+++ b/chrome/browser/profiles/profile_window.h
@@ -9,6 +9,7 @@
#include "chrome/browser/ui/startup/startup_types.h"
class Profile;
+namespace base { class FilePath; }
namespace profiles {
@@ -25,6 +26,14 @@
chrome::HostDesktopType desktop_type,
bool always_create);
+// Opens a Browser with the specified profile given by |path|.
+// If |always_create| is true then a new window is created
+// even if a window for that profile already exists.
+void SwitchToProfile(
+ const base::FilePath& path,
+ chrome::HostDesktopType desktop_type,
+ bool always_create);
+
} // namespace profiles
#endif // CHROME_BROWSER_PROFILES_PROFILE_WINDOW_H_
diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
index d31d01f..9e5c8eb 100644
--- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
+++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
@@ -34,7 +34,6 @@
#include "chrome/browser/ui/login/login_prompt.h"
#include "chrome/browser/ui/sync/one_click_signin_helper.h"
#include "chrome/common/extensions/mime_types_handler.h"
-#include "chrome/common/extensions/user_script.h"
#include "chrome/common/render_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
@@ -45,6 +44,7 @@
#include "content/public/browser/stream_handle.h"
#include "content/public/common/resource_response.h"
#include "extensions/common/constants.h"
+#include "extensions/common/user_script.h"
#include "net/base/load_flags.h"
#include "net/base/load_timing_info.h"
#include "net/http/http_response_headers.h"
diff --git a/chrome/browser/renderer_host/pepper/pepper_extensions_common_message_filter.cc b/chrome/browser/renderer_host/pepper/pepper_extensions_common_message_filter.cc
index a0d93e6..e766128 100644
--- a/chrome/browser/renderer_host/pepper/pepper_extensions_common_message_filter.cc
+++ b/chrome/browser/renderer_host/pepper/pepper_extensions_common_message_filter.cc
@@ -23,7 +23,6 @@
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/proxy/ppapi_messages.h"
-#include "third_party/WebKit/public/web/WebSecurityOrigin.h"
namespace chrome {
@@ -164,8 +163,6 @@
return;
Profile* profile = profile_manager->GetProfile(profile_directory_);
- source_origin_ = WebKit::WebSecurityOrigin::create(document_url_).toString();
-
// It will be automatically destroyed when |view_host| goes away.
dispatcher_owner_ = new DispatcherOwner(this, profile, view_host);
}
@@ -187,7 +184,6 @@
params->extension_id = document_url_.host();
params->source_url = document_url_;
- params->source_origin = source_origin_;
// We don't need an ID to map a response to the corresponding request.
params->request_id = 0;
diff --git a/chrome/browser/renderer_host/pepper/pepper_extensions_common_message_filter.h b/chrome/browser/renderer_host/pepper/pepper_extensions_common_message_filter.h
index 832e859..b231123 100644
--- a/chrome/browser/renderer_host/pepper/pepper_extensions_common_message_filter.h
+++ b/chrome/browser/renderer_host/pepper/pepper_extensions_common_message_filter.h
@@ -105,8 +105,6 @@
DispatcherOwner* dispatcher_owner_;
bool dispatcher_owner_initialized_;
- base::string16 source_origin_;
-
DISALLOW_COPY_AND_ASSIGN(PepperExtensionsCommonMessageFilter);
};
diff --git a/chrome/browser/renderer_host/plugin_info_message_filter_unittest.cc b/chrome/browser/renderer_host/plugin_info_message_filter_unittest.cc
index 030f659..cca278a 100644
--- a/chrome/browser/renderer_host/plugin_info_message_filter_unittest.cc
+++ b/chrome/browser/renderer_host/plugin_info_message_filter_unittest.cc
@@ -13,10 +13,13 @@
#include "chrome/common/render_messages.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/plugin_service_filter.h"
+#include "content/public/browser/render_process_host.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "webkit/plugins/npapi/mock_plugin_list.h"
+
+// Linux Aura doesn't support NPAPI.
+#if !(defined(OS_LINUX) && defined(USE_AURA))
using content::PluginService;
@@ -32,7 +35,7 @@
const void* context,
const GURL& url,
const GURL& policy_url,
- webkit::WebPluginInfo* plugin) OVERRIDE;
+ content::WebPluginInfo* plugin) OVERRIDE;
virtual bool CanLoadPlugin(int render_process_id,
const base::FilePath& path) OVERRIDE;
@@ -50,7 +53,7 @@
const void* context,
const GURL& url,
const GURL& policy_url,
- webkit::WebPluginInfo* plugin) {
+ content::WebPluginInfo* plugin) {
std::map<base::FilePath, bool>::iterator it =
plugin_state_.find(plugin->path);
if (it == plugin_state_.end()) {
@@ -76,31 +79,38 @@
}
virtual void SetUp() OVERRIDE {
- webkit::WebPluginInfo foo_plugin(ASCIIToUTF16("Foo Plug-in"),
- foo_plugin_path_,
- ASCIIToUTF16("1"),
- ASCIIToUTF16("The Foo plug-in."));
- webkit::WebPluginMimeType mimeType;
- mimeType.mime_type = "foo/bar";
- foo_plugin.mime_types.push_back(mimeType);
- plugin_list_.AddPluginToLoad(foo_plugin);
+ content::WebPluginInfo foo_plugin(ASCIIToUTF16("Foo Plug-in"),
+ foo_plugin_path_,
+ ASCIIToUTF16("1"),
+ ASCIIToUTF16("The Foo plug-in."));
+ content::WebPluginMimeType mime_type;
+ mime_type.mime_type = "foo/bar";
+ foo_plugin.mime_types.push_back(mime_type);
+ PluginService::GetInstance()->Init();
+ PluginService::GetInstance()->RegisterInternalPlugin(foo_plugin, false);
- webkit::WebPluginInfo bar_plugin(ASCIIToUTF16("Bar Plug-in"),
- bar_plugin_path_,
- ASCIIToUTF16("1"),
- ASCIIToUTF16("The Bar plug-in."));
- mimeType.mime_type = "foo/bar";
- bar_plugin.mime_types.push_back(mimeType);
- plugin_list_.AddPluginToLoad(bar_plugin);
+ content::WebPluginInfo bar_plugin(ASCIIToUTF16("Bar Plug-in"),
+ bar_plugin_path_,
+ ASCIIToUTF16("1"),
+ ASCIIToUTF16("The Bar plug-in."));
+ mime_type.mime_type = "foo/bar";
+ bar_plugin.mime_types.push_back(mime_type);
+ PluginService::GetInstance()->RegisterInternalPlugin(bar_plugin, false);
- PluginService::GetInstance()->SetPluginListForTesting(&plugin_list_);
PluginService::GetInstance()->SetFilter(&filter_);
+#if !defined(OS_WIN)
+ // Can't go out of process in unit tests.
+ content::RenderProcessHost::SetRunRendererInProcess(true);
+#endif
PluginService::GetInstance()->GetPlugins(
base::Bind(&PluginInfoMessageFilterTest::PluginsLoaded,
base::Unretained(this)));
base::RunLoop run_loop;
run_loop.Run();
+#if !defined(OS_WIN)
+ content::RenderProcessHost::SetRunRendererInProcess(false);
+#endif
}
protected:
@@ -110,7 +120,7 @@
PluginInfoMessageFilter::Context context_;
private:
- void PluginsLoaded(const std::vector<webkit::WebPluginInfo>& plugins) {
+ void PluginsLoaded(const std::vector<content::WebPluginInfo>& plugins) {
base::MessageLoop::current()->Quit();
}
@@ -119,7 +129,6 @@
// a MockPluginList.
content::TestBrowserThread file_thread_;
base::ShadowingAtExitManager at_exit_manager_; // Destroys the PluginService.
- webkit::npapi::MockPluginList plugin_list_;
};
TEST_F(PluginInfoMessageFilterTest, FindEnabledPlugin) {
@@ -127,7 +136,7 @@
filter_.set_plugin_enabled(bar_plugin_path_, true);
{
ChromeViewHostMsg_GetPluginInfo_Status status;
- webkit::WebPluginInfo plugin;
+ content::WebPluginInfo plugin;
std::string actual_mime_type;
EXPECT_TRUE(context_.FindEnabledPlugin(
0, GURL(), GURL(), "foo/bar", &status, &plugin, &actual_mime_type,
@@ -139,7 +148,7 @@
filter_.set_plugin_enabled(foo_plugin_path_, false);
{
ChromeViewHostMsg_GetPluginInfo_Status status;
- webkit::WebPluginInfo plugin;
+ content::WebPluginInfo plugin;
std::string actual_mime_type;
EXPECT_TRUE(context_.FindEnabledPlugin(
0, GURL(), GURL(), "foo/bar", &status, &plugin, &actual_mime_type,
@@ -151,7 +160,7 @@
filter_.set_plugin_enabled(bar_plugin_path_, false);
{
ChromeViewHostMsg_GetPluginInfo_Status status;
- webkit::WebPluginInfo plugin;
+ content::WebPluginInfo plugin;
std::string actual_mime_type;
std::string identifier;
string16 plugin_name;
@@ -163,7 +172,7 @@
}
{
ChromeViewHostMsg_GetPluginInfo_Status status;
- webkit::WebPluginInfo plugin;
+ content::WebPluginInfo plugin;
std::string actual_mime_type;
EXPECT_FALSE(context_.FindEnabledPlugin(
0, GURL(), GURL(), "baz/blurp", &status, &plugin, &actual_mime_type,
@@ -172,3 +181,5 @@
EXPECT_EQ(FILE_PATH_LITERAL(""), plugin.path.value());
}
}
+
+#endif
diff --git a/chrome/browser/renderer_host/web_cache_manager.cc b/chrome/browser/renderer_host/web_cache_manager.cc
index 758b4e1..d2267bd 100644
--- a/chrome/browser/renderer_host/web_cache_manager.cc
+++ b/chrome/browser/renderer_host/web_cache_manager.cc
@@ -315,15 +315,13 @@
// This is the capacity this renderer has been allocated.
size_t capacity = allocation->second;
- // We don't reserve any space for dead objects in the cache. Instead, we
- // prefer to keep live objects around. There is probably some performance
+ // We don't reserve any space for dead objects in the cache. Instead, we
+ // prefer to keep live objects around. There is probably some performance
// tuning to be done here.
size_t min_dead_capacity = 0;
- // We allow the dead objects to consume all of the cache, if the renderer
- // so desires. If we wanted this memory, we would have set the total
- // capacity lower.
- size_t max_dead_capacity = capacity;
+ // We allow the dead objects to consume up to half of the cache capacity.
+ size_t max_dead_capacity = capacity / 2;
host->Send(new ChromeViewMsg_SetCacheCapacities(min_dead_capacity,
max_dead_capacity,
diff --git a/chrome/browser/repost_form_warning_controller.cc b/chrome/browser/repost_form_warning_controller.cc
index 0d9ac56..517036a 100644
--- a/chrome/browser/repost_form_warning_controller.cc
+++ b/chrome/browser/repost_form_warning_controller.cc
@@ -15,8 +15,7 @@
RepostFormWarningController::RepostFormWarningController(
content::WebContents* web_contents)
- : TabModalConfirmDialogDelegate(web_contents),
- content::WebContentsObserver(web_contents) {
+ : content::WebContentsObserver(web_contents) {
}
RepostFormWarningController::~RepostFormWarningController() {
@@ -45,7 +44,9 @@
#endif // defined(TOOLKIT_GTK)
void RepostFormWarningController::OnAccepted() {
+ operations_delegate()->SetPreventCloseOnLoadStart(true);
web_contents()->GetController().ContinuePendingReload();
+ operations_delegate()->SetPreventCloseOnLoadStart(false);
}
void RepostFormWarningController::OnCanceled() {
diff --git a/chrome/browser/resources/OWNERS b/chrome/browser/resources/OWNERS
index f8194fa..bbebd98 100644
--- a/chrome/browser/resources/OWNERS
+++ b/chrome/browser/resources/OWNERS
@@ -1,6 +1,7 @@
arv@chromium.org
bauerb@chromium.org
dbeam@chromium.org
+dubroy@chromium.org
estade@chromium.org
jhawkins@chromium.org
nkostylev@chromium.org
diff --git a/chrome/browser/resources/bookmark_manager/js/main.js b/chrome/browser/resources/bookmark_manager/js/main.js
index 65e4053..9f58a2d 100644
--- a/chrome/browser/resources/bookmark_manager/js/main.js
+++ b/chrome/browser/resources/bookmark_manager/js/main.js
@@ -849,9 +849,7 @@
lastDeletedNodes = [];
function performDelete() {
- selectedIds.forEach(function(id) {
- chrome.bookmarks.removeTree(id);
- });
+ chrome.bookmarkManagerPrivate.removeTrees(selectedIds);
$('undo-delete-command').canExecuteChange();
performGlobalUndo = undoDelete;
}
diff --git a/chrome/browser/resources/chromeos/connectivity_diagnostics/manifest.json b/chrome/browser/resources/chromeos/connectivity_diagnostics/manifest.json
new file mode 100644
index 0000000..345a72c
--- /dev/null
+++ b/chrome/browser/resources/chromeos/connectivity_diagnostics/manifest.json
@@ -0,0 +1,31 @@
+{
+ "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGJWLUb83WKoDeODlrPIZu60M8bzbvrkg3Jf/5aO3ux2FL+G+/BO4Vyt/J0t8lXBtnTOvHo6KPpA042PyE9xMdlufFnJqEkvPXNzRlBWeVQqFHbMWE6o/x8diG69dNmHyFYcUjjFFDk2X2GOLQXNUGJQ6MIikbdzoWdLGttmhAIwIDAQAB",
+ "manifest_version": 2,
+ "name": "Chrome Connectivity Debugger (Dev)",
+ "version": "0.2.8",
+ "minimum_chrome_version": "27",
+ "offline_enabled": true,
+ "default_locale": "en",
+ "icons": {
+ "128": "img/icon_128.png",
+ "16": "img/icon_16.png"
+ },
+ "permissions" : [
+ { "socket" : [
+ "tcp-connect:*:443",
+ "tcp-connect:*:80",
+ "tcp-connect:*:25",
+ "udp-bind:*",
+ "udp-send-to:*:53"
+ ]},
+ "clipboardWrite",
+ "experimental",
+ "http://*.google.com/*",
+ "http://www.yahoo.com/*"
+ ],
+ "app": {
+ "background": {
+ "scripts": ["background.js"]
+ }
+ }
+}
diff --git a/chrome/browser/resources/chromeos/login/display_manager.js b/chrome/browser/resources/chromeos/login/display_manager.js
index eb87f87..9ddeee2 100644
--- a/chrome/browser/resources/chromeos/login/display_manager.js
+++ b/chrome/browser/resources/chromeos/login/display_manager.js
@@ -415,7 +415,9 @@
var dot = document.createElement('div');
dot.id = screenId + '-dot';
dot.className = 'progdot';
- $('progress-dots').appendChild(dot);
+ var progressDots = $('progress-dots');
+ if (progressDots)
+ progressDots.appendChild(dot);
this.appendButtons_(el.buttons, screenId);
},
diff --git a/chrome/browser/resources/chromeos/login/header_bar.js b/chrome/browser/resources/chromeos/login/header_bar.js
index efeed3d..fb8854e 100644
--- a/chrome/browser/resources/chromeos/login/header_bar.js
+++ b/chrome/browser/resources/chromeos/login/header_bar.js
@@ -44,7 +44,6 @@
this.handleSignoutClick_);
$('cancel-multiple-sign-in-button').addEventListener('click',
this.handleCancelMultipleSignInClick_);
-
if (document.documentElement.getAttribute('screen') == 'login')
login.AppsMenuButton.decorate($('show-apps-button'));
},
diff --git a/chrome/browser/resources/chromeos/login/screen_account_picker.js b/chrome/browser/resources/chromeos/login/screen_account_picker.js
index 61b9d85..ab2d4ec 100644
--- a/chrome/browser/resources/chromeos/login/screen_account_picker.js
+++ b/chrome/browser/resources/chromeos/login/screen_account_picker.js
@@ -74,7 +74,9 @@
// hide the add user button and activate the locked user's pod.
var lockedPod = podRow.lockedPod;
$('add-user-header-bar-item').hidden = !!lockedPod;
- $('sign-out-user-item').hidden = !lockedPod;
+ var signOutUserItem = $('sign-out-user-item');
+ if (signOutUserItem)
+ signOutUserItem.hidden = !lockedPod;
// In case of the preselected pod onShow will be called once pod
// receives focus.
if (!podRow.preselectedPod)
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
index fae6e89..1a00aa7 100644
--- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
+++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.js
@@ -187,6 +187,11 @@
chrome.send('loginUIStateChanged', ['gaia-signin', true]);
$('login-header-bar').signinUIState = SIGNIN_UI_STATE.GAIA_SIGNIN;
+ // Ensure that GAIA signin (or loading UI) is actually visible.
+ window.webkitRequestAnimationFrame(function() {
+ chrome.send('loginVisible', ['gaia-loading']);
+ });
+
// Announce the name of the screen, if accessibility is on.
$('gaia-signin-aria-label').setAttribute(
'aria-label', loadTimeData.getString('signinScreenTitle'));
@@ -431,7 +436,6 @@
* @param {number} error Error code.
*/
onFrameError: function(error) {
- console.error('Gaia frame error = ' + error);
this.error_ = error;
chrome.send('frameLoadingCompleted', [this.error_]);
},
diff --git a/chrome/browser/resources/chromeos/login/user_pod_row.js b/chrome/browser/resources/chromeos/login/user_pod_row.js
index 5d62216..5482a9c 100644
--- a/chrome/browser/resources/chromeos/login/user_pod_row.js
+++ b/chrome/browser/resources/chromeos/login/user_pod_row.js
@@ -154,10 +154,12 @@
this.handleRemoveCommandKeyDown_.bind(this));
this.actionBoxMenuRemoveElement.addEventListener('blur',
this.handleRemoveCommandBlur_.bind(this));
- this.actionBoxRemoveManagedUserWarningButtonElement.addEventListener(
- 'click',
- this.handleRemoveUserConfirmationClick_.bind(this));
+ if (this.actionBoxRemoveManagedUserWarningButtonElement) {
+ this.actionBoxRemoveManagedUserWarningButtonElement.addEventListener(
+ 'click',
+ this.handleRemoveUserConfirmationClick_.bind(this));
+ }
},
/**
@@ -332,12 +334,19 @@
'?id=' + UserPod.userImageSalt_[this.user.username];
this.nameElement.textContent = this.user_.displayName;
- this.actionBoxAreaElement.hidden = this.user_.publicAccount;
- this.actionBoxMenuRemoveElement.hidden = !this.user_.canRemove;
this.signedInIndicatorElement.hidden = !this.user_.signedIn;
var needSignin = this.needGaiaSignin;
this.passwordElement.hidden = needSignin;
+ this.signinButtonElement.hidden = !needSignin;
+
+ this.updateActionBoxArea();
+ },
+
+ updateActionBoxArea: function() {
+ this.actionBoxAreaElement.hidden = this.user_.publicAccount;
+ this.actionBoxMenuRemoveElement.hidden = !this.user_.canRemove;
+
this.actionBoxAreaElement.setAttribute(
'aria-label', loadTimeData.getStringF(
'podMenuButtonAccessibleName', this.user_.emailAddress));
@@ -355,7 +364,6 @@
loadTimeData.getString('removeUser');
this.passwordElement.setAttribute('aria-label', loadTimeData.getStringF(
'passwordFieldAccessibleName', this.user_.emailAddress));
- this.signinButtonElement.hidden = !needSignin;
this.userTypeIconAreaElement.hidden = !this.user_.locallyManagedUser;
},
@@ -408,7 +416,8 @@
if (active) {
this.actionBoxMenuRemoveElement.hidden = !this.user_.canRemove;
- this.actionBoxRemoveManagedUserWarningElement.hidden = true;
+ if (this.actionBoxRemoveManagedUserWarningElement)
+ this.actionBoxRemoveManagedUserWarningElement.hidden = true;
// Clear focus first if another pod is focused.
if (!this.parentNode.isFocused(this)) {
@@ -619,6 +628,7 @@
handleMouseDown_: function(e) {
if (this.parentNode.disabled)
return;
+
if (!this.signinButtonElement.hidden && !this.isActionBoxMenuActive) {
this.showSigninUI();
// Prevent default so that we don't trigger 'focus' event.
@@ -809,6 +819,79 @@
};
/**
+ * Creates a user pod to be used only in desktop chrome.
+ * @constructor
+ * @extends {UserPod}
+ */
+ var DesktopUserPod = cr.ui.define(function() {
+ // Don't just instantiate a UserPod(), as this will call decorate() on the
+ // parent object, and add duplicate event listeners.
+ var node = $('user-pod-template').cloneNode(true);
+ node.removeAttribute('id');
+ return node;
+ });
+
+ DesktopUserPod.prototype = {
+ __proto__: UserPod.prototype,
+
+ /** @override */
+ decorate: function() {
+ UserPod.prototype.decorate.call(this);
+ },
+
+ /** @override */
+ focusInput: function() {
+ var isLockedUser = this.user.needsSignin;
+ this.signinButtonElement.hidden = isLockedUser;
+ this.passwordElement.hidden = !isLockedUser;
+
+ // Move tabIndex from the whole pod to the main input.
+ this.tabIndex = -1;
+ this.mainInput.tabIndex = UserPodTabOrder.POD_INPUT;
+ this.mainInput.focus();
+ },
+
+ /** @override */
+ update: function() {
+ // TODO(noms): Use the actual profile avatar for local profiles once the
+ // new, non-pixellated avatars are available.
+ this.imageElement.src = this.user.emailAddress == '' ?
+ 'chrome://theme/IDR_USER_MANAGER_DEFAULT_AVATAR' :
+ this.user.userImage;
+ this.nameElement.textContent = this.user_.displayName;
+ var isLockedUser = this.user.needsSignin;
+ this.passwordElement.hidden = !isLockedUser;
+ this.signinButtonElement.hidden = isLockedUser;
+
+ UserPod.prototype.updateActionBoxArea.call(this);
+ },
+
+ /** @override */
+ activate: function() {
+ Oobe.launchUser(this.user.emailAddress, this.user.displayName);
+ return true;
+ },
+
+ /** @override */
+ handleMouseDown_: function(e) {
+ if (this.parentNode.disabled)
+ return;
+
+ // Don't sign in until the user presses the button. Just activate the pod.
+ Oobe.clearErrors();
+ this.parentNode.lastFocusedPod_ =
+ this.parentNode.getPodWithUsername_(this.user.emailAddress);
+ },
+
+ /** @override */
+ handleRemoveCommandClick_: function(e) {
+ //TODO(noms): Add deletion confirmation overlay before attempting
+ // to delete the user.
+ UserPod.prototype.handleRemoveCommandClick_.call(this, e);
+ },
+ };
+
+ /**
* Creates a new pod row element.
* @constructor
* @extends {HTMLDivElement}
@@ -914,7 +997,9 @@
*/
createUserPod: function(user) {
var userPod;
- if (user.publicAccount)
+ if (user.isDesktopUser)
+ userPod = new DesktopUserPod({user: user});
+ else if (user.publicAccount)
userPod = new PublicAccountUserPod({user: user});
else
userPod = new UserPod({user: user});
diff --git a/chrome/browser/resources/file_manager/css/file_manager.css b/chrome/browser/resources/file_manager/css/file_manager.css
index e4b8a8a..df84340 100644
--- a/chrome/browser/resources/file_manager/css/file_manager.css
+++ b/chrome/browser/resources/file_manager/css/file_manager.css
@@ -769,7 +769,8 @@
width: 22px;
}
-#spinner-container {
+#spinner-container,
+.spinner-container {
-webkit-box-align: center;
-webkit-box-pack: center;
bottom: 0;
@@ -1891,3 +1892,30 @@
.error-dialog-frame .cr-dialog-text {
text-align: center;
}
+
+.cr-dialog-frame.share-dialog-frame {
+ background-color: white;
+ width: auto;
+}
+
+.share-dialog-webview-wrapper {
+ height: 100px;
+ margin-top: 10px;
+ min-width: 300px;
+ overflow: hidden;
+ transition: height 200ms ease;
+}
+
+.share-dialog-webview {
+ height: 100%;
+ width: 100%;
+}
+
+.share-dialog-webview-wrapper:not(.loaded) .share-dialog-webview {
+ visibility: hidden;
+}
+
+.share-dialog-frame .cr-dialog-text,
+.share-dialog-frame .cr-dialog-buttons {
+ display: none;
+}
diff --git a/chrome/browser/resources/file_manager/images/common/2x/button.png b/chrome/browser/resources/file_manager/images/common/2x/button.png
index d185c7b..9fdd912 100644
--- a/chrome/browser/resources/file_manager/images/common/2x/button.png
+++ b/chrome/browser/resources/file_manager/images/common/2x/button.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/common/2x/button_hover.png b/chrome/browser/resources/file_manager/images/common/2x/button_hover.png
index 5de5c7e..79f492e 100644
--- a/chrome/browser/resources/file_manager/images/common/2x/button_hover.png
+++ b/chrome/browser/resources/file_manager/images/common/2x/button_hover.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/common/2x/button_pressed.png b/chrome/browser/resources/file_manager/images/common/2x/button_pressed.png
index eee68dd..00cbed6 100644
--- a/chrome/browser/resources/file_manager/images/common/2x/button_pressed.png
+++ b/chrome/browser/resources/file_manager/images/common/2x/button_pressed.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/common/button.png b/chrome/browser/resources/file_manager/images/common/button.png
index 4de5ff0..76bc97e 100644
--- a/chrome/browser/resources/file_manager/images/common/button.png
+++ b/chrome/browser/resources/file_manager/images/common/button.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/common/button_hover.png b/chrome/browser/resources/file_manager/images/common/button_hover.png
index c24d7cc..34965e0 100644
--- a/chrome/browser/resources/file_manager/images/common/button_hover.png
+++ b/chrome/browser/resources/file_manager/images/common/button_hover.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/common/button_pressed.png b/chrome/browser/resources/file_manager/images/common/button_pressed.png
index c54d6fe..3c81b8b 100644
--- a/chrome/browser/resources/file_manager/images/common/button_pressed.png
+++ b/chrome/browser/resources/file_manager/images/common/button_pressed.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/common/checkbox_white_checked.png b/chrome/browser/resources/file_manager/images/common/checkbox_white_checked.png
index c095d6c..b24de30 100644
--- a/chrome/browser/resources/file_manager/images/common/checkbox_white_checked.png
+++ b/chrome/browser/resources/file_manager/images/common/checkbox_white_checked.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/files/file_types/100/gtable_white.png b/chrome/browser/resources/file_manager/images/files/file_types/100/gtable_white.png
index f534641..9198c9e 100644
--- a/chrome/browser/resources/file_manager/images/files/file_types/100/gtable_white.png
+++ b/chrome/browser/resources/file_manager/images/files/file_types/100/gtable_white.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/files/file_types/200/form_white.png b/chrome/browser/resources/file_manager/images/files/file_types/200/form_white.png
index 540fdc2..0252d4c 100644
--- a/chrome/browser/resources/file_manager/images/files/file_types/200/form_white.png
+++ b/chrome/browser/resources/file_manager/images/files/file_types/200/form_white.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/files/ui/2x/drive_logo.png b/chrome/browser/resources/file_manager/images/files/ui/2x/drive_logo.png
index 316e8a0..be900c8 100644
--- a/chrome/browser/resources/file_manager/images/files/ui/2x/drive_logo.png
+++ b/chrome/browser/resources/file_manager/images/files/ui/2x/drive_logo.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/files/ui/2x/search_icon_active.png b/chrome/browser/resources/file_manager/images/files/ui/2x/search_icon_active.png
index 80d733b..d58cd10 100644
--- a/chrome/browser/resources/file_manager/images/files/ui/2x/search_icon_active.png
+++ b/chrome/browser/resources/file_manager/images/files/ui/2x/search_icon_active.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/files/ui/drive_logo.png b/chrome/browser/resources/file_manager/images/files/ui/drive_logo.png
index c5aef52..5e6fb3e 100644
--- a/chrome/browser/resources/file_manager/images/files/ui/drive_logo.png
+++ b/chrome/browser/resources/file_manager/images/files/ui/drive_logo.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/files/ui/search_clear_pressed.png b/chrome/browser/resources/file_manager/images/files/ui/search_clear_pressed.png
index 85f8c11..1825168 100644
--- a/chrome/browser/resources/file_manager/images/files/ui/search_clear_pressed.png
+++ b/chrome/browser/resources/file_manager/images/files/ui/search_clear_pressed.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/files/volumes/2x/black_shared.png b/chrome/browser/resources/file_manager/images/files/volumes/2x/black_shared.png
index 79b9edc..5c30267 100644
--- a/chrome/browser/resources/file_manager/images/files/volumes/2x/black_shared.png
+++ b/chrome/browser/resources/file_manager/images/files/volumes/2x/black_shared.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/gallery/2x/cursor_crop.png b/chrome/browser/resources/file_manager/images/gallery/2x/cursor_crop.png
index 6490950..6202fa9 100644
--- a/chrome/browser/resources/file_manager/images/gallery/2x/cursor_crop.png
+++ b/chrome/browser/resources/file_manager/images/gallery/2x/cursor_crop.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/gallery/2x/cursor_swne.png b/chrome/browser/resources/file_manager/images/gallery/2x/cursor_swne.png
index 5bdae73..9153d7b 100644
--- a/chrome/browser/resources/file_manager/images/gallery/2x/cursor_swne.png
+++ b/chrome/browser/resources/file_manager/images/gallery/2x/cursor_swne.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/gallery/2x/icon_print.png b/chrome/browser/resources/file_manager/images/gallery/2x/icon_print.png
index 95923a9..b5a9be0 100644
--- a/chrome/browser/resources/file_manager/images/gallery/2x/icon_print.png
+++ b/chrome/browser/resources/file_manager/images/gallery/2x/icon_print.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/gallery/2x/icon_print_selected.png b/chrome/browser/resources/file_manager/images/gallery/2x/icon_print_selected.png
index d4ac79f..048a341 100644
--- a/chrome/browser/resources/file_manager/images/gallery/2x/icon_print_selected.png
+++ b/chrome/browser/resources/file_manager/images/gallery/2x/icon_print_selected.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/gallery/2x/icon_rotate.png b/chrome/browser/resources/file_manager/images/gallery/2x/icon_rotate.png
index e7bf684..db2c0b0 100644
--- a/chrome/browser/resources/file_manager/images/gallery/2x/icon_rotate.png
+++ b/chrome/browser/resources/file_manager/images/gallery/2x/icon_rotate.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/gallery/2x/icon_rotate_left.png b/chrome/browser/resources/file_manager/images/gallery/2x/icon_rotate_left.png
index 4ebbb68..63ab3ab 100644
--- a/chrome/browser/resources/file_manager/images/gallery/2x/icon_rotate_left.png
+++ b/chrome/browser/resources/file_manager/images/gallery/2x/icon_rotate_left.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/gallery/2x/icon_rotate_selected.png b/chrome/browser/resources/file_manager/images/gallery/2x/icon_rotate_selected.png
index 1990a63..b3a9bf6 100644
--- a/chrome/browser/resources/file_manager/images/gallery/2x/icon_rotate_selected.png
+++ b/chrome/browser/resources/file_manager/images/gallery/2x/icon_rotate_selected.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/gallery/2x/icon_undo_selected.png b/chrome/browser/resources/file_manager/images/gallery/2x/icon_undo_selected.png
index 3c838c6..92d3a01 100644
--- a/chrome/browser/resources/file_manager/images/gallery/2x/icon_undo_selected.png
+++ b/chrome/browser/resources/file_manager/images/gallery/2x/icon_undo_selected.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/gallery/butterbar_close_button.png b/chrome/browser/resources/file_manager/images/gallery/butterbar_close_button.png
index bc26727..3c65c23 100644
--- a/chrome/browser/resources/file_manager/images/gallery/butterbar_close_button.png
+++ b/chrome/browser/resources/file_manager/images/gallery/butterbar_close_button.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/gallery/cursor_nwse.png b/chrome/browser/resources/file_manager/images/gallery/cursor_nwse.png
index 3f3e33c..87fb564 100644
--- a/chrome/browser/resources/file_manager/images/gallery/cursor_nwse.png
+++ b/chrome/browser/resources/file_manager/images/gallery/cursor_nwse.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/gallery/icon_print.png b/chrome/browser/resources/file_manager/images/gallery/icon_print.png
index ec5418e..b235536 100644
--- a/chrome/browser/resources/file_manager/images/gallery/icon_print.png
+++ b/chrome/browser/resources/file_manager/images/gallery/icon_print.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/gallery/icon_print_selected.png b/chrome/browser/resources/file_manager/images/gallery/icon_print_selected.png
index 89e302e..07b5f43 100644
--- a/chrome/browser/resources/file_manager/images/gallery/icon_print_selected.png
+++ b/chrome/browser/resources/file_manager/images/gallery/icon_print_selected.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/gallery/icon_undo.png b/chrome/browser/resources/file_manager/images/gallery/icon_undo.png
index 333c455..79e3fdd 100644
--- a/chrome/browser/resources/file_manager/images/gallery/icon_undo.png
+++ b/chrome/browser/resources/file_manager/images/gallery/icon_undo.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/gallery/slideshow-pause.png b/chrome/browser/resources/file_manager/images/gallery/slideshow-pause.png
index ad3633f..2170ce9 100644
--- a/chrome/browser/resources/file_manager/images/gallery/slideshow-pause.png
+++ b/chrome/browser/resources/file_manager/images/gallery/slideshow-pause.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/icon256.png b/chrome/browser/resources/file_manager/images/icon256.png
index 2e50e0f..31864fb 100644
--- a/chrome/browser/resources/file_manager/images/icon256.png
+++ b/chrome/browser/resources/file_manager/images/icon256.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/media/2x/drive.png b/chrome/browser/resources/file_manager/images/media/2x/drive.png
index e3b7973..a8f648a 100644
--- a/chrome/browser/resources/file_manager/images/media/2x/drive.png
+++ b/chrome/browser/resources/file_manager/images/media/2x/drive.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/media/2x/media_loop_hover.png b/chrome/browser/resources/file_manager/images/media/2x/media_loop_hover.png
index cb2af67..b3a6c14 100644
--- a/chrome/browser/resources/file_manager/images/media/2x/media_loop_hover.png
+++ b/chrome/browser/resources/file_manager/images/media/2x/media_loop_hover.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/media/2x/media_next_down.png b/chrome/browser/resources/file_manager/images/media/2x/media_next_down.png
index 79a370b..58d5bf7 100644
--- a/chrome/browser/resources/file_manager/images/media/2x/media_next_down.png
+++ b/chrome/browser/resources/file_manager/images/media/2x/media_next_down.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/media/2x/media_pause_down.png b/chrome/browser/resources/file_manager/images/media/2x/media_pause_down.png
index 6f8f494..9caaf7a 100644
--- a/chrome/browser/resources/file_manager/images/media/2x/media_pause_down.png
+++ b/chrome/browser/resources/file_manager/images/media/2x/media_pause_down.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/media/2x/media_slider_thumb.png b/chrome/browser/resources/file_manager/images/media/2x/media_slider_thumb.png
index 5a130bd..cd20aa2 100644
--- a/chrome/browser/resources/file_manager/images/media/2x/media_slider_thumb.png
+++ b/chrome/browser/resources/file_manager/images/media/2x/media_slider_thumb.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/media/2x/media_sound_full_hover.png b/chrome/browser/resources/file_manager/images/media/2x/media_sound_full_hover.png
index e617eab..da31aa4 100644
--- a/chrome/browser/resources/file_manager/images/media/2x/media_sound_full_hover.png
+++ b/chrome/browser/resources/file_manager/images/media/2x/media_sound_full_hover.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/media/2x/media_sound_level2_hover.png b/chrome/browser/resources/file_manager/images/media/2x/media_sound_level2_hover.png
index 9966a5e..2e3f2e8 100644
--- a/chrome/browser/resources/file_manager/images/media/2x/media_sound_level2_hover.png
+++ b/chrome/browser/resources/file_manager/images/media/2x/media_sound_level2_hover.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/media/2x/media_volume_slider_thumb.png b/chrome/browser/resources/file_manager/images/media/2x/media_volume_slider_thumb.png
index c518743..93ce5c1 100644
--- a/chrome/browser/resources/file_manager/images/media/2x/media_volume_slider_thumb.png
+++ b/chrome/browser/resources/file_manager/images/media/2x/media_volume_slider_thumb.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/media/2x/media_volume_slider_thumb_hover.png b/chrome/browser/resources/file_manager/images/media/2x/media_volume_slider_thumb_hover.png
index ae16119..4d4243d 100644
--- a/chrome/browser/resources/file_manager/images/media/2x/media_volume_slider_thumb_hover.png
+++ b/chrome/browser/resources/file_manager/images/media/2x/media_volume_slider_thumb_hover.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/media/audio_player.png b/chrome/browser/resources/file_manager/images/media/audio_player.png
index 9134bde..6921db2 100644
--- a/chrome/browser/resources/file_manager/images/media/audio_player.png
+++ b/chrome/browser/resources/file_manager/images/media/audio_player.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/media/media_loop_hover.png b/chrome/browser/resources/file_manager/images/media/media_loop_hover.png
index 805d293..a0ed21f 100644
--- a/chrome/browser/resources/file_manager/images/media/media_loop_hover.png
+++ b/chrome/browser/resources/file_manager/images/media/media_loop_hover.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/images/media/media_sound_full_down.png b/chrome/browser/resources/file_manager/images/media/media_sound_full_down.png
index 1a185ed..55d77e4 100644
--- a/chrome/browser/resources/file_manager/images/media/media_sound_full_down.png
+++ b/chrome/browser/resources/file_manager/images/media/media_sound_full_down.png
Binary files differ
diff --git a/chrome/browser/resources/file_manager/js/directory_model.js b/chrome/browser/resources/file_manager/js/directory_model.js
index 46e6015..be32e57 100644
--- a/chrome/browser/resources/file_manager/js/directory_model.js
+++ b/chrome/browser/resources/file_manager/js/directory_model.js
@@ -291,6 +291,37 @@
};
/**
+ * Updates the selection by using the updateFunc and publish the change event.
+ * If updateFunc returns true, it force to dispatch the change event even if the
+ * selection index is not changed.
+ *
+ * @param {cr.ui.ListSingleSelectionModel} selection Selection to be updated.
+ * @param {function(): boolean} updateFunc Function updating the selection.
+ * @private
+ */
+DirectoryModel.prototype.updateSelectionAndPublishEvent_ =
+ function(selection, updateFunc) {
+ // Begin change.
+ selection.beginChange();
+
+ // If dispatchNeeded is true, we should ensure the change evnet is
+ // dispatched.
+ var dispatchNeeded = updateFunc();
+
+ // Check if the change event is dispatched in the endChange function
+ // or not.
+ var eventDispatched = function() { dispatchNeeded = false; };
+ selection.addEventListener('change', eventDispatched);
+ selection.endChange();
+ selection.removeEventListener('change', eventDispatched);
+
+ // If the change evnet have been already dispatched, dispatchNeeded is false.
+ if (dispatchNeeded) {
+ selection.dispatchEvent(selection.createChangeEvent('change'));
+ }
+};
+
+/**
* Invoked when filters are changed.
* @private
*/
@@ -592,31 +623,33 @@
*/
DirectoryModel.prototype.replaceDirectoryContents_ = function(dirContents) {
cr.dispatchSimpleEvent(this, 'begin-update-files');
- this.fileListSelection_.beginChange();
+ this.updateSelectionAndPublishEvent_(this.fileListSelection_, function() {
+ var selectedPaths = this.getSelectedPaths_();
+ var selectedIndices = this.fileListSelection_.selectedIndexes;
- var selectedPaths = this.getSelectedPaths_();
- var selectedIndices = this.fileListSelection_.selectedIndexes;
+ // Restore leadIndex in case leadName no longer exists.
+ var leadIndex = this.fileListSelection_.leadIndex;
+ var leadPath = this.getLeadPath_();
- // Restore leadIndex in case leadName no longer exists.
- var leadIndex = this.fileListSelection_.leadIndex;
- var leadPath = this.getLeadPath_();
+ this.currentDirContents_ = dirContents;
+ dirContents.replaceContextFileList();
- this.currentDirContents_ = dirContents;
- dirContents.replaceContextFileList();
+ this.setSelectedPaths_(selectedPaths);
+ this.fileListSelection_.leadIndex = leadIndex;
+ this.setLeadPath_(leadPath);
- this.setSelectedPaths_(selectedPaths);
- this.fileListSelection_.leadIndex = leadIndex;
- this.setLeadPath_(leadPath);
-
- // If nothing is selected after update, then select file next to the
- // latest selection
- if (this.fileListSelection_.selectedIndexes.length == 0 &&
- selectedIndices.length != 0) {
- var maxIdx = Math.max.apply(null, selectedIndices);
- this.selectIndex(Math.min(maxIdx - selectedIndices.length + 2,
- this.getFileList().length) - 1);
- }
- this.fileListSelection_.endChange();
+ // If nothing is selected after update, then select file next to the
+ // latest selection
+ var forceChangeEvent = false;
+ if (this.fileListSelection_.selectedIndexes.length == 0 &&
+ selectedIndices.length != 0) {
+ var maxIdx = Math.max.apply(null, selectedIndices);
+ this.selectIndex(Math.min(maxIdx - selectedIndices.length + 2,
+ this.getFileList().length) - 1);
+ forceChangeEvent = true;
+ }
+ return forceChangeEvent;
+ }.bind(this));
cr.dispatchSimpleEvent(this, 'end-update-files');
};
@@ -805,8 +838,8 @@
* mounting, callbacks will be called after the mount is completed.
*
* @param {string} path Path to the directory.
- * @param {function(DirectoryEntry} successCallback Success callback.
- * @param {function(FileError} errorCallback Error callback.
+ * @param {function(DirectoryEntry)} successCallback Success callback.
+ * @param {function(FileError)} errorCallback Error callback.
*/
DirectoryModel.prototype.resolveDirectory = function(
path, successCallback, errorCallback) {
diff --git a/chrome/browser/resources/file_manager/js/file_copy_manager.js b/chrome/browser/resources/file_manager/js/file_copy_manager.js
index 7129546..5e55a13 100644
--- a/chrome/browser/resources/file_manager/js/file_copy_manager.js
+++ b/chrome/browser/resources/file_manager/js/file_copy_manager.js
@@ -4,12 +4,6 @@
'use strict';
-if (chrome.extension) {
- var getContentWindows = function() {
- return chrome.extension.getViews();
- };
-}
-
/**
* @constructor
*/
@@ -765,31 +759,8 @@
var targetDirEntry = task.targetDirEntry;
var originalPath = sourceEntry.fullPath.substr(sourcePath.length + 1);
-
originalPath = task.applyRenames(originalPath);
- var targetRelativePrefix = originalPath;
- var targetExt = '';
- var index = targetRelativePrefix.lastIndexOf('.');
- if (index != -1) {
- targetExt = targetRelativePrefix.substr(index);
- targetRelativePrefix = targetRelativePrefix.substr(0, index);
- }
-
- // If file already exists, we try to make a copy named 'file (1).ext'.
- // If file is already named 'file (X).ext', we go with 'file (X+1).ext'.
- // If new name is still occupied, we increase the number up to 10 times.
- var copyNumber = 0;
- var match = /^(.*?)(?: \((\d+)\))?$/.exec(targetRelativePrefix);
- if (match && match[2]) {
- copyNumber = parseInt(match[2], 10);
- targetRelativePrefix = match[1];
- }
-
- var targetRelativePath = '';
- var renameTries = 0;
- var firstExistingEntry = null;
-
var onCopyCompleteBase = function(entry, size) {
task.markEntryComplete(entry, size);
successCallback(entry, size);
@@ -828,18 +799,6 @@
onError('FILESYSTEM_ERROR', err);
};
- var onTargetExists = function(existingEntry) {
- if (!firstExistingEntry)
- firstExistingEntry = existingEntry;
- renameTries++;
- if (renameTries < 10) {
- copyNumber++;
- tryNextCopy();
- } else {
- onError('TARGET_EXISTS', firstExistingEntry);
- }
- };
-
/**
* Resolves the immediate parent directory entry and the file name of a
* given path, where the path is specified by a directory (not necessarily
@@ -886,13 +845,7 @@
}
};
- var onTargetNotResolved = function(err) {
- // We expect to be unable to resolve the target file, since we're going
- // to create it during the copy. However, if the resolve fails with
- // anything other than NOT_FOUND, that's trouble.
- if (err.code != FileError.NOT_FOUND_ERR)
- return onError('FILESYSTEM_ERROR', err);
-
+ var onDeduplicated = function(targetRelativePath) {
if (task.move) {
resolveDirAndBaseName(
targetDirEntry, targetRelativePath,
@@ -1046,20 +999,8 @@
}
};
- var tryNextCopy = function() {
- targetRelativePath = targetRelativePrefix;
- if (copyNumber > 0) {
- targetRelativePath += ' (' + copyNumber + ')';
- }
- targetRelativePath += targetExt;
-
- // Check to see if the target exists. This kicks off the rest of the copy
- // if the target is not found, or raises an error if it does.
- util.resolvePath(targetDirEntry, targetRelativePath, onTargetExists,
- onTargetNotResolved);
- };
-
- tryNextCopy();
+ util.deduplicatePath(targetDirEntry, originalPath,
+ onDeduplicated, onError);
};
/**
@@ -1089,27 +1030,12 @@
destName = ((i < 0) ? basename : basename.substr(0, i));
}
- var copyNumber = 0;
- var firstExistingEntry = null;
- var destPath = destName + '.zip';
-
var onError = function(reason, data) {
self.log_('serviceZipTask error: ' + reason + ':', data);
errorCallback(new FileCopyManager.Error(reason, data));
};
- var onTargetExists = function(existingEntry) {
- if (copyNumber < 10) {
- if (!firstExistingEntry)
- firstExistingEntry = existingEntry;
- copyNumber++;
- tryZipSelection();
- } else {
- onError('TARGET_EXISTS', firstExistingEntry);
- }
- };
-
- var onTargetNotResolved = function() {
+ var onDeduplicated = function(destPath) {
var onZipSelectionComplete = function(success) {
if (success) {
self.sendProgressEvent_('SUCCESS');
@@ -1125,17 +1051,8 @@
onZipSelectionComplete);
};
- var tryZipSelection = function() {
- if (copyNumber > 0)
- destPath = destName + ' (' + copyNumber + ').zip';
-
- // Check if the target exists. This kicks off the rest of the zip file
- // creation if the target is not found, or raises an error if it does.
- util.resolvePath(task.targetDirEntry, destPath, onTargetExists,
- onTargetNotResolved);
- };
-
- tryZipSelection();
+ util.deduplicatePath(
+ task.targetDirEntry, destName + '.zip', onDeduplicated, onError);
};
/**
diff --git a/chrome/browser/resources/file_manager/js/file_copy_manager_wrapper.js b/chrome/browser/resources/file_manager/js/file_copy_manager_wrapper.js
index 4172a16..f955ff4 100644
--- a/chrome/browser/resources/file_manager/js/file_copy_manager_wrapper.js
+++ b/chrome/browser/resources/file_manager/js/file_copy_manager_wrapper.js
@@ -55,30 +55,10 @@
* @private
*/
FileCopyManagerWrapper.prototype.getCopyManagerAsync_ = function(callback) {
- var MAX_RETRIES = 10;
- var TIMEOUT = 100;
-
- var retries = 0;
-
- var tryOnce = function() {
- var onGetBackgroundPage = function(bg) {
- if (bg) {
- var fileCopyManager = bg.FileCopyManager.getInstance();
- fileCopyManager.initialize(callback.bind(this, fileCopyManager));
- return;
- }
- if (++retries < MAX_RETRIES)
- setTimeout(tryOnce, TIMEOUT);
- else
- console.error('Can\'t get copy manager.');
- };
- if (chrome.runtime && chrome.runtime.getBackgroundPage)
- chrome.runtime.getBackgroundPage(onGetBackgroundPage);
- else
- onGetBackgroundPage(chrome.extension.getBackgroundPage());
- };
-
- tryOnce();
+ chrome.runtime.getBackgroundPage(function(backgroundPage) {
+ var fileCopyManager = backgroundPage.FileCopyManager.getInstance();
+ fileCopyManager.initialize(callback.bind(this, fileCopyManager));
+ });
};
/**
diff --git a/chrome/browser/resources/file_manager/js/file_grid.js b/chrome/browser/resources/file_manager/js/file_grid.js
index bb08940..5cbe2ff 100644
--- a/chrome/browser/resources/file_manager/js/file_grid.js
+++ b/chrome/browser/resources/file_manager/js/file_grid.js
@@ -57,7 +57,7 @@
/**
* Updates items to reflect metadata changes.
* @param {string} type Type of metadata changed.
- * @param {Object<string, Object>} props Map from entry URLs to metadata props.
+ * @param {Object.<string, Object>} props Map from entry URLs to metadata props.
*/
FileGrid.prototype.updateListItemsMetadata = function(type, props) {
var boxes = this.querySelectorAll('.img-container');
@@ -198,6 +198,10 @@
FileGrid.Item.prototype.__proto__ = cr.ui.ListItem.prototype;
Object.defineProperty(FileGrid.Item.prototype, 'label', {
+ /**
+ * @this {FileGrid.Item}
+ * @return {string} Label of the item.
+ */
get: function() {
return this.querySelector('filename-label').textContent;
}
diff --git a/chrome/browser/resources/file_manager/js/file_manager.js b/chrome/browser/resources/file_manager/js/file_manager.js
index 4a722bf..823d2a7 100644
--- a/chrome/browser/resources/file_manager/js/file_manager.js
+++ b/chrome/browser/resources/file_manager/js/file_manager.js
@@ -238,8 +238,8 @@
/**
* Changed metadata observers for the new directory.
- * @override
- * @param {?DirectoryEntry} entry New watched directory entry.
+ *
+ * @param {DirectoryEntry} entry New watched directory entry.
* @override
*/
FileManager.MetadataFileWatcher.prototype.changeWatchedEntry = function(
@@ -332,6 +332,15 @@
}.bind(this));
}.bind(this));
+ // TODO(yoshiki): Remove this after launching folder shortcuts feature.
+ group.add(function(done) {
+ chrome.commandLinePrivate.hasSwitch(
+ 'file-manager-enable-folder-shortcuts', function(flag) {
+ this.isFolderShortcutsEnabled_ = flag;
+ done();
+ }.bind(this));
+ }.bind(this));
+
group.run(callback);
};
@@ -888,9 +897,11 @@
var d = cr.ui.dialogs;
d.BaseDialog.OK_LABEL = str('OK_LABEL');
d.BaseDialog.CANCEL_LABEL = str('CANCEL_LABEL');
+ this.error = new ErrorDialog(this.dialogDom_);
this.alert = new d.AlertDialog(this.dialogDom_);
this.confirm = new d.ConfirmDialog(this.dialogDom_);
this.prompt = new d.PromptDialog(this.dialogDom_);
+ this.shareDialog_ = new ShareDialog(this.dialogDom_, this.metadataCache_);
this.defaultTaskPicker =
new cr.filebrowser.DefaultActionDialog(this.dialogDom_);
};
@@ -1149,7 +1160,7 @@
this.directoryModel_.start();
- this.pinnedFolderModel_ = new cr.ui.ArrayDataModel([]);
+ this.folderShortcutsModel_ = new FolderShortcutsDataModel();
this.selectionHandler_ = new FileSelectionHandler(this);
this.selectionHandler_.addEventListener('show-preview-panel',
@@ -1245,7 +1256,7 @@
this.volumeList_ = this.dialogDom_.querySelector('#volume-list');
VolumeList.decorate(this.volumeList_,
this.directoryModel_,
- this.pinnedFolderModel_);
+ this.folderShortcutsModel_);
};
/**
@@ -1865,7 +1876,7 @@
/**
* @param {string} type Type of metadata changed.
* @param {Array.<string>} urls Array of urls.
- * @param {Object<string, Object>} props Map from entry URLs to metadata
+ * @param {Object.<string, Object>} props Map from entry URLs to metadata
* props.
* @private
*/
@@ -2066,7 +2077,7 @@
};
FileManager.prototype.isDriveEnabled = function() {
- // TODO(kinaba): remove the "!shouldReturnLocalPath &&" condition once
+ // TODO(kinaba): Remove the "!shouldReturnLocalPath &&" condition once
// crbug.com/140425 is done.
return !this.params_.shouldReturnLocalPath &&
(!('driveEnabled' in this.preferences_) ||
@@ -2163,7 +2174,7 @@
/**
* Return full path of the current directory or null.
- * @return {string=} The full path of the current directory.
+ * @return {?string} The full path of the current directory.
*/
FileManager.prototype.getCurrentDirectory = function() {
return this.directoryModel_ &&
@@ -2205,10 +2216,28 @@
};
/**
- * Shows the share dialog for the selected file.
+ * Shows the share dialog for the selected file or directory.
*/
FileManager.prototype.shareSelection = function() {
- // TODO(mtomasz): Implement it. crbug.com/141396
+ var entries = this.getSelection().entries;
+ if (entries.length != 1) {
+ console.warn('Unable to share multiple items at once.');
+ return;
+ }
+ this.shareDialog_.show(entries[0], function() {
+ this.error.show(str('SHARE_ERROR'));
+ }.bind(this));
+ };
+
+ /**
+ * Folder shared feature is under development and hidden behind flag. This
+ * method returns if the feature is explicitly enabled by the flag or not.
+ * TODO(yoshiki): Remove this after launching folder feature feature.
+ *
+ * @return {boolena} True if the flag is enabled.
+ */
+ FileManager.prototype.isFolderShortcutsEnabled = function() {
+ return this.isFolderShortcutsEnabled_;
};
/**
@@ -2221,8 +2250,7 @@
if (this.isFolderPinned(entry.fullPath))
return;
- this.pinnedFolderModel_.splice(0, 0, entry.fullPath);
- this.pinnedFolderModel_.sort('name', 'asc');
+ this.folderShortcutsModel_.add(entry.fullPath);
};
/**
@@ -2230,13 +2258,7 @@
* @param {string} path Path of the folder to be checked.
*/
FileManager.prototype.isFolderPinned = function(path) {
- for (var i = 0; i < this.pinnedFolderModel_.length; i++) {
- var pinnedPath = this.pinnedFolderModel_.item(i);
- if (pinnedPath == path) {
- return true;
- }
- }
- return false;
+ return this.folderShortcutsModel_.exists(path);
};
/**
@@ -2244,13 +2266,7 @@
* @param {string} path Path of the pinned folder to be unpinnned.
*/
FileManager.prototype.unpinFolder = function(path) {
- for (var i = 0; i < this.pinnedFolderModel_.length; i++) {
- var pinnedPath = this.pinnedFolderModel_.item(i);
- if (pinnedPath == path) {
- this.pinnedFolderModel_.splice(i, 1);
- return;
- }
- }
+ this.folderShortcutsModel_.remove(path);
};
/**
@@ -3892,6 +3908,10 @@
*/
FileManager.prototype.setCtrlKeyPressed_ = function(flag) {
this.ctrlKeyPressed_ = flag;
- this.document_.querySelector('#drive-clear-local-cache').canExecuteChange();
+ // Before the DOM is constructed, the key event can be handled.
+ var cacheClearCommand =
+ this.document_.querySelector('#drive-clear-local-cache');
+ if (cacheClearCommand)
+ cacheClearCommand.canExecuteChange();
};
})();
diff --git a/chrome/browser/resources/file_manager/js/file_manager_commands.js b/chrome/browser/resources/file_manager/js/file_manager_commands.js
index 8e12f9c..f8c8b8d 100644
--- a/chrome/browser/resources/file_manager/js/file_manager_commands.js
+++ b/chrome/browser/resources/file_manager/js/file_manager_commands.js
@@ -419,7 +419,7 @@
execute: function(event, fileManager) {
var pin = !event.command.checked;
event.command.checked = pin;
- var entries = this.getTargetEntries_();
+ var entries = Commands.togglePinnedCommand.getTargetEntries_();
var currentEntry;
var error = false;
var steps = {
@@ -468,7 +468,7 @@
},
canExecute: function(event, fileManager) {
- var entries = this.getTargetEntries_();
+ var entries = Commands.togglePinnedCommand.getTargetEntries_();
var checked = true;
for (var i = 0; i < entries.length; i++) {
checked = checked && entries[i].pinned;
@@ -537,7 +537,8 @@
var selection = fileManager.getSelection();
event.canExecute = fileManager.isOnDrive() &&
!fileManager.isDriveOffline() &&
- selection && selection.totalCount == 1;
+ selection && selection.totalCount == 1 &&
+ selection.directoryCount == 0;
event.command.setHidden(!fileManager.isOnDrive());
}
};
@@ -558,6 +559,12 @@
* @param {FileManager} fileManager The file manager instance.
*/
canExecute: function(event, fileManager) {
+ // TODO(yoshiki): remove this after launching folder shortcuts feature.
+ if (!fileManager.isFolderShortcutsEnabled()) {
+ event.command.setHidden(true);
+ return;
+ }
+
var selection = fileManager.getSelection();
var selectionEntries = selection.entries;
var onlyOneFolderSelected =
@@ -589,6 +596,12 @@
* @param {DirectoryTree} directoryTree Target directory tree.
*/
canExecute: function(event, fileManager, directoryTree) {
+ // TODO(yoshiki): remove this after launching folder shortcut feature.
+ if (!fileManager.isFolderShortcutsEnabled()) {
+ event.command.setHidden(true);
+ return;
+ }
+
var path = CommandUtil.getCommandRoot(event, directoryTree);
var isPinned = path && !PathUtil.isRootPath(path);
event.canExecute = isPinned;
diff --git a/chrome/browser/resources/file_manager/js/file_table.js b/chrome/browser/resources/file_manager/js/file_table.js
index cb4923b..c52818b 100644
--- a/chrome/browser/resources/file_manager/js/file_table.js
+++ b/chrome/browser/resources/file_manager/js/file_table.js
@@ -256,6 +256,10 @@
* @type {number}
*/
size: {
+ /**
+ * @this {FileTableColumnModel}
+ * @return {number} Number of columns.
+ */
get: function() {
return this.totalSize;
}
@@ -266,6 +270,10 @@
* @type {number}
*/
totalSize: {
+ /**
+ * @this {FileTableColumnModel}
+ * @return {number} Number of columns.
+ */
get: function() {
return columns.length;
}
@@ -273,11 +281,14 @@
/**
* Obtains a column by the specified horizontal positon.
- * @param {number} x Horizontal position.
- * @return {object} The object that contains column index, column width, and
- * hitPosition where the horizontal position is hit in the column.
*/
getHitColumn: {
+ /**
+ * @this {FileTableColumnModel}
+ * @param {number} x Horizontal position.
+ * @return {object} The object that contains column index, column width,
+ * and hitPosition where the horizontal position is hit in the column.
+ */
value: function(x) {
for (var i = 0; x >= this.columns_[i].width; i++) {
x -= this.columns_[i].width;
@@ -313,9 +324,16 @@
new AsyncUtil.Aggregation(self.relayoutImmediately_.bind(self));
Object.defineProperty(self.list_, 'selectionModel', {
+ /**
+ * @this {cr.ui.List}
+ * @return {cr.ui.ListSelectionModel} The current selection model.
+ */
get: function() {
return this.selectionModel_;
},
+ /**
+ * @this {cr.ui.List}
+ */
set: function(value) {
var sm = this.selectionModel;
if (sm)
@@ -926,10 +944,17 @@
li.setAttribute('role', 'option');
Object.defineProperty(li, 'selected', {
+ /**
+ * @this {ListItem}
+ * @return {boolean} True if the list item is selected.
+ */
get: function() {
return this.hasAttribute('selected');
},
+ /**
+ * @this {ListItem}
+ */
set: function(v) {
if (v)
this.setAttribute('selected');
diff --git a/chrome/browser/resources/file_manager/js/file_tasks.js b/chrome/browser/resources/file_manager/js/file_tasks.js
index 329b29b..e6072ee 100644
--- a/chrome/browser/resources/file_manager/js/file_tasks.js
+++ b/chrome/browser/resources/file_manager/js/file_tasks.js
@@ -21,7 +21,7 @@
* List of invocations to be called once tasks are available.
*
* @private
- * @type {Array,<Object>}
+ * @type {Array.<Object>}
*/
this.pendingInvocations_ = [];
}
diff --git a/chrome/browser/resources/file_manager/js/file_transfer_controller.js b/chrome/browser/resources/file_manager/js/file_transfer_controller.js
index 1d5a90a..3afc416 100644
--- a/chrome/browser/resources/file_manager/js/file_transfer_controller.js
+++ b/chrome/browser/resources/file_manager/js/file_transfer_controller.js
@@ -737,6 +737,7 @@
/**
* @this {FileTransferController}
+ * @return {boolean} True if the current directory is read only.
*/
get readonly() {
return this.directoryModel_.isReadOnly();
@@ -744,6 +745,7 @@
/**
* @this {FileTransferController}
+ * @return {boolean} True if the current directory is on Drive.
*/
get isOnDrive() {
return PathUtil.isDriveBasedPath(this.directoryModel_.getCurrentRootPath());
@@ -762,7 +764,7 @@
/**
* @this {FileTransferController}
- * @type {Array.<Entry>}
+ * @return {Array.<Entry>} Array of the selected entries.
*/
get selectedEntries_() {
var list = this.directoryModel_.getFileList();
diff --git a/chrome/browser/resources/file_manager/js/folder_shortcuts_data_model.js b/chrome/browser/resources/file_manager/js/folder_shortcuts_data_model.js
new file mode 100644
index 0000000..271b738
--- /dev/null
+++ b/chrome/browser/resources/file_manager/js/folder_shortcuts_data_model.js
@@ -0,0 +1,345 @@
+// Copyright (c) 2013 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.
+
+/**
+ * Basic sorted array model using chrome.storage as a backend.
+ *
+ * @param {string} type Type of backend. Should be "sync" or "local".
+ * @param {string} name Name of the model.
+ * @constructor
+ * @extends {cr.EventTarget}
+ */
+function StoredSortedArray(type, name) {
+ this.type_ = type;
+ this.name_ = name;
+ this.array_ = [];
+ this.storage_ = (type == 'sync') ? chrome.storage.sync : chrome.storage.local;
+
+ // Loads the contents from the storage to initialize the array.
+ this.storage_.get(name, function(value) {
+ if (!(name in value))
+ return;
+
+ // Since the value comes from outer resource, we have to check it just in
+ // case.
+ var list = value[name];
+ if (list instanceof Array) {
+ var changedEvent = new Event('changed');
+ changedEvent.permutation = this.createPermutation_(this.array_, list);
+
+ this.array_ = list;
+ this.dispatchEvent(changedEvent);
+ }
+ }.bind(this));
+
+ // Listening for changes in the storage.
+ chrome.storage.onChanged.addListener(function(changes, namespace) {
+ if (!(name in changes) || namespace != type)
+ return;
+
+ var list = changes[name].newValue;
+ // Since the value comes from outer resource, we have to check it just in
+ // case.
+ if (list instanceof Array) {
+ var changedEvent = new Event('changed');
+ changedEvent.permutation = this.createPermutation_(this.array_, list);
+
+ this.array_ = list;
+ this.dispatchEvent(changedEvent);
+ }
+ }.bind(this));
+}
+
+StoredSortedArray.prototype = {
+ __proto__: cr.EventTarget.prototype,
+
+ /**
+ * @return {number} Number of elements in the array.
+ */
+ get length() {
+ return this.array_.length;
+ },
+
+ /**
+ * @param {number} index Index of the element to be retrieved.
+ * @return {string} The value of the |index|-th element.
+ */
+ getItem: function(index) {
+ return this.array_[index];
+ },
+
+ /**
+ * @param {string} value Value of the element to be retrieved.
+ * @return {number} Index of the element with the specified |value|.
+ */
+ getIndex: function(value) {
+ for (var i = 0; i < this.length; i++) {
+ if (this.array_[i].localeCompare(value) == 0) {
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ /**
+ * Adds the given item to the array.
+ * @param {string} value Value to be added into the array.
+ * @return {number} Index in the list which the element added to.
+ */
+ add: function(value) {
+ var i = 0;
+ for (; i < this.length; i++) {
+ // Since the array is sorted, new item will be added just before the first
+ // larger item. If the same item exists, do nothing.
+ if (this.array_[i].localeCompare(value) == 0) {
+ return i;
+ } else if (this.array_[i].localeCompare(value) >= 0) {
+ this.array_.splice(i, 0, value);
+ break;
+ }
+ }
+ // If value is not added yet, add it at the last.
+ if (i == this.length)
+ this.array_.push(value);
+ this.save_();
+ return i;
+ },
+
+ /**
+ * Removes the given item from the array.
+ * @param {string} value Value to be removed from the array.
+ * @return {number} Index in the list which the element removed from.
+ */
+ remove: function(value) {
+ var i = 0;
+ for (; i < this.length; i++) {
+ if (this.array_[i] == value) {
+ this.array_.splice(i, 1);
+ break;
+ }
+ }
+ this.save_();
+ return i;
+ },
+
+ /**
+ * Saves the current array to chrome.storage.
+ * @private
+ */
+ save_: function() {
+ var obj = {};
+ obj[this.name_] = this.array_;
+ this.storage_.set(obj, function() {});
+ },
+
+ /**
+ * Creates a permutation array for 'changed' event, which is compatible with
+ * a parmutation array used in cr/ui/array_data_model.js.
+ *
+ * @param {array} oldArray Previous array before changing.
+ * @param {array} newArray New array after changing.
+ * @return {Array.<number>} Created permutation array.
+ * @private
+ */
+ createPermutation_: function(oldArray, newArray) {
+ var oldIndex = 0; // Index of oldArray.
+ var newIndex = 0; // Index of newArray.
+
+ // Note that both new and old arrays are sorted.
+ var permutation = [];
+ for (; oldIndex < oldArray.length; oldIndex++) {
+ if (newIndex >= newArray.length) {
+ // oldArray[oldIndex] is deleted, which is not in the new array.
+ permutation[oldIndex] = -1;
+ continue;
+ }
+
+ while (newIndex < newArray.length) {
+ if (oldArray[oldIndex] == newArray[newIndex]) {
+ // Unchanged item, which exists in both new and old array. But the
+ // index may be changed.
+ permutation[oldIndex] = newIndex;
+ newIndex++;
+ break;
+ } else if (oldArray[oldIndex] < newArray[newIndex]) {
+ // oldArray[oldIndex] is deleted, which is not in the new array.
+ permutation[oldIndex] = -1;
+ break;
+ } else { // oldArray[oldIndex] > newArray[newIndex]
+ // newArray[newIndex] is added, which is not in the old array.
+ newIndex++;
+ }
+ }
+ }
+ return permutation;
+ }
+};
+
+/**
+ * Model for the folder shortcuts.
+ * This list is the combined array of the following arrays.
+ * 1) syncable list of the folder shortcuts on drive
+ * 2) non-syncable list of the folder shortcuts on the other volumes.
+ * Each array uses StoredSortedArray as implementation.
+ *
+ * @constructor
+ * @extends {cr.EventTarget}
+ */
+function FolderShortcutsDataModel() {
+ // Syncable array for Drive.
+ this.remoteList_ = new StoredSortedArray('sync', 'folder-shortcuts-list');
+ this.remoteList_.addEventListener(
+ 'changed',
+ this.onArrayChanged_.bind(this, 'sync'));
+
+ // Syncable array for other volumes.
+ this.localList_ = new StoredSortedArray('local', 'folder-shortcuts-list');
+ this.localList_.addEventListener(
+ 'changed',
+ this.onArrayChanged_.bind(this, 'local'));
+}
+
+/**
+ * Type of an event.
+ * @enum {number}
+ */
+FolderShortcutsDataModel.EventType = {
+ ADDED: 0,
+ REMOVED: 1
+};
+
+FolderShortcutsDataModel.prototype = {
+ __proto__: cr.EventTarget.prototype,
+
+ /**
+ * @return {number} The number of elements in the array.
+ */
+ get length() {
+ return this.remoteList_.length + this.localList_.length;
+ },
+
+ /**
+ * @param {string} path Path to be added.
+ */
+ add: function(path) {
+ if (PathUtil.isDriveBasedPath(path)) {
+ var index = this.remoteList_.add(path);
+ this.fireChangeEvents_('sync', index,
+ FolderShortcutsDataModel.EventType.ADDED);
+ } else {
+ var index = this.localList_.add(path);
+ this.fireChangeEvents_('local', index,
+ FolderShortcutsDataModel.EventType.ADDED);
+ }
+ },
+
+ /**
+ * @param {string} path Path to be removed.
+ */
+ remove: function(path) {
+ if (PathUtil.isDriveBasedPath(path)) {
+ var index = this.remoteList_.remove(path);
+ this.fireChangeEvents_('sync', index,
+ FolderShortcutsDataModel.EventType.REMOVED);
+ } else {
+ var index = this.localList_.remove(path);
+ this.fireChangeEvents_('local', index,
+ FolderShortcutsDataModel.EventType.REMOVED);
+ }
+ },
+
+ /**
+ * @param {string} path Path to be checked.
+ * @return {boolean} True if the given |path| exists in the array. False
+ * otherwise.
+ */
+ exists: function(path) {
+ if (PathUtil.isDriveBasedPath(path)) {
+ var index = this.remoteList_.getIndex(path);
+ return (index >= 0);
+ } else {
+ var index = this.localList_.getIndex(path);
+ return (index >= 0);
+ }
+ },
+
+ /**
+ * @param {number} index Index of the element to be retrieved.
+ * @return {string=} The value of the |index|-th element.
+ */
+ item: function(index) {
+ if (0 <= index && index < this.remoteList_.length)
+ return this.remoteList_.getItem(index);
+ if (this.remoteList_.length <= index && index < this.length)
+ return this.localList_.getItem(index - this.remoteList_.length);
+ return undefined;
+ },
+
+ /**
+ * Invoked when any of the subarray is changed. This method propagates
+ * 'change' and 'permuted' events.
+ *
+ * @param {string} type Type of the array from which the change event comes.
+ * @param {Event} event The 'changed' event from the array.
+ */
+ onArrayChanged_: function(type, event) {
+ var changeEvent = new Event('change');
+ changeEvent.index = (type == 'sync') ? 0 : this.remoteList_.length;
+ this.dispatchEvent(changeEvent);
+
+ var permutedEvent = new Event('permuted');
+ permutedEvent.newLength = this.length;
+ permutedEvent.permutation = event.permutation;
+ this.dispatchEvent(permutedEvent);
+
+ // 'splice' and 'sorted' events are not implemented.
+ },
+
+ /**
+ * Fires 'change' and 'permuted' event.
+ *
+ * @param {string} type Type of the array from which the change event comes.
+ * @param {number} index Changed index in the array.
+ * @param {FolderShortcutsDataModel.EventType} type Type of the event.
+ */
+ fireChangeEvents_: function(type, index, eventType) {
+ var changedIndex = ((type == 'sync') ? 0 : this.remoteList_.length) + index;
+
+ var changeEvent = new Event('change');
+ changeEvent.index = changedIndex;
+ this.dispatchEvent(changeEvent);
+
+ var permutation = [];
+ if (eventType == FolderShortcutsDataModel.EventType.ADDED) {
+ // Old length should be (current length) - 1, since an item is added.
+ var oldLength = this.length - 1;
+ for (var i = 0; i < oldLength; i++) {
+ if (i < changedIndex)
+ permutation[i] = i;
+ else if (i == changedIndex)
+ permutation[i] = i + 1;
+ else
+ permutation[i] = i + 1;
+ }
+ } else { // eventType == FolderShortcutsDataModel.EventType.REMOVED
+ // Old length should be (current length) + 1, since an item is removed.
+ var oldLength = this.length + 1;
+ for (var i = 0; i < oldLength; i++) {
+ if (i < changedIndex)
+ permutation[i] = i;
+ else if (i == changedIndex)
+ permutation[i] = -1; // Item is removed.
+ else
+ permutation[i] = i - 1;
+ }
+ }
+
+ var permutedEvent = new Event('permuted');
+ permutedEvent.newLength = this.length;
+ permutedEvent.permutation = permutation;
+ this.dispatchEvent(permutedEvent);
+
+ // 'splice' and 'sorted' events are not implemented.
+ }
+};
diff --git a/chrome/browser/resources/file_manager/js/main_scripts.js b/chrome/browser/resources/file_manager/js/main_scripts.js
index a99f813..8c35a69 100644
--- a/chrome/browser/resources/file_manager/js/main_scripts.js
+++ b/chrome/browser/resources/file_manager/js/main_scripts.js
@@ -90,7 +90,10 @@
//<include src="file_tasks.js"/>
//<include src="file_transfer_controller.js"/>
//<include src="file_type.js"/>
+//<include src="folder_shortcuts_data_model.js"/>
//<include src="scrollbar.js"/>
+//<include src="share_client.js"/>
+//<include src="share_dialog.js"/>
//<include src="tree.css.js"/>
//<include src="volume_list.js"/>
//<include src="volume_manager.js"/>
diff --git a/chrome/browser/resources/file_manager/js/media/media_util.js b/chrome/browser/resources/file_manager/js/media/media_util.js
index 75b344a..e4e0e59 100644
--- a/chrome/browser/resources/file_manager/js/media/media_util.js
+++ b/chrome/browser/resources/file_manager/js/media/media_util.js
@@ -127,7 +127,7 @@
* @param {ThumbnailLoader.FillMode} fillMode Fill mode.
* @param {ThumbnailLoader.OptimizationMode=} opt_optimizationMode Optimization
* for downloading thumbnails. By default optimizations are disabled.
- * @param {function(Image, object} opt_onSuccess Success callback,
+ * @param {function(Image, Object)} opt_onSuccess Success callback,
* accepts the image and the transform.
* @param {function} opt_onError Error callback.
* @param {function} opt_onGeneric Callback for generic image used.
diff --git a/chrome/browser/resources/file_manager/js/metadata/metadata_cache.js b/chrome/browser/resources/file_manager/js/metadata/metadata_cache.js
index e64fba3..1c29a2d 100644
--- a/chrome/browser/resources/file_manager/js/metadata/metadata_cache.js
+++ b/chrome/browser/resources/file_manager/js/metadata/metadata_cache.js
@@ -818,6 +818,7 @@
dirty: data.isDirty,
availableOffline: DriveProvider.isAvailableOffline(data, url),
availableWhenMetered: DriveProvider.isAvailableWhenMetered(data),
+ shareUrl: data.shareUrl || '',
driveApps: data.driveApps || [],
contentMimeType: data.contentMimeType || '',
sharedWithMe: data.sharedWithMe
diff --git a/chrome/browser/resources/file_manager/js/share_client.js b/chrome/browser/resources/file_manager/js/share_client.js
new file mode 100644
index 0000000..d88f014
--- /dev/null
+++ b/chrome/browser/resources/file_manager/js/share_client.js
@@ -0,0 +1,167 @@
+// Copyright 2013 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.
+
+'use strict';
+
+/**
+ * @param {WebView} webView Web View tag.
+ * @param {string} url Share Url for an entry.
+ * @param {ShareClient.Observer} observer Observer instance.
+ * @constructor
+ */
+function ShareClient(webView, url, observer) {
+ this.webView_ = webView;
+ this.url_ = url;
+ this.observer_ = observer;
+ this.loaded_ = false;
+ this.loading_ = false;
+ this.onMessageBound_ = this.onMessage_.bind(this);
+ this.onLoadStopBound_ = this.onLoadStop_.bind(this);
+ this.onLoadAbortBound_ = this.onLoadAbort_.bind(this);
+}
+
+/**
+ * Source origin of the client.
+ * @type {string}
+ * @const
+ */
+ShareClient.SHARE_ORIGIN =
+ 'chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj';
+
+/**
+ * Target origin of the embedded dialog.
+ * @type {string}
+ * @const
+ */
+ShareClient.SHARE_TARGET = 'https://drive.google.com';
+
+/**
+ * Observes for state changes of the embedded dialog.
+ * @interface
+ */
+ShareClient.Observer = function() {
+};
+
+/**
+ * Notifies about the embedded dialog being loaded.
+ */
+ShareClient.Observer.prototype.onLoaded = function() {
+};
+
+/**
+ * Notifies when the the embedded dialog failed to load.
+ */
+ShareClient.Observer.prototype.onLoadingFailed = function() {
+};
+
+/**
+ * Notifies about changed dimensions of the embedded dialog.
+ * @param {number} width Width in pixels.
+ * @param {number} height Height in pixels.
+ * @param {function()} callback Completion callback. Call when finished
+ * handling the resize.
+ */
+ShareClient.Observer.prototype.onResized = function(width, height, callback) {
+};
+
+/**
+ * Notifies about the embedded dialog being closed.
+ */
+ShareClient.Observer.prototype.onClosed = function() {
+};
+
+/**
+ * Handles messages from the embedded dialog.
+ * @param {Event} e Message event.
+ * @private
+ */
+ShareClient.prototype.onMessage_ = function(e) {
+ if (e.origin != ShareClient.SHARE_TARGET)
+ return;
+ var data = JSON.parse(e.data);
+ switch (data.type) {
+ case 'resize':
+ this.observer_.onResized(data.args.width,
+ data.args.height,
+ this.postMessage_.bind(this, 'resizeComplete'));
+ break;
+ case 'prepareForVisible':
+ this.postMessage_('prepareComplete');
+ if (!this.loaded_) {
+ this.loading_ = false;
+ this.loaded_ = true;
+ this.observer_.onLoaded();
+ }
+ break;
+ case 'setVisible':
+ if (!data.args.visible)
+ this.observer_.onClosed();
+ break;
+ }
+};
+
+/**
+ * Handles completion of the web view request.
+ * @param {Event} e Message event.
+ * @private
+ */
+ShareClient.prototype.onLoadStop_ = function(e) {
+ this.postMessage_('makeBodyVisible');
+};
+
+/**
+ * Handles termination of the web view request.
+ * @param {Event} e Message event.
+ * @private
+ */
+ShareClient.prototype.onLoadAbort_ = function(e) {
+ this.observer_.onLoadFailed();
+};
+
+/**
+ * Sends a message to the embedded dialog.
+ * @param {string} type Message type.
+ * @param {Object=} opt_args Optional arguments.
+ * @private
+ */
+ShareClient.prototype.postMessage_ = function(type, opt_args) {
+ var message = {
+ type: type,
+ args: opt_args
+ };
+ this.webView_.contentWindow.postMessage(
+ JSON.stringify(message), ShareClient.SHARE_TARGET);
+};
+
+/**
+ * Loads the embedded dialog. Can be called only one.
+ */
+ShareClient.prototype.load = function() {
+ if (this.loading_ || this.loaded_)
+ throw new Error('Already loaded.');
+ this.loading_ = true;
+
+ window.addEventListener('message', this.onMessageBound_);
+ this.webView_.addEventListener('loadstop', this.onLoadStopBound_);
+ this.webView_.addEventListener('loadabort', this.onLoadAbortBound_);
+ this.webView_.setAttribute('src', this.url_);
+};
+
+/**
+ * Aborts loading of the embedded dialog and performs cleanup.
+ */
+ShareClient.prototype.abort = function() {
+ window.removeEventListener('message', this.onMessageBound_);
+ this.webView_.removeEventListener('loadstop', this.onLoadStopBound_);
+ this.webView_.removeEventListener(
+ 'loadabort', this.onLoadAbortBound_);
+ this.webView_.stop();
+};
+
+/**
+ * Cleans the dialog by removing all handlers.
+ */
+ShareClient.prototype.dispose = function() {
+ this.abort();
+};
diff --git a/chrome/browser/resources/file_manager/js/share_dialog.js b/chrome/browser/resources/file_manager/js/share_dialog.js
new file mode 100644
index 0000000..852912e
--- /dev/null
+++ b/chrome/browser/resources/file_manager/js/share_dialog.js
@@ -0,0 +1,245 @@
+// Copyright 2013 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.
+
+'use strict';
+
+/**
+ * @param {HTMLElement} parentNode Node to be parent for this dialog.
+ * @param {MetadataCache} metadataCache Metadata cache.
+ * @constructor
+ * @extends {cr.ui.dialogs.BaseDialog}
+ * @implements {ShareClient.Observer}
+ */
+function ShareDialog(parentNode, metadataCache) {
+ this.queue_ = new AsyncUtil.Queue();
+ this.onQueueTaskFinished_ = null;
+ this.metadataCache_ = metadataCache;
+ this.shareClient_ = null;
+ this.spinner_ = null;
+ this.spinnerWrapper_ = null;
+ this.webViewWrapper_ = null;
+ this.webView_ = null;
+ this.failureTimeout_ = null;
+
+ cr.ui.dialogs.BaseDialog.call(this, parentNode);
+}
+
+/**
+ * Timeout for loading the share dialog before giving up.
+ * @type {number}
+ * @const
+ */
+ShareDialog.FAILURE_TIMEOUT = 5000;
+
+/**
+ * Wraps a Web View element and adds authorization headers to it.
+ * @param {origin} origin Origin to be authorized.
+ * @param {WebView} webView Web View element to be wrapped.
+ * @constructor
+ */
+ShareDialog.WebViewAuthorizer = function(origin, webView) {
+ this.origin_ = origin;
+ this.webView_ = webView;
+ this.initialized_ = false;
+ this.accessToken_ = null;
+};
+
+/**
+ * Initializes the web view by installing hooks injecting the authorization
+ * headers.
+ * @param {function()} callback Completion callback.
+ */
+ShareDialog.WebViewAuthorizer.prototype.initialize = function(callback) {
+ if (this.initialized_) {
+ callback();
+ return;
+ }
+
+ var registerInjectionHooks = function() {
+ this.webView_.removeEventListener('loadstop', registerInjectionHooks);
+ this.webView_.onBeforeSendHeaders.addListener(
+ this.authorizeRequest_.bind(this),
+ {urls: [this.origin_ + '/*']},
+ ['blocking', 'requestHeaders']);
+ this.initialized_ = true;
+ callback();
+ }.bind(this);
+
+ this.webView_.addEventListener('loadstop', registerInjectionHooks);
+ this.webView_.setAttribute('src', 'data:text/html,');
+};
+
+/**
+ * Authorizes the web view by fetching the freshest access tokens.
+ * @param {function()} callback Completion callback.
+ */
+ShareDialog.WebViewAuthorizer.prototype.authorize = function(callback) {
+ // Fetch or update the access token.
+ chrome.fileBrowserPrivate.requestAccessToken(false, // force_refresh
+ function(inAccessToken) {
+ this.accessToken_ = inAccessToken;
+ callback();
+ }.bind(this));
+};
+
+/**
+ * Injects headers into the passed request.
+ * @param {Event} e Request event.
+ * @return {{requestHeaders: HttpHeaders}} Modified headers.
+ * @private
+ */
+ShareDialog.WebViewAuthorizer.prototype.authorizeRequest_ = function(e) {
+ e.requestHeaders.push({
+ name: 'Authorization',
+ value: 'Bearer ' + this.accessToken_
+ });
+ return {requestHeaders: e.requestHeaders};
+};
+
+ShareDialog.prototype = {
+ __proto__: cr.ui.dialogs.BaseDialog.prototype
+};
+
+/**
+ * One-time initialization of DOM.
+ * @private
+ */
+ShareDialog.prototype.initDom_ = function() {
+ cr.ui.dialogs.BaseDialog.prototype.initDom_.call(this);
+ this.frame_.classList.add('share-dialog-frame');
+
+ this.spinnerWrapper_ = this.document_.createElement('div');
+ this.spinnerWrapper_.className = 'spinner-container';
+ this.frame_.appendChild(this.spinnerWrapper_);
+
+ this.spinner_ = this.document_.createElement('div');
+ this.spinner_.className = 'spinner';
+ this.spinnerWrapper_.appendChild(this.spinner_);
+
+ this.webViewWrapper_ = this.document_.createElement('div');
+ this.webViewWrapper_.className = 'share-dialog-webview-wrapper';
+ this.cancelButton_.hidden = true;
+ this.okButton_.hidden = true;
+ this.frame_.insertBefore(this.webViewWrapper_,
+ this.frame_.querySelector('.cr-dialog-buttons'));
+};
+
+/**
+ * @override
+ */
+ShareDialog.prototype.onResized = function(width, height, callback) {
+ if (width && height) {
+ this.webViewWrapper_.style.width = width + 'px';
+ this.webViewWrapper_.style.height = height + 'px';
+ this.webView_.style.width = width + 'px';
+ this.webView_.style.height = height + 'px';
+ }
+ setTimeout(callback, 0);
+};
+
+/**
+ * @override
+ */
+ShareDialog.prototype.onClosed = function() {
+ this.hide();
+};
+
+/**
+ * @override
+ */
+ShareDialog.prototype.onLoaded = function() {
+ if (this.failureTimeout_) {
+ clearTimeout(this.failureTimeout_);
+ this.failureTimeout_ = null;
+ }
+
+ this.okButton_.hidden = false;
+ this.spinnerWrapper_.hidden = true;
+ this.webViewWrapper_.classList.add('loaded');
+ this.webView_.focus();
+};
+
+/**
+ * @override
+ */
+ShareDialog.prototype.onLoadFailed = function() {
+ this.hide();
+ setTimeout(this.onFailure_.bind(this),
+ cr.ui.dialogs.BaseDialog.ANIMATE_STABLE_DURATION);
+};
+
+/**
+ * @override
+ */
+ShareDialog.prototype.hide = function() {
+ if (this.shareClient_) {
+ this.shareClient_.dispose();
+ this.shareClient_ = null;
+ }
+ this.webViewWrapper_.textContent = '';
+ this.onQueueTaskFinished_();
+ this.onQueueTaskFinished_ = null;
+ if (this.failureTimeout_) {
+ clearTimeout(this.failureTimeout_);
+ this.failureTimeout_ = null;
+ }
+ cr.ui.dialogs.BaseDialog.prototype.hide.call(this);
+};
+
+/**
+ * Shows the dialog.
+ * @param {FileEntry} entry Entry to share.
+ * @param {function()} onFailure Failure callback.
+ */
+ShareDialog.prototype.show = function(entry, onFailure) {
+ this.queue_.run(function(callback) {
+ this.onQueueTaskFinished_ = callback;
+ this.onFailure_ = onFailure;
+ this.spinnerWrapper_.hidden = false;
+ this.webViewWrapper_.style.width = '';
+ this.webViewWrapper_.style.height = '';
+
+ var onError = function() {
+ onFailure();
+ this.hide();
+ }.bind(this);
+
+ // If the embedded share dialog is not started within some time, then
+ // give up and show an error message.
+ this.failureTimeout_ = setTimeout(function() {
+ onError();
+ }, ShareDialog.FAILURE_TIMEOUT);
+
+ // TODO(mtomasz): Move to initDom_() once and reuse <webview> once it gets
+ // fixed. See: crbug.com/260622.
+ this.webView_ = util.createChild(
+ this.webViewWrapper_, 'share-dialog-webview', 'webview');
+ this.webView_.setAttribute('tabIndex', '-1');
+ this.webViewAuthorizer_ = new ShareDialog.WebViewAuthorizer(
+ ShareClient.SHARE_TARGET, this.webView_);
+
+ cr.ui.dialogs.BaseDialog.prototype.show.call(this, '', null, null, null);
+
+ // Initialize and authorize the Web View tag asynchronously.
+ var group = new AsyncUtil.Group();
+ group.add(this.webViewAuthorizer_.initialize.bind(this.webViewAuthorizer_));
+ group.add(this.webViewAuthorizer_.authorize.bind(this.webViewAuthorizer_));
+
+ group.run(function() {
+ // Loads the metadata and later the share widget.
+ this.metadataCache_.get(entry, 'drive', function(metadata) {
+ if (!metadata.shareUrl) {
+ onError();
+ return;
+ }
+ var shareUrl = metadata.shareUrl + '&embedOrigin=' +
+ ShareClient.SHARE_ORIGIN;
+ this.shareClient_ = new ShareClient(this.webView_,
+ shareUrl,
+ this);
+ this.shareClient_.load();
+ }.bind(this));
+ }.bind(this));
+ }.bind(this));
+};
diff --git a/chrome/browser/resources/file_manager/js/util.js b/chrome/browser/resources/file_manager/js/util.js
index 59ce54e..c5c909d 100644
--- a/chrome/browser/resources/file_manager/js/util.js
+++ b/chrome/browser/resources/file_manager/js/util.js
@@ -456,6 +456,72 @@
};
/**
+ * Checks if an entry exists at |relativePath| in |dirEntry|.
+ * If exists, tries to deduplicate the path by inserting parenthesized number,
+ * such as " (1)", before the extension. If it still exists, tries the
+ * deduplication again by increasing the number up to 10 times.
+ * For example, suppose "file.txt" is given, "file.txt", "file (1).txt",
+ * "file (2).txt", ..., "file (9).txt" will be tried.
+ *
+ * @param {DirectoryEntry} dirEntry The target directory entry.
+ * @param {string} relativePath The path to be deduplicated.
+ * @param {function(string)} onSuccess Called with the deduplicated path on
+ * success.
+ * @param {function(string,Entry|FileError)} onError Called on error.
+ */
+util.deduplicatePath = function(dirEntry, relativePath, onSuccess, onError) {
+ // The trial is up to 10.
+ var MAX_RETRY = 10;
+
+ // Crack the path into three part. The parenthesized number (if exists) will
+ // be replaced by incremented number for retry. For example, suppose
+ // |relativePath| is "file (10).txt", the second check path will be
+ // "file (11).txt".
+ var match = /^(.*?)(?: \((\d+)\))?(\.[^.]*?)?$/.exec(relativePath);
+ var prefix = match[1];
+ var copyNumber = match[2] ? parseInt(match[2], 10) : 0;
+ var ext = match[3] ? match[3] : '';
+
+ // The path currently checking the existence.
+ var trialPath = relativePath;
+
+ var onNotResolved = function(err) {
+ // We expect to be unable to resolve the target file, since we're going
+ // to create it during the copy. However, if the resolve fails with
+ // anything other than NOT_FOUND, that's trouble.
+ if (err.code != FileError.NOT_FOUND_ERR) {
+ onError('FILESYSTEM_ERROR', err);
+ return;
+ }
+
+ // Found a path that doesn't exist.
+ onSuccess(trialPath);
+ }
+
+ // Remember the first existing entry for error.
+ var firstExistingEntry = null;
+ var numRetry = MAX_RETRY;
+
+ var onResolved = function(entry) {
+ if (!firstExistingEntry)
+ firstExistingEntry = entry;
+
+ if (--numRetry == 0) {
+ // Hit the limit of the number of retrial.
+ onError('TARGET_EXISTS', firstExistingEntry);
+ return;
+ }
+
+ ++copyNumber;
+ trialPath = prefix + ' (' + copyNumber + ')' + ext;
+ util.resolvePath(dirEntry, trialPath, onResolved, onNotResolved);
+ };
+
+ // Check to see if the target exists.
+ util.resolvePath(dirEntry, trialPath, onResolved, onNotResolved);
+};
+
+/**
* Convert a number of bytes into a human friendly format, using the correct
* number separators.
*
diff --git a/chrome/browser/resources/file_manager/js/volume_list.js b/chrome/browser/resources/file_manager/js/volume_list.js
index bb77526..a0e55f3 100644
--- a/chrome/browser/resources/file_manager/js/volume_list.js
+++ b/chrome/browser/resources/file_manager/js/volume_list.js
@@ -8,6 +8,8 @@
* A volume list model. This model combines the 2 lists.
* @param {cr.ui.ArrayDataModel} volumesList The first list of the model.
* @param {cr.ui.ArrayDataModel} pinnedList The second list of the model.
+ * @constructor
+ * @extends {cr.EventTarget}
*/
function VolumeListModel(volumesList, pinnedList) {
this.volumesList_ = volumesList;
@@ -55,28 +57,8 @@
this.volumesList_.addEventListener('change', changeHandler.bind(this, 1));
this.pinnedList_.addEventListener('change', changeHandler.bind(this, 2));
- // Generates a combined 'splice' event from an event of either list.
- var spliceHandler = function(listNum, e) {
- var spliceEvent = new Event('splice');
- spliceEvent.index =
- (listNum == 1) ? e.index : (e.index + this.volumesList_.length);
-
- // spliceEvent.removed, spliceEvent.add are not supported yet.
- spliceEvent.removed = null;
- spliceEvent.add = null;
-
- this.dispatchEvent(spliceEvent);
- };
- this.volumesList_.addEventListener('splice', spliceHandler.bind(this, 1));
- this.pinnedList_.addEventListener('splice', spliceHandler.bind(this, 2));
-
- // Generates a combined 'sorted' event from an event of either list.
- var sortedHandler = function(listNum, e) {
- var sortedEvent = new Event('sorted');
- this.dispatchEvent(sortedEvent);
- }
- this.volumesList_.addEventListener('sorted', sortedHandler.bind(this, 1));
- this.pinnedList_.addEventListener('sorted', sortedHandler.bind(this, 2));
+ // 'splice' and 'sorted' events are not implemented, since they are not used
+ // in list.js.
}
/**
diff --git a/chrome/browser/resources/file_manager/main.html b/chrome/browser/resources/file_manager/main.html
index 6392051..91ac96d 100644
--- a/chrome/browser/resources/file_manager/main.html
+++ b/chrome/browser/resources/file_manager/main.html
@@ -101,7 +101,10 @@
<script src="js/file_tasks.js"></script>
<script src="js/file_transfer_controller.js"></script>
<script src="js/file_type.js"></script>
+ <script src="js/folder_shortcuts_data_model.js"></script>
<script src="js/scrollbar.js"></script>
+ <script src="js/share_client.js"></script>
+ <script src="js/share_dialog.js"></script>
<script src="js/tree.css.js"></script>
<script src="js/volume_manager.js"></script>
<script src="js/volume_list.js"></script>
diff --git a/chrome/browser/resources/file_manager/manifest.json b/chrome/browser/resources/file_manager/manifest.json
index 32bbcf8..503bce9 100644
--- a/chrome/browser/resources/file_manager/manifest.json
+++ b/chrome/browser/resources/file_manager/manifest.json
@@ -27,6 +27,7 @@
"metricsPrivate",
"commandLinePrivate",
"unlimitedStorage",
+ "webview",
// Comment out chrome:// permissions to debug on a desktop browser.
"chrome://extension-icon/",
"chrome://resources/",
@@ -229,6 +230,6 @@
"js/background.js"]
},
// chrome-extension://pmfjbimdmchhbnneeidfognadeopoehp is the image loader extension.
- "content_security_policy": "default-src 'none'; script-src 'self' chrome://resources chrome-extension://pmfjbimdmchhbnneeidfognadeopoehp; style-src 'self' 'unsafe-inline' chrome://resources; frame-src 'self' about:; img-src 'self' chrome://resources chrome://theme data: https://docs.google.com https://*.googleusercontent.com chrome://extension-icon; media-src 'self' https://*.googleusercontent.com; connect-src https://drive.google.com"
+ "content_security_policy": "default-src 'none'; script-src 'self' chrome://resources chrome-extension://pmfjbimdmchhbnneeidfognadeopoehp; style-src 'self' 'unsafe-inline' chrome://resources; frame-src 'self' about:; img-src 'self' chrome://resources chrome://theme data: https://docs.google.com https://*.googleusercontent.com chrome://extension-icon; media-src 'self' https://*.googleusercontent.com; connect-src https://drive.google.com; object-src 'self'"
}
}
diff --git a/chrome/browser/resources/gesture_config.css b/chrome/browser/resources/gesture_config.css
index 74f6a6f..eec68a9 100644
--- a/chrome/browser/resources/gesture_config.css
+++ b/chrome/browser/resources/gesture_config.css
@@ -8,7 +8,8 @@
}
form {
- width: 700px;
+ display: table;
+ margin: 8px;
}
h2 {
@@ -17,11 +18,13 @@
}
.buttons-pane {
- width: 90%;
+ display: inline-block;
+ width: 100%;
}
#reset-all-button {
float: right;
+ min-width: 15em;
}
html[dir=rtl] #reset-all-button {
diff --git a/chrome/browser/resources/gesture_config.html b/chrome/browser/resources/gesture_config.html
index 34a7215..c478bb0 100644
--- a/chrome/browser/resources/gesture_config.html
+++ b/chrome/browser/resources/gesture_config.html
@@ -10,10 +10,10 @@
</head>
<body>
<form>
- <div id="gesture-form"></div>
<div class="buttons-pane">
<button id="reset-all-button">Reset All</button>
</div>
+ <div id="gesture-form"></div>
</form>
<div id="section-template">
<h2 class="section-title"></h2>
diff --git a/chrome/browser/resources/gesture_config.js b/chrome/browser/resources/gesture_config.js
index 062cdca..e38baa9 100644
--- a/chrome/browser/resources/gesture_config.js
+++ b/chrome/browser/resources/gesture_config.js
@@ -85,6 +85,7 @@
$(field.key).onchange = (function(key) {
config.setPreferenceValue(key, $(key).value);
gesture_config.updateResetButton($(key + '-reset'), false);
+ gesture_config.updateResetAllButton(false);
}).bind(null, field.key);
$(field.key + '-reset').onclick = (function(key) {
config.resetPreferenceValue(key);
@@ -532,12 +533,26 @@
};
},
-/**
- * Updates the status and label of a preference reset button.
- * @param {HTMLInputElement} resetButton Reset button for the preference.
- * @param {boolean} isDefault Whether the preference is set to the default
- * value.
- */
+ /**
+ * Checks if all gesture preferences are set to default by checking the status
+ * of the reset button associated with each preference.
+ * @return {boolean} True if all gesture preferences are set to default.
+ */
+ areAllPrefsSetToDefault: function() {
+ var resets = $('gesture-form').querySelectorAll('.row-reset');
+ for (var i = 0; i < resets.length; i++) {
+ if (!resets[i].disabled)
+ return false;
+ }
+ return true;
+ },
+
+ /**
+ * Updates the status and label of a preference reset button.
+ * @param {HTMLInputElement} resetButton Reset button for the preference.
+ * @param {boolean} isDefault Whether the preference is set to the default
+ * value.
+ */
updateResetButton: function(resetButton, isDefault) {
/** @const */ var TITLE_DEFAULT = 'Default';
@@ -548,6 +563,21 @@
},
/**
+ * Updates the status and label of "Reset All" button.
+ * @param {boolean} isDefault Whether all preference are set to their default
+ * values.
+ */
+ updateResetAllButton: function(isDefault) {
+ /** @const */ var TITLE_DEFAULT = 'Everything is set to default';
+
+ /** @const */ var TITLE_NOT_DEFAULT = 'Reset All To Default';
+
+ var button = $('reset-all-button');
+ button.innerHTML = isDefault ? TITLE_DEFAULT : TITLE_NOT_DEFAULT;
+ button.disabled = isDefault;
+ },
+
+ /**
* Handle callback from call to updatePreferenceValue.
* @param {string} prefName The name of the requested preference value.
* @param {value} value The current value associated with prefName.
@@ -557,6 +587,7 @@
prefName = prefName.substring(prefName.indexOf('.') + 1);
$(prefName).value = value;
this.updateResetButton($(prefName + '-reset'), isDefault);
+ this.updateResetAllButton(this.areAllPrefsSetToDefault());
},
};
diff --git a/chrome/browser/resources/google_now/background.js b/chrome/browser/resources/google_now/background.js
index e651a18..534ff65 100644
--- a/chrome/browser/resources/google_now/background.js
+++ b/chrome/browser/resources/google_now/background.js
@@ -32,8 +32,10 @@
*/
var HTTP_OK = 200;
+var HTTP_BAD_REQUEST = 400;
var HTTP_UNAUTHORIZED = 401;
var HTTP_FORBIDDEN = 403;
+var HTTP_METHOD_NOT_ALLOWED = 405;
/**
* Initial period for polling for Google Now Notifications cards to use when the
@@ -58,6 +60,11 @@
var MAXIMUM_RETRY_DISMISS_PERIOD_SECONDS = 60 * 60; // 1 hour
/**
+ * Time we keep retrying dismissals.
+ */
+var MAXIMUM_DISMISSAL_AGE_MS = 24 * 60 * 60 * 1000; // 1 day
+
+/**
* Time we keep dismissals after successful server dismiss requests.
*/
var DISMISS_RETENTION_TIME_MS = 20 * 60 * 1000; // 20 minutes
@@ -274,7 +281,8 @@
notificationsData[card.notificationId] = {
actionUrls: card.actionUrls,
- version: card.version
+ version: card.version,
+ dismissalParameters: card.dismissal
};
}
@@ -405,7 +413,8 @@
',' + position.coords.longitude +
',' + position.coords.accuracy;
- var request = buildServerRequest('notifications');
+ var request = buildServerRequest('notifications',
+ 'application/x-www-form-urlencoded');
request.onloadend = function(event) {
console.log('requestNotificationCards-onloadend ' + request.status);
@@ -466,30 +475,47 @@
* @param {string} notificationId Unique identifier of the card.
* @param {number} dismissalTimeMs Time of the user's dismissal of the card in
* milliseconds since epoch.
- * @param {function(boolean)} callbackBoolean Completion callback with 'success'
+ * @param {Object} dismissalParameters Dismissal parameters.
+ * @param {function(boolean)} callbackBoolean Completion callback with 'done'
* parameter.
*/
function requestCardDismissal(
- notificationId, dismissalTimeMs, callbackBoolean) {
+ notificationId, dismissalTimeMs, dismissalParameters, callbackBoolean) {
console.log('requestDismissingCard ' + notificationId + ' from ' +
NOTIFICATION_CARDS_URL);
+
+ var dismissalAge = Date.now() - dismissalTimeMs;
+
+ if (dismissalAge > MAXIMUM_DISMISSAL_AGE_MS) {
+ callbackBoolean(true);
+ return;
+ }
+
recordEvent(DiagnosticEvent.DISMISS_REQUEST_TOTAL);
- // Send a dismiss request to the server.
- var requestParameters = 'id=' + notificationId +
- '&dismissalAge=' + (Date.now() - dismissalTimeMs);
- var request = buildServerRequest('dismiss');
+ var request = buildServerRequest('dismiss', 'application/json');
request.onloadend = function(event) {
console.log('requestDismissingCard-onloadend ' + request.status);
if (request.status == HTTP_OK)
recordEvent(DiagnosticEvent.DISMISS_REQUEST_SUCCESS);
- callbackBoolean(request.status == HTTP_OK);
+ // A dismissal doesn't require further retries if it was successful or
+ // doesn't have a chance for successful completion.
+ var done = request.status == HTTP_OK ||
+ request.status == HTTP_BAD_REQUEST ||
+ request.status == HTTP_METHOD_NOT_ALLOWED;
+ callbackBoolean(done);
};
setAuthorization(request, function(success) {
if (success) {
tasks.debugSetStepName('requestCardDismissal-send-request');
- request.send(requestParameters);
+
+ var dismissalObject = {
+ id: notificationId,
+ age: dismissalAge,
+ dismissal: dismissalParameters
+ };
+ request.send(JSON.stringify(dismissalObject));
} else {
callbackBoolean(false);
}
@@ -532,16 +558,19 @@
// recursively with the rest.
var dismissal = items.pendingDismissals[0];
requestCardDismissal(
- dismissal.notificationId, dismissal.time, function(success) {
- if (success) {
- dismissalsChanged = true;
- items.pendingDismissals.splice(0, 1);
- items.recentDismissals[dismissal.notificationId] = Date.now();
- doProcessDismissals();
- } else {
- onFinish(false);
- }
- });
+ dismissal.notificationId,
+ dismissal.time,
+ dismissal.parameters,
+ function(done) {
+ if (done) {
+ dismissalsChanged = true;
+ items.pendingDismissals.splice(0, 1);
+ items.recentDismissals[dismissal.notificationId] = Date.now();
+ doProcessDismissals();
+ } else {
+ onFinish(false);
+ }
+ });
}
doProcessDismissals();
@@ -645,13 +674,17 @@
notificationId,
function() {});
- tasks.debugSetStepName('onNotificationClosed-get-pendingDismissals');
- storage.get('pendingDismissals', function(items) {
+ tasks.debugSetStepName('onNotificationClosed-storage-get');
+ storage.get(['pendingDismissals', 'notificationsData'], function(items) {
items.pendingDismissals = items.pendingDismissals || [];
+ items.notificationsData = items.notificationsData || {};
+
+ var notificationData = items.notificationsData[notificationId];
var dismissal = {
notificationId: notificationId,
- time: Date.now()
+ time: Date.now(),
+ parameters: notificationData && notificationData.dismissalParameters
};
items.pendingDismissals.push(dismissal);
storage.set({pendingDismissals: items.pendingDismissals});
diff --git a/chrome/browser/resources/google_now/utility.js b/chrome/browser/resources/google_now/utility.js
index 9405bde..eb8f5cc 100644
--- a/chrome/browser/resources/google_now/utility.js
+++ b/chrome/browser/resources/google_now/utility.js
@@ -32,14 +32,15 @@
/**
* Builds a request to the notification server.
* @param {string} handlerName Server handler to send the request to.
+ * @param {string} contentType Value for the Content-type header.
* @return {XMLHttpRequest} Server request.
*/
-function buildServerRequest(handlerName) {
+function buildServerRequest(handlerName, contentType) {
var request = new XMLHttpRequest();
request.responseType = 'text';
request.open('POST', NOTIFICATION_CARDS_URL + '/' + handlerName, true);
- request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
+ request.setRequestHeader('Content-type', contentType);
return request;
}
@@ -177,7 +178,8 @@
'&script=' + encodeURIComponent(file) +
'&line=' + encodeURIComponent(line) +
'&trace=' + encodeURIComponent(filteredStack);
- var request = buildServerRequest('jserror');
+ var request = buildServerRequest('jserror',
+ 'application/x-www-form-urlencoded');
request.onloadend = function(event) {
console.log('sendErrorReport status: ' + request.status);
};
diff --git a/chrome/browser/resources/history/history.js b/chrome/browser/resources/history/history.js
index 3408a74..d5a8ef8 100644
--- a/chrome/browser/resources/history/history.js
+++ b/chrome/browser/resources/history/history.js
@@ -162,6 +162,7 @@
// Clicking anywhere in the entryBox will check/uncheck the checkbox.
entryBox.setAttribute('for', checkbox.id);
entryBox.addEventListener('mousedown', entryBoxMousedown);
+ entryBox.addEventListener('click', entryBoxClick);
}
// Keep track of the drop down that triggered the menu, so we know
@@ -489,17 +490,17 @@
* @param {Array} results A list of results.
*/
HistoryModel.prototype.addResults = function(info, results) {
+ // If no requests are in flight then this was an old request so we drop the
+ // results. Double check the search term as well.
+ if (!this.inFlight_ || info.term != this.searchText_)
+ return;
+
$('loading-spinner').hidden = true;
this.inFlight_ = false;
this.isQueryFinished_ = info.finished;
this.queryStartTime = info.queryStartTime;
this.queryEndTime = info.queryEndTime;
- // If the results are not for the current search term then there is nothing
- // more to do.
- if (info.term != this.searchText_)
- return;
-
var lastVisit = this.visits_.slice(-1)[0];
var lastDay = lastVisit ? lastVisit.dateRelativeDay : null;
@@ -1693,11 +1694,20 @@
* @param {Event} e The click event.
*/
function checkboxClicked(e) {
- var checkbox = e.currentTarget;
+ handleCheckboxStateChange(e.currentTarget, e.shiftKey);
+}
+
+/**
+ * Post-process of checkbox state change. This handles range selection and
+ * updates internal state.
+ * @param {!HTMLInputElement} checkbox Clicked checkbox.
+ * @param {boolean} shiftKey true if shift key is pressed.
+ */
+function handleCheckboxStateChange(checkbox, shiftKey) {
updateParentCheckbox(checkbox);
var id = Number(checkbox.id.slice('checkbox-'.length));
// Handle multi-select if shift was pressed.
- if (event.shiftKey && (selectionAnchor != -1)) {
+ if (shiftKey && (selectionAnchor != -1)) {
var checked = checkbox.checked;
// Set all checkboxes from the anchor up to the clicked checkbox to the
// state of the clicked one.
@@ -1753,9 +1763,23 @@
function entryBoxMousedown(event) {
// Prevent text selection when shift-clicking to select multiple entries.
- if (event.shiftKey) {
+ if (event.shiftKey)
event.preventDefault();
- }
+}
+
+/**
+ * Handle click event for entryBox labels.
+ * @param {!MouseEvent} event A click event.
+ */
+function entryBoxClick(event) {
+ var tagName = event.target.tagName;
+ if (tagName == 'BUTTON' || tagName == 'INPUT' || tagName == 'A')
+ return;
+ var checkbox = event.currentTarget.control;
+ checkbox.checked = !checkbox.checked;
+ handleCheckboxStateChange(checkbox, event.shiftKey);
+ // We don't want to focus on the checkbox.
+ event.preventDefault();
}
// This is pulled out so we can wait for it in tests.
@@ -1763,12 +1787,20 @@
node.parentNode.removeChild(node);
}
-function removeNode(node) {
+/**
+ * Triggers a fade-out animation, and then removes |node| from the DOM.
+ * @param {Node} node The node to be removed.
+ * @param {Function?} onRemove A function to be called after the node
+ * has been removed from the DOM.
+ */
+function removeNode(node, onRemove) {
node.classList.add('fade-out'); // Trigger CSS fade out animation.
// Delete the node when the animation is complete.
node.addEventListener('webkitTransitionEnd', function() {
removeNodeWithoutTransition(node);
+ if (onRemove)
+ onRemove();
});
}
@@ -1781,17 +1813,17 @@
var nextEntry = entry.nextSibling;
var previousEntry = entry.previousSibling;
- removeNode(entry);
+ removeNode(entry, function() {
+ historyView.updateSelectionEditButtons();
+ });
// if there is no previous entry, and the next entry is a gap, remove it
- if (!previousEntry && nextEntry && nextEntry.className == 'gap') {
+ if (!previousEntry && nextEntry && nextEntry.className == 'gap')
removeNode(nextEntry);
- }
// if there is no next entry, and the previous entry is a gap, remove it
- if (!nextEntry && previousEntry && previousEntry.className == 'gap') {
+ if (!nextEntry && previousEntry && previousEntry.className == 'gap')
removeNode(previousEntry);
- }
// if both the next and previous entries are gaps, remove one
if (nextEntry && nextEntry.className == 'gap' &&
diff --git a/chrome/browser/resources/inspect/inspect.css b/chrome/browser/resources/inspect/inspect.css
index e6bcfd0..1d5bc7d 100644
--- a/chrome/browser/resources/inspect/inspect.css
+++ b/chrome/browser/resources/inspect/inspect.css
@@ -7,34 +7,87 @@
body {
color: rgb(48, 57, 66);
font-family: Arial, sans-serif;
- font-size: 12px;
- margin: 20px;
+ font-size: 13px;
+ margin: 0;
min-width: 47em;
- padding-bottom: 65px;
+ padding: 20px 20px 65px 0;
}
img {
float: left;
height: 16px;
+ padding-left: 2px;
padding-right: 5px;
width: 16px;
}
-.section {
+#container {
+ -webkit-flex-direction: row;
+ display: -webkit-flex;
+}
+
+#navigation {
+ width: 150px;
+}
+
+#content {
+ -webkit-flex: 1;
+}
+
+#caption {
+ color: rgb(92, 97, 102);
+ font-size: 150%;
+ padding-bottom: 10px;
+ padding-left: 20px;
+}
+
+.tab-header {
+ -webkit-border-start: 6px solid transparent;
+ padding-left: 15px;
+}
+
+.tab-header.selected {
+ -webkit-border-start-color: rgb(78, 87, 100);
+}
+
+.tab-header > button {
+ background-color: white;
+ border: 0;
+ cursor: pointer;
+ font: inherit;
+ line-height: 17px;
+ margin: 6px 0;
+ padding: 0 2px;
+}
+
+.tab-header:not(.selected) > button {
+ color: #999;
+}
+
+#content > div:not(.selected) {
+ display: none;
+}
+
+.content-header {
border-bottom: 1px solid #eee;
- font-size: 1.5em;
+ font-size: 150%;
+ padding-bottom: 4px;
+}
+
+.section {
+ font-size: 150%;
margin: 10px 0 0;
- padding: 2px 2px;
+ padding: 2px 0;
}
.small-section {
font-weight: bold;
margin: 5px 0 0;
- padding: 2px 2px;
+ padding: 2px 0;
}
.row {
- padding: 5px;
+ padding: 5px 0;
}
.url {
diff --git a/chrome/browser/resources/inspect/inspect.html b/chrome/browser/resources/inspect/inspect.html
index 835aff9..389a7a3 100644
--- a/chrome/browser/resources/inspect/inspect.html
+++ b/chrome/browser/resources/inspect/inspect.html
@@ -16,24 +16,32 @@
<body>
-<div id="top">
- <div class="section-header">
+<div id="container">
+ <div id="navigation">
+ <div id="caption">DevTools</div>
+ </div>
+ <div id="content">
+ <div id="devices-tab">
+ <div class="content-header">Devices</div>
+ <div id="devices"></div>
+ </div>
+ <div id="pages-tab">
+ <div class="content-header">Pages</div>
+ <div id="pages" class="list"></div>
+ </div>
+ <div id="extensions-tab">
+ <div class="content-header">Extensions</div>
+ <div id="extensions" class="list"></div>
+ </div>
+ <div id="workers-tab">
+ <div class="content-header">Shared workers</div>
+ <div id="workers" class="list"></div>
+ </div>
+ <div id="other-tab">
+ <div class="content-header">Other</div>
+ <div id="others" class="list"></div>
+ </div>
</div>
</div>
-
-<div id="devices"></div>
-
-<div class="section">Pages</div>
-<div id="pages" class="list"></div>
-
-<div class="section">Extensions</div>
-<div id="extensions" class="list"></div>
-
-<div class="section">Shared workers</div>
-<div id="workers" class="list"></div>
-
-<div class="section">Other</div>
-<div id="others" class="list"></div>
-
</body>
</html>
diff --git a/chrome/browser/resources/inspect/inspect.js b/chrome/browser/resources/inspect/inspect.js
index 3344e14..819272b 100644
--- a/chrome/browser/resources/inspect/inspect.js
+++ b/chrome/browser/resources/inspect/inspect.js
@@ -25,9 +25,39 @@
}
function onload() {
+ var tabContents = document.querySelectorAll('#content > div');
+ for (var i = 0; i != tabContents.length; i++) {
+ var tabContent = tabContents[i];
+ var tabName = tabContent.querySelector('.content-header').textContent;
+
+ var tabHeader = document.createElement('div');
+ tabHeader.className = 'tab-header';
+ var button = document.createElement('button');
+ button.textContent = tabName;
+ tabHeader.appendChild(button);
+ tabHeader.addEventListener('click', selectTab.bind(null, tabContent.id));
+ $('navigation').appendChild(tabHeader);
+ }
+ selectTab('devices-tab');
populateLists();
}
+function selectTab(id) {
+ var tabContents = document.querySelectorAll('#content > div');
+ var tabHeaders = $('navigation').querySelectorAll('.tab-header');
+ for (var i = 0; i != tabContents.length; i++) {
+ var tabContent = tabContents[i];
+ var tabHeader = tabHeaders[i];
+ if (tabContent.id == id) {
+ tabContent.classList.add('selected');
+ tabHeader.classList.add('selected');
+ } else {
+ tabContent.classList.remove('selected');
+ tabHeader.classList.remove('selected');
+ }
+ }
+}
+
function populateLists() {
var data = requestData();
diff --git a/chrome/browser/resources/local_omnibox_popup/images/2x/history_icon.png b/chrome/browser/resources/local_omnibox_popup/images/2x/history_icon.png
deleted file mode 100644
index ec5e4ba..0000000
--- a/chrome/browser/resources/local_omnibox_popup/images/2x/history_icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/browser/resources/local_omnibox_popup/images/2x/page_icon.png b/chrome/browser/resources/local_omnibox_popup/images/2x/page_icon.png
deleted file mode 100644
index a7cf3cc..0000000
--- a/chrome/browser/resources/local_omnibox_popup/images/2x/page_icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/browser/resources/local_omnibox_popup/images/2x/search_icon.png b/chrome/browser/resources/local_omnibox_popup/images/2x/search_icon.png
deleted file mode 100644
index ac74fd7..0000000
--- a/chrome/browser/resources/local_omnibox_popup/images/2x/search_icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/browser/resources/local_omnibox_popup/images/history_icon.png b/chrome/browser/resources/local_omnibox_popup/images/history_icon.png
deleted file mode 100644
index 6e7f731..0000000
--- a/chrome/browser/resources/local_omnibox_popup/images/history_icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/browser/resources/local_omnibox_popup/images/page_icon.png b/chrome/browser/resources/local_omnibox_popup/images/page_icon.png
deleted file mode 100644
index b782547..0000000
--- a/chrome/browser/resources/local_omnibox_popup/images/page_icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/browser/resources/local_omnibox_popup/images/search_icon.png b/chrome/browser/resources/local_omnibox_popup/images/search_icon.png
deleted file mode 100644
index ed89c7b..0000000
--- a/chrome/browser/resources/local_omnibox_popup/images/search_icon.png
+++ /dev/null
Binary files differ
diff --git a/chrome/browser/resources/ntp_android/ntp_android.js b/chrome/browser/resources/ntp_android/ntp_android.js
index e276677..9ec3a10 100644
--- a/chrome/browser/resources/ntp_android/ntp_android.js
+++ b/chrome/browser/resources/ntp_android/ntp_android.js
@@ -535,6 +535,7 @@
* reopen a tab.
*/
function openRecentlyClosedTab(item, evt) {
+ chrome.send('openedRecentlyClosed');
chrome.send('reopenTab', [item.sessionId]);
}
@@ -946,7 +947,7 @@
return;
var clickFunction = function(item) {
- chrome.send('metricsHandler:recordAction', ['MobileNTPMostVisited']);
+ chrome.send('openedMostVisited');
window.location = item.url;
};
populateData(findList('most_visited'), SectionType.MOST_VISITED, data,
@@ -1018,7 +1019,7 @@
if (item['folder']) {
browseToBookmarkFolder(item.id);
} else if (!!item.url) {
- chrome.send('metricsHandler:recordAction', ['MobileNTPBookmark']);
+ chrome.send('openedBookmark');
window.location = item.url;
}
};
@@ -1195,6 +1196,25 @@
* when chrome.send('showContextMenu') was called.
*/
function onCustomMenuSelected(itemId) {
+ if (contextMenuUrl != null) {
+ switch (itemId) {
+ case ContextMenuItemIds.BOOKMARK_OPEN_IN_NEW_TAB:
+ case ContextMenuItemIds.BOOKMARK_OPEN_IN_INCOGNITO_TAB:
+ chrome.send('openedBookmark');
+ break;
+
+ case ContextMenuItemIds.MOST_VISITED_OPEN_IN_NEW_TAB:
+ case ContextMenuItemIds.MOST_VISITED_OPEN_IN_INCOGNITO_TAB:
+ chrome.send('openedMostVisited');
+ break;
+
+ case ContextMenuItemIds.RECENTLY_CLOSED_OPEN_IN_NEW_TAB:
+ case ContextMenuItemIds.RECENTLY_CLOSED_OPEN_IN_INCOGNITO_TAB:
+ chrome.send('openedRecentlyClosed');
+ break;
+ }
+ }
+
switch (itemId) {
case ContextMenuItemIds.BOOKMARK_OPEN_IN_NEW_TAB:
case ContextMenuItemIds.MOST_VISITED_OPEN_IN_NEW_TAB:
@@ -1835,7 +1855,7 @@
metaKeyPressed = evt.metaKey;
shiftKeyPressed = evt.shiftKey;
}
- chrome.send('metricsHandler:recordAction', ['MobileNTPForeignSession']);
+ chrome.send('openedForeignSession');
chrome.send('openForeignSession', [String(item.sessionTag),
String(item.winNum), String(item.sessionId), buttonIndex,
altKeyPressed, ctrlKeyPressed, metaKeyPressed, shiftKeyPressed]);
diff --git a/chrome/browser/resources/omnibox/omnibox.js b/chrome/browser/resources/omnibox/omnibox.js
index fd327fa..8292cf7 100644
--- a/chrome/browser/resources/omnibox/omnibox.js
+++ b/chrome/browser/resources/omnibox/omnibox.js
@@ -126,8 +126,9 @@
new PresentationInfoRecord('Fill Into Edit', '', 'fill_into_edit', false,
'The text shown in the omnibox when the result is selected.'),
new PresentationInfoRecord(
- 'IAO', '', 'inline_autocomplete_offset', false,
- 'The Inline Autocomplete Offset.'),
+ 'Inline Autocompletion', '', 'inline_autocompletion', false,
+ 'The text shown in the omnibox as a blue highlight selection ' +
+ 'following the cursor, if this match is shown inline.'),
new PresentationInfoRecord('Del', '', 'deletable', false,
'A green checkmark indicates that the results can be deleted from ' +
'the visit history.'),
diff --git a/chrome/browser/resources/options/browser_options.js b/chrome/browser/resources/options/browser_options.js
index ca5e832..f221e88 100644
--- a/chrome/browser/resources/options/browser_options.js
+++ b/chrome/browser/resources/options/browser_options.js
@@ -29,13 +29,6 @@
signedIn_: false,
/**
- * Keeps track of whether the user has completed sync setup or not.
- * @type {boolean}
- * @private
- */
- setupCompleted_: false,
-
- /**
* Keeps track of whether |onShowHomeButtonChanged_| has been called. See
* |onShowHomeButtonChanged_|.
* @type {boolean}
@@ -722,16 +715,15 @@
$('sync-status').hidden = true;
return;
}
- // If the user gets signed out or if sync gets disabled while the advanced
- // sync settings dialog is visible, say, due to a dashboard clear, close
- // the dialog.
- if ((this.signedIn_ && !syncData.signedIn) ||
- (this.setupCompleted_ && !syncData.setupCompleted)) {
+
+ // If the user gets signed out while the advanced sync settings dialog is
+ // visible, say, due to a dashboard clear, close the dialog.
+ // Note: SyncSetupOverlay.closeOverlay is a no-op if the overlay is
+ // already hidden.
+ if (this.signedIn_ && !syncData.signedIn)
SyncSetupOverlay.closeOverlay();
- }
this.signedIn_ = syncData.signedIn;
- this.setupCompleted_ = syncData.setupCompleted;
// Display the "advanced settings" button if we're signed in and sync is
// not managed/disabled. If the user is signed in, but sync is disabled,
diff --git a/chrome/browser/resources/options/deletable_item_list.js b/chrome/browser/resources/options/deletable_item_list.js
index 9908f0d..403dc0f 100644
--- a/chrome/browser/resources/options/deletable_item_list.js
+++ b/chrome/browser/resources/options/deletable_item_list.js
@@ -98,13 +98,16 @@
/**
* Don't let the list have a crack at the event. We don't want clicking the
- * close button to change the selection of the list.
+ * close button to change the selection of the list or to focus on the close
+ * button.
* @param {Event} e The mouse down/up event object.
* @private
*/
handleMouseDownUpOnClose_: function(e) {
- if (!e.target.disabled)
- e.stopPropagation();
+ if (e.target.disabled)
+ return;
+ e.stopPropagation();
+ e.preventDefault();
},
};
diff --git a/chrome/browser/resources/options/import_data_overlay.js b/chrome/browser/resources/options/import_data_overlay.js
index 9800340..ba7949c 100644
--- a/chrome/browser/resources/options/import_data_overlay.js
+++ b/chrome/browser/resources/options/import_data_overlay.js
@@ -236,6 +236,7 @@
// Make sure that any previous import success message is hidden, and
// we're showing the UI to import further data.
ImportDataOverlay.getInstance().updateSuccessState_(false);
+ ImportDataOverlay.getInstance().validateCommitButton_();
OptionsPage.navigateToPage('importData');
};
diff --git a/chrome/browser/resources/options/inline_editable_list.js b/chrome/browser/resources/options/inline_editable_list.js
index 3b84302..55a38b7 100644
--- a/chrome/browser/resources/options/inline_editable_list.js
+++ b/chrome/browser/resources/options/inline_editable_list.js
@@ -95,8 +95,10 @@
* Updates the edit state based on the current selected and lead states.
*/
updateEditState: function() {
- if (this.editable)
- this.editing = this.selected && this.lead;
+ if (this.editable) {
+ this.editing = this.selected && this.lead &&
+ !this.isExtraFocusableControl(document.activeElement);
+ }
},
/**
@@ -110,9 +112,6 @@
if (this.editing == editing)
return;
- if (this.isExtraFocusableControl(document.activeElement))
- editing = false;
-
if (editing)
this.setAttribute('editing', '');
else
@@ -343,6 +342,11 @@
return;
var clickTarget = e.target;
+ if (this.isExtraFocusableControl(clickTarget)) {
+ clickTarget.focus();
+ return;
+ }
+
var editFields = this.editFields_;
for (var i = 0; i < editFields.length; i++) {
if (editFields[i] == clickTarget ||
diff --git a/chrome/browser/resources/print_preview/native_layer.js b/chrome/browser/resources/print_preview/native_layer.js
index 469c362..bda89a7 100644
--- a/chrome/browser/resources/print_preview/native_layer.js
+++ b/chrome/browser/resources/print_preview/native_layer.js
@@ -345,7 +345,7 @@
numberFormatSymbols[1] || '.',
unitType,
initialSettings['previewModifiable'] || false,
- initialSettings['initiatorTabTitle'] || '',
+ initialSettings['initiatorTitle'] || '',
initialSettings['documentHasSelection'] || false,
initialSettings['shouldPrintSelectionOnly'] || false,
initialSettings['printerName'] || null,
@@ -417,7 +417,7 @@
/**
* Called from the C++ layer.
* Take the PDF data handed to us and submit it to the cloud, closing the
- * print preview tab once the upload is successful.
+ * print preview dialog once the upload is successful.
* @param {string} data Data to send as the print job.
* @private
*/
@@ -430,7 +430,7 @@
/**
* Called from PrintPreviewUI::OnFileSelectionCancelled to notify the print
- * preview tab regarding the file selection cancel event.
+ * preview dialog regarding the file selection cancel event.
* @private
*/
onFileSelectionCancelled_: function() {
@@ -439,12 +439,12 @@
/**
* Called from PrintPreviewUI::OnFileSelectionCompleted to notify the print
- * preview tab regarding the file selection completed event.
+ * preview dialog regarding the file selection completed event.
* @private
*/
onFileSelectionCompleted_: function() {
- // If the file selection is completed and the tab is not already closed it
- // means that a pending print to pdf request exists.
+ // If the file selection is completed and the dialog is not already closed
+ // it means that a pending print to pdf request exists.
cr.dispatchSimpleEvent(
this, NativeLayer.EventType.FILE_SELECTION_COMPLETE);
},
diff --git a/chrome/browser/resources/quick_office/manifest.json b/chrome/browser/resources/quick_office/manifest.json
index e2bb7f6..ce80073 100644
--- a/chrome/browser/resources/quick_office/manifest.json
+++ b/chrome/browser/resources/quick_office/manifest.json
@@ -73,7 +73,7 @@
"sub_package_path": "_platform_specific/arm/"
}
],
- "version": "2.9.2.35",
+ "version": "2.9.3.9",
"web_accessible_resources": [
"views/qowt.html"]
}
diff --git a/chrome/browser/resources/quick_office/manifest_experimental.json b/chrome/browser/resources/quick_office/manifest_experimental.json
index d6de353..c8cd2f7 100644
--- a/chrome/browser/resources/quick_office/manifest_experimental.json
+++ b/chrome/browser/resources/quick_office/manifest_experimental.json
@@ -74,7 +74,7 @@
"sub_package_path": "_platform_specific/arm/"
}
],
- "version": "2.9.2.35",
+ "version": "2.9.3.9",
"web_accessible_resources": [
"views/qowt.html"]
}
diff --git a/chrome/browser/resources/user_chooser/control_bar.css b/chrome/browser/resources/user_chooser/control_bar.css
new file mode 100644
index 0000000..3eadc52
--- /dev/null
+++ b/chrome/browser/resources/user_chooser/control_bar.css
@@ -0,0 +1,51 @@
+/* Copyright 2013 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.
+ */
+
+/* Overrides of styles in chrome/browser/resources/chromeos/login/header_bar.js
+* that are needed by the desktop user chooser screen
+*/
+#login-header-bar {
+ -webkit-padding-after: 7px;
+ bottom: 0;
+ left: 0;
+ position: absolute;
+ right: 0;
+}
+
+#login-header-bar {
+ -webkit-padding-before: 7px;
+}
+
+.header-bar-item:first-child {
+ -webkit-padding-start: 15px;
+}
+
+.header-bar-item {
+ display: inline-block;
+ height: 34px;
+}
+
+html[dir=rtl] .header-bar-item {
+ background-position: right center;
+}
+
+html[dir=rtl] #login-header-bar button {
+ background-position: right center;
+}
+
+#login-header-bar #add-user-button {
+ background-image: url('chrome://theme/IDR_ICON_ADD_USER_WHITE');
+}
+
+#login-header-bar #guest-user-button {
+ background-image: url('chrome://theme/IDR_ICON_GUEST_WHITE');
+}
+
+#login-header-bar button {
+ -webkit-padding-start: 24px;
+ background-position: left center;
+ background-repeat: no-repeat;
+ background-size: 24px;
+}
diff --git a/chrome/browser/resources/user_chooser/control_bar.html b/chrome/browser/resources/user_chooser/control_bar.html
new file mode 100644
index 0000000..2d44ee8
--- /dev/null
+++ b/chrome/browser/resources/user_chooser/control_bar.html
@@ -0,0 +1,9 @@
+<div id="login-header-bar" class="login-header-bar">
+ <div id="add-user-header-bar-item" class="header-bar-item">
+ <button id="add-user-button" i18n-content="addUser"></button>
+ <button id="cancel-add-user-button" i18n-content="cancel" hidden></button>
+ </div>
+ <div id="guest-user-header-bar-item" class="header-bar-item">
+ <button id="guest-user-button" i18n-content="browseAsGuest"></button>
+ </div>
+</div>
diff --git a/chrome/browser/resources/user_chooser/control_bar.js b/chrome/browser/resources/user_chooser/control_bar.js
new file mode 100644
index 0000000..2fe4ac4
--- /dev/null
+++ b/chrome/browser/resources/user_chooser/control_bar.js
@@ -0,0 +1,183 @@
+// Copyright 2013 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.
+
+/**
+ * @fileoverview Desktop User Chooser UI control bar implementation.
+ */
+
+cr.define('login', function() {
+ /**
+ * Creates a header bar element.
+ * @constructor
+ * @extends {HTMLDivElement}
+ */
+ var HeaderBar = cr.ui.define('div');
+
+ HeaderBar.prototype = {
+ __proto__: HTMLDivElement.prototype,
+
+ // Whether guest button should be shown when header bar is in normal mode.
+ showGuest_: true,
+
+ // Current UI state of the sign-in screen.
+ signinUIState_: SIGNIN_UI_STATE.ACCOUNT_PICKER,
+
+ // Whether to show kiosk apps menu.
+ hasApps_: false,
+
+ /** @override */
+ decorate: function() {
+ $('add-user-button').addEventListener('click',
+ this.handleAddUserClick_);
+ $('cancel-add-user-button').addEventListener('click',
+ this.handleCancelAddUserClick_);
+ $('guest-user-header-bar-item').addEventListener('click',
+ this.handleGuestClick_);
+ $('guest-user-button').addEventListener('click',
+ this.handleGuestClick_);
+ this.updateUI_();
+ },
+
+ /**
+ * Tab index value for all button elements.
+ * @type {number}
+ */
+ set buttonsTabIndex(tabIndex) {
+ var buttons = this.getElementsByTagName('button');
+ for (var i = 0, button; button = buttons[i]; ++i) {
+ button.tabIndex = tabIndex;
+ }
+ },
+
+ /**
+ * Disables the header bar and all of its elements.
+ * @type {boolean}
+ */
+ set disabled(value) {
+ var buttons = this.getElementsByTagName('button');
+ for (var i = 0, button; button = buttons[i]; ++i)
+ if (!button.classList.contains('button-restricted'))
+ button.disabled = value;
+ },
+
+ /**
+ * Add user button click handler.
+ * @private
+ */
+ handleAddUserClick_: function(e) {
+ chrome.send('addUser');
+ // Prevent further propagation of click event. Otherwise, the click event
+ // handler of document object will set wallpaper to user's wallpaper when
+ // there is only one existing user. See http://crbug.com/166477
+ e.stopPropagation();
+ },
+
+ /**
+ * Cancel add user button click handler.
+ * @private
+ */
+ handleCancelAddUserClick_: function(e) {
+ // Let screen handle cancel itself if that is capable of doing so.
+ if (Oobe.getInstance().currentScreen &&
+ Oobe.getInstance().currentScreen.cancel) {
+ Oobe.getInstance().currentScreen.cancel();
+ return;
+ }
+
+ Oobe.showScreen({id: SCREEN_ACCOUNT_PICKER});
+ Oobe.resetSigninUI(true);
+ },
+
+ /**
+ * Guest button click handler.
+ * @private
+ */
+ handleGuestClick_: function(e) {
+ chrome.send('launchGuest');
+ e.stopPropagation();
+ },
+
+ /**
+ * If true then "Browse as Guest" button is shown.
+ * @type {boolean}
+ */
+ set showGuestButton(value) {
+ this.showGuest_ = value;
+ this.updateUI_();
+ },
+
+ /**
+ * Update current header bar UI.
+ * @type {number} state Current state of the sign-in screen
+ * (see SIGNIN_UI_STATE).
+ */
+ set signinUIState(state) {
+ this.signinUIState_ = state;
+ this.updateUI_();
+ },
+
+ /**
+ * Whether the Cancel button is enabled during Gaia sign-in.
+ * @type {boolean}
+ */
+ set allowCancel(value) {
+ this.allowCancel_ = value;
+ this.updateUI_();
+ },
+
+ /**
+ * Updates visibility state of action buttons.
+ * @private
+ */
+ updateUI_: function() {
+ $('add-user-button').hidden = false;
+ $('cancel-add-user-button').hidden = !this.allowCancel_;
+ $('guest-user-header-bar-item').hidden = false;
+ $('add-user-header-bar-item').hidden = false;
+ },
+
+ /**
+ * Animates Header bar to hide from the screen.
+ * @param {function()} callback will be called once animation is finished.
+ */
+ animateOut: function(callback) {
+ var launcher = this;
+ launcher.addEventListener(
+ 'webkitTransitionEnd', function f(e) {
+ launcher.removeEventListener('webkitTransitionEnd', f);
+ callback();
+ });
+ this.classList.remove('login-header-bar-animate-slow');
+ this.classList.add('login-header-bar-animate-fast');
+ this.classList.add('login-header-bar-hidden');
+ },
+
+ /**
+ * Animates Header bar to slowly appear on the screen.
+ */
+ animateIn: function() {
+ this.classList.remove('login-header-bar-animate-fast');
+ this.classList.add('login-header-bar-animate-slow');
+ this.classList.remove('login-header-bar-hidden');
+ },
+ };
+
+ /**
+ * Convenience wrapper of animateOut.
+ */
+ HeaderBar.animateOut = function(callback) {
+ $('login-header-bar').animateOut(callback);
+ };
+
+ /**
+ * Convenience wrapper of animateIn.
+ */
+ HeaderBar.animateIn = function() {
+ $('login-header-bar').animateIn();
+ }
+
+ return {
+ HeaderBar: HeaderBar
+ };
+});
diff --git a/chrome/browser/resources/user_chooser/desktop_user_pod_template.html b/chrome/browser/resources/user_chooser/desktop_user_pod_template.html
new file mode 100644
index 0000000..73a13cd
--- /dev/null
+++ b/chrome/browser/resources/user_chooser/desktop_user_pod_template.html
@@ -0,0 +1,25 @@
+<div id="user-pod-template" class="pod need-password" hidden>
+ <div class="main-pane">
+ <div class="signed-in-indicator" i18n-content="signedIn" hidden></div>
+ <img class="user-image" alt="">
+ <div class="name"></div>
+ <input type="password" class="password"
+ i18n-values="placeholder:passwordHint">
+ <button class="signin-button" i18n-content="signinButton"></button>
+ </div>
+ <div class="action-box-area">
+ <div class="custom-appearance action-box-button"></div>
+ </div>
+ <div class="user-type-icon-area" hidden>
+ <div class="custom-appearance user-type-icon-image"></div>
+ </div>
+ <div class="action-box-menu">
+ <div class="action-box-menu-title">
+ <span class="action-box-menu-title-name"></span>
+ <span class="action-box-menu-title-email"></span>
+ </div>
+ <div class="action-box-menu-remove">
+ <span class="action-box-menu-remove-command"/>
+ </div>
+ </div>
+</div>
diff --git a/chrome/browser/resources/user_chooser/user_chooser.html b/chrome/browser/resources/user_chooser/user_chooser.html
new file mode 100644
index 0000000..ccbea9d
--- /dev/null
+++ b/chrome/browser/resources/user_chooser/user_chooser.html
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML>
+<html i18n-values="dir:textdirection;screen:screenType;build:buildType">
+<head>
+<title i18n-content="title"></title>
+<link rel="stylesheet" href="../chromeos/login/oobe.css">
+<link rel="stylesheet" href="../chromeos/login/user_pod_row.css">
+<!-- desktop user chooser specific overrides -->
+<link rel="stylesheet" href="control_bar.css">
+<link rel="stylesheet" href="../chromeos/login/bubble.css">
+<link rel="stylesheet" href="chrome://resources/css/chrome_shared.css">
+<link rel="stylesheet" href="../chromeos/login/screen_account_picker.css">
+<link rel="stylesheet" href="../chromeos/login/screen_container.css">
+<!-- framework imports -->
+<!-- as per chrome/browser/resources/chromeos/login/login_resources.html -->
+<script src="chrome://resources/js/cr.js"></script>
+<script src="chrome://resources/js/event_tracker.js"></script>
+<script src="chrome://resources/js/cr/event_target.js"></script>
+<script src="chrome://resources/js/cr/ui.js"></script>
+<script src="chrome://resources/js/cr/ui/array_data_model.js"></script>
+<script src="chrome://resources/js/cr/ui/list_selection_controller.js"></script>
+<script src="chrome://resources/js/cr/ui/list_selection_model.js"></script>
+<script src="chrome://resources/js/cr/ui/list_single_selection_model.js"></script>
+<script src="chrome://resources/js/cr/ui/list.js"></script>
+<script src="chrome://resources/js/cr/ui/list_item.js"></script>
+<script src="chrome://resources/js/cr/ui/grid.js"></script>
+<script src="chrome://resources/js/cr/ui/menu_item.js"></script>
+<script src="chrome://resources/js/cr/ui/menu.js"></script>
+<script src="chrome://resources/js/cr/ui/menu_button.js"></script>
+<script src="chrome://resources/js/load_time_data.js"></script>
+<script src="chrome://resources/js/util.js"></script>
+<script src="user_chooser.js"></script>
+<script src="chrome://user-chooser/strings.js"></script>
+</head>
+<body class="login-display" i18n-values=".style.fontFamily:fontfamily;">
+ <div id="outer-container">
+ <div id="oobe" class="faded">
+ <div id="inner-container">
+ <div id="step-logo" hidden>
+ <div id="header-sections"></div>
+ </div>
+ <include src="../chromeos/login/screen_account_picker.html">
+ </div>
+ </div>
+ </div>
+ <div id="bubble" class="bubble faded" hidden></div>
+ <include src="control_bar.html">
+ <include src="desktop_user_pod_template.html">
+ <script src="chrome://resources/js/i18n_template2.js"></script>
+</body>
+</html>
diff --git a/chrome/browser/resources/user_chooser/user_chooser.js b/chrome/browser/resources/user_chooser/user_chooser.js
new file mode 100644
index 0000000..a98e703
--- /dev/null
+++ b/chrome/browser/resources/user_chooser/user_chooser.js
@@ -0,0 +1,119 @@
+// Copyright 2013 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 src="../chromeos/login/screen.js"></include>
+<include src="../chromeos/login/bubble.js"></include>
+<include src="../chromeos/login/display_manager.js"></include>
+<include src="control_bar.js"></include>
+<include src="../chromeos/login/screen_account_picker.js"></include>
+<include src="../chromeos/login/user_pod_row.js"></include>
+<include src="../chromeos/login/resource_loader.js"></include>
+
+cr.define('cr.ui', function() {
+ var DisplayManager = cr.ui.login.DisplayManager;
+
+ /**
+ * Constructs an Out of box controller. It manages initialization of screens,
+ * transitions, error messages display.
+ * @extends {DisplayManager}
+ * @constructor
+ */
+ function Oobe() {
+ }
+
+ cr.addSingletonGetter(Oobe);
+
+ Oobe.prototype = {
+ __proto__: DisplayManager.prototype,
+ };
+
+ /**
+ * Shows the given screen.
+ * @param {Object} screen Screen params dict, e.g. {id: screenId, data: data}
+ */
+ Oobe.showUserChooserScreen = function() {
+ Oobe.getInstance().showScreen({id: 'account-picker',
+ data: {disableAddUser: false}});
+ // The ChromeOS account-picker will hide the AddUser button if a user is
+ // logged in and the screen is "locked", so we must re-enabled it
+ $('add-user-header-bar-item').hidden = false;
+ };
+
+ /**
+ * Shows signin UI.
+ * @param {string} opt_email An optional email for signin UI.
+ */
+ Oobe.launchUser = function(email, displayName) {
+ chrome.send('launchUser', [email, displayName]);
+ };
+
+ /**
+ * Disables signin UI.
+ */
+ Oobe.disableSigninUI = function() {
+ DisplayManager.disableSigninUI();
+ };
+
+ /**
+ * Shows signin UI.
+ * @param {string} opt_email An optional email for signin UI.
+ */
+ Oobe.showSigninUI = function(opt_email) {
+ DisplayManager.showSigninUI(opt_email);
+ };
+
+ /**
+ * Clears error bubble as well as optional menus that could be open.
+ */
+ Oobe.clearErrors = function() {
+ DisplayManager.clearErrors();
+ };
+
+ /**
+ * Clears password field in user-pod.
+ */
+ Oobe.clearUserPodPassword = function() {
+ DisplayManager.clearUserPodPassword();
+ };
+
+ /**
+ * Restores input focus to currently selected pod.
+ */
+ Oobe.refocusCurrentPod = function() {
+ DisplayManager.refocusCurrentPod();
+ };
+
+ // Export
+ return {
+ Oobe: Oobe
+ };
+});
+
+cr.define('UserChooser', function() {
+ 'use strict';
+
+ function initialize() {
+ login.AccountPickerScreen.register();
+ cr.ui.Bubble.decorate($('bubble'));
+ login.HeaderBar.decorate($('login-header-bar'));
+ chrome.send('userChooserInitialize');
+ }
+
+ // Return an object with all of the exports.
+ return {
+ initialize: initialize
+ };
+});
+
+var Oobe = cr.ui.Oobe;
+
+// Allow selection events on components with editable text (password field)
+// bug (http://code.google.com/p/chromium/issues/detail?id=125863)
+disableTextSelectAndDrag(function(e) {
+ var src = e.target;
+ return src instanceof HTMLTextAreaElement ||
+ src instanceof HTMLInputElement &&
+ /text|password|search/.test(src.type);
+});
+
+document.addEventListener('DOMContentLoaded', UserChooser.initialize);
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
index 70683c5..485046f 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -35,6 +35,10 @@
#include "content/public/test/test_browser_thread.h"
#include "content/public/test/test_utils.h"
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
using content::BrowserThread;
using content::InterstitialPage;
using content::NavigationController;
@@ -616,6 +620,12 @@
}
IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, MalwareDontProceed) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
SetupWarningAndNavigate(SB_THREAT_TYPE_URL_MALWARE);
EXPECT_EQ(VISIBLE, GetVisibility("malware-icon"));
@@ -661,6 +671,12 @@
IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest,
MalwareIframeDontProceed) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
SetupMalwareIframeWarningAndNavigate();
EXPECT_EQ(HIDDEN, GetVisibility("malware-icon"));
@@ -717,6 +733,12 @@
// by the corresponding policy. Also verifies that sending the "proceed"
// command anyway doesn't advance to the malware site.
IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, ProceedDisabled) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
// Simulate a policy disabling the "proceed anyway" link.
browser()->profile()->GetPrefs()->SetBoolean(
prefs::kSafeBrowsingProceedAnywayDisabled, true);
@@ -744,6 +766,12 @@
// TODO(mattm): Should also verify that no report is sent, but there isn't a
// good way to do that in the current design.
IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, ReportingDisabled) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
browser()->profile()->GetPrefs()->SetBoolean(
prefs::kSafeBrowsingReportingEnabled, true);
@@ -771,6 +799,12 @@
}
IN_PROC_BROWSER_TEST_F(SafeBrowsingBlockingPageTest, PhishingDontProceed) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
SetupWarningAndNavigate(SB_THREAT_TYPE_URL_PHISHING);
EXPECT_EQ(HIDDEN, GetVisibility("malware-icon"));
diff --git a/chrome/browser/search/instant_service.cc b/chrome/browser/search/instant_service.cc
index 20fb466..014cbf8 100644
--- a/chrome/browser/search/instant_service.cc
+++ b/chrome/browser/search/instant_service.cc
@@ -56,6 +56,8 @@
InstantService::InstantService(Profile* profile)
: profile_(profile),
+ ntp_prerenderer_(profile, profile->GetPrefs()),
+ browser_instant_controller_object_count_(0),
weak_ptr_factory_(this) {
// Stub for unit tests.
if (!BrowserThread::CurrentlyOn(BrowserThread::UI))
@@ -174,6 +176,37 @@
instant_io_context_ = NULL;
}
+scoped_ptr<content::WebContents> InstantService::ReleaseNTPContents() {
+ return ntp_prerenderer_.ReleaseNTPContents();
+}
+
+content::WebContents* InstantService::GetNTPContents() const {
+ return ntp_prerenderer_.GetNTPContents();
+}
+
+void InstantService::OnBrowserInstantControllerCreated() {
+ if (profile_->IsOffTheRecord())
+ return;
+
+ ++browser_instant_controller_object_count_;
+
+ if (browser_instant_controller_object_count_ == 1)
+ ntp_prerenderer_.PreloadInstantNTP();
+}
+
+void InstantService::OnBrowserInstantControllerDestroyed() {
+ if (profile_->IsOffTheRecord())
+ return;
+
+ DCHECK_GT(browser_instant_controller_object_count_, 0U);
+ --browser_instant_controller_object_count_;
+
+ // All browser windows have closed, so release the InstantNTP resources to
+ // work around http://crbug.com/180810.
+ if (browser_instant_controller_object_count_ == 0)
+ ntp_prerenderer_.DeleteNTPContents();
+}
+
void InstantService::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
@@ -348,3 +381,7 @@
FOR_EACH_OBSERVER(InstantServiceObserver, observers_,
ThemeInfoChanged(*theme_info_));
}
+
+InstantNTPPrerenderer* InstantService::ntp_prerenderer() {
+ return &ntp_prerenderer_;
+}
diff --git a/chrome/browser/search/instant_service.h b/chrome/browser/search/instant_service.h
index 1e0d6f3..789d5c7 100644
--- a/chrome/browser/search/instant_service.h
+++ b/chrome/browser/search/instant_service.h
@@ -12,22 +12,30 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "chrome/browser/history/history_types.h"
+#include "chrome/browser/ui/search/instant_ntp_prerenderer.h"
#include "chrome/common/instant_types.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
class GURL;
+class InstantExtendedTest;
class InstantIOContext;
class InstantServiceObserver;
+class InstantTestBase;
class Profile;
class ThemeService;
+namespace content {
+class WebContents;
+}
+
namespace net {
class URLRequest;
}
@@ -78,7 +86,33 @@
// NTP.
void UpdateMostVisitedItemsInfo();
+ // Forwards the request to InstantNTPPrerenderer to release and return the
+ // preloaded InstantNTP WebContents. May be NULL. InstantNTPPrerenderer will
+ // load a new InstantNTP after releasing the preloaded contents.
+ scoped_ptr<content::WebContents> ReleaseNTPContents() WARN_UNUSED_RESULT;
+
+ // The NTP WebContents. May be NULL. InstantNTPPrerenderer retains ownership.
+ content::WebContents* GetNTPContents() const;
+
+ // Notifies InstantService about the creation of a BrowserInstantController
+ // object. Used to preload InstantNTP.
+ void OnBrowserInstantControllerCreated();
+
+ // Notifies InstantService about the destruction of a BrowserInstantController
+ // object. Used to destroy the preloaded InstantNTP.
+ void OnBrowserInstantControllerDestroyed();
+
private:
+ friend class InstantExtendedTest;
+ friend class InstantTestBase;
+
+ FRIEND_TEST_ALL_PREFIXES(InstantExtendedNetworkTest,
+ NTPReactsToNetworkChanges);
+ FRIEND_TEST_ALL_PREFIXES(InstantExtendedManualTest,
+ MANUAL_ShowsGoogleNTP);
+ FRIEND_TEST_ALL_PREFIXES(InstantExtendedManualTest,
+ MANUAL_SearchesFromFakebox);
+
// Overridden from BrowserContextKeyedService:
virtual void Shutdown() OVERRIDE;
@@ -98,6 +132,9 @@
// Theme changed notification handler.
void OnThemeChanged(ThemeService* theme_service);
+ // Used by tests.
+ InstantNTPPrerenderer* ntp_prerenderer();
+
Profile* const profile_;
// The process ids associated with Instant processes.
@@ -115,6 +152,12 @@
scoped_refptr<InstantIOContext> instant_io_context_;
+ InstantNTPPrerenderer ntp_prerenderer_;
+
+ // Total number of BrowserInstantController objects (does not include objects
+ // created for OTR browser windows). Used to preload and delete InstantNTP.
+ size_t browser_instant_controller_object_count_;
+
// Used for Top Sites async retrieval.
base::WeakPtrFactory<InstantService> weak_ptr_factory_;
diff --git a/chrome/browser/search/local_ntp_source.cc b/chrome/browser/search/local_ntp_source.cc
index e95bd57..66fef8a 100644
--- a/chrome/browser/search/local_ntp_source.cc
+++ b/chrome/browser/search/local_ntp_source.cc
@@ -46,14 +46,6 @@
{ "images/close_2_hover.png", IDR_CLOSE_2_H, "image/png" },
{ "images/close_2_active.png", IDR_CLOSE_2_P, "image/png" },
{ "images/close_2_white.png", IDR_CLOSE_2_MASK, "image/png" },
- { "images/page_icon.png", IDR_LOCAL_OMNIBOX_POPUP_IMAGES_PAGE_ICON_PNG,
- "image/png" },
- { "images/2x/page_icon.png",
- IDR_LOCAL_OMNIBOX_POPUP_IMAGES_2X_PAGE_ICON_PNG, "image/png" },
- { "images/search_icon.png",
- IDR_LOCAL_OMNIBOX_POPUP_IMAGES_SEARCH_ICON_PNG, "image/png" },
- { "images/2x/search_icon.png",
- IDR_LOCAL_OMNIBOX_POPUP_IMAGES_2X_SEARCH_ICON_PNG, "image/png" },
{ "images/2x/google_logo.png",
IDR_LOCAL_NTP_IMAGES_2X_LOGO_PNG, "image/png" },
{ "images/2x/white_google_logo.png",
diff --git a/chrome/browser/search/search.cc b/chrome/browser/search/search.cc
index b38c8b7..ec6b193 100644
--- a/chrome/browser/search/search.cc
+++ b/chrome/browser/search/search.cc
@@ -11,8 +11,10 @@
#include "base/rand_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
+#include "chrome/browser/browser_process.h"
#include "chrome/browser/google/google_util.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/search/instant_service.h"
#include "chrome/browser/search/instant_service_factory.h"
#include "chrome/browser/search_engines/template_url_service.h"
@@ -371,10 +373,6 @@
return false;
}
-bool ShouldPreloadInstantNTP(Profile* profile) {
- return !GetInstantURL(profile, kDisableStartMargin).is_empty();
-}
-
bool ShouldShowInstantNTP() {
FieldTrialFlags flags;
if (GetFieldTrialInfo(
@@ -415,6 +413,20 @@
std::string search_scheme(chrome::kChromeSearchScheme);
replacements.SetScheme(search_scheme.data(),
url_parse::Component(0, search_scheme.length()));
+
+ // If the URL corresponds to an online NTP, replace the host with
+ // "online-ntp".
+ std::string online_ntp_host(chrome::kChromeSearchOnlineNtpHost);
+ TemplateURL* template_url = GetDefaultSearchProviderTemplateURL(profile);
+ if (template_url) {
+ const GURL instant_url = TemplateURLRefToGURL(
+ template_url->instant_url_ref(), kDisableStartMargin, false);
+ if (instant_url.is_valid() && MatchesOriginAndPath(url, instant_url)) {
+ replacements.SetHost(online_ntp_host.c_str(),
+ url_parse::Component(0, online_ntp_host.length()));
+ }
+ }
+
privileged_url = privileged_url.ReplaceComponents(replacements);
return privileged_url;
}
@@ -446,11 +458,16 @@
}
bool IsPreloadedInstantExtendedNTP(const content::WebContents* contents) {
- for (chrome::BrowserIterator it; !it.done(); it.Next()) {
- if (it->instant_controller() &&
- it->instant_controller()->instant()->GetNTPContents() == contents) {
+ ProfileManager* profile_manager = g_browser_process->profile_manager();
+ if (!profile_manager)
+ return false; // The profile manager can be NULL while testing.
+
+ const std::vector<Profile*>& profiles = profile_manager->GetLoadedProfiles();
+ for (size_t i = 0; i < profiles.size(); ++i) {
+ const InstantService* instant_service =
+ InstantServiceFactory::GetForProfile(profiles[i]);
+ if (instant_service && instant_service->GetNTPContents() == contents)
return true;
- }
}
return false;
}
diff --git a/chrome/browser/search/search.h b/chrome/browser/search/search.h
index c4338ec..f7630a5 100644
--- a/chrome/browser/search/search.h
+++ b/chrome/browser/search/search.h
@@ -105,9 +105,6 @@
// to always show the remote NTP on browser startup.
bool ShouldPreferRemoteNTPOnStartup();
-// Returns true if the Instant NTP should be preloaded before it is shown.
-bool ShouldPreloadInstantNTP(Profile* profile);
-
// Returns true if the Instant NTP should be shown and false if not.
bool ShouldShowInstantNTP();
@@ -131,6 +128,10 @@
// Notice the scheme change.
//
// If the input is already a privileged URL then that same URL is returned.
+//
+// If |url| is that of the online NTP, its host is replaced with "online-ntp".
+// This forces the NTP and search results pages to have different SiteIntances,
+// and hence different processes.
GURL GetPrivilegedURLForInstant(const GURL& url, Profile* profile);
// Returns true if the input |url| is a privileged Instant URL.
diff --git a/chrome/browser/search/search_unittest.cc b/chrome/browser/search/search_unittest.cc
index 0172f2a..b718e06 100644
--- a/chrome/browser/search/search_unittest.cc
+++ b/chrome/browser/search/search_unittest.cc
@@ -19,6 +19,9 @@
#include "chrome/common/url_constants.h"
#include "chrome/test/base/browser_with_test_window_test.h"
#include "chrome/test/base/ui_test_utils.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents.h"
namespace chrome {
@@ -287,6 +290,112 @@
}
}
+struct PrivilegedURLTestCase {
+ bool add_as_alternate_url;
+ const char* input_url;
+ const char* privileged_url;
+ bool different_site_instance;
+ const char* comment;
+};
+
+TEST_F(SearchTest, GetPrivilegedURLForInstant) {
+ EnableInstantExtendedAPIForTesting();
+
+ const PrivilegedURLTestCase kTestCases[] = {
+ { false, // don't append input_url as alternate URL.
+ chrome::kChromeSearchLocalNtpUrl, // input URL.
+ chrome::kChromeSearchLocalNtpUrl, // expected privileged URL.
+ true, // expected different SiteInstance.
+ "local NTP" },
+ { false, // don't append input_url as alternate URL.
+ "https://foo.com/instant?strk",
+ "chrome-search://online-ntp/instant?strk",
+ true, // expected different SiteInstance.
+ "Valid Instant NTP" },
+ { false, // don't append input_url as alternate URL.
+ "https://foo.com/instant?strk&more=junk",
+ "chrome-search://online-ntp/instant?strk&more=junk",
+ true, // expected different SiteInstance.
+ "Valid Instant NTP with extra query" },
+ { false, // don't append input_url as alternate URL.
+ "https://foo.com/url?strk",
+ "chrome-search://foo.com/url?strk",
+ false, // expected same SiteInstance.
+ "Search URL" },
+ { true, // append input_url as alternate URL.
+ "https://notfoo.com/instant?strk",
+ "chrome-search://notfoo.com/instant?strk",
+ true, // expected different SiteInstance.
+ "Invalid host in URL" },
+ { true, // append input_url as alternate URL.
+ "https://foo.com/webhp?strk",
+ "chrome-search://foo.com/webhp?strk",
+ false, // expected same SiteInstance.
+ "Invalid path in URL" },
+ { true, // append input_url as alternate URL.
+ "https://foo.com/search?strk",
+ "chrome-search://foo.com/search?strk",
+ false, // expected same SiteInstance.
+ "Invalid path in URL" },
+ };
+
+ // GetPrivilegedURLForInstant expects ShouldAssignURLToInstantRenderer to
+ // be true, and the latter expects chrome-search: scheme or IsInstantURL to be
+ // true. To force IsInstantURL to return true, add the input_url of each
+ // PrivilegedURLTestCase as the alternate URL for the default template URL.
+ const char* kSearchURL = "https://foo.com/url?strk";
+ TemplateURLService* template_url_service =
+ TemplateURLServiceFactory::GetForProfile(profile());
+ TemplateURLData data;
+ data.SetURL(kSearchURL);
+ data.instant_url = "http://foo.com/instant?strk";
+ data.search_terms_replacement_key = "strk";
+ for (size_t i = 0; i < arraysize(kTestCases); ++i) {
+ const PrivilegedURLTestCase& test = kTestCases[i];
+ if (test.add_as_alternate_url)
+ data.alternate_urls.push_back(test.input_url);
+ }
+ TemplateURL* template_url = new TemplateURL(profile(), data);
+ // Takes ownership of |template_url|.
+ template_url_service->Add(template_url);
+ template_url_service->SetDefaultSearchProvider(template_url);
+
+ AddTab(browser(), GURL("chrome://blank"));
+ for (size_t i = 0; i < arraysize(kTestCases); ++i) {
+ const PrivilegedURLTestCase& test = kTestCases[i];
+
+ // Verify GetPrivilegedURLForInstant.
+ EXPECT_EQ(GURL(test.privileged_url),
+ GetPrivilegedURLForInstant(GURL(test.input_url), profile()))
+ << test.input_url << " " << test.comment;
+
+ // Verify that navigating from input_url to search URL results in same or
+ // different SiteInstance.
+ // First, navigate to input_url.
+ NavigateAndCommitActiveTab(GURL(test.input_url));
+ content::WebContents* contents =
+ browser()->tab_strip_model()->GetWebContentsAt(0);
+ // Cache the SiteInstance, RenderViewHost and RenderProcessHost for
+ // input_url.
+ const scoped_refptr<content::SiteInstance> prev_site_instance =
+ contents->GetSiteInstance();
+ const content::RenderViewHost* prev_rvh = contents->GetRenderViewHost();
+ const content::RenderProcessHost* prev_rph =
+ contents->GetRenderProcessHost();
+ // Then, navigate to search URL.
+ NavigateAndCommitActiveTab(GURL(kSearchURL));
+ EXPECT_EQ(test.different_site_instance,
+ contents->GetSiteInstance() != prev_site_instance)
+ << test.input_url << " " << test.comment;
+ EXPECT_EQ(test.different_site_instance,
+ contents->GetRenderViewHost() != prev_rvh)
+ << test.input_url << " " << test.comment;
+ EXPECT_EQ(test.different_site_instance,
+ contents->GetRenderProcessHost() != prev_rph)
+ << test.input_url << " " << test.comment;
+ }
+}
+
const SearchTestCase kInstantNTPTestCases[] = {
{"https://foo.com/instant?strk", true, "Valid Instant URL"},
{"https://foo.com/instant#strk", true, "Valid Instant URL"},
diff --git a/chrome/browser/search_engines/template_url_service.cc b/chrome/browser/search_engines/template_url_service.cc
index e897739..7392921 100644
--- a/chrome/browser/search_engines/template_url_service.cc
+++ b/chrome/browser/search_engines/template_url_service.cc
@@ -20,6 +20,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/google/google_url_tracker.h"
#include "chrome/browser/history/history_notifications.h"
#include "chrome/browser/history/history_service.h"
@@ -36,6 +37,7 @@
#include "chrome/browser/webdata/web_data_service.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/env_vars.h"
+#include "chrome/common/extensions/api/omnibox/omnibox_handler.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/notification_service.h"
@@ -244,8 +246,52 @@
UMA_HISTOGRAM_COUNTS_100("Search.SearchEngineDuplicateCounts", num_dupes);
}
+typedef std::vector<TemplateURLService::ExtensionKeyword> ExtensionKeywords;
+
+#if !defined(OS_ANDROID)
+// Extract all installed Omnibox Extensions.
+ExtensionKeywords GetExtensionKeywords(Profile* profile) {
+ DCHECK(profile);
+ ExtensionService* extension_service = profile->GetExtensionService();
+ DCHECK(extension_service);
+ const ExtensionSet* extensions = extension_service->extensions();
+ ExtensionKeywords extension_keywords;
+ for (ExtensionSet::const_iterator it = extensions->begin();
+ it != extensions->end(); ++it) {
+ const std::string& keyword = extensions::OmniboxInfo::GetKeyword(*it);
+ if (!keyword.empty()) {
+ extension_keywords.push_back(TemplateURLService::ExtensionKeyword(
+ (*it)->id(), (*it)->name(), keyword));
+ }
+ }
+ return extension_keywords;
+}
+#else
+// Extensions are not supported.
+ExtensionKeywords GetExtensionKeywords(Profile* profile) {
+ return ExtensionKeywords();
+}
+#endif
+
} // namespace
+
+// TemplateURLService::ExtensionKeyword ---------------------------------------
+
+TemplateURLService::ExtensionKeyword::ExtensionKeyword(
+ const std::string& id,
+ const std::string& name,
+ const std::string& keyword)
+ : extension_id(id),
+ extension_name(name),
+ extension_keyword(keyword) {
+}
+
+TemplateURLService::ExtensionKeyword::~ExtensionKeyword() {}
+
+
+// TemplateURLService::LessWithPrefix -----------------------------------------
+
class TemplateURLService::LessWithPrefix {
public:
// We want to find the set of keywords that begin with a prefix. The STL
@@ -268,6 +314,9 @@
}
};
+
+// TemplateURLService ---------------------------------------------------------
+
TemplateURLService::TemplateURLService(Profile* profile)
: provider_map_(new SearchHostToURLsMap),
profile_(profile),
@@ -545,14 +594,8 @@
DCHECK(loaded_);
if (!GetTemplateURLForExtension(extension_id)) {
- TemplateURLData data;
- data.short_name = UTF8ToUTF16(extension_name);
- data.SetKeyword(UTF8ToUTF16(keyword));
- // This URL is not actually used for navigation. It holds the extension's
- // ID, as well as forcing the TemplateURL to be treated as a search keyword.
- data.SetURL(std::string(extensions::kExtensionScheme) + "://" +
- extension_id + "/?q={searchTerms}");
- Add(new TemplateURL(profile_, data));
+ ExtensionKeyword extension_url(extension_id, extension_name, keyword);
+ Add(CreateTemplateURLForExtension(extension_url));
}
}
@@ -670,30 +713,20 @@
return FirstPotentialDefaultEngine(template_urls_);
}
-void TemplateURLService::ResetNonExtensionURLs() {
+void TemplateURLService::ResetURLs() {
// Can't clean DB if it hasn't been loaded.
DCHECK(loaded());
+ DCHECK(service_);
ClearDefaultProviderFromPrefs();
- // Preserve all extension URLs, as they should not be reset.
- TemplateURLVector entries_to_process;
- for (TemplateURLVector::const_iterator i = template_urls_.begin();
- i != template_urls_.end(); ++i) {
- if (!(*i)->IsExtensionKeyword())
- entries_to_process.push_back(*i);
- }
+ TemplateURLVector entries_to_process = template_urls_;
// Clear default provider to be able to delete it.
default_search_provider_ = NULL;
for (TemplateURLVector::const_iterator i = entries_to_process.begin();
i != entries_to_process.end(); ++i)
RemoveNoNotify(*i);
- // Store the remaining engines in entries_to_process and merge them with
- // prepopulated ones. NOTE: Because this class owns the pointers stored in
- // |template_urls_|, the swap() call below means this function is taking
- // ownership of all these pointers; see comments below.
entries_to_process.clear();
- entries_to_process.swap(template_urls_);
provider_map_.reset(new SearchHostToURLsMap);
UIThreadSearchTermsData search_terms_data(profile_);
provider_map_->Init(TemplateURLVector(), search_terms_data);
@@ -708,24 +741,21 @@
&default_search_provider,
&new_resource_keyword_version,
&pre_sync_deletes_);
- // We don't want to pass any extension URLs to
- // AddTemplateURLsAndSetupDefaultEngine(), since they were never removed
- // from the model to begin with.
- TemplateURLVector::iterator extensions(std::partition(
- entries_to_process.begin(), entries_to_process.end(),
- std::not1(std::mem_fun(&TemplateURL::IsExtensionKeyword))));
- // Right now we own all pointers in |entries_to_process| (see above).
- // AddTemplateURLsAndSetupDefaultEngine() will take ownership of all
- // passed-in TemplateURLs (generally by passing them to AddNoNotify()). Any
- // URLs we aren't going to pass to it have to be freed here.
- STLDeleteContainerPointers(extensions, entries_to_process.end());
- entries_to_process.erase(extensions, entries_to_process.end());
// Setup search engines and a default one.
base::AutoReset<DefaultSearchChangeOrigin> change_origin(
&dsp_change_origin_, DSP_CHANGE_PROFILE_RESET);
AddTemplateURLsAndSetupDefaultEngine(&entries_to_process,
default_search_provider);
+ // Repopulate extension keywords.
+ std::vector<ExtensionKeyword> extension_keywords =
+ GetExtensionKeywords(profile());
+ for (size_t i = 0; i < extension_keywords.size(); ++i) {
+ TemplateURL* extension_url =
+ CreateTemplateURLForExtension(extension_keywords[i]);
+ AddNoNotify(extension_url, true);
+ }
+
if (new_resource_keyword_version)
service_->SetBuiltinKeywordVersion(new_resource_keyword_version);
@@ -2544,3 +2574,15 @@
}
}
}
+
+TemplateURL* TemplateURLService::CreateTemplateURLForExtension(
+ const ExtensionKeyword& extension_keyword) const {
+ TemplateURLData data;
+ data.short_name = UTF8ToUTF16(extension_keyword.extension_name);
+ data.SetKeyword(UTF8ToUTF16(extension_keyword.extension_keyword));
+ // This URL is not actually used for navigation. It holds the extension's
+ // ID, as well as forcing the TemplateURL to be treated as a search keyword.
+ data.SetURL(std::string(extensions::kExtensionScheme) + "://" +
+ extension_keyword.extension_id + "/?q={searchTerms}");
+ return new TemplateURL(profile_, data);
+}
diff --git a/chrome/browser/search_engines/template_url_service.h b/chrome/browser/search_engines/template_url_service.h
index 31d6186..a7e3e24 100644
--- a/chrome/browser/search_engines/template_url_service.h
+++ b/chrome/browser/search_engines/template_url_service.h
@@ -79,6 +79,18 @@
const char* const content;
};
+ // Struct describes a search engine added by an extension.
+ struct ExtensionKeyword {
+ ExtensionKeyword(const std::string& id,
+ const std::string& name,
+ const std::string& keyword);
+ ~ExtensionKeyword();
+
+ std::string extension_id;
+ std::string extension_name;
+ std::string extension_keyword;
+ };
+
explicit TemplateURLService(Profile* profile);
// The following is for testing.
TemplateURLService(const Initializer* initializers, const int count);
@@ -225,10 +237,12 @@
// destroyed at any time so should be used right after the call.
TemplateURL* FindNewDefaultSearchProvider();
- // Resets the search providers to the prepopulated engines plus any
- // extension-supplied engines. Also resets the default search engine unless
- // it's managed.
- void ResetNonExtensionURLs();
+ // Resets the search providers to the prepopulated engines plus any keywords
+ // from currently-installed extensions. The user will lose all auto-added
+ // keywords from webpages, all edits to both normal and extension keywords,
+ // and any keywords belonging to no-longer-installed extensions.
+ // Modifications will be synced later.
+ void ResetURLs();
// Observers used to listen for changes to the model.
// TemplateURLService does NOT delete the observers when deleted.
@@ -362,7 +376,7 @@
IsLocalTemplateURLBetter);
FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, MergeInSyncTemplateURL);
- friend class TemplateURLServiceTestUtil;
+ friend class TemplateURLServiceTestUtilBase;
typedef std::map<string16, TemplateURL*> KeywordToTemplateMap;
typedef std::map<std::string, TemplateURL*> GUIDToTemplateMap;
@@ -605,6 +619,10 @@
// result of calling FindNewDefaultSearchProvider().
void EnsureDefaultSearchProviderExists();
+ // Returns a new TemplateURL for the given extension.
+ TemplateURL* CreateTemplateURLForExtension(
+ const ExtensionKeyword& extension_keyword) const;
+
content::NotificationRegistrar notification_registrar_;
PrefChangeRegistrar pref_change_registrar_;
diff --git a/chrome/browser/search_engines/template_url_service_android.cc b/chrome/browser/search_engines/template_url_service_android.cc
index e03325d..262dc34 100644
--- a/chrome/browser/search_engines/template_url_service_android.cc
+++ b/chrome/browser/search_engines/template_url_service_android.cc
@@ -100,6 +100,14 @@
return template_url_service_->is_default_search_managed();
}
+jboolean TemplateUrlServiceAndroid::IsDefaultSearchEngineGoogle(JNIEnv* env,
+ jobject obj) {
+ TemplateURL* default_search_provider =
+ template_url_service_->GetDefaultSearchProvider();
+ return default_search_provider &&
+ default_search_provider->url_ref().HasGoogleBaseURLs();
+}
+
base::android::ScopedJavaLocalRef<jobject>
TemplateUrlServiceAndroid::GetPrepopulatedTemplateUrlAt(JNIEnv* env,
jobject obj,
diff --git a/chrome/browser/search_engines/template_url_service_android.h b/chrome/browser/search_engines/template_url_service_android.h
index 97336e8..9c6fad5 100644
--- a/chrome/browser/search_engines/template_url_service_android.h
+++ b/chrome/browser/search_engines/template_url_service_android.h
@@ -29,6 +29,7 @@
base::android::ScopedJavaLocalRef<jobject>
GetPrepopulatedTemplateUrlAt(JNIEnv* env, jobject obj, jint index);
jboolean IsSearchProviderManaged(JNIEnv* env, jobject obj);
+ jboolean IsDefaultSearchEngineGoogle(JNIEnv* env, jobject obj);
// NotificationObserver:
virtual void Observe(int type,
diff --git a/chrome/browser/search_engines/template_url_service_test_util.cc b/chrome/browser/search_engines/template_url_service_test_util.cc
index 18e2964..850b5e3 100644
--- a/chrome/browser/search_engines/template_url_service_test_util.cc
+++ b/chrome/browser/search_engines/template_url_service_test_util.cc
@@ -54,6 +54,9 @@
} // namespace
+
+// TestingTemplateURLService --------------------------------------------------
+
// Trivial subclass of TemplateURLService that records the last invocation of
// SetKeywordSearchTermsForURL.
class TestingTemplateURLService : public TemplateURLService {
@@ -85,90 +88,45 @@
DISALLOW_COPY_AND_ASSIGN(TestingTemplateURLService);
};
-TemplateURLServiceTestUtil::TemplateURLServiceTestUtil()
- : ui_thread_(BrowserThread::UI, &message_loop_),
- db_thread_(BrowserThread::DB),
- io_thread_(BrowserThread::IO),
- changed_count_(0) {
+
+// TemplateURLServiceTestUtilBase ---------------------------------------------
+
+TemplateURLServiceTestUtilBase::TemplateURLServiceTestUtilBase()
+ : changed_count_(0) {
}
-TemplateURLServiceTestUtil::~TemplateURLServiceTestUtil() {
-}
+TemplateURLServiceTestUtilBase::~TemplateURLServiceTestUtilBase() {}
-void TemplateURLServiceTestUtil::SetUp() {
- // Make unique temp directory.
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- profile_.reset(new TestingProfile(temp_dir_.path()));
- db_thread_.Start();
- profile_->CreateWebDataService();
+void TemplateURLServiceTestUtilBase::CreateTemplateUrlService() {
+ profile()->CreateWebDataService();
TemplateURLService* service = static_cast<TemplateURLService*>(
TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
- profile_.get(), TestingTemplateURLService::Build));
+ profile(), TestingTemplateURLService::Build));
service->AddObserver(this);
-
-#if defined(OS_CHROMEOS)
- google_util::chromeos::ClearBrandForCurrentSession();
-#endif
}
-void TemplateURLServiceTestUtil::TearDown() {
- if (profile_.get()) {
- // Clear the request context so it will get deleted. This should be done
- // before shutting down the I/O thread to avoid memory leaks.
- profile_->ResetRequestContext();
- profile_.reset();
- }
-
- // Wait for the delete of the request context to happen.
- if (io_thread_.IsRunning())
- TemplateURLServiceTestUtil::BlockTillIOThreadProcessesRequests();
-
- // The I/O thread must be shutdown before the DB thread.
- io_thread_.Stop();
-
- // Note that we must ensure the DB thread is stopped after WDS
- // shutdown (so it can commit pending transactions) but before
- // deleting the test profile directory, otherwise we may not be
- // able to delete it due to an open transaction.
- // Schedule another task on the DB thread to notify us that it's safe to
- // carry on with the test.
- base::WaitableEvent done(false, false);
- BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
- base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done)));
- done.Wait();
- base::MessageLoop::current()->PostTask(FROM_HERE,
- base::MessageLoop::QuitClosure());
- base::MessageLoop::current()->Run();
- db_thread_.Stop();
-
- UIThreadSearchTermsData::SetGoogleBaseURL(std::string());
-
- // Flush the message loop to make application verifiers happy.
- message_loop_.RunUntilIdle();
-}
-
-void TemplateURLServiceTestUtil::OnTemplateURLServiceChanged() {
+void TemplateURLServiceTestUtilBase::OnTemplateURLServiceChanged() {
changed_count_++;
}
-int TemplateURLServiceTestUtil::GetObserverCount() {
+int TemplateURLServiceTestUtilBase::GetObserverCount() {
return changed_count_;
}
-void TemplateURLServiceTestUtil::ResetObserverCount() {
+void TemplateURLServiceTestUtilBase::ResetObserverCount() {
changed_count_ = 0;
}
-void TemplateURLServiceTestUtil::BlockTillServiceProcessesRequests() {
+void TemplateURLServiceTestUtilBase::BlockTillServiceProcessesRequests() {
WaitForThreadToProcessRequests(BrowserThread::DB);
}
-void TemplateURLServiceTestUtil::BlockTillIOThreadProcessesRequests() {
+void TemplateURLServiceTestUtilBase::BlockTillIOThreadProcessesRequests() {
WaitForThreadToProcessRequests(BrowserThread::IO);
}
-void TemplateURLServiceTestUtil::VerifyLoad() {
+void TemplateURLServiceTestUtilBase::VerifyLoad() {
ASSERT_FALSE(model()->loaded());
model()->Load();
BlockTillServiceProcessesRequests();
@@ -176,47 +134,48 @@
ResetObserverCount();
}
-void TemplateURLServiceTestUtil::ChangeModelToLoadState() {
+void TemplateURLServiceTestUtilBase::ChangeModelToLoadState() {
model()->ChangeToLoadedState();
// Initialize the web data service so that the database gets updated with
// any changes made.
- model()->service_ = WebDataService::FromBrowserContext(profile_.get());
+ model()->service_ = WebDataService::FromBrowserContext(profile());
BlockTillServiceProcessesRequests();
}
-void TemplateURLServiceTestUtil::ClearModel() {
+void TemplateURLServiceTestUtilBase::ClearModel() {
TemplateURLServiceFactory::GetInstance()->SetTestingFactory(
- profile_.get(), NULL);
+ profile(), NULL);
}
-void TemplateURLServiceTestUtil::ResetModel(bool verify_load) {
+void TemplateURLServiceTestUtilBase::ResetModel(bool verify_load) {
TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
- profile_.get(), TestingTemplateURLService::Build);
+ profile(), TestingTemplateURLService::Build);
model()->AddObserver(this);
changed_count_ = 0;
if (verify_load)
VerifyLoad();
}
-string16 TemplateURLServiceTestUtil::GetAndClearSearchTerm() {
+string16 TemplateURLServiceTestUtilBase::GetAndClearSearchTerm() {
return
static_cast<TestingTemplateURLService*>(model())->GetAndClearSearchTerm();
}
-void TemplateURLServiceTestUtil::SetGoogleBaseURL(const GURL& base_url) const {
+void TemplateURLServiceTestUtilBase::SetGoogleBaseURL(
+ const GURL& base_url) const {
DCHECK(base_url.is_valid());
- UIThreadSearchTermsData data(profile_.get());
+ UIThreadSearchTermsData data(profile());
GoogleURLTracker::UpdatedDetails urls(GURL(data.GoogleBaseURLValue()),
base_url);
UIThreadSearchTermsData::SetGoogleBaseURL(base_url.spec());
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_GOOGLE_URL_UPDATED,
- content::Source<Profile>(profile_.get()),
+ content::Source<Profile>(profile()),
content::Details<GoogleURLTracker::UpdatedDetails>(&urls));
}
-void TemplateURLServiceTestUtil::SetManagedDefaultSearchPreferences(
+void TemplateURLServiceTestUtilBase::SetManagedDefaultSearchPreferences(
bool enabled,
const std::string& name,
const std::string& keyword,
@@ -226,7 +185,7 @@
const std::string& encodings,
const std::string& alternate_url,
const std::string& search_terms_replacement_key) {
- TestingPrefServiceSyncable* pref_service = profile_->GetTestingPrefService();
+ TestingPrefServiceSyncable* pref_service = profile()->GetTestingPrefService();
pref_service->SetManagedPref(prefs::kDefaultSearchProviderEnabled,
Value::CreateBooleanValue(enabled));
pref_service->SetManagedPref(prefs::kDefaultSearchProviderName,
@@ -252,8 +211,8 @@
content::NotificationService::NoDetails());
}
-void TemplateURLServiceTestUtil::RemoveManagedDefaultSearchPreferences() {
- TestingPrefServiceSyncable* pref_service = profile_->GetTestingPrefService();
+void TemplateURLServiceTestUtilBase::RemoveManagedDefaultSearchPreferences() {
+ TestingPrefServiceSyncable* pref_service = profile()->GetTestingPrefService();
pref_service->RemoveManagedPref(prefs::kDefaultSearchProviderEnabled);
pref_service->RemoveManagedPref(prefs::kDefaultSearchProviderName);
pref_service->RemoveManagedPref(prefs::kDefaultSearchProviderKeyword);
@@ -271,8 +230,69 @@
content::NotificationService::NoDetails());
}
-TemplateURLService* TemplateURLServiceTestUtil::model() const {
- return TemplateURLServiceFactory::GetForProfile(profile_.get());
+TemplateURLService* TemplateURLServiceTestUtilBase::model() const {
+ return TemplateURLServiceFactory::GetForProfile(profile());
+}
+
+
+// TemplateURLServiceTestUtil -------------------------------------------------
+
+TemplateURLServiceTestUtil::TemplateURLServiceTestUtil()
+ : ui_thread_(BrowserThread::UI, &message_loop_),
+ db_thread_(BrowserThread::DB),
+ io_thread_(BrowserThread::IO) {
+}
+
+TemplateURLServiceTestUtil::~TemplateURLServiceTestUtil() {
+}
+
+void TemplateURLServiceTestUtil::SetUp() {
+ // Make unique temp directory.
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ profile_.reset(new TestingProfile(temp_dir_.path()));
+ db_thread_.Start();
+
+ TemplateURLServiceTestUtilBase::CreateTemplateUrlService();
+
+#if defined(OS_CHROMEOS)
+ google_util::chromeos::ClearBrandForCurrentSession();
+#endif
+}
+
+void TemplateURLServiceTestUtil::TearDown() {
+ if (profile_.get()) {
+ // Clear the request context so it will get deleted. This should be done
+ // before shutting down the I/O thread to avoid memory leaks.
+ profile_->ResetRequestContext();
+ profile_.reset();
+ }
+
+ // Wait for the delete of the request context to happen.
+ if (io_thread_.IsRunning())
+ TemplateURLServiceTestUtilBase::BlockTillIOThreadProcessesRequests();
+
+ // The I/O thread must be shutdown before the DB thread.
+ io_thread_.Stop();
+
+ // Note that we must ensure the DB thread is stopped after WDS
+ // shutdown (so it can commit pending transactions) but before
+ // deleting the test profile directory, otherwise we may not be
+ // able to delete it due to an open transaction.
+ // Schedule another task on the DB thread to notify us that it's safe to
+ // carry on with the test.
+ base::WaitableEvent done(false, false);
+ BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
+ base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done)));
+ done.Wait();
+ base::MessageLoop::current()->PostTask(FROM_HERE,
+ base::MessageLoop::QuitClosure());
+ base::MessageLoop::current()->Run();
+ db_thread_.Stop();
+
+ UIThreadSearchTermsData::SetGoogleBaseURL(std::string());
+
+ // Flush the message loop to make application verifiers happy.
+ message_loop_.RunUntilIdle();
}
TestingProfile* TemplateURLServiceTestUtil::profile() const {
diff --git a/chrome/browser/search_engines/template_url_service_test_util.h b/chrome/browser/search_engines/template_url_service_test_util.h
index ba8375f..7ddd4fd 100644
--- a/chrome/browser/search_engines/template_url_service_test_util.h
+++ b/chrome/browser/search_engines/template_url_service_test_util.h
@@ -24,21 +24,14 @@
class TestingProfile;
class WebDataService;
-// Implements functionality to make it easier to test TemplateURLService and
-// make changes to it.
-class TemplateURLServiceTestUtil : public TemplateURLServiceObserver {
+// TemplateURLServiceTestUtilBase contains basic API to ease testing of
+// TemplateURLService. User should take care of the infrastructure separately.
+class TemplateURLServiceTestUtilBase : public TemplateURLServiceObserver {
public:
- TemplateURLServiceTestUtil();
+ TemplateURLServiceTestUtilBase();
+ virtual ~TemplateURLServiceTestUtilBase();
- virtual ~TemplateURLServiceTestUtil();
-
- // Sets up the data structures for this class (mirroring gtest standard
- // methods).
- void SetUp();
-
- // Cleans up data structures for this class (mirroring gtest standard
- // methods).
- void TearDown();
+ void CreateTemplateUrlService();
// TemplateURLServiceObserver implemementation.
virtual void OnTemplateURLServiceChanged() OVERRIDE;
@@ -82,15 +75,15 @@
// notification. If |alternate_url| is empty, uses an empty list of alternate
// URLs, otherwise use a list containing a single entry.
void SetManagedDefaultSearchPreferences(
- bool enabled,
- const std::string& name,
- const std::string& keyword,
- const std::string& search_url,
- const std::string& suggest_url,
- const std::string& icon_url,
- const std::string& encodings,
- const std::string& alternate_url,
- const std::string& search_terms_replacement_key);
+ bool enabled,
+ const std::string& name,
+ const std::string& keyword,
+ const std::string& search_url,
+ const std::string& suggest_url,
+ const std::string& icon_url,
+ const std::string& encodings,
+ const std::string& alternate_url,
+ const std::string& search_terms_replacement_key);
// Remove all the managed preferences for the default search provider and
// trigger notification.
@@ -100,7 +93,31 @@
TemplateURLService* model() const;
// Returns the TestingProfile.
- TestingProfile* profile() const;
+ virtual TestingProfile* profile() const = 0;
+
+ private:
+ int changed_count_;
+
+ DISALLOW_COPY_AND_ASSIGN(TemplateURLServiceTestUtilBase);
+};
+
+// TemplateURLServiceTestUtil sets up TestingProfile, TemplateURLService and
+// required threads.
+class TemplateURLServiceTestUtil : public TemplateURLServiceTestUtilBase {
+ public:
+ TemplateURLServiceTestUtil();
+ virtual ~TemplateURLServiceTestUtil();
+
+ // Sets up the data structures for this class (mirroring gtest standard
+ // methods).
+ void SetUp();
+
+ // Cleans up data structures for this class (mirroring gtest standard
+ // methods).
+ void TearDown();
+
+ // Returns the TestingProfile.
+ virtual TestingProfile* profile() const OVERRIDE;
// Starts an I/O thread.
void StartIOThread();
@@ -116,7 +133,6 @@
content::TestBrowserThread db_thread_;
content::TestBrowserThread io_thread_;
scoped_ptr<TestingProfile> profile_;
- int changed_count_;
base::ScopedTempDir temp_dir_;
DISALLOW_COPY_AND_ASSIGN(TemplateURLServiceTestUtil);
diff --git a/chrome/browser/search_engines/template_url_service_unittest.cc b/chrome/browser/search_engines/template_url_service_unittest.cc
index 94026be..b1e95de 100644
--- a/chrome/browser/search_engines/template_url_service_unittest.cc
+++ b/chrome/browser/search_engines/template_url_service_unittest.cc
@@ -13,6 +13,7 @@
#include "base/test/mock_time_provider.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
+#include "chrome/browser/extensions/extension_service_unittest.h"
#include "chrome/browser/history/history_notifications.h"
#include "chrome/browser/history/history_service.h"
#include "chrome/browser/history/history_service_factory.h"
@@ -23,6 +24,8 @@
#include "chrome/browser/search_engines/template_url_service.h"
#include "chrome/browser/search_engines/template_url_service_test_util.h"
#include "chrome/browser/webdata/web_data_service_factory.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_manifest_constants.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/testing_profile.h"
#include "components/webdata/common/web_database.h"
@@ -149,7 +152,103 @@
history::VisitVector visits;
};
-}; // namespace
+TemplateURL* AddKeywordWithDate(
+ TemplateURLService* model,
+ const std::string& short_name,
+ const std::string& keyword,
+ const std::string& url,
+ const std::string& suggest_url,
+ const std::string& alternate_url,
+ const std::string& favicon_url,
+ bool safe_for_autoreplace,
+ const std::string& encodings,
+ Time date_created,
+ Time last_modified) {
+ TemplateURLData data;
+ data.short_name = UTF8ToUTF16(short_name);
+ data.SetKeyword(UTF8ToUTF16(keyword));
+ data.SetURL(url);
+ data.suggestions_url = suggest_url;
+ if (!alternate_url.empty())
+ data.alternate_urls.push_back(alternate_url);
+ data.favicon_url = GURL(favicon_url);
+ data.safe_for_autoreplace = safe_for_autoreplace;
+ base::SplitString(encodings, ';', &data.input_encodings);
+ data.date_created = date_created;
+ data.last_modified = last_modified;
+ TemplateURL* t_url = new TemplateURL(model->profile(), data);
+ model->Add(t_url);
+ EXPECT_NE(0, t_url->id());
+ return t_url;
+}
+
+// Checks that the two TemplateURLs are similar. It does not check the id, the
+// date_created or the last_modified time. Neither pointer should be NULL.
+void ExpectSimilar(const TemplateURL* expected, const TemplateURL* actual) {
+ ASSERT_TRUE(expected != NULL);
+ ASSERT_TRUE(actual != NULL);
+ EXPECT_EQ(expected->short_name(), actual->short_name());
+ EXPECT_EQ(expected->keyword(), actual->keyword());
+ EXPECT_EQ(expected->url(), actual->url());
+ EXPECT_EQ(expected->suggestions_url(), actual->suggestions_url());
+ EXPECT_EQ(expected->favicon_url(), actual->favicon_url());
+ EXPECT_EQ(expected->alternate_urls(), actual->alternate_urls());
+ EXPECT_EQ(expected->show_in_default_list(), actual->show_in_default_list());
+ EXPECT_EQ(expected->safe_for_autoreplace(), actual->safe_for_autoreplace());
+ EXPECT_EQ(expected->input_encodings(), actual->input_encodings());
+ EXPECT_EQ(expected->search_terms_replacement_key(),
+ actual->search_terms_replacement_key());
+}
+
+} // namespace
+
+
+// TemplateURLServiceExtensionTest --------------------------------------------
+
+class TemplateURLServiceExtensionTest : public ExtensionServiceTestBase,
+ public TemplateURLServiceTestUtilBase {
+ public:
+ TemplateURLServiceExtensionTest();
+ virtual ~TemplateURLServiceExtensionTest();
+
+ // ExtensionServiceTestBase:
+ virtual void SetUp() OVERRIDE;
+
+ // TemplateURLServiceTestUtilBase:
+ virtual TestingProfile* profile() const OVERRIDE;
+
+ void CheckExtensionKeyword(const string16& keyword, const string16& name);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TemplateURLServiceExtensionTest);
+};
+
+TemplateURLServiceExtensionTest::TemplateURLServiceExtensionTest() {}
+
+TemplateURLServiceExtensionTest::~TemplateURLServiceExtensionTest() {}
+
+void TemplateURLServiceExtensionTest::SetUp() {
+ ExtensionServiceTestBase::SetUp();
+ ExtensionServiceInitParams params;
+ InitializeExtensionService(params);
+ TemplateURLServiceTestUtilBase::CreateTemplateUrlService();
+}
+
+
+TestingProfile* TemplateURLServiceExtensionTest::profile() const {
+ return profile_.get();
+}
+
+void TemplateURLServiceExtensionTest::CheckExtensionKeyword(
+ const string16& keyword, const string16& name) {
+#if !defined(OS_ANDROID)
+ TemplateURL* ext_url =
+ model()->GetTemplateURLForKeyword(keyword);
+ ASSERT_TRUE(ext_url);
+ EXPECT_EQ(keyword, ext_url->keyword());
+ EXPECT_EQ(name, ext_url->short_name());
+#endif
+}
// TemplateURLServiceTest -----------------------------------------------------
@@ -176,10 +275,6 @@
// Verifies the two TemplateURLs are equal.
void AssertEquals(const TemplateURL& expected, const TemplateURL& actual);
- // Checks that the two TemplateURLs are similar. It does not check the id, the
- // date_created or the last_modified time. Neither pointer should be NULL.
- void ExpectSimilar(const TemplateURL* expected, const TemplateURL* actual);
-
// Create an URL that appears to have been prepopulated, but won't be in the
// current data. The caller owns the returned TemplateURL*.
TemplateURL* CreatePreloadedTemplateURL(bool safe_for_autoreplace,
@@ -233,22 +328,9 @@
const std::string& encodings,
Time date_created,
Time last_modified) {
- TemplateURLData data;
- data.short_name = UTF8ToUTF16(short_name);
- data.SetKeyword(UTF8ToUTF16(keyword));
- data.SetURL(url);
- data.suggestions_url = suggest_url;
- if (!alternate_url.empty())
- data.alternate_urls.push_back(alternate_url);
- data.favicon_url = GURL(favicon_url);
- data.safe_for_autoreplace = safe_for_autoreplace;
- base::SplitString(encodings, ';', &data.input_encodings);
- data.date_created = date_created;
- data.last_modified = last_modified;
- TemplateURL* t_url = new TemplateURL(test_util_.profile(), data);
- model()->Add(t_url);
- EXPECT_NE(0, t_url->id());
- return t_url;
+ return ::AddKeywordWithDate(model(), short_name, keyword, url, suggest_url,
+ alternate_url, favicon_url, safe_for_autoreplace,
+ encodings, date_created, last_modified);
}
void TemplateURLServiceTest::AssertEquals(const TemplateURL& expected,
@@ -270,23 +352,6 @@
actual.search_terms_replacement_key());
}
-void TemplateURLServiceTest::ExpectSimilar(const TemplateURL* expected,
- const TemplateURL* actual) {
- ASSERT_TRUE(expected != NULL);
- ASSERT_TRUE(actual != NULL);
- EXPECT_EQ(expected->short_name(), actual->short_name());
- EXPECT_EQ(expected->keyword(), actual->keyword());
- EXPECT_EQ(expected->url(), actual->url());
- EXPECT_EQ(expected->suggestions_url(), actual->suggestions_url());
- EXPECT_EQ(expected->favicon_url(), actual->favicon_url());
- EXPECT_EQ(expected->alternate_urls(), actual->alternate_urls());
- EXPECT_EQ(expected->show_in_default_list(), actual->show_in_default_list());
- EXPECT_EQ(expected->safe_for_autoreplace(), actual->safe_for_autoreplace());
- EXPECT_EQ(expected->input_encodings(), actual->input_encodings());
- EXPECT_EQ(expected->search_terms_replacement_key(),
- actual->search_terms_replacement_key());
-}
-
TemplateURL* TemplateURLServiceTest::CreatePreloadedTemplateURL(
bool safe_for_autoreplace,
int prepopulate_id) {
@@ -913,43 +978,68 @@
AssertEquals(*cloned_url, *model()->GetDefaultSearchProvider());
}
-TEST_F(TemplateURLServiceTest, ResetNonExtensionURLs) {
- test_util_.VerifyLoad();
+TEST_F(TemplateURLServiceExtensionTest, ResetURLs) {
+ VerifyLoad();
TemplateURL* new_provider = AddKeywordWithDate(
- "short_name", "keyword", "http://test.com/search?t={searchTerms}",
+ model(), "short_name", "keyword", "http://test.com/search?t={searchTerms}",
std::string(), std::string(), std::string(),
true, "UTF-8", Time(), Time());
model()->SetDefaultSearchProvider(new_provider);
AddKeywordWithDate(
- "extension1", "ext_keyword",
+ model(), "extension1", "ext_keyword",
std::string(extensions::kExtensionScheme) + "://test1", std::string(),
std::string(), std::string(), false, "UTF-8", Time(), Time());
+ AddKeywordWithDate(
+ model(), "extension2", "ext_keyword2",
+ std::string(extensions::kExtensionScheme) + "://test2", std::string(),
+ std::string(), std::string(), false, "UTF-8", Time(), Time());
TemplateURL* default_provider = model()->GetDefaultSearchProvider();
EXPECT_NE(SEARCH_ENGINE_GOOGLE,
TemplateURLPrepopulateData::GetEngineType(default_provider->url()));
- // Non-extension URLs should go away. Default search engine is Google again.
- model()->ResetNonExtensionURLs();
+ DictionaryValue manifest;
+ manifest.SetString(extension_manifest_keys::kVersion, "1.0.0.0");
+ manifest.SetString(extension_manifest_keys::kName, "ext1");
+ manifest.SetString("app.launch.web_url", "http://www.google.com");
+ manifest.SetString(extension_manifest_keys::kOmniboxKeyword, "ext_keyword");
+ std::string error;
+ scoped_refptr<extensions::Extension> extension =
+ extensions::Extension::Create(
+ base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
+ extensions::Manifest::COMPONENT,
+ manifest,
+ extensions::Extension::NO_FLAGS,
+ &error);
+ EXPECT_TRUE(extension.get() != NULL) << error;
+ ExtensionService* extension_service = profile()->GetExtensionService();
+ ASSERT_TRUE(extension_service);
+ extension_service->AddExtension(extension.get());
+ // All URLs except |extension_keywords| should go away. Default search engine
+ // is Google again.
+ model()->ResetURLs();
+
default_provider = model()->GetDefaultSearchProvider();
ASSERT_TRUE(default_provider);
EXPECT_EQ(SEARCH_ENGINE_GOOGLE,
TemplateURLPrepopulateData::GetEngineType(default_provider->url()));
- EXPECT_TRUE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("ext_keyword")));
+ CheckExtensionKeyword(ASCIIToUTF16("ext_keyword"), ASCIIToUTF16("ext1"));
+ EXPECT_FALSE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("ext_keyword2")));
EXPECT_FALSE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword")));
// Reload URLs. Result should be the same, as extension keywords are now
// persisted.
- test_util_.ResetModel(true);
+ ResetModel(true);
default_provider = model()->GetDefaultSearchProvider();
ASSERT_TRUE(default_provider);
EXPECT_EQ(SEARCH_ENGINE_GOOGLE,
TemplateURLPrepopulateData::GetEngineType(default_provider->url()));
- EXPECT_TRUE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("ext_keyword")));
+ CheckExtensionKeyword(ASCIIToUTF16("ext_keyword"), ASCIIToUTF16("ext1"));
+ EXPECT_FALSE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("ext_keyword2")));
EXPECT_FALSE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword")));
}
-TEST_F(TemplateURLServiceTest, ResetURLsWithManagedDefault) {
+TEST_F(TemplateURLServiceExtensionTest, ResetURLsWithManagedDefault) {
// Set a managed preference that establishes a default search provider.
const char kName[] = "test1";
const char kKeyword[] = "test.com";
@@ -958,12 +1048,12 @@
const char kEncodings[] = "UTF-16;UTF-32";
const char kAlternateURL[] = "http://test.com/search#t={searchTerms}";
const char kSearchTermsReplacementKey[] = "espv";
- test_util_.SetManagedDefaultSearchPreferences(true, kName, kKeyword,
- kSearchURL, std::string(),
- kIconURL, kEncodings,
- kAlternateURL,
- kSearchTermsReplacementKey);
- test_util_.VerifyLoad();
+ SetManagedDefaultSearchPreferences(true, kName, kKeyword,
+ kSearchURL, std::string(),
+ kIconURL, kEncodings,
+ kAlternateURL,
+ kSearchTermsReplacementKey);
+ VerifyLoad();
// Verify that the default manager we are getting is the managed one.
TemplateURLData data;
data.short_name = ASCIIToUTF16(kName);
@@ -974,16 +1064,15 @@
base::SplitString(kEncodings, ';', &data.input_encodings);
data.alternate_urls.push_back(kAlternateURL);
data.search_terms_replacement_key = kSearchTermsReplacementKey;
- Profile* profile = test_util_.profile();
- scoped_ptr<TemplateURL> expected_managed_default(new TemplateURL(profile,
- data));
+ scoped_ptr<TemplateURL> expected_managed_default(new TemplateURL(profile(),
+ data));
EXPECT_TRUE(model()->is_default_search_managed());
const TemplateURL* actual_managed_default =
model()->GetDefaultSearchProvider();
ExpectSimilar(expected_managed_default.get(), actual_managed_default);
// The following call has no effect on the managed search engine.
- model()->ResetNonExtensionURLs();
+ model()->ResetURLs();
EXPECT_TRUE(model()->is_default_search_managed());
actual_managed_default = model()->GetDefaultSearchProvider();
diff --git a/chrome/browser/sessions/persistent_tab_restore_service_browsertest.cc b/chrome/browser/sessions/persistent_tab_restore_service_browsertest.cc
index 84c63a2..1840bd0 100644
--- a/chrome/browser/sessions/persistent_tab_restore_service_browsertest.cc
+++ b/chrome/browser/sessions/persistent_tab_restore_service_browsertest.cc
@@ -32,7 +32,6 @@
#include "content/public/test/test_utils.h"
#include "content/public/test/web_contents_tester.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/web/WebKit.h"
typedef TabRestoreService::Tab Tab;
typedef TabRestoreService::Window Window;
@@ -79,7 +78,6 @@
// testing::Test:
virtual void SetUp() OVERRIDE {
- WebKit::initialize(webkit_platform_support_.Get());
ChromeRenderViewHostTestHarness::SetUp();
time_factory_ = new PersistentTabRestoreTimeFactory();
service_.reset(new PersistentTabRestoreService(profile(), time_factory_));
@@ -90,7 +88,6 @@
service_.reset();
delete time_factory_;
ChromeRenderViewHostTestHarness::TearDown();
- WebKit::shutdown();
}
TabRestoreService::Entries* mutable_entries() {
@@ -171,8 +168,6 @@
std::string user_agent_override_;
scoped_ptr<PersistentTabRestoreService> service_;
PersistentTabRestoreTimeFactory* time_factory_;
- content::RenderViewTest::RendererWebKitPlatformSupportImplNoSandbox
- webkit_platform_support_;
};
namespace {
diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc
index 59945a7..6154185 100644
--- a/chrome/browser/sessions/session_restore_browsertest.cc
+++ b/chrome/browser/sessions/session_restore_browsertest.cc
@@ -50,6 +50,10 @@
#include "base/mac/scoped_nsautorelease_pool.h"
#endif
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
class SessionRestoreTest : public InProcessBrowserTest {
public:
SessionRestoreTest() : active_browser_list_(NULL) {}
@@ -851,6 +855,12 @@
// If this test flakes, use http://crbug.com/29110
IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
RestoreAfterClosingTabbedBrowserWithAppAndLaunching) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
ui_test_utils::NavigateToURL(browser(), url1_);
// Launch an app.
@@ -1073,18 +1083,18 @@
ui_test_utils::NavigateToURL(browser(), url1_);
content::NavigationController* controller =
&browser()->tab_strip_model()->GetActiveWebContents()->GetController();
- ASSERT_TRUE(controller->GetSessionStorageNamespace());
+ ASSERT_TRUE(controller->GetDefaultSessionStorageNamespace());
std::string session_storage_persistent_id =
- controller->GetSessionStorageNamespace()->persistent_id();
+ controller->GetDefaultSessionStorageNamespace()->persistent_id();
Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
ASSERT_EQ(1u, active_browser_list_->size());
ASSERT_EQ(url1_,
new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
content::NavigationController* new_controller =
&new_browser->tab_strip_model()->GetActiveWebContents()->GetController();
- ASSERT_TRUE(new_controller->GetSessionStorageNamespace());
+ ASSERT_TRUE(new_controller->GetDefaultSessionStorageNamespace());
std::string restored_session_storage_persistent_id =
- new_controller->GetSessionStorageNamespace()->persistent_id();
+ new_controller->GetDefaultSessionStorageNamespace()->persistent_id();
EXPECT_EQ(session_storage_persistent_id,
restored_session_storage_persistent_id);
}
@@ -1095,12 +1105,15 @@
{
content::NavigationController* controller =
&browser()->tab_strip_model()->GetActiveWebContents()->GetController();
- ASSERT_TRUE(controller->GetSessionStorageNamespace());
+ ASSERT_TRUE(controller->GetDefaultSessionStorageNamespace());
+ content::SessionStorageNamespaceMap session_storage_namespace_map;
+ session_storage_namespace_map[std::string()] =
+ controller->GetDefaultSessionStorageNamespace();
scoped_ptr<content::WebContents> web_contents(
content::WebContents::CreateWithSessionStorage(
content::WebContents::CreateParams(browser()->profile()),
- controller->GetSessionStorageNamespace()));
+ session_storage_namespace_map));
TabStripModel* tab_strip_model = browser()->tab_strip_model();
scoped_ptr<content::WebContents> old_web_contents(
@@ -1115,7 +1128,7 @@
content::NavigationController* controller =
&browser()->tab_strip_model()->GetActiveWebContents()->GetController();
EXPECT_TRUE(
- controller->GetSessionStorageNamespace()->should_persist());
+ controller->GetDefaultSessionStorageNamespace()->should_persist());
// Quit and restore. Check that no extra tabs were created.
Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
diff --git a/chrome/browser/sessions/session_service.cc b/chrome/browser/sessions/session_service.cc
index 05bf038..dd97f43 100644
--- a/chrome/browser/sessions/session_service.cc
+++ b/chrome/browser/sessions/session_service.cc
@@ -1334,7 +1334,7 @@
// Record the association between the sessionStorage namespace and the tab.
content::SessionStorageNamespace* session_storage_namespace =
- tab->GetController().GetSessionStorageNamespace();
+ tab->GetController().GetDefaultSessionStorageNamespace();
ScheduleCommand(CreateSessionStorageAssociatedCommand(
session_tab_helper->session_id(),
session_storage_namespace->persistent_id()));
@@ -1736,8 +1736,12 @@
// Record the association between the SessionStorageNamespace and the
// tab.
+ //
+ // TODO(ajwong): This should be processing the whole map rather than
+ // just the default. This in particular will not work for tabs with only
+ // isolated apps which won't have a default partition.
content::SessionStorageNamespace* session_storage_namespace =
- contents->GetController().GetSessionStorageNamespace();
+ contents->GetController().GetDefaultSessionStorageNamespace();
ScheduleCommand(CreateSessionStorageAssociatedCommand(
session_tab_helper->session_id(),
session_storage_namespace->persistent_id()));
@@ -1748,7 +1752,7 @@
// Allow the associated sessionStorage to get deleted; it won't be needed
// in the session restore.
content::SessionStorageNamespace* session_storage_namespace =
- contents->GetController().GetSessionStorageNamespace();
+ contents->GetController().GetDefaultSessionStorageNamespace();
session_storage_namespace->SetShouldPersist(false);
SessionTabHelper* session_tab_helper =
SessionTabHelper::FromWebContents(contents);
diff --git a/chrome/browser/sessions/tab_restore_service_helper.cc b/chrome/browser/sessions/tab_restore_service_helper.cc
index 2782b47..2b13861 100644
--- a/chrome/browser/sessions/tab_restore_service_helper.cc
+++ b/chrome/browser/sessions/tab_restore_service_helper.cc
@@ -419,7 +419,9 @@
tab->user_agent_override =
controller->GetWebContents()->GetUserAgentOverride();
- tab->session_storage_namespace = controller->GetSessionStorageNamespace();
+ // TODO(ajwong): This does not correctly handle storage for isolated apps.
+ tab->session_storage_namespace =
+ controller->GetDefaultSessionStorageNamespace();
// Delegate may be NULL during unit tests.
if (delegate) {
diff --git a/chrome/browser/signin/android_profile_oauth2_token_service.cc b/chrome/browser/signin/android_profile_oauth2_token_service.cc
index 8516a87..f79eb63 100644
--- a/chrome/browser/signin/android_profile_oauth2_token_service.cc
+++ b/chrome/browser/signin/android_profile_oauth2_token_service.cc
@@ -13,7 +13,6 @@
#include "chrome/browser/sync/profile_sync_service_android.h"
#include "content/public/browser/browser_thread.h"
#include "jni/AndroidProfileOAuth2TokenServiceHelper_jni.h"
-#include "net/url_request/url_request_context_getter.h"
using base::android::AttachCurrentThread;
using base::android::CheckException;
@@ -39,9 +38,7 @@
} // namespace
-AndroidProfileOAuth2TokenService::AndroidProfileOAuth2TokenService(
- net::URLRequestContextGetter* getter)
- : ProfileOAuth2TokenService(getter) {
+AndroidProfileOAuth2TokenService::AndroidProfileOAuth2TokenService() {
}
AndroidProfileOAuth2TokenService::~AndroidProfileOAuth2TokenService() {
diff --git a/chrome/browser/signin/android_profile_oauth2_token_service.h b/chrome/browser/signin/android_profile_oauth2_token_service.h
index 22c805b..39680fe 100644
--- a/chrome/browser/signin/android_profile_oauth2_token_service.h
+++ b/chrome/browser/signin/android_profile_oauth2_token_service.h
@@ -15,10 +15,6 @@
#include "chrome/browser/signin/profile_oauth2_token_service.h"
#include "google_apis/gaia/google_service_auth_error.h"
-namespace net {
-class URLRequestContextGetter;
-}
-
class TokenService;
@@ -67,8 +63,7 @@
protected:
friend class ProfileOAuth2TokenServiceFactory;
- explicit AndroidProfileOAuth2TokenService(
- net::URLRequestContextGetter* getter);
+ AndroidProfileOAuth2TokenService();
virtual ~AndroidProfileOAuth2TokenService();
// virtual for testing.
diff --git a/chrome/browser/signin/oauth2_token_service.cc b/chrome/browser/signin/oauth2_token_service.cc
index e0b2414..1790aea 100644
--- a/chrome/browser/signin/oauth2_token_service.cc
+++ b/chrome/browser/signin/oauth2_token_service.cc
@@ -283,8 +283,7 @@
OAuth2TokenService::Consumer::~Consumer() {
}
-OAuth2TokenService::OAuth2TokenService(net::URLRequestContextGetter* getter)
- : request_context_getter_(getter) {
+OAuth2TokenService::OAuth2TokenService() {
}
OAuth2TokenService::~OAuth2TokenService() {
@@ -342,7 +341,7 @@
pending_fetchers_[fetch_parameters] =
Fetcher::CreateAndStart(this,
- request_context_getter_.get(),
+ GetRequestContext(),
refresh_token,
scopes,
request->AsWeakPtr());
diff --git a/chrome/browser/signin/oauth2_token_service.h b/chrome/browser/signin/oauth2_token_service.h
index f961505..b40066e 100644
--- a/chrome/browser/signin/oauth2_token_service.h
+++ b/chrome/browser/signin/oauth2_token_service.h
@@ -101,7 +101,7 @@
// A set of scopes in OAuth2 authentication.
typedef std::set<std::string> ScopeSet;
- explicit OAuth2TokenService(net::URLRequestContextGetter* getter);
+ OAuth2TokenService();
virtual ~OAuth2TokenService();
// Add or remove observers of this token service.
@@ -188,6 +188,10 @@
void FireRefreshTokensCleared();
private:
+ // Derived classes must provide a request context used for fetching access
+ // tokens with the |StartRequest| method.
+ virtual net::URLRequestContextGetter* GetRequestContext() = 0;
+
// Class that fetches an OAuth2 access token for a given set of scopes and
// OAuth2 refresh token.
class Fetcher;
@@ -215,9 +219,6 @@
// Called when |fetcher| finishes fetching.
void OnFetchComplete(Fetcher* fetcher);
- // Getter to use for fetchers.
- scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
-
// The cache of currently valid tokens.
typedef std::map<ScopeSet, CacheEntry> TokenCache;
TokenCache token_cache_;
diff --git a/chrome/browser/signin/oauth2_token_service_unittest.cc b/chrome/browser/signin/oauth2_token_service_unittest.cc
index 901258b..6859f37 100644
--- a/chrome/browser/signin/oauth2_token_service_unittest.cc
+++ b/chrome/browser/signin/oauth2_token_service_unittest.cc
@@ -44,8 +44,8 @@
class TestOAuth2TokenService : public OAuth2TokenService {
public:
- explicit TestOAuth2TokenService(net::URLRequestContextGetter* getter)
- : OAuth2TokenService(getter) {
+ explicit TestOAuth2TokenService(net::TestURLRequestContextGetter* getter)
+ : request_context_getter_(getter) {
}
// For testing: set the refresh token to be used.
@@ -57,22 +57,24 @@
virtual std::string GetRefreshToken() OVERRIDE { return refresh_token_; }
private:
+ // OAuth2TokenService implementation.
+ virtual net::URLRequestContextGetter* GetRequestContext() OVERRIDE {
+ return request_context_getter_.get();
+ }
+
std::string refresh_token_;
+ scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
};
class OAuth2TokenServiceTest : public TokenServiceTestHarness {
public:
- OAuth2TokenServiceTest()
- : request_context_getter_(new net::TestURLRequestContextGetter(
- message_loop_.message_loop_proxy())) {
- }
-
virtual void SetUp() OVERRIDE {
TokenServiceTestHarness::SetUp();
io_thread_.reset(new content::TestBrowserThread(content::BrowserThread::IO,
&message_loop_));
oauth2_service_.reset(
- new TestOAuth2TokenService(request_context_getter_.get()));
+ new TestOAuth2TokenService(new net::TestURLRequestContextGetter(
+ message_loop_.message_loop_proxy())));
}
virtual void TearDown() OVERRIDE {
@@ -81,7 +83,6 @@
protected:
scoped_ptr<content::TestBrowserThread> io_thread_;
- scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
net::TestURLFetcherFactory factory_;
scoped_ptr<TestOAuth2TokenService> oauth2_service_;
TestingOAuth2TokenServiceConsumer consumer_;
diff --git a/chrome/browser/signin/profile_oauth2_token_service.cc b/chrome/browser/signin/profile_oauth2_token_service.cc
index f846059..26b337f 100644
--- a/chrome/browser/signin/profile_oauth2_token_service.cc
+++ b/chrome/browser/signin/profile_oauth2_token_service.cc
@@ -35,10 +35,8 @@
} // namespace
-ProfileOAuth2TokenService::ProfileOAuth2TokenService(
- net::URLRequestContextGetter* getter)
- : OAuth2TokenService(getter),
- profile_(NULL),
+ProfileOAuth2TokenService::ProfileOAuth2TokenService()
+ : profile_(NULL),
last_auth_error_(GoogleServiceAuthError::NONE) {
}
@@ -153,6 +151,10 @@
return last_auth_error_;
}
+net::URLRequestContextGetter* ProfileOAuth2TokenService::GetRequestContext() {
+ return profile_->GetRequestContext();
+}
+
void ProfileOAuth2TokenService::RegisterCacheEntry(
const std::string& refresh_token,
const ScopeSet& scopes,
diff --git a/chrome/browser/signin/profile_oauth2_token_service.h b/chrome/browser/signin/profile_oauth2_token_service.h
index d5cbe9f..28ee5d5 100644
--- a/chrome/browser/signin/profile_oauth2_token_service.h
+++ b/chrome/browser/signin/profile_oauth2_token_service.h
@@ -56,6 +56,9 @@
// SigninGlobalError::AuthStatusProvider implementation.
virtual GoogleServiceAuthError GetAuthStatus() const OVERRIDE;
+ // OAuth2TokenService implementation.
+ virtual net::URLRequestContextGetter* GetRequestContext() OVERRIDE;
+
// Takes injected TokenService for testing.
bool ShouldCacheForRefreshToken(TokenService *token_service,
const std::string& refresh_token);
@@ -72,7 +75,7 @@
protected:
friend class ProfileOAuth2TokenServiceFactory;
- explicit ProfileOAuth2TokenService(net::URLRequestContextGetter* getter);
+ ProfileOAuth2TokenService();
virtual ~ProfileOAuth2TokenService();
// OAuth2TokenService overrides.
diff --git a/chrome/browser/signin/profile_oauth2_token_service_factory.cc b/chrome/browser/signin/profile_oauth2_token_service_factory.cc
index 92c88e6..e40433b 100644
--- a/chrome/browser/signin/profile_oauth2_token_service_factory.cc
+++ b/chrome/browser/signin/profile_oauth2_token_service_factory.cc
@@ -49,9 +49,9 @@
Profile* profile = static_cast<Profile*>(context);
ProfileOAuth2TokenService* service;
#if defined(OS_ANDROID)
- service = new AndroidProfileOAuth2TokenService(profile->GetRequestContext());
+ service = new AndroidProfileOAuth2TokenService();
#else
- service = new ProfileOAuth2TokenService(profile->GetRequestContext());
+ service = new ProfileOAuth2TokenService();
#endif
service->Initialize(profile);
return service;
diff --git a/chrome/browser/signin/profile_oauth2_token_service_request_unittest.cc b/chrome/browser/signin/profile_oauth2_token_service_request_unittest.cc
index adcf700..ef1c18b 100644
--- a/chrome/browser/signin/profile_oauth2_token_service_request_unittest.cc
+++ b/chrome/browser/signin/profile_oauth2_token_service_request_unittest.cc
@@ -115,8 +115,7 @@
}
MockProfileOAuth2TokenService::MockProfileOAuth2TokenService()
- : ProfileOAuth2TokenService(NULL /* URLRequestContextGetter */),
- success_(true),
+ : success_(true),
oauth2_access_token_(std::string("success token")) {
}
diff --git a/chrome/browser/signin/signin_manager.cc b/chrome/browser/signin/signin_manager.cc
index d0629e5..f419d84 100644
--- a/chrome/browser/signin/signin_manager.cc
+++ b/chrome/browser/signin/signin_manager.cc
@@ -38,7 +38,7 @@
#include "google_apis/gaia/gaia_urls.h"
#include "net/base/escape.h"
#include "net/url_request/url_request_context.h"
-#include "third_party/icu/public/i18n/unicode/regex.h"
+#include "third_party/icu/source/i18n/unicode/regex.h"
using namespace signin_internals_util;
diff --git a/chrome/browser/ssl/ssl_tab_helper.cc b/chrome/browser/ssl/ssl_tab_helper.cc
index 802687e..9cb9fde 100644
--- a/chrome/browser/ssl/ssl_tab_helper.cc
+++ b/chrome/browser/ssl/ssl_tab_helper.cc
@@ -42,9 +42,9 @@
class SSLCertResultInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
- // Creates an SSL cert result delegate. If |previous_infobar| is
+ // Creates an SSL cert result infobar delegate. If |previous_infobar| is
// NULL, adds the infobar to |infobar_service|; otherwise, replaces
- // |previous_infobar|. Returns the new delegate if it was successfully added.
+ // |previous_infobar|. Returns the new infobar if it was successfully added.
// |cert| is valid iff cert addition was successful.
static InfoBarDelegate* Create(InfoBarService* infobar_service,
InfoBarDelegate* previous_infobar,
@@ -137,7 +137,7 @@
explicit SSLAddCertData(InfoBarService* infobar_service);
virtual ~SSLAddCertData();
- // Displays an infobar, replacing |infobar_delegate_| if it exists.
+ // Displays an infobar, replacing |infobar_| if it exists.
void ShowInfoBar(const string16& message, net::X509Certificate* cert);
private:
@@ -147,7 +147,7 @@
const content::NotificationDetails& details) OVERRIDE;
InfoBarService* infobar_service_;
- InfoBarDelegate* infobar_delegate_;
+ InfoBarDelegate* infobar_;
content::NotificationRegistrar registrar_;
DISALLOW_COPY_AND_ASSIGN(SSLAddCertData);
@@ -155,7 +155,7 @@
SSLTabHelper::SSLAddCertData::SSLAddCertData(InfoBarService* infobar_service)
: infobar_service_(infobar_service),
- infobar_delegate_(NULL) {
+ infobar_(NULL) {
content::Source<InfoBarService> source(infobar_service_);
registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
source);
@@ -168,8 +168,8 @@
void SSLTabHelper::SSLAddCertData::ShowInfoBar(const string16& message,
net::X509Certificate* cert) {
- infobar_delegate_ = SSLCertResultInfoBarDelegate::Create(
- infobar_service_, infobar_delegate_, message, cert);
+ infobar_ = SSLCertResultInfoBarDelegate::Create(infobar_service_, infobar_,
+ message, cert);
}
void SSLTabHelper::SSLAddCertData::Observe(
@@ -178,11 +178,11 @@
const content::NotificationDetails& details) {
DCHECK(type == chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED ||
type == chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REPLACED);
- if (infobar_delegate_ ==
+ if (infobar_ ==
((type == chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED) ?
content::Details<InfoBarRemovedDetails>(details)->first :
content::Details<InfoBarReplacedDetails>(details)->first))
- infobar_delegate_ = NULL;
+ infobar_ = NULL;
}
diff --git a/chrome/browser/status_icons/status_icon.cc b/chrome/browser/status_icons/status_icon.cc
index 00270d2..79efafc 100644
--- a/chrome/browser/status_icons/status_icon.cc
+++ b/chrome/browser/status_icons/status_icon.cc
@@ -29,6 +29,9 @@
FOR_EACH_OBSERVER(StatusIconObserver, observers_, OnStatusIconClicked());
}
+void StatusIcon::SetClickActionLabel(const string16& label) {
+}
+
#if defined(OS_WIN)
void StatusIcon::DispatchBalloonClickEvent() {
FOR_EACH_OBSERVER(StatusIconObserver, observers_, OnBalloonClicked());
diff --git a/chrome/browser/status_icons/status_icon.h b/chrome/browser/status_icons/status_icon.h
index 8d846a5..6110c64 100644
--- a/chrome/browser/status_icons/status_icon.h
+++ b/chrome/browser/status_icons/status_icon.h
@@ -34,6 +34,12 @@
// Sets the hover text for this status icon.
virtual void SetToolTip(const string16& tool_tip) = 0;
+ // Sets the label for the menu item which is created as a replacement for the
+ // status icon click action on platforms that do not support custom click
+ // actions for the status icon (e.g. Ubuntu Unity). Since only a few platforms
+ // would need this, the default action is to ignore the call.
+ virtual void SetClickActionLabel(const string16& label);
+
// Displays a notification balloon with the specified contents.
// Depending on the platform it might not appear by the icon tray.
virtual void DisplayBalloon(const gfx::ImageSkia& icon,
diff --git a/chrome/browser/status_icons/status_tray.cc b/chrome/browser/status_icons/status_tray.cc
index 3d99ad5..aaa7a57 100644
--- a/chrome/browser/status_icons/status_tray.cc
+++ b/chrome/browser/status_icons/status_tray.cc
@@ -11,8 +11,8 @@
StatusTray::~StatusTray() {
}
-StatusIcon* StatusTray::CreateStatusIcon() {
- StatusIcon* icon = CreatePlatformStatusIcon();
+StatusIcon* StatusTray::CreateStatusIcon(StatusIconType type) {
+ StatusIcon* icon = CreatePlatformStatusIcon(type);
if (icon)
status_icons_.push_back(icon);
return icon;
diff --git a/chrome/browser/status_icons/status_tray.h b/chrome/browser/status_icons/status_tray.h
index c715ec5..e4f240d 100644
--- a/chrome/browser/status_icons/status_tray.h
+++ b/chrome/browser/status_icons/status_tray.h
@@ -15,6 +15,14 @@
// APIs to add/remove icons to the tray and attach context menus.
class StatusTray {
public:
+ enum StatusIconType {
+ NOTIFICATION_TRAY_ICON = 0,
+ MEDIA_STREAM_CAPTURE_ICON,
+ BACKGROUND_MODE_ICON,
+ OTHER_ICON,
+ NAMED_STATUS_ICON_COUNT
+ };
+
// Static factory method that is implemented separately for each platform to
// produce the appropriate platform-specific instance. Returns NULL if this
// platform does not support status icons.
@@ -24,7 +32,7 @@
// Creates a new StatusIcon. The StatusTray retains ownership of the
// StatusIcon. Returns NULL if the StatusIcon could not be created.
- StatusIcon* CreateStatusIcon();
+ StatusIcon* CreateStatusIcon(StatusIconType type);
// Removes |icon| from this status tray.
void RemoveStatusIcon(StatusIcon* icon);
@@ -35,14 +43,12 @@
StatusTray();
// Factory method for creating a status icon for this platform.
- virtual StatusIcon* CreatePlatformStatusIcon() = 0;
+ virtual StatusIcon* CreatePlatformStatusIcon(StatusIconType type) = 0;
// Returns the list of active status icons so subclasses can operate on them.
const StatusIcons& status_icons() const { return status_icons_; }
private:
- FRIEND_TEST_ALL_PREFIXES(StatusTrayTest, CreateRemove);
-
// List containing all active StatusIcons. The icons are owned by this
// StatusTray.
StatusIcons status_icons_;
diff --git a/chrome/browser/status_icons/status_tray_unittest.cc b/chrome/browser/status_icons/status_tray_unittest.cc
index 818a4fa..a71fa9a 100644
--- a/chrome/browser/status_icons/status_tray_unittest.cc
+++ b/chrome/browser/status_icons/status_tray_unittest.cc
@@ -24,25 +24,28 @@
class TestStatusTray : public StatusTray {
public:
- MOCK_METHOD0(CreatePlatformStatusIcon, StatusIcon*());
+ MOCK_METHOD1(CreatePlatformStatusIcon,
+ StatusIcon*(StatusTray::StatusIconType type));
MOCK_METHOD1(UpdatePlatformContextMenu, void(ui::MenuModel*));
+
+ const StatusIcons& GetStatusIconsForTest() const { return status_icons(); }
};
TEST(StatusTrayTest, Create) {
// Check for creation and leaks.
TestStatusTray tray;
- EXPECT_CALL(tray,
- CreatePlatformStatusIcon()).WillOnce(Return(new MockStatusIcon()));
- tray.CreateStatusIcon();
+ EXPECT_CALL(tray, CreatePlatformStatusIcon(StatusTray::OTHER_ICON)).WillOnce(
+ Return(new MockStatusIcon()));
+ tray.CreateStatusIcon(StatusTray::OTHER_ICON);
}
// Make sure that removing an icon removes it from the list.
TEST(StatusTrayTest, CreateRemove) {
TestStatusTray tray;
- EXPECT_CALL(tray,
- CreatePlatformStatusIcon()).WillOnce(Return(new MockStatusIcon()));
- StatusIcon* icon = tray.CreateStatusIcon();
- EXPECT_EQ(1U, tray.status_icons_.size());
+ EXPECT_CALL(tray, CreatePlatformStatusIcon(StatusTray::OTHER_ICON)).WillOnce(
+ Return(new MockStatusIcon()));
+ StatusIcon* icon = tray.CreateStatusIcon(StatusTray::OTHER_ICON);
+ EXPECT_EQ(1U, tray.GetStatusIconsForTest().size());
tray.RemoveStatusIcon(icon);
- EXPECT_EQ(0U, tray.status_icons_.size());
+ EXPECT_EQ(0U, tray.GetStatusIconsForTest().size());
}
diff --git a/chrome/browser/storage_monitor/image_capture_device_manager_unittest.mm b/chrome/browser/storage_monitor/image_capture_device_manager_unittest.mm
index d6be33d..a259ef1 100644
--- a/chrome/browser/storage_monitor/image_capture_device_manager_unittest.mm
+++ b/chrome/browser/storage_monitor/image_capture_device_manager_unittest.mm
@@ -15,6 +15,7 @@
#include "chrome/browser/storage_monitor/image_capture_device.h"
#include "chrome/browser/storage_monitor/image_capture_device_manager.h"
#include "chrome/browser/storage_monitor/test_storage_monitor.h"
+#include "chrome/test/base/testing_browser_process.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -257,6 +258,8 @@
virtual void SetUp() OVERRIDE {
ui_thread_.reset(new content::TestBrowserThread(
content::BrowserThread::UI, &message_loop_));
+
+ monitor_ = chrome::test::TestStorageMonitor::CreateAndInstall();
}
MockICCameraDevice* AttachDevice(
@@ -278,28 +281,29 @@
protected:
base::MessageLoopForUI message_loop_;
scoped_ptr<content::TestBrowserThread> ui_thread_;
- chrome::test::TestStorageMonitor monitor_;
+
+ chrome::test::TestStorageMonitor* monitor_;
TestCameraListener listener_;
};
TEST_F(ImageCaptureDeviceManagerTest, TestAttachDetach) {
chrome::ImageCaptureDeviceManager manager;
- manager.SetNotifications(monitor_.receiver());
+ manager.SetNotifications(monitor_->receiver());
ICCameraDevice* device = AttachDevice(&manager);
std::vector<chrome::StorageInfo> devices =
- monitor_.GetAllAvailableStorages();
+ monitor_->GetAllAvailableStorages();
ASSERT_EQ(1U, devices.size());
EXPECT_EQ(std::string("ic:") + kDeviceId, devices[0].device_id());
DetachDevice(&manager, device);
- devices = monitor_.GetAllAvailableStorages();
+ devices = monitor_->GetAllAvailableStorages();
ASSERT_EQ(0U, devices.size());
};
TEST_F(ImageCaptureDeviceManagerTest, OpenCamera) {
chrome::ImageCaptureDeviceManager manager;
- manager.SetNotifications(monitor_.receiver());
+ manager.SetNotifications(monitor_->receiver());
ICCameraDevice* device = AttachDevice(&manager);
EXPECT_FALSE(chrome::ImageCaptureDeviceManager::deviceForUUID(
@@ -335,7 +339,7 @@
TEST_F(ImageCaptureDeviceManagerTest, RemoveCamera) {
chrome::ImageCaptureDeviceManager manager;
- manager.SetNotifications(monitor_.receiver());
+ manager.SetNotifications(monitor_->receiver());
ICCameraDevice* device = AttachDevice(&manager);
base::scoped_nsobject<ImageCaptureDevice> camera(
@@ -354,7 +358,7 @@
content::BrowserThread::FILE, &message_loop_));
chrome::ImageCaptureDeviceManager manager;
- manager.SetNotifications(monitor_.receiver());
+ manager.SetNotifications(monitor_->receiver());
MockICCameraDevice* device = AttachDevice(&manager);
base::scoped_nsobject<ImageCaptureDevice> camera(
@@ -410,7 +414,7 @@
content::BrowserThread::FILE, &message_loop_));
chrome::ImageCaptureDeviceManager manager;
- manager.SetNotifications(monitor_.receiver());
+ manager.SetNotifications(monitor_->receiver());
MockICCameraDevice* device = AttachDevice(&manager);
base::scoped_nsobject<ImageCaptureDevice> camera(
diff --git a/chrome/browser/storage_monitor/media_storage_util_unittest.cc b/chrome/browser/storage_monitor/media_storage_util_unittest.cc
index 12fd336..4ed217e 100644
--- a/chrome/browser/storage_monitor/media_storage_util_unittest.cc
+++ b/chrome/browser/storage_monitor/media_storage_util_unittest.cc
@@ -13,6 +13,7 @@
#include "chrome/browser/storage_monitor/removable_device_constants.h"
#include "chrome/browser/storage_monitor/storage_monitor.h"
#include "chrome/browser/storage_monitor/test_storage_monitor.h"
+#include "chrome/test/base/testing_browser_process.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -47,7 +48,7 @@
const string16& name,
const base::FilePath::StringType& location) {
StorageInfo info(id, name, location, string16(), string16(), string16(), 0);
- monitor_.receiver()->ProcessAttach(info);
+ monitor_->receiver()->ProcessAttach(info);
}
protected:
@@ -62,11 +63,12 @@
}
virtual void SetUp() OVERRIDE {
+ monitor_ = chrome::test::TestStorageMonitor::CreateAndInstall();
ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
file_thread_.Start();
}
- virtual void TearDown() {
+ virtual void TearDown() OVERRIDE {
WaitForFileThread();
}
@@ -86,7 +88,7 @@
base::MessageLoop message_loop_;
private:
- chrome::test::TestStorageMonitor monitor_;
+ chrome::test::TestStorageMonitor* monitor_;
content::TestBrowserThread ui_thread_;
content::TestBrowserThread file_thread_;
base::ScopedTempDir scoped_temp_dir_;
diff --git a/chrome/browser/storage_monitor/media_transfer_protocol_device_observer_linux_unittest.cc b/chrome/browser/storage_monitor/media_transfer_protocol_device_observer_linux_unittest.cc
index 4a1827b..c895cee 100644
--- a/chrome/browser/storage_monitor/media_transfer_protocol_device_observer_linux_unittest.cc
+++ b/chrome/browser/storage_monitor/media_transfer_protocol_device_observer_linux_unittest.cc
@@ -12,10 +12,12 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/browser_process.h"
#include "chrome/browser/storage_monitor/mock_removable_storage_observer.h"
#include "chrome/browser/storage_monitor/storage_info.h"
#include "chrome/browser/storage_monitor/storage_monitor.h"
#include "chrome/browser/storage_monitor/test_storage_monitor.h"
+#include "chrome/test/base/testing_browser_process.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -92,13 +94,16 @@
protected:
virtual void SetUp() OVERRIDE {
mock_storage_observer_.reset(new MockRemovableStorageObserver);
+ chrome::test::TestStorageMonitor* monitor =
+ chrome::test::TestStorageMonitor::CreateAndInstall();
mtp_device_observer_.reset(
- new TestMediaTransferProtocolDeviceObserverLinux(monitor_.receiver()));
- monitor_.AddObserver(mock_storage_observer_.get());
+ new TestMediaTransferProtocolDeviceObserverLinux(monitor->receiver()));
+ monitor->AddObserver(mock_storage_observer_.get());
}
virtual void TearDown() OVERRIDE {
- monitor_.RemoveObserver(mock_storage_observer_.get());
+ StorageMonitor* monitor = g_browser_process->storage_monitor();
+ monitor->RemoveObserver(mock_storage_observer_.get());
mtp_device_observer_.reset();
}
@@ -115,7 +120,6 @@
base::MessageLoop message_loop_;
content::TestBrowserThread file_thread_;
- chrome::test::TestStorageMonitor monitor_;
scoped_ptr<TestMediaTransferProtocolDeviceObserverLinux> mtp_device_observer_;
scoped_ptr<MockRemovableStorageObserver> mock_storage_observer_;
diff --git a/chrome/browser/storage_monitor/storage_monitor.cc b/chrome/browser/storage_monitor/storage_monitor.cc
index a771fd5..10d043e 100644
--- a/chrome/browser/storage_monitor/storage_monitor.cc
+++ b/chrome/browser/storage_monitor/storage_monitor.cc
@@ -6,13 +6,12 @@
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/browser_process.h"
#include "chrome/browser/storage_monitor/removable_storage_observer.h"
#include "chrome/browser/storage_monitor/transient_device_ids.h"
namespace chrome {
-static StorageMonitor* g_storage_monitor = NULL;
-
StorageMonitor::Receiver::~Receiver() {
}
@@ -46,7 +45,10 @@
}
StorageMonitor* StorageMonitor::GetInstance() {
- return g_storage_monitor;
+ if (g_browser_process)
+ return g_browser_process->storage_monitor();
+
+ return NULL;
}
std::vector<StorageInfo> StorageMonitor::GetAllAvailableStorages() const {
@@ -117,18 +119,9 @@
initialized_(false),
transient_device_ids_(new TransientDeviceIds) {
receiver_.reset(new ReceiverImpl(this));
-
- DCHECK(!g_storage_monitor);
- g_storage_monitor = this;
}
StorageMonitor::~StorageMonitor() {
- g_storage_monitor = NULL;
-}
-
-// static
-void StorageMonitor::RemoveSingletonForTesting() {
- g_storage_monitor = NULL;
}
StorageMonitor::Receiver* StorageMonitor::receiver() const {
diff --git a/chrome/browser/storage_monitor/storage_monitor.h b/chrome/browser/storage_monitor/storage_monitor.h
index 9258dd4..9d20d60 100644
--- a/chrome/browser/storage_monitor/storage_monitor.h
+++ b/chrome/browser/storage_monitor/storage_monitor.h
@@ -14,7 +14,6 @@
#include "base/observer_list_threadsafe.h"
#include "base/strings/string16.h"
#include "base/synchronization/lock.h"
-#include "base/threading/thread_checker.h"
#include "chrome/browser/storage_monitor/storage_info.h"
class ChromeBrowserMainPartsLinux;
@@ -37,8 +36,8 @@
// Base class for platform-specific instances watching for removable storage
// attachments/detachments.
-// Lifecycle contracts: This class is created by ChromeBrowserMain
-// implementations before the profile is initialized, so listeners can be
+// Lifecycle contracts: This class is created in the browser process
+// before the profile is initialized, so listeners can be
// created during profile construction. The platform-specific initialization,
// which can lead to calling registered listeners with notifications of
// attached volumes, are done lazily at first use through the async
@@ -70,10 +69,18 @@
EJECT_FAILURE
};
- // Returns a pointer to an object owned by the BrowserMainParts, with lifetime
- // somewhat shorter than a process Singleton.
+ // Returns a pointer to a newly created per-platform object with the
+ // StorageMonitor interface.
+ static StorageMonitor* Create();
+
+ // Returns a pointer to an object owned by BrowserProcess, with lifetime
+ // starting before main message loop start, and ending after main message loop
+ // shutdown. Called outside it's lifetime (or with no browser process),
+ // returns NULL.
static StorageMonitor* GetInstance();
+ virtual ~StorageMonitor();
+
// Ensures that the storage monitor is initialized. The provided callback, If
// non-null, will be called when initialization is complete. If initialization
// has already completed, this callback will be invoked within the calling
@@ -135,11 +142,6 @@
friend class ::SystemInfoStorageEjectApiTest;
StorageMonitor();
- virtual ~StorageMonitor();
-
- // Removes the existing singleton for testing.
- // (So that a new one can be created.)
- static void RemoveSingletonForTesting();
virtual Receiver* receiver() const;
diff --git a/chrome/browser/storage_monitor/storage_monitor_chromeos.cc b/chrome/browser/storage_monitor/storage_monitor_chromeos.cc
index c61f530..a871fa8 100644
--- a/chrome/browser/storage_monitor/storage_monitor_chromeos.cc
+++ b/chrome/browser/storage_monitor/storage_monitor_chromeos.cc
@@ -307,3 +307,11 @@
}
} // namespace chromeos
+
+namespace chrome {
+
+StorageMonitor* StorageMonitor::Create() {
+ return new chromeos::StorageMonitorCros();
+}
+
+} // namespace chrome
diff --git a/chrome/browser/storage_monitor/storage_monitor_chromeos_unittest.cc b/chrome/browser/storage_monitor/storage_monitor_chromeos_unittest.cc
index 67302fd..f972c87 100644
--- a/chrome/browser/storage_monitor/storage_monitor_chromeos_unittest.cc
+++ b/chrome/browser/storage_monitor/storage_monitor_chromeos_unittest.cc
@@ -16,6 +16,8 @@
#include "chrome/browser/storage_monitor/removable_device_constants.h"
#include "chrome/browser/storage_monitor/storage_info.h"
#include "chrome/browser/storage_monitor/test_media_transfer_protocol_manager_linux.h"
+#include "chrome/browser/storage_monitor/test_storage_monitor.h"
+#include "chrome/test/base/testing_browser_process.h"
#include "chromeos/disks/mock_disk_mount_manager.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -135,7 +137,7 @@
base::MessageLoop ui_loop_;
- scoped_ptr<TestStorageMonitorCros> monitor_;
+ TestStorageMonitorCros* monitor_;
// Owned by DiskMountManager.
disks::MockDiskMountManager* disk_mount_manager_mock_;
@@ -176,14 +178,20 @@
mock_storage_observer_.reset(new chrome::MockRemovableStorageObserver);
// Initialize the test subject.
- monitor_.reset(new TestStorageMonitorCros());
+ chrome::test::TestStorageMonitor::RemoveSingleton();
+ monitor_ = new TestStorageMonitorCros();
+ scoped_ptr<chrome::StorageMonitor> pass_monitor(monitor_);
+ TestingBrowserProcess* browser_process = TestingBrowserProcess::GetGlobal();
+ DCHECK(browser_process);
+ browser_process->SetStorageMonitor(pass_monitor.Pass());
+
monitor_->Init();
monitor_->AddObserver(mock_storage_observer_.get());
}
void StorageMonitorCrosTest::TearDown() {
monitor_->RemoveObserver(mock_storage_observer_.get());
- monitor_.reset();
+ monitor_ = NULL;
disk_mount_manager_mock_ = NULL;
DiskMountManager::Shutdown();
diff --git a/chrome/browser/storage_monitor/storage_monitor_linux.cc b/chrome/browser/storage_monitor/storage_monitor_linux.cc
index 6435529..f2154ed 100644
--- a/chrome/browser/storage_monitor/storage_monitor_linux.cc
+++ b/chrome/browser/storage_monitor/storage_monitor_linux.cc
@@ -513,4 +513,9 @@
receiver()->ProcessAttach(*storage_info);
}
+StorageMonitor* StorageMonitor::Create() {
+ const base::FilePath kDefaultMtabPath("/etc/mtab");
+ return new StorageMonitorLinux(kDefaultMtabPath);
+}
+
} // namespace chrome
diff --git a/chrome/browser/storage_monitor/storage_monitor_linux_unittest.cc b/chrome/browser/storage_monitor/storage_monitor_linux_unittest.cc
index 4c87e3d..1a19918 100644
--- a/chrome/browser/storage_monitor/storage_monitor_linux_unittest.cc
+++ b/chrome/browser/storage_monitor/storage_monitor_linux_unittest.cc
@@ -23,6 +23,8 @@
#include "chrome/browser/storage_monitor/storage_info.h"
#include "chrome/browser/storage_monitor/storage_monitor.h"
#include "chrome/browser/storage_monitor/test_media_transfer_protocol_manager_linux.h"
+#include "chrome/browser/storage_monitor/test_storage_monitor.h"
+#include "chrome/test/base/testing_browser_process.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -181,8 +183,13 @@
arraysize(initial_test_data),
true /* overwrite */);
- // Initialize the test subject.
- monitor_.reset(new TestStorageMonitorLinux(mtab_file_, &message_loop_));
+ test::TestStorageMonitor::RemoveSingleton();
+ monitor_ = new TestStorageMonitorLinux(mtab_file_, &message_loop_);
+ scoped_ptr<StorageMonitor> pass_monitor(monitor_);
+ TestingBrowserProcess* browser_process = TestingBrowserProcess::GetGlobal();
+ DCHECK(browser_process);
+ browser_process->SetStorageMonitor(pass_monitor.Pass());
+
mock_storage_observer_.reset(new MockRemovableStorageObserver);
monitor_->AddObserver(mock_storage_observer_.get());
@@ -193,8 +200,10 @@
virtual void TearDown() OVERRIDE {
base::RunLoop().RunUntilIdle();
monitor_->RemoveObserver(mock_storage_observer_.get());
- monitor_.reset();
base::RunLoop().RunUntilIdle();
+
+ // Linux storage monitor must be destroyed on the UI thread, so do it here.
+ test::TestStorageMonitor::RemoveSingleton();
}
// Append mtab entries from the |data| array of size |data_size| to the mtab
@@ -243,7 +252,7 @@
}
StorageMonitor* notifier() {
- return monitor_.get();
+ return monitor_;
}
uint64 GetStorageSize(const base::FilePath& path) {
@@ -316,7 +325,7 @@
// Path to the test mtab file.
base::FilePath mtab_file_;
- scoped_ptr<TestStorageMonitorLinux> monitor_;
+ TestStorageMonitorLinux* monitor_;
DISALLOW_COPY_AND_ASSIGN(StorageMonitorLinuxTest);
};
diff --git a/chrome/browser/storage_monitor/storage_monitor_mac.mm b/chrome/browser/storage_monitor/storage_monitor_mac.mm
index 346f958..f642864 100644
--- a/chrome/browser/storage_monitor/storage_monitor_mac.mm
+++ b/chrome/browser/storage_monitor/storage_monitor_mac.mm
@@ -369,4 +369,8 @@
return false;
}
+StorageMonitor* StorageMonitor::Create() {
+ return new StorageMonitorMac();
+}
+
} // namespace chrome
diff --git a/chrome/browser/storage_monitor/storage_monitor_mac_unittest.mm b/chrome/browser/storage_monitor/storage_monitor_mac_unittest.mm
index b8c584f..ec3f7ff 100644
--- a/chrome/browser/storage_monitor/storage_monitor_mac_unittest.mm
+++ b/chrome/browser/storage_monitor/storage_monitor_mac_unittest.mm
@@ -14,6 +14,8 @@
#include "chrome/browser/storage_monitor/mock_removable_storage_observer.h"
#include "chrome/browser/storage_monitor/removable_device_constants.h"
#include "chrome/browser/storage_monitor/storage_info.h"
+#include "chrome/browser/storage_monitor/test_storage_monitor.h"
+#include "chrome/test/base/testing_browser_process.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -44,7 +46,12 @@
}
virtual void SetUp() OVERRIDE {
- monitor_.reset(new StorageMonitorMac);
+ test::TestStorageMonitor::RemoveSingleton();
+ monitor_ = new StorageMonitorMac;
+ scoped_ptr<StorageMonitor> pass_monitor(monitor_);
+ TestingBrowserProcess* browser_process = TestingBrowserProcess::GetGlobal();
+ DCHECK(browser_process);
+ browser_process->SetStorageMonitor(pass_monitor.Pass());
mock_storage_observer_.reset(new MockRemovableStorageObserver);
monitor_->AddObserver(mock_storage_observer_.get());
@@ -60,7 +67,7 @@
void UpdateDisk(StorageInfo info, StorageMonitorMac::UpdateType update_type) {
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
base::Bind(&StorageMonitorMac::UpdateDisk,
- base::Unretained(monitor_.get()),
+ base::Unretained(monitor_),
"dummy_bsd_name", info, update_type));
base::RunLoop().RunUntilIdle();
}
@@ -79,7 +86,7 @@
std::string device_id_;
StorageInfo disk_info_;
- scoped_ptr<StorageMonitorMac> monitor_;
+ StorageMonitorMac* monitor_;
};
TEST_F(StorageMonitorMacTest, AddRemove) {
diff --git a/chrome/browser/storage_monitor/storage_monitor_unittest.cc b/chrome/browser/storage_monitor/storage_monitor_unittest.cc
index 50a3a4a..a98ec54 100644
--- a/chrome/browser/storage_monitor/storage_monitor_unittest.cc
+++ b/chrome/browser/storage_monitor/storage_monitor_unittest.cc
@@ -10,22 +10,31 @@
#include "chrome/browser/storage_monitor/test_storage_monitor.h"
#include "testing/gtest/include/gtest/gtest.h"
+namespace {
+
+void SetLatch(bool* called) {
+ *called = true;
+}
+
+} // namespace
+
namespace chrome {
TEST(StorageMonitorTest, TestInitialize) {
+ test::TestStorageMonitor::RemoveSingleton();
test::TestStorageMonitor monitor;
EXPECT_FALSE(monitor.init_called_);
- base::WaitableEvent event(false, false);
- monitor.EnsureInitialized(base::Bind(&base::WaitableEvent::Signal,
- base::Unretained(&event)));
+ bool initialized = false;
+ monitor.EnsureInitialized(base::Bind(&SetLatch, &initialized));
EXPECT_TRUE(monitor.init_called_);
- EXPECT_FALSE(event.IsSignaled());
+ EXPECT_FALSE(initialized);
monitor.MarkInitialized();
- EXPECT_TRUE(event.IsSignaled());
+ EXPECT_TRUE(initialized);
}
TEST(StorageMonitorTest, DeviceAttachDetachNotifications) {
+ test::TestStorageMonitor::RemoveSingleton();
base::MessageLoop message_loop;
const string16 kDeviceName = ASCIIToUTF16("media device");
const std::string kDeviceId1 = "dcim:UUID:FFF0-0001";
@@ -73,6 +82,7 @@
}
TEST(StorageMonitorTest, GetAllAvailableStoragesEmpty) {
+ test::TestStorageMonitor::RemoveSingleton();
base::MessageLoop message_loop;
test::TestStorageMonitor monitor;
std::vector<StorageInfo> devices = monitor.GetAllAvailableStorages();
@@ -80,6 +90,7 @@
}
TEST(StorageMonitorTest, GetAllAvailableStorageAttachDetach) {
+ test::TestStorageMonitor::RemoveSingleton();
base::MessageLoop message_loop;
test::TestStorageMonitor monitor;
const std::string kDeviceId1 = "dcim:UUID:FFF0-0042";
diff --git a/chrome/browser/storage_monitor/storage_monitor_win.cc b/chrome/browser/storage_monitor/storage_monitor_win.cc
index 4fcc8f6..beec36d 100644
--- a/chrome/browser/storage_monitor/storage_monitor_win.cc
+++ b/chrome/browser/storage_monitor/storage_monitor_win.cc
@@ -18,12 +18,6 @@
// StorageMonitorWin -------------------------------------------------------
-// static
-StorageMonitorWin* StorageMonitorWin::Create() {
- return new StorageMonitorWin(new VolumeMountWatcherWin(),
- new PortableDeviceWatcherWin());
-}
-
StorageMonitorWin::StorageMonitorWin(
VolumeMountWatcherWin* volume_mount_watcher,
PortableDeviceWatcherWin* portable_device_watcher)
@@ -167,4 +161,9 @@
portable_device_watcher_->OnWindowMessage(event_type, data);
}
+StorageMonitor* StorageMonitor::Create() {
+ return new StorageMonitorWin(new VolumeMountWatcherWin(),
+ new PortableDeviceWatcherWin());
+}
+
} // namespace chrome
diff --git a/chrome/browser/storage_monitor/storage_monitor_win.h b/chrome/browser/storage_monitor/storage_monitor_win.h
index 6472c0d..c036fbb 100644
--- a/chrome/browser/storage_monitor/storage_monitor_win.h
+++ b/chrome/browser/storage_monitor/storage_monitor_win.h
@@ -25,10 +25,6 @@
class StorageMonitorWin : public StorageMonitor {
public:
- // Creates an instance of StorageMonitorWin. Should only be called by browser
- // start up code. Use GetInstance() instead.
- static StorageMonitorWin* Create();
-
virtual ~StorageMonitorWin();
// Must be called after the file thread is created.
@@ -49,10 +45,11 @@
private:
class PortableDeviceNotifications;
friend class test::TestStorageMonitorWin;
+ friend StorageMonitor* StorageMonitor::Create();
// To support unit tests, this constructor takes |volume_mount_watcher| and
// |portable_device_watcher| objects. These params are either constructed in
- // unit tests or in StorageMonitorWin::Create() function.
+ // unit tests or in StorageMonitorWin Create() function.
StorageMonitorWin(VolumeMountWatcherWin* volume_mount_watcher,
PortableDeviceWatcherWin* portable_device_watcher);
diff --git a/chrome/browser/storage_monitor/storage_monitor_win_unittest.cc b/chrome/browser/storage_monitor/storage_monitor_win_unittest.cc
index 12a742b..c23cb34 100644
--- a/chrome/browser/storage_monitor/storage_monitor_win_unittest.cc
+++ b/chrome/browser/storage_monitor/storage_monitor_win_unittest.cc
@@ -19,9 +19,11 @@
#include "chrome/browser/storage_monitor/storage_info.h"
#include "chrome/browser/storage_monitor/storage_monitor_win.h"
#include "chrome/browser/storage_monitor/test_portable_device_watcher_win.h"
+#include "chrome/browser/storage_monitor/test_storage_monitor.h"
#include "chrome/browser/storage_monitor/test_storage_monitor_win.h"
#include "chrome/browser/storage_monitor/test_volume_mount_watcher_win.h"
#include "chrome/browser/storage_monitor/volume_mount_watcher_win.h"
+#include "chrome/test/base/testing_browser_process.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -63,7 +65,7 @@
base::string16* pnp_device_id,
base::string16* storage_object_id);
- scoped_ptr<TestStorageMonitorWin> monitor_;
+ TestStorageMonitorWin* monitor_;
// Weak pointer; owned by the device notifications class.
TestVolumeMountWatcherWin* volume_mount_watcher_;
@@ -86,9 +88,15 @@
void StorageMonitorWinTest::SetUp() {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ test::TestStorageMonitor::RemoveSingleton();
volume_mount_watcher_ = new TestVolumeMountWatcherWin;
- monitor_.reset(new TestStorageMonitorWin(volume_mount_watcher_,
- new TestPortableDeviceWatcherWin));
+ monitor_ = new TestStorageMonitorWin(volume_mount_watcher_,
+ new TestPortableDeviceWatcherWin);
+ scoped_ptr<StorageMonitor> pass_monitor(monitor_);
+ TestingBrowserProcess* browser_process = TestingBrowserProcess::GetGlobal();
+ DCHECK(browser_process);
+ browser_process->SetStorageMonitor(pass_monitor.Pass());
+
monitor_->Init();
RunUntilIdle();
monitor_->AddObserver(&observer_);
@@ -98,11 +106,16 @@
RunUntilIdle();
monitor_->RemoveObserver(&observer_);
volume_mount_watcher_->ShutdownWorkerPool();
- monitor_.reset();
+ monitor_ = NULL;
+
+ // Windows storage monitor must be destroyed on the same thread
+ // as construction.
+ test::TestStorageMonitor::RemoveSingleton();
}
void StorageMonitorWinTest::PreAttachDevices() {
- monitor_.reset();
+ test::TestStorageMonitor::RemoveSingleton();
+ monitor_ = NULL;
volume_mount_watcher_ = new TestVolumeMountWatcherWin;
volume_mount_watcher_->SetAttachedDevicesFake();
@@ -117,8 +130,13 @@
expect_attach_calls++;
}
- monitor_.reset(new TestStorageMonitorWin(volume_mount_watcher_,
- new TestPortableDeviceWatcherWin));
+ monitor_ = new TestStorageMonitorWin(volume_mount_watcher_,
+ new TestPortableDeviceWatcherWin);
+ scoped_ptr<StorageMonitor> pass_monitor(monitor_);
+ TestingBrowserProcess* browser_process = TestingBrowserProcess::GetGlobal();
+ DCHECK(browser_process);
+ browser_process->SetStorageMonitor(pass_monitor.Pass());
+
monitor_->AddObserver(&observer_);
monitor_->Init();
diff --git a/chrome/browser/storage_monitor/test_storage_monitor.cc b/chrome/browser/storage_monitor/test_storage_monitor.cc
index e28ce2c..22c3f7d 100644
--- a/chrome/browser/storage_monitor/test_storage_monitor.cc
+++ b/chrome/browser/storage_monitor/test_storage_monitor.cc
@@ -4,7 +4,12 @@
#include "chrome/browser/storage_monitor/test_storage_monitor.h"
+#include "base/run_loop.h"
+#include "base/synchronization/waitable_event.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_process_impl.h"
#include "chrome/browser/storage_monitor/storage_info.h"
+#include "chrome/test/base/testing_browser_process.h"
#if defined(OS_LINUX)
#include "chrome/browser/storage_monitor/test_media_transfer_protocol_manager_linux.h"
@@ -25,10 +30,52 @@
TestStorageMonitor::~TestStorageMonitor() {}
-TestStorageMonitor*
-TestStorageMonitor::CreateForBrowserTests() {
- StorageMonitor::RemoveSingletonForTesting();
- return new TestStorageMonitor();
+TestStorageMonitor* TestStorageMonitor::CreateAndInstall() {
+ RemoveSingleton();
+ TestStorageMonitor* monitor = new TestStorageMonitor();
+ scoped_ptr<StorageMonitor> pass_monitor(monitor);
+ monitor->Init();
+ monitor->MarkInitialized();
+ TestingBrowserProcess* browser_process = TestingBrowserProcess::GetGlobal();
+ if (browser_process) {
+ browser_process->SetStorageMonitor(pass_monitor.Pass());
+ return monitor;
+ }
+ return NULL;
+}
+
+TestStorageMonitor* TestStorageMonitor::CreateForBrowserTests() {
+ TestStorageMonitor* return_monitor = new TestStorageMonitor();
+ return_monitor->Init();
+ return_monitor->MarkInitialized();
+
+ scoped_ptr<StorageMonitor> monitor(return_monitor);
+ BrowserProcessImpl* browser_process =
+ static_cast<BrowserProcessImpl*>(g_browser_process);
+ DCHECK(browser_process);
+ browser_process->set_storage_monitor_for_test(monitor.Pass());
+ return return_monitor;
+}
+
+void TestStorageMonitor::RemoveSingleton() {
+ TestingBrowserProcess* browser_process = TestingBrowserProcess::GetGlobal();
+ if (browser_process)
+ browser_process->SetStorageMonitor(scoped_ptr<StorageMonitor>());
+}
+
+// static
+void TestStorageMonitor::SyncInitialize() {
+ StorageMonitor* monitor = g_browser_process->storage_monitor();
+ if (monitor->IsInitialized())
+ return;
+
+ base::WaitableEvent event(true, false);
+ monitor->EnsureInitialized(base::Bind(&base::WaitableEvent::Signal,
+ base::Unretained(&event)));
+ while (!event.IsSignaled()) {
+ base::RunLoop().RunUntilIdle();
+ }
+ DCHECK(monitor->IsInitialized());
}
void TestStorageMonitor::Init() {
diff --git a/chrome/browser/storage_monitor/test_storage_monitor.h b/chrome/browser/storage_monitor/test_storage_monitor.h
index 6408e66..26ff133 100644
--- a/chrome/browser/storage_monitor/test_storage_monitor.h
+++ b/chrome/browser/storage_monitor/test_storage_monitor.h
@@ -21,10 +21,21 @@
void MarkInitialized();
- // Will create a new testing implementation for browser tests,
- // taking care to deal with the existing singleton correctly.
+ // Create and initialize a new TestStorageMonitor and install it
+ // in the TestingBrowserProcess.
+ static TestStorageMonitor* CreateAndInstall();
+
+ // Create and initialize a new TestStorageMonitor, and install it
+ // in the BrowserProcessImpl. (Browser tests use the production browser
+ // process implementation.)
static TestStorageMonitor* CreateForBrowserTests();
+ // Remove the singleton StorageMonitor from the TestingBrowserProcess.
+ static void RemoveSingleton();
+
+ // Synchronously initialize the current storage monitor.
+ static void SyncInitialize();
+
virtual bool GetStorageInfoForPath(
const base::FilePath& path,
StorageInfo* device_info) const OVERRIDE;
diff --git a/chrome/browser/sync/glue/android_invalidator_bridge_proxy_unittest.cc b/chrome/browser/sync/glue/android_invalidator_bridge_proxy_unittest.cc
deleted file mode 100644
index d3b9011..0000000
--- a/chrome/browser/sync/glue/android_invalidator_bridge_proxy_unittest.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-// 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/sync/glue/android_invalidator_bridge_proxy.h"
-
-#include <string>
-
-#include "base/memory/scoped_ptr.h"
-#include "base/threading/thread.h"
-#include "chrome/browser/sync/glue/android_invalidator_bridge.h"
-#include "chrome/test/base/profile_mock.h"
-#include "content/public/test/test_browser_thread.h"
-#include "sync/internal_api/public/base/model_type.h"
-#include "sync/internal_api/public/base/model_type_test_util.h"
-#include "sync/notifier/fake_invalidation_handler.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace syncer {
-class InvalidationStateTracker;
-} // namespace syncer
-
-namespace browser_sync {
-
-namespace {
-
-// All tests just verify that each call is passed through to the delegate, with
-// the exception of RegisterHandler, UnregisterHandler, and
-// UpdateRegisteredIds, which also verifies the call is forwarded to the
-// bridge.
-class AndroidInvalidatorBridgeProxyTest : public testing::Test {
- public:
- AndroidInvalidatorBridgeProxyTest()
- : ui_thread_(content::BrowserThread::UI, &ui_loop_),
- bridge_(&mock_profile_, ui_loop_.message_loop_proxy()),
- invalidator_(new AndroidInvalidatorBridgeProxy(&bridge_)) {
- // Pump |ui_loop_| to fully initialize |bridge_|.
- ui_loop_.RunUntilIdle();
- }
-
- virtual ~AndroidInvalidatorBridgeProxyTest() {
- DestroyInvalidator();
- }
-
- AndroidInvalidatorBridge* GetBridge() {
- return &bridge_;
- }
-
- AndroidInvalidatorBridgeProxy* GetInvalidator() {
- return invalidator_.get();
- }
-
- protected:
- void DestroyInvalidator() {
- invalidator_.reset();
- bridge_.StopForShutdown();
- ui_loop_.RunUntilIdle();
- }
-
- base::MessageLoop ui_loop_;
- content::TestBrowserThread ui_thread_;
- ::testing::NiceMock<ProfileMock> mock_profile_;
- AndroidInvalidatorBridge bridge_;
- scoped_ptr<AndroidInvalidatorBridgeProxy> invalidator_;
-};
-
-TEST_F(AndroidInvalidatorBridgeProxyTest, HandlerMethods) {
- syncer::ObjectIdSet ids;
- ids.insert(invalidation::ObjectId(1, "id1"));
-
- syncer::FakeInvalidationHandler handler;
-
- GetInvalidator()->RegisterHandler(&handler);
- EXPECT_TRUE(GetBridge()->IsHandlerRegisteredForTest(&handler));
-
- GetInvalidator()->UpdateRegisteredIds(&handler, ids);
- EXPECT_EQ(ids, GetBridge()->GetRegisteredIdsForTest(&handler));
-
- GetInvalidator()->UnregisterHandler(&handler);
- EXPECT_FALSE(GetBridge()->IsHandlerRegisteredForTest(&handler));
-}
-
-TEST_F(AndroidInvalidatorBridgeProxyTest, GetInvalidatorState) {
- // The AndroidInvalidatorBridge never enters an error state.
- EXPECT_EQ(syncer::INVALIDATIONS_ENABLED,
- GetInvalidator()->GetInvalidatorState());
- EXPECT_EQ(syncer::INVALIDATIONS_ENABLED,
- GetBridge()->GetInvalidatorState());
-}
-
-} // namespace
-} // namespace browser_sync
-
diff --git a/chrome/browser/sync/glue/android_invalidator_bridge_unittest.cc b/chrome/browser/sync/glue/android_invalidator_bridge_unittest.cc
deleted file mode 100644
index 3fae404..0000000
--- a/chrome/browser/sync/glue/android_invalidator_bridge_unittest.cc
+++ /dev/null
@@ -1,190 +0,0 @@
-// 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/sync/glue/android_invalidator_bridge.h"
-
-#include <cstddef>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/compiler_specific.h"
-#include "base/location.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop.h"
-#include "base/message_loop/message_loop_proxy.h"
-#include "base/run_loop.h"
-#include "base/sequenced_task_runner.h"
-#include "base/threading/thread.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/test/base/profile_mock.h"
-#include "content/public/browser/notification_details.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/test/test_browser_thread.h"
-#include "sync/internal_api/public/base/model_type.h"
-#include "sync/internal_api/public/base/model_type_invalidation_map.h"
-#include "sync/notifier/fake_invalidation_handler.h"
-#include "sync/notifier/object_id_invalidation_map_test_util.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace browser_sync {
-namespace {
-
-using ::testing::NiceMock;
-
-// Since all the interesting stuff happens on the sync thread, we have
-// to be careful to use GTest/GMock only on the main thread since they
-// are not thread-safe.
-
-class AndroidInvalidatorBridgeTest : public testing::Test {
- public:
- AndroidInvalidatorBridgeTest()
- : ui_thread_(content::BrowserThread::UI, &ui_loop_),
- sync_thread_("Sync thread"),
- sync_handler_notification_success_(false) {}
-
- virtual ~AndroidInvalidatorBridgeTest() {}
-
- protected:
- virtual void SetUp() OVERRIDE {
- ASSERT_TRUE(sync_thread_.Start());
- bridge_.reset(
- new AndroidInvalidatorBridge(
- &mock_profile_, sync_thread_.message_loop_proxy()));
- }
-
- virtual void TearDown() OVERRIDE {
- bridge_->StopForShutdown();
- sync_thread_.Stop();
- // Must be reset only after the sync thread is stopped.
- bridge_.reset();
- EXPECT_EQ(NULL, sync_handler_.get());
- if (!sync_handler_notification_success_)
- ADD_FAILURE() << "Sync handler did not receive proper notification.";
- }
-
- void VerifyAndDestroyObserver(
- const syncer::ModelTypeInvalidationMap& expected_invalidations) {
- ASSERT_TRUE(sync_thread_.message_loop_proxy()->PostTask(
- FROM_HERE,
- base::Bind(&AndroidInvalidatorBridgeTest::
- VerifyAndDestroyObserverOnSyncThread,
- base::Unretained(this),
- expected_invalidations)));
- BlockForSyncThread();
- }
-
- void CreateObserver() {
- ASSERT_TRUE(sync_thread_.message_loop_proxy()->PostTask(
- FROM_HERE,
- base::Bind(
- &AndroidInvalidatorBridgeTest::CreateObserverOnSyncThread,
- base::Unretained(this))));
- BlockForSyncThread();
- }
-
- void UpdateEnabledTypes(syncer::ModelTypeSet enabled_types) {
- ASSERT_TRUE(sync_thread_.message_loop_proxy()->PostTask(
- FROM_HERE,
- base::Bind(
- &AndroidInvalidatorBridgeTest::
- UpdateEnabledTypesOnSyncThread,
- base::Unretained(this),
- enabled_types)));
- BlockForSyncThread();
- }
-
- void TriggerRefreshNotification(
- const syncer::ModelTypeInvalidationMap& invalidation_map) {
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_SYNC_REFRESH_REMOTE,
- content::Source<Profile>(&mock_profile_),
- content::Details<const syncer::ObjectIdInvalidationMap>(
- ModelTypeInvalidationMapToObjectIdInvalidationMap(
- &invalidation_map));
- BlockForSyncThread();
- }
-
- private:
- void VerifyAndDestroyObserverOnSyncThread(
- const syncer::ModelTypeInvalidationMap& expected_invalidations) {
- DCHECK(sync_thread_.message_loop_proxy()->RunsTasksOnCurrentThread());
- if (sync_handler_) {
- sync_handler_notification_success_ =
- (sync_handler_->GetInvalidationCount() == 1) &&
- ObjectIdInvalidationMapEquals(
- sync_handler_->GetLastInvalidationMap(),
- syncer::ModelTypeInvalidationMapToObjectIdInvalidationMap(
- expected_invalidations));
- bridge_->UnregisterHandler(sync_handler_.get());
- } else {
- sync_handler_notification_success_ = false;
- }
- sync_handler_.reset();
- }
-
- void CreateObserverOnSyncThread() {
- DCHECK(sync_thread_.message_loop_proxy()->RunsTasksOnCurrentThread());
- sync_handler_.reset(new syncer::FakeInvalidationHandler());
- bridge_->RegisterHandler(sync_handler_.get());
- }
-
- void UpdateEnabledTypesOnSyncThread(
- syncer::ModelTypeSet enabled_types) {
- DCHECK(sync_thread_.message_loop_proxy()->RunsTasksOnCurrentThread());
- bridge_->UpdateRegisteredIds(
- sync_handler_.get(), ModelTypeSetToObjectIdSet(enabled_types));
- }
-
- void BlockForSyncThread() {
- // Post a task to the sync thread's message loop and block until
- // it runs.
- base::RunLoop run_loop;
- ASSERT_TRUE(sync_thread_.message_loop_proxy()->PostTaskAndReply(
- FROM_HERE,
- base::Bind(&base::DoNothing),
- run_loop.QuitClosure()));
- run_loop.Run();
- }
-
- base::MessageLoop ui_loop_;
- content::TestBrowserThread ui_thread_;
- base::Thread sync_thread_;
- NiceMock<ProfileMock> mock_profile_;
- // Created/used/destroyed on sync thread.
- scoped_ptr<syncer::FakeInvalidationHandler> sync_handler_;
- bool sync_handler_notification_success_;
- scoped_ptr<AndroidInvalidatorBridge> bridge_;
-};
-
-// Adds an observer on the sync thread, triggers a remote refresh
-// invalidation, and ensures the bridge posts a REMOTE_INVALIDATION
-// with the proper state to it.
-TEST_F(AndroidInvalidatorBridgeTest, RemoteNotification) {
- const syncer::ModelTypeSet types(syncer::SESSIONS);
- const syncer::ModelTypeInvalidationMap& invalidation_map =
- ModelTypeSetToInvalidationMap(types, std::string());
- CreateObserver();
- UpdateEnabledTypes(syncer::ModelTypeSet(syncer::SESSIONS));
- TriggerRefreshNotification(invalidation_map);
- VerifyAndDestroyObserver(invalidation_map);
-}
-
-// Adds an observer on the sync thread, triggers a remote refresh
-// notification with empty state map and ensures the bridge posts a
-// REMOTE_INVALIDATION with the proper state to it.
-TEST_F(AndroidInvalidatorBridgeTest, RemoteNotificationEmptyPayloadMap) {
- const syncer::ModelTypeSet enabled_types(
- syncer::BOOKMARKS, syncer::TYPED_URLS);
- const syncer::ModelTypeInvalidationMap enabled_types_invalidation_map =
- syncer::ModelTypeSetToInvalidationMap(enabled_types, std::string());
- CreateObserver();
- UpdateEnabledTypes(enabled_types);
- TriggerRefreshNotification(syncer::ModelTypeInvalidationMap());
- VerifyAndDestroyObserver(enabled_types_invalidation_map);
-}
-
-} // namespace
-} // namespace browser_sync
diff --git a/chrome/browser/sync/glue/data_type_manager_impl.cc b/chrome/browser/sync/glue/data_type_manager_impl.cc
index 63611d6..c5cbc8e 100644
--- a/chrome/browser/sync/glue/data_type_manager_impl.cc
+++ b/chrome/browser/sync/glue/data_type_manager_impl.cc
@@ -77,10 +77,7 @@
void DataTypeManagerImpl::Configure(syncer::ModelTypeSet desired_types,
syncer::ConfigureReason reason) {
- desired_types.PutAll(syncer::ControlTypes());
- // The list of managed users created by this profile is always synced,
- // but they are not a control type.
- desired_types.Put(syncer::MANAGED_USERS);
+ desired_types.PutAll(syncer::CoreTypes());
ConfigureImpl(desired_types, reason);
}
@@ -242,7 +239,7 @@
syncer::ModelTypeSet DataTypeManagerImpl::GetPriorityTypes() const {
syncer::ModelTypeSet high_priority_types;
- high_priority_types.PutAll(syncer::ControlTypes());
+ high_priority_types.PutAll(syncer::PriorityCoreTypes());
high_priority_types.PutAll(syncer::PriorityUserTypes());
return high_priority_types;
}
@@ -447,9 +444,8 @@
}
DCHECK(result.status == PARTIAL_SUCCESS || result.status == OK);
- DCHECK(!result.status == OK ||
- (result.needs_crypto.Empty() &&
- result.failed_data_types.empty()));
+ DCHECK(result.status != OK ||
+ (result.needs_crypto.Empty() && result.failed_data_types.empty()));
// It's possible this is a retry to disable failed types, in which case
// the association would be SUCCESS, but the overall configuration should
diff --git a/chrome/browser/sync/glue/data_type_manager_impl_unittest.cc b/chrome/browser/sync/glue/data_type_manager_impl_unittest.cc
index 254ba72..48eeef5 100644
--- a/chrome/browser/sync/glue/data_type_manager_impl_unittest.cc
+++ b/chrome/browser/sync/glue/data_type_manager_impl_unittest.cc
@@ -41,15 +41,23 @@
return result.status;
}
-syncer::ModelTypeSet PriorityTypes() {
- syncer::ModelTypeSet result = syncer::ControlTypes();
- result.Put(syncer::MANAGED_USERS);
+// Those types that are priority AND always configured.
+syncer::ModelTypeSet HighPriorityTypes() {
+ syncer::ModelTypeSet result = syncer::PriorityCoreTypes();
return result;
}
-// Helper for unioning with control types.
-syncer::ModelTypeSet AddPriorityTypesTo(syncer::ModelTypeSet types) {
- syncer::ModelTypeSet result = PriorityTypes();
+// Helper for unioning with priority types.
+syncer::ModelTypeSet AddHighPriorityTypesTo(syncer::ModelTypeSet types) {
+ syncer::ModelTypeSet result = HighPriorityTypes();
+ result.PutAll(types);
+ return result;
+}
+
+// Helper for unioning with core types.
+syncer::ModelTypeSet AddLowPriorityCoreTypesTo(syncer::ModelTypeSet types) {
+ syncer::ModelTypeSet result = syncer::Difference(syncer::CoreTypes(),
+ syncer::PriorityCoreTypes());
result.PutAll(types);
return result;
}
@@ -155,7 +163,7 @@
configurer,
observer,
failed_data_types_handler),
- custom_priority_types_(PriorityTypes()) {}
+ custom_priority_types_(HighPriorityTypes()) {}
void set_priority_types(const syncer::ModelTypeSet& priority_types) {
custom_priority_types_ = priority_types;
@@ -262,6 +270,7 @@
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
dtm_->Stop();
@@ -272,7 +281,6 @@
// downloading, finish starting the controller, and then stop the DTM.
TEST_F(SyncDataTypeManagerImplTest, ConfigureOne) {
AddController(BOOKMARKS);
- dtm_->set_priority_types(AddPriorityTypesTo(syncer::ModelTypeSet(BOOKMARKS)));
SetConfigureStartExpectation();
SetConfigureDoneExpectation(DataTypeManager::OK);
@@ -280,6 +288,7 @@
Configure(dtm_.get(), ModelTypeSet(BOOKMARKS));
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -295,8 +304,6 @@
TEST_F(SyncDataTypeManagerImplTest, ConfigureSlowLoadingType) {
AddController(BOOKMARKS);
AddController(APPS);
- dtm_->set_priority_types(
- AddPriorityTypesTo(syncer::ModelTypeSet(BOOKMARKS, APPS)));
GetController(BOOKMARKS)->SetDelayModelLoad();
@@ -310,6 +317,7 @@
Configure(dtm_.get(), types);
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
FinishDownload(*dtm_, types, ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -327,6 +335,7 @@
GetController(BOOKMARKS)->SimulateModelLoadFinishing();
FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
GetController(BOOKMARKS)->SimulateModelLoadFinishing();
GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
@@ -342,7 +351,6 @@
// download callback even after the DTM is stopped and destroyed.
TEST_F(SyncDataTypeManagerImplTest, ConfigureOneStopWhileDownloadPending) {
AddController(BOOKMARKS);
- dtm_->set_priority_types(AddPriorityTypesTo(syncer::ModelTypeSet(BOOKMARKS)));
{
SetConfigureStartExpectation();
@@ -364,7 +372,6 @@
// controller even after the DTM is stopped and destroyed.
TEST_F(SyncDataTypeManagerImplTest, ConfigureOneStopWhileStartingModel) {
AddController(BOOKMARKS);
- dtm_->set_priority_types(AddPriorityTypesTo(syncer::ModelTypeSet(BOOKMARKS)));
{
SetConfigureStartExpectation();
@@ -373,6 +380,7 @@
Configure(dtm_.get(), ModelTypeSet(BOOKMARKS));
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -391,7 +399,6 @@
// destroyed.
TEST_F(SyncDataTypeManagerImplTest, ConfigureOneStopWhileAssociating) {
AddController(BOOKMARKS);
- dtm_->set_priority_types(AddPriorityTypesTo(syncer::ModelTypeSet(BOOKMARKS)));
{
SetConfigureStartExpectation();
@@ -400,6 +407,7 @@
Configure(dtm_.get(), ModelTypeSet(BOOKMARKS));
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -420,7 +428,6 @@
// 5) Stop the DTM.
TEST_F(SyncDataTypeManagerImplTest, OneWaitingForCrypto) {
AddController(PASSWORDS);
- dtm_->set_priority_types(AddPriorityTypesTo(syncer::ModelTypeSet(PASSWORDS)));
SetConfigureStartExpectation();
SetConfigureDoneExpectation(DataTypeManager::PARTIAL_SUCCESS);
@@ -432,6 +439,7 @@
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
// Step 2.
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
FinishDownload(*dtm_, types, ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -442,6 +450,7 @@
// Step 4.
FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
// Step 5.
@@ -461,8 +470,6 @@
TEST_F(SyncDataTypeManagerImplTest, ConfigureOneThenBoth) {
AddController(BOOKMARKS);
AddController(PREFERENCES);
- dtm_->set_priority_types(
- AddPriorityTypesTo(syncer::ModelTypeSet(BOOKMARKS, PREFERENCES)));
SetConfigureStartExpectation();
SetConfigureDoneExpectation(DataTypeManager::OK);
@@ -472,6 +479,7 @@
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
// Step 2.
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -488,6 +496,7 @@
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
// Step 5.
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -512,8 +521,6 @@
TEST_F(SyncDataTypeManagerImplTest, ConfigureOneThenSwitch) {
AddController(BOOKMARKS);
AddController(PREFERENCES);
- dtm_->set_priority_types(
- AddPriorityTypesTo(syncer::ModelTypeSet(BOOKMARKS, PREFERENCES)));
SetConfigureStartExpectation();
SetConfigureDoneExpectation(DataTypeManager::OK);
@@ -523,6 +530,7 @@
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
// Step 2.
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -539,6 +547,7 @@
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
// Step 5.
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -563,8 +572,6 @@
TEST_F(SyncDataTypeManagerImplTest, ConfigureWhileOneInFlight) {
AddController(BOOKMARKS);
AddController(PREFERENCES);
- dtm_->set_priority_types(
- AddPriorityTypesTo(syncer::ModelTypeSet(BOOKMARKS, PREFERENCES)));
SetConfigureStartExpectation();
SetConfigureDoneExpectation(DataTypeManager::OK);
@@ -574,6 +581,7 @@
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
// Step 2.
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -586,6 +594,7 @@
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
// Step 5.
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -603,7 +612,6 @@
// The unrecoverable error should cause the DTM to stop.
TEST_F(SyncDataTypeManagerImplTest, OneFailingController) {
AddController(BOOKMARKS);
- dtm_->set_priority_types(AddPriorityTypesTo(syncer::ModelTypeSet(BOOKMARKS)));
SetConfigureStartExpectation();
SetConfigureDoneExpectation(DataTypeManager::UNRECOVERABLE_ERROR);
@@ -611,6 +619,7 @@
Configure(dtm_.get(), ModelTypeSet(BOOKMARKS));
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -630,8 +639,6 @@
TEST_F(SyncDataTypeManagerImplTest, SecondControllerFails) {
AddController(BOOKMARKS);
AddController(PREFERENCES);
- dtm_->set_priority_types(
- AddPriorityTypesTo(syncer::ModelTypeSet(BOOKMARKS, PREFERENCES)));
SetConfigureStartExpectation();
SetConfigureDoneExpectation(DataTypeManager::UNRECOVERABLE_ERROR);
@@ -641,6 +648,7 @@
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
// Step 2.
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -670,8 +678,6 @@
TEST_F(SyncDataTypeManagerImplTest, OneControllerFailsAssociation) {
AddController(BOOKMARKS);
AddController(PREFERENCES);
- dtm_->set_priority_types(
- AddPriorityTypesTo(syncer::ModelTypeSet(BOOKMARKS, PREFERENCES)));
SetConfigureStartExpectation();
SetConfigureDoneExpectation(DataTypeManager::PARTIAL_SUCCESS);
@@ -681,6 +687,7 @@
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
// Step 2.
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -694,6 +701,7 @@
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
// Step 5.
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
@@ -713,8 +721,6 @@
TEST_F(SyncDataTypeManagerImplTest, ConfigureWhileDownloadPending) {
AddController(BOOKMARKS);
AddController(PREFERENCES);
- dtm_->set_priority_types(
- AddPriorityTypesTo(syncer::ModelTypeSet(BOOKMARKS, PREFERENCES)));
SetConfigureStartExpectation();
SetConfigureDoneExpectation(DataTypeManager::OK);
@@ -728,10 +734,11 @@
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
// Step 3.
- FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
// Step 4.
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -760,23 +767,23 @@
TEST_F(SyncDataTypeManagerImplTest, ConfigureWhileDownloadPendingWithFailure) {
AddController(BOOKMARKS);
AddController(PREFERENCES);
- dtm_->set_priority_types(
- AddPriorityTypesTo(syncer::ModelTypeSet(BOOKMARKS, PREFERENCES)));
SetConfigureStartExpectation();
SetConfigureDoneExpectation(DataTypeManager::OK);
// Step 1.
Configure(dtm_.get(), ModelTypeSet(BOOKMARKS));
- EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
+ EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
// Step 2.
Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES));
- EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
+ EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
// Step 3.
- FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet(BOOKMARKS));
- EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
+ FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
+ EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
// Step 4.
FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet());
@@ -797,13 +804,13 @@
// operations that would be invoked by the BackendMigrator.
TEST_F(SyncDataTypeManagerImplTest, MigrateAll) {
AddController(BOOKMARKS);
- dtm_->set_priority_types(AddPriorityTypesTo(syncer::ModelTypeSet(BOOKMARKS)));
SetConfigureStartExpectation();
SetConfigureDoneExpectation(DataTypeManager::OK);
// Initial setup.
Configure(dtm_.get(), ModelTypeSet(BOOKMARKS));
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
@@ -824,6 +831,7 @@
// The DTM will call ConfigureDataTypes(), even though it is unnecessary.
FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
Mock::VerifyAndClearExpectations(&observer_);
@@ -831,6 +839,7 @@
SetConfigureStartExpectation();
SetConfigureDoneExpectation(DataTypeManager::OK);
Configure(dtm_.get(), to_migrate);
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
FinishDownload(*dtm_, to_migrate, ModelTypeSet());
GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
@@ -840,13 +849,12 @@
TEST_F(SyncDataTypeManagerImplTest, ConfigureDuringPurge) {
AddController(BOOKMARKS);
AddController(PREFERENCES);
- dtm_->set_priority_types(
- AddPriorityTypesTo(syncer::ModelTypeSet(BOOKMARKS, PREFERENCES)));
// Initial configure.
SetConfigureStartExpectation();
SetConfigureDoneExpectation(DataTypeManager::OK);
Configure(dtm_.get(), ModelTypeSet(BOOKMARKS));
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
@@ -876,6 +884,7 @@
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
// Now invoke the callback for the second configure request.
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -889,11 +898,9 @@
TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfiguration) {
AddController(BOOKMARKS);
AddController(PREFERENCES);
- dtm_->set_priority_types(
- AddPriorityTypesTo(syncer::ModelTypeSet(BOOKMARKS, PREFERENCES)));
dtm_->set_priority_types(
- AddPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES)));
+ AddHighPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES)));
// Initial configure.
SetConfigureStartExpectation();
@@ -901,12 +908,13 @@
// Initially only PREFERENCES is configured.
configurer_.set_expected_configure_types(
- AddPriorityTypesTo(ModelTypeSet(PREFERENCES)));
+ AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES)));
Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES));
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
// BOOKMARKS is configured after download of PREFERENCES finishes.
- configurer_.set_expected_configure_types(ModelTypeSet(BOOKMARKS));
+ configurer_.set_expected_configure_types(
+ AddLowPriorityCoreTypesTo(ModelTypeSet(BOOKMARKS)));
FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -924,7 +932,7 @@
AddController(APPS);
dtm_->set_priority_types(
- AddPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES)));
+ AddHighPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES)));
// Initial configure.
SetConfigureStartExpectation();
@@ -932,11 +940,12 @@
// Reconfigure while associating PREFERENCES and downloading BOOKMARKS.
configurer_.set_expected_configure_types(
- AddPriorityTypesTo(ModelTypeSet(PREFERENCES)));
+ AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES)));
Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES));
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
- configurer_.set_expected_configure_types(ModelTypeSet(BOOKMARKS));
+ configurer_.set_expected_configure_types(
+ AddLowPriorityCoreTypesTo(ModelTypeSet(BOOKMARKS)));
FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -947,12 +956,13 @@
// Reconfiguration starts after downloading and association of previous
// types finish.
configurer_.set_expected_configure_types(
- AddPriorityTypesTo(ModelTypeSet(PREFERENCES)));
+ AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES)));
FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
GetController(PREFERENCES)->FinishStart(DataTypeController::OK);
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
- configurer_.set_expected_configure_types(ModelTypeSet(BOOKMARKS, APPS));
+ configurer_.set_expected_configure_types(
+ AddLowPriorityCoreTypesTo(ModelTypeSet(BOOKMARKS, APPS)));
FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -971,7 +981,7 @@
AddController(PREFERENCES);
dtm_->set_priority_types(
- AddPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES)));
+ AddHighPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES)));
// Initial configure.
SetConfigureStartExpectation();
@@ -979,12 +989,13 @@
// Initially only PREFERENCES is configured.
configurer_.set_expected_configure_types(
- AddPriorityTypesTo(ModelTypeSet(PREFERENCES)));
+ AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES)));
Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES));
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
// BOOKMARKS is configured after download of PREFERENCES finishes.
- configurer_.set_expected_configure_types(ModelTypeSet(BOOKMARKS));
+ configurer_.set_expected_configure_types(
+ AddLowPriorityCoreTypesTo(ModelTypeSet(BOOKMARKS)));
FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -1005,7 +1016,7 @@
AddController(PREFERENCES);
dtm_->set_priority_types(
- AddPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES)));
+ AddHighPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES)));
// Initial configure.
SetConfigureStartExpectation();
@@ -1013,12 +1024,13 @@
// Initially only PREFERENCES is configured.
configurer_.set_expected_configure_types(
- AddPriorityTypesTo(ModelTypeSet(PREFERENCES)));
+ AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES)));
Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES));
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
// BOOKMARKS is configured after download of PREFERENCES finishes.
- configurer_.set_expected_configure_types(ModelTypeSet(BOOKMARKS));
+ configurer_.set_expected_configure_types(
+ AddLowPriorityCoreTypesTo(ModelTypeSet(BOOKMARKS)));
FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -1040,7 +1052,7 @@
AddController(BOOKMARKS); // Will succeed.
dtm_->set_priority_types(
- AddPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES)));
+ AddHighPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES)));
// Initial configure.
SetConfigureStartExpectation();
@@ -1048,12 +1060,13 @@
// Initially only PREFERENCES is configured.
configurer_.set_expected_configure_types(
- AddPriorityTypesTo(ModelTypeSet(PREFERENCES)));
+ AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES)));
Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES));
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
// BOOKMARKS is configured after download of PREFERENCES finishes.
- configurer_.set_expected_configure_types(ModelTypeSet(BOOKMARKS));
+ configurer_.set_expected_configure_types(
+ AddLowPriorityCoreTypesTo(ModelTypeSet(BOOKMARKS)));
FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -1069,9 +1082,10 @@
// Reconfigure without PREFERENCES after the BOOKMARKS download completes,
// then reconfigure with BOOKMARKS.
- configurer_.set_expected_configure_types(PriorityTypes());
+ configurer_.set_expected_configure_types(HighPriorityTypes());
FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
- configurer_.set_expected_configure_types(ModelTypeSet(BOOKMARKS));
+ configurer_.set_expected_configure_types(
+ AddLowPriorityCoreTypesTo(ModelTypeSet(BOOKMARKS)));
FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
// Reconfigure with BOOKMARKS.
@@ -1091,7 +1105,7 @@
AddController(BOOKMARKS); // Will fail.
dtm_->set_priority_types(
- AddPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES)));
+ AddHighPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES)));
// Initial configure.
SetConfigureStartExpectation();
@@ -1099,12 +1113,13 @@
// Initially only PREFERENCES is configured.
configurer_.set_expected_configure_types(
- AddPriorityTypesTo(ModelTypeSet(PREFERENCES)));
+ AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES)));
Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES));
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
// BOOKMARKS is configured after download of PREFERENCES finishes.
- configurer_.set_expected_configure_types(ModelTypeSet(BOOKMARKS));
+ configurer_.set_expected_configure_types(
+ AddLowPriorityCoreTypesTo(ModelTypeSet(BOOKMARKS)));
FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
@@ -1121,15 +1136,17 @@
// Make BOOKMARKS association fail, which triggers reconfigure with only
// PREFERENCES.
configurer_.set_expected_configure_types(
- AddPriorityTypesTo(ModelTypeSet(PREFERENCES)));
- GetController(BOOKMARKS)->FinishStart(
- DataTypeController::ASSOCIATION_FAILED);
+ AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES)));
+ GetController(BOOKMARKS)->FinishStart(DataTypeController::ASSOCIATION_FAILED);
EXPECT_EQ(DataTypeController::NOT_RUNNING,
GetController(BOOKMARKS)->state());
EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
// Finish configuration with only PREFERENCES.
+ configurer_.set_expected_configure_types(
+ AddLowPriorityCoreTypesTo(ModelTypeSet()));
FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet());
+ FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
EXPECT_EQ(DataTypeController::RUNNING, GetController(PREFERENCES)->state());
EXPECT_EQ(DataTypeController::NOT_RUNNING,
diff --git a/chrome/browser/sync/glue/device_info.cc b/chrome/browser/sync/glue/device_info.cc
index e593d00..c21a74b 100644
--- a/chrome/browser/sync/glue/device_info.cc
+++ b/chrome/browser/sync/glue/device_info.cc
@@ -6,6 +6,7 @@
#include "base/command_line.h"
#include "base/threading/sequenced_worker_pool.h"
+#include "base/values.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/chrome_switches.h"
#include "content/public/browser/browser_thread.h"
@@ -40,6 +41,28 @@
};
}
+std::string DeviceTypeToString(sync_pb::SyncEnums::DeviceType device_type) {
+ switch (device_type) {
+ case sync_pb::SyncEnums_DeviceType_TYPE_WIN:
+ return "WIN";
+ case sync_pb::SyncEnums_DeviceType_TYPE_MAC:
+ return "MAC";
+ case sync_pb::SyncEnums_DeviceType_TYPE_LINUX:
+ return "LINUX";
+ case sync_pb::SyncEnums_DeviceType_TYPE_CROS:
+ return "CHROME OS";
+ case sync_pb::SyncEnums_DeviceType_TYPE_OTHER:
+ return "OTHER";
+ case sync_pb::SyncEnums_DeviceType_TYPE_PHONE:
+ return "PHONE";
+ case sync_pb::SyncEnums_DeviceType_TYPE_TABLET:
+ return "TABLET";
+ default:
+ NOTREACHED();
+ return "UNKNOWN";
+ }
+}
+
} // namespace
DeviceInfo::DeviceInfo(const std::string& guid,
@@ -143,6 +166,20 @@
return user_agent;
}
+base::DictionaryValue* DeviceInfo::ToValue() {
+ base::DictionaryValue* value = new base::DictionaryValue();
+ value->SetString("Id", public_id_);
+ value->SetString("Client Name", client_name_);
+ value->SetString("Chrome Version", chrome_version_);
+ value->SetString("Sync User Agent", sync_user_agent_);
+ value->SetString("Device Type", DeviceTypeToString(device_type_));
+ return value;
+}
+
+void DeviceInfo::SetPublicId(std::string id) {
+ public_id_ = id;
+}
+
// static.
void DeviceInfo::CreateLocalDeviceInfo(
const std::string& guid,
diff --git a/chrome/browser/sync/glue/device_info.h b/chrome/browser/sync/glue/device_info.h
index 4711925..f8645a0 100644
--- a/chrome/browser/sync/glue/device_info.h
+++ b/chrome/browser/sync/glue/device_info.h
@@ -11,6 +11,10 @@
#include "base/bind.h"
#include "sync/protocol/sync.pb.h"
+namespace base {
+class DictionaryValue;
+}
+
namespace chrome {
class VersionInfo;
}
@@ -50,6 +54,16 @@
// Compares this object's fields with another's.
bool Equals(const DeviceInfo& other) const;
+ // Apps can set ids for a device that is meaningful to them but
+ // not unique enough so the user can be tracked. Exposing |guid|
+ // would lead to a stable unique id for a device which can potentially
+ // be used for tracking.
+ void SetPublicId(std::string id);
+
+ // Converts the |DeviceInfo| values to a JS friendly DictionaryValue,
+ // which extension APIs can expose to third party apps.
+ base::DictionaryValue* ToValue();
+
static sync_pb::SyncEnums::DeviceType GetLocalDeviceType();
// Creates a |DeviceInfo| object representing the local device and passes
@@ -88,6 +102,8 @@
const sync_pb::SyncEnums::DeviceType device_type_;
+ std::string public_id_;
+
DISALLOW_COPY_AND_ASSIGN(DeviceInfo);
};
diff --git a/chrome/browser/sync/glue/session_change_processor.cc b/chrome/browser/sync/glue/session_change_processor.cc
index 24b90c9..ff73af1 100644
--- a/chrome/browser/sync/glue/session_change_processor.cc
+++ b/chrome/browser/sync/glue/session_change_processor.cc
@@ -277,8 +277,13 @@
LOG(WARNING) << "Local session data deleted. Ignoring until next local "
<< "navigation event.";
} else {
- session_model_associator_->DisassociateForeignSession(
- specifics.session_tag());
+ if (specifics.has_header()) {
+ // Disassociate only when header node is deleted. For tab node
+ // deletions, the header node will be updated and foreign tab will
+ // get deleted.
+ session_model_associator_->DisassociateForeignSession(
+ specifics.session_tag());
+ }
}
continue;
}
diff --git a/chrome/browser/sync/glue/session_model_associator.cc b/chrome/browser/sync/glue/session_model_associator.cc
index ec7e281..d66a96c 100644
--- a/chrome/browser/sync/glue/session_model_associator.cc
+++ b/chrome/browser/sync/glue/session_model_associator.cc
@@ -176,7 +176,6 @@
synced_session_tracker_.ResetSessionTracking(local_tag);
std::set<SyncedWindowDelegate*> windows =
SyncedWindowDelegate::GetSyncedWindowDelegates();
- std::set<int64> used_sync_ids;
for (std::set<SyncedWindowDelegate*>::const_iterator i =
windows.begin(); i != windows.end(); ++i) {
// Make sure the window has tabs and a viewable window. The viewable window
@@ -223,7 +222,6 @@
tab_id > TabNodePool::kInvalidTabID) {
UpdateTabIdIfNecessary(synced_tab->GetSyncId(), tab_id);
found_tabs = true;
- used_sync_ids.insert(synced_tab->GetSyncId());
window_s.add_tab(tab_id);
}
continue;
@@ -269,14 +267,8 @@
}
}
- // Sync nodes tracked by tab_map_ are used.
- for (TabLinksMap::const_iterator tab_iter = tab_map_.begin();
- tab_iter != tab_map_.end(); ++tab_iter) {
- used_sync_ids.insert(tab_iter->second->sync_id());
- }
-
// Free old sync nodes.
- tab_pool_.FreeUnusedTabNodes(used_sync_ids);
+ tab_pool_.FreeUnassociatedTabNodes();
// Free memory for closed windows and tabs.
synced_session_tracker_.CleanupSession(local_tag);
@@ -345,7 +337,7 @@
if (tab_map_iter == tab_map_.end()) {
sync_id = tab->GetSyncId();
// if there is an old sync node for the tab, reuse it.
- if (!tab_pool_.ReassociateTabNode(sync_id, tab_id)) {
+ if (!tab_pool_.IsUnassociatedTabNode(sync_id)) {
// This is a new tab, get a sync node for it.
sync_id = tab_pool_.GetFreeTabNode();
if (sync_id == syncer::kInvalidId) {
@@ -357,9 +349,9 @@
}
return false;
}
- tab_pool_.AssociateTabNode(sync_id, tab_id);
tab->SetSyncId(sync_id);
}
+ tab_pool_.AssociateTabNode(sync_id, tab_id);
tab_link = new TabLink(sync_id, tab);
tab_map_[tab_id] = make_linked_ptr<TabLink>(tab_link);
} else {
diff --git a/chrome/browser/sync/glue/session_model_associator.h b/chrome/browser/sync/glue/session_model_associator.h
index 6aaa00b..9870053 100644
--- a/chrome/browser/sync/glue/session_model_associator.h
+++ b/chrome/browser/sync/glue/session_model_associator.h
@@ -217,6 +217,8 @@
FRIEND_TEST_ALL_PREFIXES(ProfileSyncServiceSessionTest, ValidTabs);
FRIEND_TEST_ALL_PREFIXES(ProfileSyncServiceSessionTest, ExistingTabs);
FRIEND_TEST_ALL_PREFIXES(ProfileSyncServiceSessionTest, MissingLocalTabNode);
+ FRIEND_TEST_ALL_PREFIXES(ProfileSyncServiceSessionTest,
+ TabPoolFreeNodeLimits);
FRIEND_TEST_ALL_PREFIXES(SyncSessionModelAssociatorTest,
PopulateSessionHeader);
FRIEND_TEST_ALL_PREFIXES(SyncSessionModelAssociatorTest,
diff --git a/chrome/browser/sync/glue/sync_backend_host.cc b/chrome/browser/sync/glue/sync_backend_host.cc
index 294742e..3ab713f 100644
--- a/chrome/browser/sync/glue/sync_backend_host.cc
+++ b/chrome/browser/sync/glue/sync_backend_host.cc
@@ -383,6 +383,10 @@
factory_switches.backoff_override =
InternalComponentsFactoryImpl::BACKOFF_SHORT_INITIAL_RETRY_OVERRIDE;
}
+ if (cl->HasSwitch(switches::kSyncEnableGetUpdateAvoidance)) {
+ factory_switches.pre_commit_updates_policy =
+ InternalComponentsFactoryImpl::FORCE_ENABLE_PRE_COMMIT_UPDATE_AVOIDANCE;
+ }
initialization_state_ = CREATING_SYNC_MANAGER;
InitCore(DoInitializeOptions(
@@ -561,9 +565,7 @@
if (invalidation_handler_registered_) {
if (sync_disabled) {
- invalidator_->UpdateRegisteredInvalidationIds(
- this,
- syncer::ObjectIdSet());
+ UnregisterInvalidationIds();
}
invalidator_->UnregisterInvalidationHandler(this);
invalidator_ = NULL;
@@ -603,6 +605,14 @@
core_ = NULL; // Releases reference to core_.
}
+void SyncBackendHost::UnregisterInvalidationIds() {
+ if (invalidation_handler_registered_) {
+ invalidator_->UpdateRegisteredInvalidationIds(
+ this,
+ syncer::ObjectIdSet());
+ }
+}
+
void SyncBackendHost::ConfigureDataTypes(
syncer::ConfigureReason reason,
const DataTypeConfigStateMap& config_state_map,
diff --git a/chrome/browser/sync/glue/sync_backend_host.h b/chrome/browser/sync/glue/sync_backend_host.h
index 9498ece..a539ec6 100644
--- a/chrome/browser/sync/glue/sync_backend_host.h
+++ b/chrome/browser/sync/glue/sync_backend_host.h
@@ -228,6 +228,10 @@
// Must be called *after* StopSyncingForShutdown.
void Shutdown(bool sync_disabled);
+ // Removes all current registrations from the backend on the
+ // InvalidationService.
+ void UnregisterInvalidationIds();
+
// Changes the set of data types that are currently being synced.
// The ready_task will be run when configuration is done with the
// set of all types that failed configuration (i.e., if its argument
diff --git a/chrome/browser/sync/glue/tab_node_pool.cc b/chrome/browser/sync/glue/tab_node_pool.cc
index 5d44c39..2b41851 100644
--- a/chrome/browser/sync/glue/tab_node_pool.cc
+++ b/chrome/browser/sync/glue/tab_node_pool.cc
@@ -20,7 +20,8 @@
"Server did not create the top-level sessions node. We "
"might be running against an out-of-date server.";
-static const size_t kMaxNumberOfFreeNodes = 25;
+const size_t TabNodePool::kFreeNodesLowWatermark = 25;
+const size_t TabNodePool::kFreeNodesHighWatermark = 100;
TabNodePool::TabNodePool(ProfileSyncService* sync_service)
: max_used_tab_node_id_(0), sync_service_(sync_service) {}
@@ -40,17 +41,24 @@
DCHECK_GT(sync_id, syncer::kInvalidId);
DCHECK_GT(tab_id.id(), kInvalidTabID);
DCHECK(syncid_tabid_map_.find(sync_id) == syncid_tabid_map_.end());
- syncid_tabid_map_[sync_id] = tab_id.id();
+ unassociated_nodes_.insert(sync_id);
if (max_used_tab_node_id_ < tab_node_id)
max_used_tab_node_id_ = tab_node_id;
}
void TabNodePool::AssociateTabNode(int64 sync_id, SessionID::id_type tab_id) {
DCHECK_GT(sync_id, 0);
- // Remove node from free node pool and associate it with tab.
- std::set<int64>::iterator it = free_nodes_pool_.find(sync_id);
- DCHECK(it != free_nodes_pool_.end());
- free_nodes_pool_.erase(it);
+ // Remove sync node if it is in unassociated nodes pool.
+ std::set<int64>::iterator u_it = unassociated_nodes_.find(sync_id);
+ if (u_it != unassociated_nodes_.end()) {
+ unassociated_nodes_.erase(u_it);
+ } else {
+ // This is a new node association, the sync node should be free.
+ // Remove node from free node pool and then associate it with the tab.
+ std::set<int64>::iterator it = free_nodes_pool_.find(sync_id);
+ DCHECK(it != free_nodes_pool_.end());
+ free_nodes_pool_.erase(it);
+ }
DCHECK(syncid_tabid_map_.find(sync_id) == syncid_tabid_map_.end());
syncid_tabid_map_[sync_id] = tab_id;
}
@@ -99,30 +107,49 @@
SyncIDToTabIDMap::iterator it = syncid_tabid_map_.find(sync_id);
DCHECK(it != syncid_tabid_map_.end());
syncid_tabid_map_.erase(it);
- DCHECK(free_nodes_pool_.find(sync_id) == free_nodes_pool_.end());
+ FreeTabNodeInternal(sync_id);
+}
- // If number of free nodes exceed number of maximum allowed free nodes,
- // delete the sync node.
- if (free_nodes_pool_.size() < kMaxNumberOfFreeNodes) {
- free_nodes_pool_.insert(sync_id);
- } else {
+void TabNodePool::FreeTabNodeInternal(int64 sync_id) {
+ DCHECK(free_nodes_pool_.find(sync_id) == free_nodes_pool_.end());
+ free_nodes_pool_.insert(sync_id);
+
+ // If number of free nodes exceed kFreeNodesHighWatermark,
+ // delete sync nodes till number reaches kFreeNodesLowWatermark.
+ // Note: This logic is to mitigate temporary disassociation issues with old
+ // clients: http://crbug.com/259918. Newer versions do not need this.
+ if (free_nodes_pool_.size() > kFreeNodesHighWatermark) {
syncer::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
- syncer::WriteNode tab_node(&trans);
- if (tab_node.InitByIdLookup(sync_id) != syncer::BaseNode::INIT_OK) {
- LOG(ERROR) << "Could not find sync node with id: " << sync_id;
- return;
+ for (std::set<int64>::iterator free_it = free_nodes_pool_.begin();
+ free_it != free_nodes_pool_.end();) {
+ syncer::WriteNode tab_node(&trans);
+ if (tab_node.InitByIdLookup(*free_it) != syncer::BaseNode::INIT_OK) {
+ LOG(ERROR) << "Could not find sync node with id: " << *free_it;
+ return;
+ }
+ free_nodes_pool_.erase(free_it++);
+ tab_node.Tombstone();
+ if (free_nodes_pool_.size() <= kFreeNodesLowWatermark) {
+ return;
+ }
}
- tab_node.Tombstone();
}
}
-bool TabNodePool::ReassociateTabNode(int64 sync_id, SessionID::id_type tab_id) {
- SyncIDToTabIDMap::iterator it = syncid_tabid_map_.find(sync_id);
- if (it != syncid_tabid_map_.end()) {
- syncid_tabid_map_[sync_id] = tab_id;
- return true;
+bool TabNodePool::IsUnassociatedTabNode(int64 sync_id) {
+ return unassociated_nodes_.find(sync_id) != unassociated_nodes_.end();
+}
+
+void TabNodePool::ReassociateTabNode(int64 sync_id, SessionID::id_type tab_id) {
+ // Remove from list of unassociated sync_nodes if present.
+ std::set<int64>::iterator it = unassociated_nodes_.find(sync_id);
+ if (it != unassociated_nodes_.end()) {
+ unassociated_nodes_.erase(it);
+ } else {
+ // sync_id must be an already associated node.
+ DCHECK(syncid_tabid_map_.find(sync_id) != syncid_tabid_map_.end());
}
- return false;
+ syncid_tabid_map_[sync_id] = tab_id;
}
SessionID::id_type TabNodePool::GetTabIdFromSyncId(int64 sync_id) const {
@@ -133,29 +160,26 @@
return kInvalidTabID;
}
-void TabNodePool::FreeUnusedTabNodes(const std::set<int64>& used_sync_ids) {
- for (SyncIDToTabIDMap::iterator it = syncid_tabid_map_.begin();
- it != syncid_tabid_map_.end();) {
- if (used_sync_ids.find(it->first) == used_sync_ids.end()) {
- // This sync node is not used, return it to free node pool.
- int64 sync_id = it->first;
- ++it;
- FreeTabNode(sync_id);
- } else {
- ++it;
- }
+void TabNodePool::FreeUnassociatedTabNodes() {
+ for (std::set<int64>::iterator it = unassociated_nodes_.begin();
+ it != unassociated_nodes_.end();) {
+ FreeTabNodeInternal(*it);
+ unassociated_nodes_.erase(it++);
}
+ DCHECK(unassociated_nodes_.empty());
}
// Clear tab pool.
void TabNodePool::Clear() {
+ unassociated_nodes_.clear();
free_nodes_pool_.clear();
syncid_tabid_map_.clear();
max_used_tab_node_id_ = 0;
}
size_t TabNodePool::Capacity() const {
- return syncid_tabid_map_.size() + free_nodes_pool_.size();
+ return syncid_tabid_map_.size() + unassociated_nodes_.size() +
+ free_nodes_pool_.size();
}
bool TabNodePool::Empty() const { return free_nodes_pool_.empty(); }
diff --git a/chrome/browser/sync/glue/tab_node_pool.h b/chrome/browser/sync/glue/tab_node_pool.h
index 4ad3fef..7727ba3 100644
--- a/chrome/browser/sync/glue/tab_node_pool.h
+++ b/chrome/browser/sync/glue/tab_node_pool.h
@@ -29,6 +29,17 @@
// difference is that tab_node_id is controlled by the model associator and
// is used when creating a new sync node, which returns the sync_id, created
// by the sync db.
+//
+// A sync node can be in one of the three states:
+// 1. Associated : Sync node is used and associated with a tab.
+// 2. Unassociated : Sync node is used but currently unassociated with any tab.
+// This is true for old nodes that remain from a session
+// restart. Nodes are only unassociated temporarily while the
+// model associator figures out which tabs belong to which
+// nodes. Eventually any remaining unassociated nodes are
+// freed.
+// 3. Free : Sync node is unused.
+
class TabNodePool {
public:
explicit TabNodePool(ProfileSyncService* sync_service);
@@ -36,6 +47,14 @@
enum InvalidTab {
kInvalidTabID = -1
};
+
+ // If free nodes > kFreeNodesHighWatermark, delete all free nodes until
+ // free nodes <= kFreeNodesLowWatermark.
+ static const size_t kFreeNodesLowWatermark;
+
+ // Maximum limit of FreeNodes allowed on the client.
+ static const size_t kFreeNodesHighWatermark;
+
// Build a sync tag from tab_node_id.
static std::string TabIdToTag(const std::string machine_tag,
size_t tab_node_id);
@@ -48,40 +67,39 @@
// associated.
int64 GetFreeTabNode();
- // Removes the node from |syncid_tabid_map_| and returns the node to free
- // pool.
+ // Removes association for |sync_id| and returns it to the free node pool.
void FreeTabNode(int64 sync_id);
- // Removes |sync_id| from free node pool and associates it with |tab_id|.
- // sync_id should be id of a free node. In order to associate a non free
- // sync node, use ReassociateTabNode.
+ // Associates |sync_id| with |tab_id|. |sync_id| should either be unassociated
+ // or free. If |sync_id| is free, |sync_id| is removed from the free node pool
+ // In order to associate a non free sync node, use ReassociateTabNode.
void AssociateTabNode(int64 sync_id, SessionID::id_type tab_id);
- // Associate sync_id with tab_id but does not add it to free node pool.
+ // Adds |sync_id| as an unassociated sync node.
// Note: this should only be called when we discover tab sync nodes from
// previous sessions, not for freeing tab nodes we created through
// GetFreeTabNode (use FreeTabNode below for that).
- // The difference between AddTabNode and AssociateTabNode is that
- // AssociateTabNode requires the sync node to be free to be associated.
- // AddTabNode just adds the association.
void AddTabNode(int64 sync_id, const SessionID& tab_id, size_t tab_node_id);
- // Returns the tab_id for |sync_id| if it exists else returns kInvalidTabID.
+ // Returns the tab_id for |sync_id| if it is associated else returns
+ // kInvalidTabID.
SessionID::id_type GetTabIdFromSyncId(int64 sync_id) const;
- // Reassociates sync node with id |sync_id| with tab node with |tab_id|.
- // Returns true if it is able to reassociate the node, false if a sync node
- // with id |sync_id| is not associated with any tab.
- bool ReassociateTabNode(int64 sync_id, SessionID::id_type tab_id);
+ // Reassociates |sync_id| with |tab_id|. |sync_id| must be either associated
+ // with a tab or in the set of unassociated nodes.
+ void ReassociateTabNode(int64 sync_id, SessionID::id_type tab_id);
- // Returns any nodes with sync_ids not in |used_synced_ids| to free node pool.
- void FreeUnusedTabNodes(const std::set<int64>& used_sync_ids);
+ // Returns true if |sync_id| is an unassociated tab node.
+ bool IsUnassociatedTabNode(int64 sync_id);
+
+ // Returns any unassociated nodes to the free node pool.
+ void FreeUnassociatedTabNodes();
// Clear tab pool.
void Clear();
// Return the number of tab nodes this client currently has allocated
- // (including both free and used nodes)
+ // (including both free, unassociated and associated nodes)
size_t Capacity() const;
// Return empty status (all tab nodes are in use).
@@ -96,6 +114,9 @@
friend class SyncTabNodePoolTest;
typedef std::map<int64, SessionID::id_type> SyncIDToTabIDMap;
+ // Adds |sync_id| to free node pool.
+ void FreeTabNodeInternal(int64 sync_id);
+
// Stores mapping of sync_ids associated with tab_ids, these are the used
// nodes of tab node pool.
// The nodes in the map can be returned to free tab node pool by calling
@@ -105,6 +126,11 @@
// The sync ids for the set of free sync nodes.
std::set<int64> free_nodes_pool_;
+ // The sync ids that are added to pool using AddTabNode and are currently
+ // not associated with any tab. They can be reassociated using
+ // ReassociateTabNode.
+ std::set<int64> unassociated_nodes_;
+
// The maximum used tab_node id for a sync node. A new sync node will always
// be created with max_used_tab_node_id_ + 1.
size_t max_used_tab_node_id_;
diff --git a/chrome/browser/sync/glue/tab_node_pool_unittest.cc b/chrome/browser/sync/glue/tab_node_pool_unittest.cc
index b3ee12f..4487df6 100644
--- a/chrome/browser/sync/glue/tab_node_pool_unittest.cc
+++ b/chrome/browser/sync/glue/tab_node_pool_unittest.cc
@@ -33,8 +33,8 @@
EXPECT_EQ(1000u, GetMaxUsedTabNodeId());
pool_.ReassociateTabNode(6, 500);
// Freeing a tab node does not change max_used_tab_node_id_.
- pool_.FreeTabNode(4);
- pool_.FreeUnusedTabNodes(std::set<int64>());
+ pool_.FreeTabNode(6);
+ pool_.FreeUnassociatedTabNodes();
EXPECT_EQ(1000u, GetMaxUsedTabNodeId());
for (int i = 0; i < 3; ++i) {
pool_.AssociateTabNode(pool_.GetFreeTabNode(), i + 1);
@@ -55,20 +55,16 @@
pool_.AddTabNode(5, session_id, 2);
EXPECT_EQ(2u, pool_.Capacity());
EXPECT_TRUE(pool_.Empty());
- EXPECT_TRUE(pool_.ReassociateTabNode(4, 2));
- EXPECT_TRUE(pool_.ReassociateTabNode(5, 1));
+ EXPECT_TRUE(pool_.IsUnassociatedTabNode(4));
+ pool_.ReassociateTabNode(4, 2);
EXPECT_TRUE(pool_.Empty());
- // Check free unused tab nodes returns the node to free node pool_.
- std::set<int64> used_sync_ids;
- used_sync_ids.insert(5);
- pool_.FreeUnusedTabNodes(used_sync_ids);
- // 4 should be returned to free node pool_.
+ // Check FreeUnassociatedTabNodes returns the node to free node pool_.
+ pool_.FreeUnassociatedTabNodes();
+ // 5 should be returned to free node pool_.
EXPECT_EQ(2u, pool_.Capacity());
+ // Should be able to free 4.
+ pool_.FreeTabNode(4);
EXPECT_FALSE(pool_.Empty());
- // 5 should still be in the associated nodes.
- EXPECT_FALSE(pool_.Full());
- pool_.FreeTabNode(5);
- // 5 should be returned to free nodes pool and pool should be full.
EXPECT_TRUE(pool_.Full());
EXPECT_EQ(4, pool_.GetFreeTabNode());
pool_.AssociateTabNode(4, 1);
@@ -87,24 +83,24 @@
// sync_id = 5, tab_node_id = 2, tab_id = 2
session_id.set_id(2);
pool_.AddTabNode(5, session_id, 2);
- // sync_id = 5, tab_node_id = 3, tab_id =3
+ // sync_id = 6, tab_node_id = 3, tab_id =3
session_id.set_id(3);
pool_.AddTabNode(6, session_id, 3);
EXPECT_EQ(3u, pool_.Capacity());
EXPECT_TRUE(pool_.Empty());
+ EXPECT_TRUE(pool_.IsUnassociatedTabNode(4));
+ pool_.ReassociateTabNode(4, 5);
// Free 5 and 6.
- pool_.FreeTabNode(5);
- pool_.FreeTabNode(6);
- // 5 and 6 nodes should not get reassociated.
- EXPECT_TRUE(pool_.ReassociateTabNode(4, 5));
- EXPECT_FALSE(pool_.ReassociateTabNode(5, 6));
- EXPECT_FALSE(pool_.ReassociateTabNode(6, 7));
+ pool_.FreeUnassociatedTabNodes();
+ // 5 and 6 nodes should not be unassociated.
+ EXPECT_FALSE(pool_.IsUnassociatedTabNode(5));
+ EXPECT_FALSE(pool_.IsUnassociatedTabNode(6));
// Free node pool should have 5 and 6.
EXPECT_FALSE(pool_.Empty());
EXPECT_EQ(3u, pool_.Capacity());
// Free all nodes
- pool_.FreeUnusedTabNodes(std::set<int64>());
+ pool_.FreeTabNode(4);
EXPECT_TRUE(pool_.Full());
std::set<int64> free_sync_ids;
for (int i = 0; i < 3; ++i) {
@@ -132,7 +128,7 @@
pool_.AddTabNode(5, session_id, 1);
session_id.set_id(2);
pool_.AddTabNode(10, session_id, 2);
- pool_.FreeUnusedTabNodes(std::set<int64>());
+ pool_.FreeUnassociatedTabNodes();
EXPECT_FALSE(pool_.Empty());
EXPECT_TRUE(pool_.Full());
@@ -156,7 +152,7 @@
session_id.set_id(2);
pool_.AddTabNode(10, session_id, 2);
// Free added nodes.
- pool_.FreeUnusedTabNodes(std::set<int64>());
+ pool_.FreeUnassociatedTabNodes();
EXPECT_FALSE(pool_.Empty());
EXPECT_TRUE(pool_.Full());
EXPECT_EQ(2U, pool_.Capacity());
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc
index 2754e65..c045d86 100644
--- a/chrome/browser/sync/profile_sync_service.cc
+++ b/chrome/browser/sync/profile_sync_service.cc
@@ -347,19 +347,10 @@
}
void ProfileSyncService::RegisterAuthNotifications() {
- TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
- registrar_.Add(this,
- chrome::NOTIFICATION_TOKEN_AVAILABLE,
- content::Source<TokenService>(token_service));
- registrar_.Add(this,
- chrome::NOTIFICATION_TOKEN_LOADING_FINISHED,
- content::Source<TokenService>(token_service));
- registrar_.Add(this,
- chrome::NOTIFICATION_TOKEN_REQUEST_FAILED,
- content::Source<TokenService>(token_service));
- registrar_.Add(this,
- chrome::NOTIFICATION_TOKENS_CLEARED,
- content::Source<TokenService>(token_service));
+ ProfileOAuth2TokenService* token_service =
+ ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
+ token_service->AddObserver(this);
+
registrar_.Add(this,
chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL,
content::Source<Profile>(profile_));
@@ -368,6 +359,13 @@
content::Source<Profile>(profile_));
}
+void ProfileSyncService::UnregisterAuthNotifications() {
+ ProfileOAuth2TokenService* token_service =
+ ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
+ token_service->RemoveObserver(this);
+ registrar_.RemoveAll();
+}
+
void ProfileSyncService::RegisterDataTypeController(
DataTypeController* data_type_controller) {
DCHECK_EQ(data_type_controllers_.count(data_type_controller->type()), 0U);
@@ -681,7 +679,45 @@
}
}
+void ProfileSyncService::OnRefreshTokenAvailable(
+ const std::string& account_id) {
+ OnRefreshTokensLoaded();
+}
+
+void ProfileSyncService::OnRefreshTokenRevoked(
+ const std::string& account_id,
+ const GoogleServiceAuthError& error) {
+ if (!IsOAuthRefreshTokenAvailable()) {
+ // The additional check around IsOAuthRefreshTokenAvailable() above
+ // prevents us sounding the alarm if we actually have a valid token but
+ // a refresh attempt by TokenService failed for any variety of reasons
+ // (e.g. flaky network). It's possible the token we do have is also
+ // invalid, but in that case we should already have (or can expect) an
+ // auth error sent from the sync backend.
+ UpdateAuthErrorState(error);
+ }
+}
+
+void ProfileSyncService::OnRefreshTokensLoaded() {
+ // This notification gets fired when TokenService loads the tokens
+ // from storage.
+ // Initialize the backend if sync is enabled. If the sync token was
+ // not loaded, GetCredentials() will generate invalid credentials to
+ // cause the backend to generate an auth error (crbug.com/121755).
+ if (backend_) {
+ RequestAccessToken();
+ } else {
+ TryStart();
+ }
+}
+
+void ProfileSyncService::OnRefreshTokensCleared() {
+ access_token_.clear();
+}
+
void ProfileSyncService::Shutdown() {
+ UnregisterAuthNotifications();
+
if (profile_)
SigninGlobalError::GetForProfile(profile_)->RemoveProvider(this);
@@ -778,14 +814,16 @@
}
void ProfileSyncService::NotifyObservers() {
- FOR_EACH_OBSERVER(Observer, observers_, OnStateChanged());
+ FOR_EACH_OBSERVER(ProfileSyncServiceBase::Observer, observers_,
+ OnStateChanged());
// TODO(akalin): Make an Observer subclass that listens and does the
// event routing.
sync_js_controller_.HandleJsEvent("onServiceStateChanged", JsEventDetails());
}
void ProfileSyncService::NotifySyncCycleCompleted() {
- FOR_EACH_OBSERVER(Observer, observers_, OnSyncCycleCompleted());
+ FOR_EACH_OBSERVER(ProfileSyncServiceBase::Observer, observers_,
+ OnSyncCycleCompleted());
sync_js_controller_.HandleJsEvent(
"onServiceStateChanged", JsEventDetails());
}
@@ -1898,8 +1936,6 @@
void ProfileSyncService::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
- const char* sync_token_service = use_oauth2_token_ ?
- GaiaConstants::kGaiaOAuth2LoginRefreshToken : GaiaConstants::kSyncService;
switch (type) {
case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: {
const GoogleServiceSigninSuccessDetails* successful =
@@ -1923,58 +1959,6 @@
}
break;
}
- case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: {
- // TODO(atwilson): sync shouldn't report refresh token request failures.
- // TokenService should do that instead.
- const TokenService::TokenRequestFailedDetails& token_details =
- *(content::Details<const TokenService::TokenRequestFailedDetails>(
- details).ptr());
- if (token_details.service() == sync_token_service &&
- !IsOAuthRefreshTokenAvailable()) {
- // The additional check around IsOAuthRefreshTokenAvailable() above
- // prevents us sounding the alarm if we actually have a valid token but
- // a refresh attempt by TokenService failed for any variety of reasons
- // (e.g. flaky network). It's possible the token we do have is also
- // invalid, but in that case we should already have (or can expect) an
- // auth error sent from the sync backend.
- AuthError error(AuthError::INVALID_GAIA_CREDENTIALS);
- UpdateAuthErrorState(error);
- }
- break;
- }
- case chrome::NOTIFICATION_TOKEN_AVAILABLE: {
- // TODO(atwilson): Listen for notifications on OAuth2TokenService
- // (crbug.com/243737)
- const TokenService::TokenAvailableDetails& token_details =
- *(content::Details<const TokenService::TokenAvailableDetails>(
- details).ptr());
- if (token_details.service() != sync_token_service)
- break;
- } // Fall through.
- case chrome::NOTIFICATION_TOKEN_LOADING_FINISHED: {
- // This notification gets fired when TokenService loads the tokens
- // from storage.
- // Initialize the backend if sync is enabled. If the sync token was
- // not loaded, GetCredentials() will generate invalid credentials to
- // cause the backend to generate an auth error (crbug.com/121755).
- if (backend_) {
- if (use_oauth2_token_)
- RequestAccessToken();
- else
- backend_->UpdateCredentials(GetCredentials());
- } else {
- TryStart();
- }
- break;
- }
- case chrome::NOTIFICATION_TOKENS_CLEARED: {
- // GetCredentials() will generate invalid credentials to cause the backend
- // to generate an auth error.
- access_token_.clear();
- if (backend_)
- backend_->UpdateCredentials(GetCredentials());
- break;
- }
case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT:
sync_disabled_by_admin_ = false;
DisableForUser();
@@ -1985,15 +1969,18 @@
}
}
-void ProfileSyncService::AddObserver(Observer* observer) {
+void ProfileSyncService::AddObserver(
+ ProfileSyncServiceBase::Observer* observer) {
observers_.AddObserver(observer);
}
-void ProfileSyncService::RemoveObserver(Observer* observer) {
+void ProfileSyncService::RemoveObserver(
+ ProfileSyncServiceBase::Observer* observer) {
observers_.RemoveObserver(observer);
}
-bool ProfileSyncService::HasObserver(Observer* observer) const {
+bool ProfileSyncService::HasObserver(
+ ProfileSyncServiceBase::Observer* observer) const {
return observers_.HasObserver(observer);
}
@@ -2031,6 +2018,9 @@
void ProfileSyncService::StopAndSuppress() {
sync_prefs_.SetStartSuppressed(true);
+ if (backend_) {
+ backend_->UnregisterInvalidationIds();
+ }
ShutdownImpl(false);
}
diff --git a/chrome/browser/sync/profile_sync_service.h b/chrome/browser/sync/profile_sync_service.h
index 18dc129..89edb3b 100644
--- a/chrome/browser/sync/profile_sync_service.h
+++ b/chrome/browser/sync/profile_sync_service.h
@@ -163,7 +163,8 @@
public content::NotificationObserver,
public BrowserContextKeyedService,
public browser_sync::DataTypeEncryptionHandler,
- public OAuth2TokenService::Consumer {
+ public OAuth2TokenService::Consumer,
+ public OAuth2TokenService::Observer {
public:
typedef browser_sync::SyncBackendHost::Status Status;
@@ -235,11 +236,14 @@
virtual bool HasSyncSetupCompleted() const OVERRIDE;
virtual bool ShouldPushChanges() OVERRIDE;
virtual syncer::ModelTypeSet GetActiveDataTypes() const OVERRIDE;
- virtual void AddObserver(Observer* observer) OVERRIDE;
- virtual void RemoveObserver(Observer* observer) OVERRIDE;
- virtual bool HasObserver(Observer* observer) const OVERRIDE;
+ virtual void AddObserver(ProfileSyncServiceBase::Observer* observer) OVERRIDE;
+ virtual void RemoveObserver(
+ ProfileSyncServiceBase::Observer* observer) OVERRIDE;
+ virtual bool HasObserver(
+ ProfileSyncServiceBase::Observer* observer) const OVERRIDE;
void RegisterAuthNotifications();
+ void UnregisterAuthNotifications();
// Returns true if sync is enabled/not suppressed and the user is logged in.
// (being logged in does not mean that tokens are available - tokens may
@@ -590,7 +594,7 @@
// The set of currently enabled sync experiments.
const syncer::Experiments& current_experiments() const;
- // OAuth2TokenService::Consumer implementation
+ // OAuth2TokenService::Consumer implementation.
virtual void OnGetTokenSuccess(
const OAuth2TokenService::Request* request,
const std::string& access_token,
@@ -599,6 +603,14 @@
const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) OVERRIDE;
+ // OAuth2TokenService::Observer implementation.
+ virtual void OnRefreshTokenAvailable(const std::string& account_id) OVERRIDE;
+ virtual void OnRefreshTokenRevoked(
+ const std::string& account_id,
+ const GoogleServiceAuthError& error) OVERRIDE;
+ virtual void OnRefreshTokensLoaded() OVERRIDE;
+ virtual void OnRefreshTokensCleared() OVERRIDE;
+
// BrowserContextKeyedService implementation. This must be called exactly
// once (before this object is destroyed).
virtual void Shutdown() OVERRIDE;
@@ -838,7 +850,7 @@
// Manages the start and stop of the various data types.
scoped_ptr<browser_sync::DataTypeManager> data_type_manager_;
- ObserverList<Observer> observers_;
+ ObserverList<ProfileSyncServiceBase::Observer> observers_;
syncer::SyncJsController sync_js_controller_;
diff --git a/chrome/browser/sync/profile_sync_service_android.cc b/chrome/browser/sync/profile_sync_service_android.cc
index ffefa2e..8abc53b 100644
--- a/chrome/browser/sync/profile_sync_service_android.cc
+++ b/chrome/browser/sync/profile_sync_service_android.cc
@@ -119,7 +119,7 @@
syncer::ObjectIdSet object_ids;
object_ids.insert(object_id);
syncer::ObjectIdInvalidationMap object_ids_with_states =
- syncer::ObjectIdSetToInvalidationMap(object_ids, state);
+ syncer::ObjectIdSetToInvalidationMap(object_ids, version, state);
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_SYNC_REFRESH_REMOTE,
diff --git a/chrome/browser/sync/profile_sync_service_mock.h b/chrome/browser/sync/profile_sync_service_mock.h
index 128422c..ce3aec2 100644
--- a/chrome/browser/sync/profile_sync_service_mock.h
+++ b/chrome/browser/sync/profile_sync_service_mock.h
@@ -65,8 +65,8 @@
MOCK_METHOD1(DeactivateDataType, void(syncer::ModelType));
MOCK_METHOD0(UnsuppressAndStart, void());
- MOCK_METHOD1(AddObserver, void(Observer*));
- MOCK_METHOD1(RemoveObserver, void(Observer*));
+ MOCK_METHOD1(AddObserver, void(ProfileSyncServiceBase::Observer*));
+ MOCK_METHOD1(RemoveObserver, void(ProfileSyncServiceBase::Observer*));
MOCK_METHOD0(GetJsController, base::WeakPtr<syncer::JsController>());
MOCK_CONST_METHOD0(HasSyncSetupCompleted, bool());
diff --git a/chrome/browser/sync/profile_sync_service_session_unittest.cc b/chrome/browser/sync/profile_sync_service_session_unittest.cc
index b400e9e..6643286 100644
--- a/chrome/browser/sync/profile_sync_service_session_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_session_unittest.cc
@@ -798,7 +798,7 @@
model_associator_->tab_pool_.AddTabNode(i + 1, session_id, i);
}
- model_associator_->tab_pool_.FreeUnusedTabNodes(std::set<int64>());
+ model_associator_->tab_pool_.FreeUnassociatedTabNodes();
std::vector<int64> node_ids;
ASSERT_EQ(num_starting_nodes, model_associator_->tab_pool_.Capacity());
ASSERT_FALSE(model_associator_->tab_pool_.Empty());
@@ -1292,7 +1292,7 @@
// Create new WebContents, with the required tab helpers.
WebContents* new_web_contents = WebContents::CreateWithSessionStorage(
WebContents::CreateParams(profile()),
- old_web_contents->GetController().GetSessionStorageNamespace());
+ old_web_contents->GetController().GetSessionStorageNamespaceMap());
SessionTabHelper::CreateForWebContents(new_web_contents);
TabContentsSyncedTabDelegate::CreateForWebContents(new_web_contents);
new_web_contents->GetController()
@@ -1328,4 +1328,46 @@
ASSERT_FALSE(error.IsSet());
}
+TEST_F(ProfileSyncServiceSessionTest, TabPoolFreeNodeLimits) {
+ CreateRootHelper create_root(this);
+ ASSERT_TRUE(StartSyncService(create_root.callback(), false));
+ ASSERT_TRUE(create_root.success());
+
+ // Allocate TabNodePool::kFreeNodesHighWatermark + 1 nodes and verify that
+ // freeing the last node reduces the free node pool size to
+ // kFreeNodesLowWatermark.
+
+ SessionID session_id;
+ std::vector<int64> used_sync_ids;
+ for (size_t i = 1; i <= TabNodePool::kFreeNodesHighWatermark + 1; ++i) {
+ session_id.set_id(i);
+ int64 sync_id = model_associator_->tab_pool_.GetFreeTabNode();
+ model_associator_->tab_pool_.AssociateTabNode(sync_id, i);
+ used_sync_ids.push_back(sync_id);
+ }
+
+ // Free all except one node.
+ int64 last_sync_id = used_sync_ids.back();
+ used_sync_ids.pop_back();
+
+ for (size_t i = 0; i < used_sync_ids.size(); ++i) {
+ model_associator_->tab_pool_.FreeTabNode(used_sync_ids[i]);
+ }
+
+ // Except one node all nodes should be in FreeNode pool.
+ EXPECT_FALSE(model_associator_->tab_pool_.Full());
+ EXPECT_FALSE(model_associator_->tab_pool_.Empty());
+ // Total capacity = 1 Associated Node + kFreeNodesHighWatermark free node.
+ EXPECT_EQ(TabNodePool::kFreeNodesHighWatermark + 1,
+ model_associator_->tab_pool_.Capacity());
+
+ // Freeing the last sync node should drop the free nodes to
+ // kFreeNodesLowWatermark.
+ model_associator_->tab_pool_.FreeTabNode(last_sync_id);
+ EXPECT_FALSE(model_associator_->tab_pool_.Empty());
+ EXPECT_TRUE(model_associator_->tab_pool_.Full());
+ EXPECT_EQ(TabNodePool::kFreeNodesLowWatermark,
+ model_associator_->tab_pool_.Capacity());
+}
+
} // namespace browser_sync
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc
index c8cf87c..ff6ed2c 100644
--- a/chrome/browser/sync/test/integration/sync_test.cc
+++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -671,7 +671,9 @@
"from_server",
syncer::NOTIFY_ALL,
syncer::ObjectIdSetToInvalidationMap(
- syncer::ModelTypeSetToObjectIdSet(changed_types), std::string())
+ syncer::ModelTypeSetToObjectIdSet(changed_types),
+ syncer::Invalidation::kUnknownVersion,
+ std::string())
).ToString();
const std::string& path =
std::string("chromiumsync/sendnotification?channel=") +
diff --git a/chrome/browser/sync/test_profile_sync_service.cc b/chrome/browser/sync/test_profile_sync_service.cc
index 2fefd29..499d2be 100644
--- a/chrome/browser/sync/test_profile_sync_service.cc
+++ b/chrome/browser/sync/test_profile_sync_service.cc
@@ -327,8 +327,7 @@
content::BrowserContext* context) {
Profile* profile = static_cast<Profile*>(context);
- FakeOAuth2TokenService* service =
- new FakeOAuth2TokenService(context->GetRequestContext());
+ FakeOAuth2TokenService* service = new FakeOAuth2TokenService();
service->Initialize(profile);
return service;
}
diff --git a/chrome/browser/sync/test_profile_sync_service.h b/chrome/browser/sync/test_profile_sync_service.h
index 41d2687..3322258 100644
--- a/chrome/browser/sync/test_profile_sync_service.h
+++ b/chrome/browser/sync/test_profile_sync_service.h
@@ -193,9 +193,6 @@
class FakeOAuth2TokenService : public ProfileOAuth2TokenService {
public:
- explicit FakeOAuth2TokenService(net::URLRequestContextGetter* getter)
- : ProfileOAuth2TokenService(getter) {}
-
virtual scoped_ptr<OAuth2TokenService::Request> StartRequest(
const OAuth2TokenService::ScopeSet& scopes,
OAuth2TokenService::Consumer* consumer) OVERRIDE;
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_database.cc b/chrome/browser/sync_file_system/drive_backend/metadata_database.cc
index 468632e..5440d98 100644
--- a/chrome/browser/sync_file_system/drive_backend/metadata_database.cc
+++ b/chrome/browser/sync_file_system/drive_backend/metadata_database.cc
@@ -55,6 +55,57 @@
return str;
}
+base::FilePath ReverseConcatPathComponents(
+ const std::vector<base::FilePath>& components) {
+ if (components.empty())
+ return base::FilePath(FILE_PATH_LITERAL("/")).NormalizePathSeparators();
+
+ size_t total_size = 0;
+ typedef std::vector<base::FilePath> PathComponents;
+ for (PathComponents::const_iterator itr = components.begin();
+ itr != components.end(); ++itr)
+ total_size += itr->value().size() + 1;
+
+ base::FilePath::StringType result;
+ result.reserve(total_size);
+ for (PathComponents::const_reverse_iterator itr = components.rbegin();
+ itr != components.rend(); ++itr) {
+ result.append(1, base::FilePath::kSeparators[0]);
+ result.append(itr->value());
+ }
+
+ return base::FilePath(result).NormalizePathSeparators();
+}
+
+void PopulateFileDetailsFromFileResource(
+ int64 change_id,
+ const google_apis::FileResource& file_resource,
+ DriveFileMetadata::Details* details) {
+ details->set_change_id(change_id);
+ for (ScopedVector<google_apis::ParentReference>::const_iterator itr =
+ file_resource.parents().begin();
+ itr != file_resource.parents().end();
+ ++itr) {
+ details->add_parent_folder_id((*itr)->file_id());
+ }
+ details->set_title(file_resource.title());
+
+ google_apis::DriveEntryKind kind = file_resource.GetKind();
+ if (kind == google_apis::ENTRY_KIND_FILE)
+ details->set_kind(KIND_FILE);
+ else if (kind == google_apis::ENTRY_KIND_FOLDER)
+ details->set_kind(KIND_FOLDER);
+ else
+ details->set_kind(KIND_UNSUPPORTED);
+
+ details->set_md5(file_resource.md5_checksum());
+ details->set_etag(file_resource.etag());
+ details->set_creation_time(file_resource.created_date().ToInternalValue());
+ details->set_modification_time(
+ file_resource.modified_date().ToInternalValue());
+ details->set_deleted(false);
+}
+
void AdaptLevelDBStatusToSyncStatusCode(const SyncStatusCallback& callback,
const leveldb::Status& status) {
callback.Run(LevelDBStatusToSyncStatusCode(status));
@@ -251,7 +302,7 @@
unvisited_files.erase(found);
reachable_files.push_back(metadata);
- if (!metadata->active())
+ if (!metadata->active() && !metadata->is_app_root())
continue;
}
@@ -449,14 +500,75 @@
bool MetadataDatabase::BuildPathForFile(const std::string& file_id,
base::FilePath* path) const {
- NOTIMPLEMENTED();
- return false;
+ DriveFileMetadata current;
+ if (!FindFileByFileID(file_id, ¤t) || !current.active())
+ return false;
+
+ std::vector<base::FilePath> components;
+ while (!current.is_app_root()) {
+ components.push_back(base::FilePath::FromUTF8Unsafe(
+ current.synced_details().title()));
+ if (!FindFileByFileID(current.parent_folder_id(), ¤t) ||
+ !current.active())
+ return false;
+ }
+
+ if (path)
+ *path = ReverseConcatPathComponents(components);
+
+ return true;
}
void MetadataDatabase::UpdateByChangeList(
ScopedVector<google_apis::ChangeResource> changes,
const SyncStatusCallback& callback) {
- NOTIMPLEMENTED();
+ scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
+
+ for (ScopedVector<google_apis::ChangeResource>::iterator itr =
+ changes.begin();
+ itr != changes.end();
+ ++itr) {
+ const google_apis::ChangeResource& change = **itr;
+ DriveFileMetadata file;
+
+ // If the remote file already has an entry in the database, update its
+ // |remote_detais| and mark it dirty.
+ if (FindFileByFileID(change.file_id(), NULL)) {
+ const google_apis::FileResource* file_resource = NULL;
+ if (!change.is_deleted())
+ file_resource = change.file();
+ UpdateRemoteDetails(change.change_id(), change.file_id(), file_resource,
+ batch.get());
+ continue;
+ }
+
+ // Deletion of an unknown file can be safely ignorable.
+ if (change.is_deleted())
+ continue;
+
+ // Find first active parent.
+ std::string parent_folder_id;
+ DriveFileMetadata parent;
+ for (ScopedVector<google_apis::ParentReference>::const_iterator itr =
+ change.file()->parents().begin();
+ itr != change.file()->parents().end();
+ ++itr) {
+ if (FindFileByFileID((*itr)->file_id(), &parent) &&
+ (parent.active() || parent.is_app_root())) {
+ parent_folder_id = parent.file_id();
+ break;
+ }
+ }
+
+ // If the remote file doesn't have active parent, ignore the file.
+ if (parent_folder_id.empty())
+ continue;
+
+ RegisterNewFile(change.change_id(), parent, *change.file(),
+ batch.get());
+ }
+
+ WriteToDatabase(batch.Pass(), callback);
}
void MetadataDatabase::PopulateFolder(
@@ -696,6 +808,56 @@
dirty_files_.erase(file.get());
}
+void MetadataDatabase::UpdateRemoteDetails(
+ int64 change_id,
+ const std::string& file_id,
+ const google_apis::FileResource* file_resource,
+ leveldb::WriteBatch* batch) {
+ DriveFileMetadata* file = file_by_file_id_[file_id];
+
+ file->clear_remote_details();
+ DriveFileMetadata::Details* details = file->mutable_remote_details();
+ if (file_resource) {
+ PopulateFileDetailsFromFileResource(change_id, *file_resource, details);
+ } else {
+ details->set_deleted(true);
+ details->set_change_id(change_id);
+ }
+
+ file->set_dirty(true);
+ PutFileToBatch(*file, batch);
+
+ dirty_files_.insert(file);
+}
+
+void MetadataDatabase::RegisterNewFile(
+ int64 change_id,
+ const DriveFileMetadata& parent_folder,
+ const google_apis::FileResource& new_file_resource,
+ leveldb::WriteBatch* batch) {
+ scoped_ptr<DriveFileMetadata> file(new DriveFileMetadata);
+ std::string file_id = new_file_resource.file_id();
+ file->set_file_id(file_id);
+ file->set_parent_folder_id(parent_folder.file_id());
+ file->set_app_id(parent_folder.app_id());
+ file->set_is_app_root(false);
+
+ PopulateFileDetailsFromFileResource(
+ change_id, new_file_resource, file->mutable_remote_details());
+
+ file->set_dirty(true);
+ file->set_active(false);
+ file->set_needs_folder_listing(
+ new_file_resource.GetKind() == google_apis::ENTRY_KIND_FOLDER);
+
+ PutFileToBatch(*file, batch);
+
+ files_by_parent_[parent_folder.file_id()].insert(file.get());
+ dirty_files_.insert(file.get());
+
+ file_by_file_id_[file_id] = file.release();
+}
+
void MetadataDatabase::WriteToDatabase(scoped_ptr<leveldb::WriteBatch> batch,
const SyncStatusCallback& callback) {
base::PostTaskAndReplyWithResult(
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_database.h b/chrome/browser/sync_file_system/drive_backend/metadata_database.h
index a248f9a..205a1cc 100644
--- a/chrome/browser/sync_file_system/drive_backend/metadata_database.h
+++ b/chrome/browser/sync_file_system/drive_backend/metadata_database.h
@@ -191,14 +191,22 @@
void RegisterFolderAsAppRoot(const std::string& app_id,
const std::string& folder,
leveldb::WriteBatch* batch);
- void MakeFileActive(const std::string& file,
+ void MakeFileActive(const std::string& file_id,
leveldb::WriteBatch* batch);
- void MakeFileInactive(const std::string& file,
+ void MakeFileInactive(const std::string& file_id,
leveldb::WriteBatch* batch);
void UnregisterFolderAsAppRoot(const std::string& app_id,
leveldb::WriteBatch* batch);
- void RemoveFile(const std::string& file,
+ void RemoveFile(const std::string& file_id,
leveldb::WriteBatch* batch);
+ void UpdateRemoteDetails(int64 change_id,
+ const std::string& file_id,
+ const google_apis::FileResource* file,
+ leveldb::WriteBatch* batch);
+ void RegisterNewFile(int64 change_id,
+ const DriveFileMetadata& parent_folder,
+ const google_apis::FileResource& new_file,
+ leveldb::WriteBatch* batch);
void WriteToDatabase(scoped_ptr<leveldb::WriteBatch> batch,
const SyncStatusCallback& callback);
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc b/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc
index d8fa77d..0d2d234 100644
--- a/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc
@@ -9,11 +9,14 @@
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/strings/string_number_conversions.h"
+#include "chrome/browser/google_apis/drive_api_parser.h"
#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/leveldatabase/src/include/leveldb/db.h"
#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
+#define FPL(a) FILE_PATH_LITERAL(a)
+
namespace sync_file_system {
namespace drive_backend {
@@ -28,74 +31,83 @@
const int64 kInitialChangeID = 1234;
const char kSyncRootFolderID[] = "sync_root_folder_id";
-bool AreEquivalentMessages(const google::protobuf::MessageLite& left,
- const google::protobuf::MessageLite& right);
-bool AreEquivalent(const google::protobuf::MessageLite* left,
- const google::protobuf::MessageLite* right) {
- return AreEquivalentMessages(*left, *right);
+void ExpectEquivalent(const DriveFileMetadata::Details* left,
+ const DriveFileMetadata::Details* right) {
+ EXPECT_EQ(left->title(), right->title());
+ EXPECT_EQ(left->kind(), right->kind());
+ EXPECT_EQ(left->md5(), right->md5());
+ EXPECT_EQ(left->etag(), right->etag());
+ EXPECT_EQ(left->creation_time(), right->creation_time());
+ EXPECT_EQ(left->modification_time(), right->modification_time());
+ EXPECT_EQ(left->deleted(), right->deleted());
+ EXPECT_EQ(left->change_id(), right->change_id());
+}
+
+void ExpectEquivalent(const DriveFileMetadata* left,
+ const DriveFileMetadata* right) {
+ EXPECT_EQ(left->file_id(), right->file_id());
+ EXPECT_EQ(left->parent_folder_id(), right->parent_folder_id());
+ EXPECT_EQ(left->app_id(), right->app_id());
+ EXPECT_EQ(left->is_app_root(), right->is_app_root());
+
+ {
+ SCOPED_TRACE("Expect equivalent synced_details.");
+ ExpectEquivalent(&left->synced_details(), &right->synced_details());
+ }
+
+ {
+ SCOPED_TRACE("Expect equivalent remote_details.");
+ ExpectEquivalent(&left->remote_details(), &right->remote_details());
+ }
+
+ EXPECT_EQ(left->dirty(), right->dirty());
+ EXPECT_EQ(left->active(), right->active());
+ EXPECT_EQ(left->needs_folder_listing(), right->needs_folder_listing());
}
template <typename Container>
-bool AreEquivalentMaps(const Container& left, const Container& right);
+void ExpectEquivalentMaps(const Container& left, const Container& right);
template <typename Key, typename Value, typename Compare>
-bool AreEquivalent(const std::map<Key, Value, Compare>& left,
- const std::map<Key, Value, Compare>& right) {
- return AreEquivalentMaps(left, right);
+void ExpectEquivalent(const std::map<Key, Value, Compare>& left,
+ const std::map<Key, Value, Compare>& right) {
+ ExpectEquivalentMaps(left, right);
}
template <typename Container>
-bool AreEquivalentSets(const Container& left, const Container& right);
+void ExpectEquivalentSets(const Container& left, const Container& right);
template <typename Value, typename Compare>
-bool AreEquivalent(const std::set<Value, Compare>& left,
- const std::set<Value, Compare>& right) {
- return AreEquivalentSets(left, right);
-}
-
-bool AreEquivalentMessages(const google::protobuf::MessageLite& left,
- const google::protobuf::MessageLite& right) {
- std::string serialized_left;
- std::string serialized_right;
- left.SerializeToString(&serialized_left);
- right.SerializeToString(&serialized_right);
- return serialized_left == serialized_right;
+void ExpectEquivalent(const std::set<Value, Compare>& left,
+ const std::set<Value, Compare>& right) {
+ return ExpectEquivalentSets(left, right);
}
template <typename Container>
-bool AreEquivalentMaps(const Container& left, const Container& right) {
- if (left.size() != right.size())
- return false;
-
- typedef typename Container::const_iterator const_iterator;
- const_iterator left_itr = left.begin();
- const_iterator right_itr = right.begin();
-
- while (left_itr != left.end()) {
- if (left_itr->first != right_itr->first)
- return false;
- if (!AreEquivalent(left_itr->second, right_itr->second))
- return false;
-
- ++left_itr;
- ++right_itr;
- }
- return true;
-}
-
-template <typename Container>
-bool AreEquivalentSets(const Container& left, const Container& right) {
- if (left.size() != right.size())
- return false;
+void ExpectEquivalentMaps(const Container& left, const Container& right) {
+ ASSERT_EQ(left.size(), right.size());
typedef typename Container::const_iterator const_iterator;
const_iterator left_itr = left.begin();
const_iterator right_itr = right.begin();
while (left_itr != left.end()) {
- if (!AreEquivalent(*left_itr, *right_itr))
- return false;
+ EXPECT_EQ(left_itr->first, right_itr->first);
+ ExpectEquivalent(left_itr->second, right_itr->second);
++left_itr;
++right_itr;
}
- return true;
+}
+
+template <typename Container>
+void ExpectEquivalentSets(const Container& left, const Container& right) {
+ ASSERT_EQ(left.size(), right.size());
+
+ typedef typename Container::const_iterator const_iterator;
+ const_iterator left_itr = left.begin();
+ const_iterator right_itr = right.begin();
+ while (left_itr != left.end()) {
+ ExpectEquivalent(*left_itr, *right_itr);
+ ++left_itr;
+ ++right_itr;
+ }
}
void SyncStatusResultCallback(SyncStatusCode* status_out,
@@ -117,7 +129,10 @@
class MetadataDatabaseTest : public testing::Test {
public:
- MetadataDatabaseTest() : next_file_id_number_(1) {}
+ MetadataDatabaseTest()
+ : next_change_id_(kInitialChangeID + 1),
+ next_file_id_number_(1),
+ next_md5_sequence_number_(1) {}
virtual ~MetadataDatabaseTest() {}
@@ -132,7 +147,7 @@
return "file_id_" + base::Int64ToString(next_file_id_number_++);
}
- SyncStatusCode InitializeDatabase() {
+ SyncStatusCode InitializeMetadataDatabase() {
SyncStatusCode status = SYNC_STATUS_UNKNOWN;
MetadataDatabase::Create(base::MessageLoopProxy::current(),
database_dir_.path(),
@@ -155,7 +170,7 @@
return metadata_database_->db_.get();
}
- scoped_ptr<leveldb::DB> OpenLevelDB() {
+ scoped_ptr<leveldb::DB> InitializeLevelDB() {
leveldb::DB* db = NULL;
leveldb::Options options;
options.create_if_missing = true;
@@ -163,6 +178,10 @@
leveldb::Status status =
leveldb::DB::Open(options, database_dir_.path().AsUTF8Unsafe(), &db);
EXPECT_TRUE(status.ok());
+
+ db->Put(leveldb::WriteOptions(), "VERSION", base::Int64ToString(3));
+ SetUpServiceMetadata(db);
+
return make_scoped_ptr(db);
}
@@ -175,45 +194,52 @@
db->Put(leveldb::WriteOptions(), "SERVICE", value);
}
- DriveFileMetadata CreateSyncRoot() {
- DriveFileMetadata metadata;
- metadata.set_file_id(kSyncRootFolderID);
- metadata.set_parent_folder_id(std::string());
- metadata.mutable_synced_details()->set_title("Chrome Syncable FileSystem");
- metadata.mutable_synced_details()->set_kind(KIND_FOLDER);
- metadata.set_active(true);
- metadata.set_dirty(false);
- return metadata;
+ DriveFileMetadata CreateSyncRootMetadata() {
+ DriveFileMetadata sync_root;
+ sync_root.set_file_id(kSyncRootFolderID);
+ sync_root.set_parent_folder_id(std::string());
+ sync_root.mutable_synced_details()->set_title("Chrome Syncable FileSystem");
+ sync_root.mutable_synced_details()->set_kind(KIND_FOLDER);
+ sync_root.set_active(true);
+ sync_root.set_dirty(false);
+ return sync_root;
}
- DriveFileMetadata CreateUnknownFile(const std::string& app_id,
- const std::string& parent_folder_id) {
- DriveFileMetadata metadata;
- metadata.set_file_id(GenerateFileID());
- metadata.set_parent_folder_id(parent_folder_id);
- metadata.set_app_id(app_id);
- metadata.set_is_app_root(
- !app_id.empty() && parent_folder_id == kSyncRootFolderID);
- return metadata;
+ DriveFileMetadata CreateAppRootMetadata(const DriveFileMetadata& sync_root,
+ const std::string& app_id) {
+ DriveFileMetadata app_root(
+ CreateFolderMetadata(sync_root, app_id /* title */));
+ app_root.set_app_id(app_id);
+ app_root.set_is_app_root(true);
+ return app_root;
}
- DriveFileMetadata CreateFile(const std::string& app_id,
- const std::string& parent_folder_id,
- const std::string& title) {
- DriveFileMetadata file(CreateUnknownFile(app_id, parent_folder_id));
- file.mutable_synced_details()->add_parent_folder_id(parent_folder_id);
+ DriveFileMetadata CreateUnknownFileMetadata(const DriveFileMetadata& parent) {
+ DriveFileMetadata file;
+ file.set_file_id(GenerateFileID());
+ file.set_parent_folder_id(parent.file_id());
+ file.set_app_id(parent.app_id());
+ file.set_is_app_root(false);
+ return file;
+ }
+
+ DriveFileMetadata CreateFileMetadata(const DriveFileMetadata& parent,
+ const std::string& title) {
+ DriveFileMetadata file(CreateUnknownFileMetadata(parent));
+ file.mutable_synced_details()->add_parent_folder_id(parent.file_id());
file.mutable_synced_details()->set_title(title);
file.mutable_synced_details()->set_kind(KIND_FILE);
+ file.mutable_synced_details()->set_md5(
+ "md5_value_" + base::Int64ToString(next_md5_sequence_number_++));
file.set_active(true);
file.set_dirty(false);
return file;
}
- DriveFileMetadata CreateFolder(const std::string& app_id,
- const std::string& parent_folder_id,
- const std::string& title) {
- DriveFileMetadata folder(CreateUnknownFile(app_id, parent_folder_id));
- folder.mutable_synced_details()->add_parent_folder_id(parent_folder_id);
+ DriveFileMetadata CreateFolderMetadata(const DriveFileMetadata& parent,
+ const std::string& title) {
+ DriveFileMetadata folder(CreateUnknownFileMetadata(parent));
+ folder.mutable_synced_details()->add_parent_folder_id(parent.file_id());
folder.mutable_synced_details()->set_title(title);
folder.mutable_synced_details()->set_kind(KIND_FOLDER);
folder.set_active(true);
@@ -221,6 +247,93 @@
return folder;
}
+ scoped_ptr<google_apis::ChangeResource> CreateChangeResourceFromMetadata(
+ const DriveFileMetadata& file) {
+ scoped_ptr<google_apis::ChangeResource> change(
+ new google_apis::ChangeResource);
+ change->set_change_id(file.remote_details().change_id());
+ change->set_file_id(file.file_id());
+ change->set_deleted(file.remote_details().deleted());
+ if (change->is_deleted())
+ return change.Pass();
+
+ scoped_ptr<google_apis::FileResource> file_resource(
+ new google_apis::FileResource);
+ ScopedVector<google_apis::ParentReference> parents;
+ for (int i = 0; i < file.remote_details().parent_folder_id_size(); ++i) {
+ scoped_ptr<google_apis::ParentReference> parent(
+ new google_apis::ParentReference);
+ parent->set_file_id(file.remote_details().parent_folder_id(i));
+ parents.push_back(parent.release());
+ }
+
+ file_resource->set_file_id(file.file_id());
+ file_resource->set_parents(&parents);
+ file_resource->set_title(file.remote_details().title());
+ if (file.remote_details().kind() == KIND_FOLDER)
+ file_resource->set_mime_type("application/vnd.google-apps.folder");
+ else if (file.remote_details().kind() == KIND_FILE)
+ file_resource->set_mime_type("text/plain");
+ else
+ file_resource->set_mime_type("application/vnd.google-apps.document");
+ file_resource->set_md5_checksum(file.remote_details().md5());
+ file_resource->set_etag(file.remote_details().etag());
+ file_resource->set_created_date(base::Time::FromInternalValue(
+ file.remote_details().creation_time()));
+ file_resource->set_modified_date(base::Time::FromInternalValue(
+ file.remote_details().modification_time()));
+
+ change->set_file(file_resource.Pass());
+ return change.Pass();
+ }
+
+ void ApplyRenameChangeToMetadata(const std::string& new_title,
+ DriveFileMetadata* file) {
+ DriveFileMetadata::Details* details = file->mutable_remote_details();
+ *details = file->synced_details();
+ details->set_title(new_title);
+ details->set_change_id(next_change_id_++);
+ file->set_dirty(true);
+ }
+
+ void ApplyReorganizeChangeToMetadata(const std::string& new_parent,
+ DriveFileMetadata* file) {
+ DriveFileMetadata::Details* details = file->mutable_remote_details();
+ *details = file->synced_details();
+ details->clear_parent_folder_id();
+ details->add_parent_folder_id(new_parent);
+ details->set_change_id(next_change_id_++);
+ file->set_dirty(true);
+ }
+
+ void ApplyContentChangeToMetadata(DriveFileMetadata* file) {
+ DriveFileMetadata::Details* details = file->mutable_remote_details();
+ *details = file->synced_details();
+ details->set_md5(
+ "md5_value_" + base::Int64ToString(next_md5_sequence_number_++));
+ details->set_change_id(next_change_id_++);
+ file->set_dirty(true);
+ }
+
+ void ApplyNoopChangeToMetadata(DriveFileMetadata* file) {
+ *file->mutable_remote_details() = file->synced_details();
+ file->mutable_remote_details()->set_change_id(next_change_id_++);
+ file->set_dirty(true);
+ }
+
+ void ApplyNewFileChangeToMetadata(DriveFileMetadata* file) {
+ *file->mutable_remote_details() = file->synced_details();
+ file->clear_synced_details();
+ file->mutable_remote_details()->set_change_id(next_change_id_++);
+ file->set_active(false);
+ file->set_dirty(true);
+ }
+
+ void PushToChangeList(scoped_ptr<google_apis::ChangeResource> change,
+ ScopedVector<google_apis::ChangeResource>* changes) {
+ changes->push_back(change.release());
+ }
+
leveldb::Status PutFileToDB(leveldb::DB* db, const DriveFileMetadata& file) {
std::string key = "FILE: " + file.file_id();
std::string value;
@@ -236,24 +349,45 @@
&metadata_database_2));
metadata_database_->db_ = metadata_database_2->db_.Pass();
- EXPECT_TRUE(AreEquivalent(metadata_database_->file_by_file_id_,
- metadata_database_2->file_by_file_id_));
- EXPECT_TRUE(AreEquivalent(metadata_database_->files_by_parent_,
- metadata_database_2->files_by_parent_));
- EXPECT_TRUE(AreEquivalent(metadata_database_->app_root_by_app_id_,
- metadata_database_2->app_root_by_app_id_));
- EXPECT_TRUE(AreEquivalent(
- metadata_database_->active_file_by_parent_and_title_,
- metadata_database_2->active_file_by_parent_and_title_));
- EXPECT_TRUE(AreEquivalent(metadata_database_->dirty_files_,
- metadata_database_2->dirty_files_));
+ {
+ SCOPED_TRACE("Expect equivalent file_by_file_id_ contents.");
+ ExpectEquivalent(metadata_database_->file_by_file_id_,
+ metadata_database_2->file_by_file_id_);
+ }
+
+ {
+ SCOPED_TRACE("Expect equivalent files_by_parent_ contents.");
+ ExpectEquivalent(metadata_database_->files_by_parent_,
+ metadata_database_2->files_by_parent_);
+ }
+
+ {
+ SCOPED_TRACE("Expect equivalent app_root_by_app_id_ contents.");
+ ExpectEquivalent(metadata_database_->app_root_by_app_id_,
+ metadata_database_2->app_root_by_app_id_);
+ }
+
+ {
+ SCOPED_TRACE("Expect equivalent"
+ " active_file_by_parent_and_title_ contents.");
+ ExpectEquivalent(metadata_database_->active_file_by_parent_and_title_,
+ metadata_database_2->active_file_by_parent_and_title_);
+ }
+
+ {
+ SCOPED_TRACE("Expect equivalent dirty_files_ contents.");
+ ExpectEquivalent(metadata_database_->dirty_files_,
+ metadata_database_2->dirty_files_);
+ }
}
void VerifyFile(const DriveFileMetadata& file) {
DriveFileMetadata file_in_metadata_db;
ASSERT_TRUE(metadata_database()->FindFileByFileID(
file.file_id(), &file_in_metadata_db));
- EXPECT_TRUE(AreEquivalentMessages(file, file_in_metadata_db));
+
+ SCOPED_TRACE("Expect equivalent " + file.file_id());
+ ExpectEquivalent(&file, &file_in_metadata_db);
}
SyncStatusCode RegisterApp(const std::string& app_id,
@@ -290,38 +424,49 @@
return status;
}
+ SyncStatusCode UpdateByChangeList(
+ ScopedVector<google_apis::ChangeResource> changes) {
+ SyncStatusCode status = SYNC_STATUS_UNKNOWN;
+ metadata_database_->UpdateByChangeList(
+ changes.Pass(), base::Bind(&SyncStatusResultCallback, &status));
+ message_loop_.RunUntilIdle();
+ return status;
+ }
+
private:
+
base::ScopedTempDir database_dir_;
base::MessageLoop message_loop_;
scoped_ptr<MetadataDatabase> metadata_database_;
+ int64 next_change_id_;
int64 next_file_id_number_;
+ int64 next_md5_sequence_number_;
DISALLOW_COPY_AND_ASSIGN(MetadataDatabaseTest);
};
TEST_F(MetadataDatabaseTest, InitializationTest_Empty) {
- EXPECT_EQ(SYNC_STATUS_OK, InitializeDatabase());
+ EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
DropDatabase();
- EXPECT_EQ(SYNC_STATUS_OK, InitializeDatabase());
+ EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
}
TEST_F(MetadataDatabaseTest, InitializationTest_SimpleTree) {
std::string app_id = "app_id";
- DriveFileMetadata sync_root(CreateSyncRoot());
- DriveFileMetadata app_root(CreateFolder(app_id, kSyncRootFolderID, app_id));
- DriveFileMetadata file(CreateFile(app_id, app_root.file_id(), "file"));
- DriveFileMetadata folder(CreateFolder(app_id, app_root.file_id(), "folder"));
+ DriveFileMetadata sync_root(CreateSyncRootMetadata());
+ DriveFileMetadata app_root(CreateAppRootMetadata(sync_root, "app_id"));
+ DriveFileMetadata file(CreateFileMetadata(app_root, "file"));
+ DriveFileMetadata folder(CreateFolderMetadata(app_root, "folder"));
DriveFileMetadata file_in_folder(
- CreateFile(app_id, folder.file_id(), "file_in_folder"));
- DriveFileMetadata orphaned(CreateUnknownFile(std::string(), "root"));
+ CreateFileMetadata(folder, "file_in_folder"));
+ DriveFileMetadata orphaned(CreateUnknownFileMetadata(sync_root));
+ orphaned.set_parent_folder_id(std::string());
{
- scoped_ptr<leveldb::DB> db = OpenLevelDB();
+ scoped_ptr<leveldb::DB> db = InitializeLevelDB();
ASSERT_TRUE(db);
- db->Put(leveldb::WriteOptions(), "VERSION", base::Int64ToString(3));
- SetUpServiceMetadata(db.get());
EXPECT_TRUE(PutFileToDB(db.get(), sync_root).ok());
EXPECT_TRUE(PutFileToDB(db.get(), app_root).ok());
@@ -331,7 +476,7 @@
EXPECT_TRUE(PutFileToDB(db.get(), orphaned).ok());
}
- EXPECT_EQ(SYNC_STATUS_OK, InitializeDatabase());
+ EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
VerifyFile(sync_root);
VerifyFile(app_root);
@@ -342,25 +487,21 @@
}
TEST_F(MetadataDatabaseTest, AppManagementTest) {
- DriveFileMetadata sync_root(CreateSyncRoot());
- DriveFileMetadata app_root(
- CreateFolder("app_id", kSyncRootFolderID, "app_id"));
- DriveFileMetadata folder(
- CreateFolder(std::string(), kSyncRootFolderID, "folder"));
+ DriveFileMetadata sync_root(CreateSyncRootMetadata());
+ DriveFileMetadata app_root(CreateAppRootMetadata(sync_root, "app_id"));
+ DriveFileMetadata folder(CreateFolderMetadata(sync_root, "folder"));
folder.set_active(false);
{
- scoped_ptr<leveldb::DB> db = OpenLevelDB();
+ scoped_ptr<leveldb::DB> db = InitializeLevelDB();
ASSERT_TRUE(db);
- db->Put(leveldb::WriteOptions(), "VERSION", base::Int64ToString(3));
- SetUpServiceMetadata(db.get());
EXPECT_TRUE(PutFileToDB(db.get(), sync_root).ok());
EXPECT_TRUE(PutFileToDB(db.get(), app_root).ok());
EXPECT_TRUE(PutFileToDB(db.get(), folder).ok());
}
- EXPECT_EQ(SYNC_STATUS_OK, InitializeDatabase());
+ EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
VerifyFile(sync_root);
VerifyFile(app_root);
VerifyFile(folder);
@@ -393,5 +534,95 @@
VerifyReloadConsistency();
}
+TEST_F(MetadataDatabaseTest, BuildPathTest) {
+ DriveFileMetadata sync_root(CreateSyncRootMetadata());
+ DriveFileMetadata app_root(
+ CreateAppRootMetadata(sync_root, "app_id"));
+ DriveFileMetadata folder(CreateFolderMetadata(app_root, "folder"));
+ DriveFileMetadata file(CreateFolderMetadata(folder, "file"));
+ DriveFileMetadata inactive_folder(CreateFolderMetadata(app_root, "folder"));
+
+ {
+ scoped_ptr<leveldb::DB> db = InitializeLevelDB();
+ ASSERT_TRUE(db);
+
+ EXPECT_TRUE(PutFileToDB(db.get(), sync_root).ok());
+ EXPECT_TRUE(PutFileToDB(db.get(), app_root).ok());
+ EXPECT_TRUE(PutFileToDB(db.get(), folder).ok());
+ EXPECT_TRUE(PutFileToDB(db.get(), file).ok());
+ }
+
+ EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
+
+ base::FilePath path;
+ EXPECT_FALSE(metadata_database()->BuildPathForFile(sync_root.file_id(),
+ &path));
+ EXPECT_TRUE(metadata_database()->BuildPathForFile(app_root.file_id(), &path));
+ EXPECT_EQ(base::FilePath(FPL("/")).NormalizePathSeparators(),
+ path);
+ EXPECT_TRUE(metadata_database()->BuildPathForFile(file.file_id(), &path));
+ EXPECT_EQ(base::FilePath(FPL("/folder/file")).NormalizePathSeparators(),
+ path);
+}
+
+TEST_F(MetadataDatabaseTest, UpdateByChangeListTest) {
+ DriveFileMetadata sync_root(CreateSyncRootMetadata());
+ DriveFileMetadata app_root(CreateAppRootMetadata(sync_root, "app_id"));
+ DriveFileMetadata disabled_app_root(
+ CreateAppRootMetadata(sync_root, "disabled_app"));
+ DriveFileMetadata file(CreateFileMetadata(app_root, "file"));
+ DriveFileMetadata renamed_file(CreateFileMetadata(app_root, "to be renamed"));
+ DriveFileMetadata folder(CreateFolderMetadata(app_root, "folder"));
+ DriveFileMetadata reorganized_file(
+ CreateFileMetadata(app_root, "to be reorganized"));
+ DriveFileMetadata updated_file(CreateFileMetadata(app_root, "to be updated"));
+ DriveFileMetadata noop_file(CreateFileMetadata(app_root, "have noop change"));
+ DriveFileMetadata new_file(CreateFileMetadata(app_root, "to be added later"));
+
+ {
+ scoped_ptr<leveldb::DB> db = InitializeLevelDB();
+ ASSERT_TRUE(db);
+
+ EXPECT_TRUE(PutFileToDB(db.get(), sync_root).ok());
+ EXPECT_TRUE(PutFileToDB(db.get(), app_root).ok());
+ EXPECT_TRUE(PutFileToDB(db.get(), disabled_app_root).ok());
+ EXPECT_TRUE(PutFileToDB(db.get(), file).ok());
+ EXPECT_TRUE(PutFileToDB(db.get(), renamed_file).ok());
+ EXPECT_TRUE(PutFileToDB(db.get(), folder).ok());
+ EXPECT_TRUE(PutFileToDB(db.get(), reorganized_file).ok());
+ EXPECT_TRUE(PutFileToDB(db.get(), updated_file).ok());
+ EXPECT_TRUE(PutFileToDB(db.get(), noop_file).ok());
+ }
+
+ EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
+
+ ApplyRenameChangeToMetadata("renamed", &renamed_file);
+ ApplyReorganizeChangeToMetadata(folder.file_id(), &reorganized_file);
+ ApplyContentChangeToMetadata(&updated_file);
+ ApplyNoopChangeToMetadata(&noop_file);
+ ApplyNewFileChangeToMetadata(&new_file);
+
+ ScopedVector<google_apis::ChangeResource> changes;
+ PushToChangeList(CreateChangeResourceFromMetadata(renamed_file), &changes);
+ PushToChangeList(CreateChangeResourceFromMetadata(
+ reorganized_file), &changes);
+ PushToChangeList(CreateChangeResourceFromMetadata(updated_file), &changes);
+ PushToChangeList(CreateChangeResourceFromMetadata(noop_file), &changes);
+ PushToChangeList(CreateChangeResourceFromMetadata(new_file), &changes);
+ EXPECT_EQ(SYNC_STATUS_OK, UpdateByChangeList(changes.Pass()));
+
+ VerifyFile(sync_root);
+ VerifyFile(app_root);
+ VerifyFile(disabled_app_root);
+ VerifyFile(file);
+ VerifyFile(renamed_file);
+ VerifyFile(folder);
+ VerifyFile(reorganized_file);
+ VerifyFile(updated_file);
+ VerifyFile(noop_file);
+ VerifyFile(new_file);
+ VerifyReloadConsistency();
+}
+
} // namespace drive_backend
} // namespace sync_file_system
diff --git a/chrome/browser/tab_contents/render_view_context_menu.cc b/chrome/browser/tab_contents/render_view_context_menu.cc
index ee6ebed..17bcca6 100644
--- a/chrome/browser/tab_contents/render_view_context_menu.cc
+++ b/chrome/browser/tab_contents/render_view_context_menu.cc
@@ -60,6 +60,7 @@
#include "chrome/browser/ui/tab_contents/core_tab_helper.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/common/content_restriction.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/net/url_util.h"
#include "chrome/common/pref_names.h"
@@ -78,7 +79,6 @@
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h"
-#include "content/public/common/content_restriction.h"
#include "content/public/common/menu_item.h"
#include "content/public/common/ssl_status.h"
#include "content/public/common/url_utils.h"
@@ -1122,15 +1122,18 @@
return observer->IsCommandIdEnabled(id);
}
+ CoreTabHelper* core_tab_helper =
+ CoreTabHelper::FromWebContents(source_web_contents_);
+ int content_restrictions = 0;
+ if (core_tab_helper)
+ content_restrictions = core_tab_helper->content_restrictions();
if (id == IDC_PRINT &&
- (source_web_contents_->GetContentRestrictions() &
- content::CONTENT_RESTRICTION_PRINT)) {
+ (content_restrictions & CONTENT_RESTRICTION_PRINT)) {
return false;
}
if (id == IDC_SAVE_PAGE &&
- (source_web_contents_->GetContentRestrictions() &
- content::CONTENT_RESTRICTION_SAVE)) {
+ (content_restrictions & CONTENT_RESTRICTION_SAVE)) {
return false;
}
diff --git a/chrome/browser/tab_contents/tab_util.cc b/chrome/browser/tab_contents/tab_util.cc
index 9d82f22..fae1201 100644
--- a/chrome/browser/tab_contents/tab_util.cc
+++ b/chrome/browser/tab_contents/tab_util.cc
@@ -38,7 +38,7 @@
if (ChromeWebUIControllerFactory::GetInstance()->UseWebUIForURL(
profile, url) ||
(service &&
- service->extensions()->GetHostedAppByURL(ExtensionURLInfo(url)))) {
+ service->extensions()->GetHostedAppByURL(url))) {
return SiteInstance::CreateForURL(profile, url);
}
diff --git a/chrome/browser/task_manager/tab_contents_resource_provider.cc b/chrome/browser/task_manager/tab_contents_resource_provider.cc
index f4c1370..bce027d 100644
--- a/chrome/browser/task_manager/tab_contents_resource_provider.cc
+++ b/chrome/browser/task_manager/tab_contents_resource_provider.cc
@@ -13,6 +13,8 @@
#include "chrome/browser/printing/background_printing_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/search/instant_service.h"
+#include "chrome/browser/search/instant_service_factory.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/browser/task_manager/renderer_resource.h"
@@ -21,7 +23,6 @@
#include "chrome/browser/task_manager/task_manager_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/browser_instant_controller.h"
#include "chrome/browser/ui/browser_iterator.h"
#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
#include "content/public/browser/notification_service.h"
@@ -207,14 +208,6 @@
for (TabContentsIterator iterator; !iterator.done(); iterator.Next())
Add(*iterator);
- // Add all the Instant pages.
- for (chrome::BrowserIterator it; !it.done(); it.Next()) {
- if (it->instant_controller()) {
- if (it->instant_controller()->instant()->GetNTPContents())
- Add(it->instant_controller()->instant()->GetNTPContents());
- }
- }
-
// Add all the prerender pages.
std::vector<Profile*> profiles(
g_browser_process->profile_manager()->GetLoadedProfiles());
@@ -229,6 +222,14 @@
}
}
+ // Add all the Instant Extended prerendered NTPs.
+ for (size_t i = 0; i < profiles.size(); ++i) {
+ const InstantService* instant_service =
+ InstantServiceFactory::GetForProfile(profiles[i]);
+ if (instant_service && instant_service->GetNTPContents())
+ Add(instant_service->GetNTPContents());
+ }
+
// Add all the pages being background printed.
printing::BackgroundPrintingManager* printing_manager =
g_browser_process->background_printing_manager();
diff --git a/chrome/browser/task_manager/task_manager.cc b/chrome/browser/task_manager/task_manager.cc
index be9a3b9..8c5bae6 100644
--- a/chrome/browser/task_manager/task_manager.cc
+++ b/chrome/browser/task_manager/task_manager.cc
@@ -41,7 +41,7 @@
#include "content/public/common/result_codes.h"
#include "grit/generated_resources.h"
#include "grit/ui_resources.h"
-#include "third_party/icu/public/i18n/unicode/coll.h"
+#include "third_party/icu/source/i18n/unicode/coll.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/text/bytes_formatting.h"
diff --git a/chrome/browser/translate/options_menu_model.cc b/chrome/browser/translate/options_menu_model.cc
index 0abea91..a6cd71b 100644
--- a/chrome/browser/translate/options_menu_model.cc
+++ b/chrome/browser/translate/options_menu_model.cc
@@ -6,7 +6,6 @@
#include "base/metrics/histogram.h"
#include "chrome/app/chrome_command_ids.h"
-#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/translate/translate_infobar_delegate.h"
#include "chrome/common/url_constants.h"
diff --git a/chrome/browser/translate/translate_infobar_delegate.cc b/chrome/browser/translate/translate_infobar_delegate.cc
index 20a5b0a..726be78 100644
--- a/chrome/browser/translate/translate_infobar_delegate.cc
+++ b/chrome/browser/translate/translate_infobar_delegate.cc
@@ -20,7 +20,7 @@
#include "content/public/browser/web_contents.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
-#include "third_party/icu/public/i18n/unicode/coll.h"
+#include "third_party/icu/source/i18n/unicode/coll.h"
#include "ui/base/l10n/l10n_util.h"
using content::NavigationEntry;
@@ -43,10 +43,14 @@
// static
void TranslateInfoBarDelegate::Create(
- InfoBarService* infobar_service, bool replace_existing_infobar,
- Type infobar_type, TranslateErrors::Type error_type, PrefService* prefs,
- const ShortcutConfiguration& shortcut_config,
- const std::string& original_language, const std::string& target_language) {
+ bool replace_existing_infobar,
+ InfoBarService* infobar_service,
+ Type infobar_type,
+ const std::string& original_language,
+ const std::string& target_language,
+ TranslateErrors::Type error_type,
+ PrefService* prefs,
+ const ShortcutConfiguration& shortcut_config) {
// Check preconditions.
if (infobar_type != TRANSLATION_ERROR) {
DCHECK(TranslateManager::IsSupportedLanguage(target_language));
@@ -63,20 +67,22 @@
TranslateInfoBarDelegate* old_delegate = NULL;
for (size_t i = 0; i < infobar_service->infobar_count(); ++i) {
old_delegate = infobar_service->infobar_at(i)->AsTranslateInfoBarDelegate();
- if (old_delegate)
+ if (old_delegate) {
+ if (!replace_existing_infobar)
+ return;
break;
+ }
}
// Create the new delegate.
scoped_ptr<TranslateInfoBarDelegate> infobar(
- new TranslateInfoBarDelegate(infobar_type, error_type, infobar_service,
- prefs, shortcut_config,
- original_language, target_language));
- infobar->UpdateBackgroundAnimation(old_delegate);
+ new TranslateInfoBarDelegate(infobar_service, infobar_type, old_delegate,
+ original_language, target_language,
+ error_type, prefs, shortcut_config));
// Do not create the after translate infobar if we are auto translating.
- if (infobar_type == TranslateInfoBarDelegate::AFTER_TRANSLATE ||
- infobar_type == TranslateInfoBarDelegate::TRANSLATING) {
+ if ((infobar_type == TranslateInfoBarDelegate::AFTER_TRANSLATE) ||
+ (infobar_type == TranslateInfoBarDelegate::TRANSLATING)) {
TranslateTabHelper* translate_tab_helper =
TranslateTabHelper::FromWebContents(infobar_service->web_contents());
if (!translate_tab_helper ||
@@ -87,7 +93,8 @@
// Add the new delegate if necessary.
if (!old_delegate) {
infobar_service->AddInfoBar(infobar.PassAs<InfoBarDelegate>());
- } else if (replace_existing_infobar) {
+ } else {
+ DCHECK(replace_existing_infobar);
infobar_service->ReplaceInfoBar(old_delegate,
infobar.PassAs<InfoBarDelegate>());
}
@@ -276,14 +283,6 @@
shortcut_config_.always_translate_min_count);
}
-void TranslateInfoBarDelegate::UpdateBackgroundAnimation(
- TranslateInfoBarDelegate* previous_infobar) {
- if (!previous_infobar || previous_infobar->IsError() == IsError())
- background_animation_ = NONE;
- else
- background_animation_ = IsError() ? NORMAL_TO_ERROR : ERROR_TO_NORMAL;
-}
-
// static
string16 TranslateInfoBarDelegate::GetLanguageDisplayableName(
const std::string& language_code) {
@@ -326,13 +325,14 @@
}
TranslateInfoBarDelegate::TranslateInfoBarDelegate(
- Type infobar_type,
- TranslateErrors::Type error_type,
InfoBarService* infobar_service,
- PrefService* prefs,
- ShortcutConfiguration shortcut_config,
+ Type infobar_type,
+ TranslateInfoBarDelegate* old_delegate,
const std::string& original_language,
- const std::string& target_language)
+ const std::string& target_language,
+ TranslateErrors::Type error_type,
+ PrefService* prefs,
+ ShortcutConfiguration shortcut_config)
: InfoBarDelegate(infobar_service),
infobar_type_(infobar_type),
background_animation_(NONE),
@@ -345,6 +345,9 @@
DCHECK_NE((infobar_type_ == TRANSLATION_ERROR),
(error_type_ == TranslateErrors::NONE));
+ if (old_delegate && (old_delegate->is_error() != is_error()))
+ background_animation_ = is_error() ? NORMAL_TO_ERROR : ERROR_TO_NORMAL;
+
std::vector<std::string> language_codes;
TranslateManager::GetSupportedLanguages(&language_codes);
@@ -384,16 +387,6 @@
DCHECK_NE(kNoIndex, target_language_index_);
}
-bool TranslateInfoBarDelegate::ShouldExpire(
- const content::LoadCommittedDetails& details) const {
- // Note: we allow closing this infobar even if the main frame navigation
- // was programmatic and not initiated by the user - crbug.com/70261 .
- if (!details.is_navigation_to_different_page() && !details.is_main_frame)
- return false;
-
- return InfoBarDelegate::ShouldExpireInternal(details);
-}
-
void TranslateInfoBarDelegate::InfoBarDismissed() {
if (infobar_type_ != BEFORE_TRANSLATE)
return;
@@ -411,6 +404,16 @@
return PAGE_ACTION_TYPE;
}
+bool TranslateInfoBarDelegate::ShouldExpire(
+ const content::LoadCommittedDetails& details) const {
+ // Note: we allow closing this infobar even if the main frame navigation
+ // was programmatic and not initiated by the user - crbug.com/70261 .
+ if (!details.is_navigation_to_different_page() && !details.is_main_frame)
+ return false;
+
+ return InfoBarDelegate::ShouldExpireInternal(details);
+}
+
TranslateInfoBarDelegate*
TranslateInfoBarDelegate::AsTranslateInfoBarDelegate() {
return this;
diff --git a/chrome/browser/translate/translate_infobar_delegate.h b/chrome/browser/translate/translate_infobar_delegate.h
index b934d32..5b21995 100644
--- a/chrome/browser/translate/translate_infobar_delegate.h
+++ b/chrome/browser/translate/translate_infobar_delegate.h
@@ -59,14 +59,14 @@
// |infobar_service|, replacing any other translate infobar already present
// there. Otherwise, the infobar will only be added if there is no other
// translate infobar already present.
- static void Create(InfoBarService* infobar_service,
- bool replace_existing_infobar,
+ static void Create(bool replace_existing_infobar,
+ InfoBarService* infobar_service,
Type infobar_type,
+ const std::string& original_language,
+ const std::string& target_language,
TranslateErrors::Type error_type,
PrefService* prefs,
- const ShortcutConfiguration& shortcut_config,
- const std::string& original_language,
- const std::string& target_language);
+ const ShortcutConfiguration& shortcut_config);
// Returns the number of languages supported.
size_t num_languages() const { return languages_.size(); }
@@ -112,7 +112,7 @@
// Returns true if the current infobar indicates an error (in which case it
// should get a yellow background instead of a blue one).
- bool IsError() const { return infobar_type_ == TRANSLATION_ERROR; }
+ bool is_error() const { return infobar_type_ == TRANSLATION_ERROR; }
// Returns what kind of background fading effect the infobar should use when
// its is shown.
@@ -157,11 +157,6 @@
bool ShouldShowNeverTranslateShortcut();
bool ShouldShowAlwaysTranslateShortcut();
- // Sets this infobar background animation based on the previous infobar shown.
- // A fading background effect is used when transitioning from a normal state
- // to an error state (and vice-versa).
- void UpdateBackgroundAnimation(TranslateInfoBarDelegate* previous_infobar);
-
// Convenience method that returns the displayable language name for
// |language_code| in the current application locale.
static string16 GetLanguageDisplayableName(const std::string& language_code);
@@ -183,13 +178,14 @@
bool autodetermined_source_language);
protected:
- TranslateInfoBarDelegate(Type infobar_type,
- TranslateErrors::Type error_type,
- InfoBarService* infobar_service,
- PrefService* prefs,
- ShortcutConfiguration shortcut_config,
+ TranslateInfoBarDelegate(InfoBarService* infobar_service,
+ Type infobar_type,
+ TranslateInfoBarDelegate* old_delegate,
const std::string& original_language,
- const std::string& target_language);
+ const std::string& target_language,
+ TranslateErrors::Type error_type,
+ PrefService* prefs,
+ ShortcutConfiguration shortcut_config);
private:
typedef std::pair<std::string, string16> LanguageNamePair;
diff --git a/chrome/browser/translate/translate_manager.cc b/chrome/browser/translate/translate_manager.cc
index 99fcf12..057084e 100644
--- a/chrome/browser/translate/translate_manager.cc
+++ b/chrome/browser/translate/translate_manager.cc
@@ -427,10 +427,9 @@
TranslateBrowserMetrics::ReportInitiationStatus(
TranslateBrowserMetrics::INITIATION_STATUS_SHOW_INFOBAR);
TranslateInfoBarDelegate::Create(
- InfoBarService::FromWebContents(web_contents), false,
- TranslateInfoBarDelegate::BEFORE_TRANSLATE, TranslateErrors::NONE,
- profile->GetPrefs(), ShortcutConfig(),
- language_code, target_lang);
+ false, InfoBarService::FromWebContents(web_contents),
+ TranslateInfoBarDelegate::BEFORE_TRANSLATE, language_code, target_lang,
+ TranslateErrors::NONE, profile->GetPrefs(), ShortcutConfig());
}
void TranslateManager::InitiateTranslationPosted(int process_id,
@@ -474,22 +473,20 @@
return;
}
- Profile* profile =
- Profile::FromBrowserContext(web_contents->GetBrowserContext());
-
- std::string source_lang(original_source_lang);
-
// Translation can be kicked by context menu against unsupported languages.
// Unsupported language strings should be replaced with
// kUnknownLanguageCode in order to send a translation request with enabling
// server side auto language detection.
+ std::string source_lang(original_source_lang);
if (!IsSupportedLanguage(source_lang))
source_lang = std::string(chrome::kUnknownLanguageCode);
+ Profile* profile =
+ Profile::FromBrowserContext(web_contents->GetBrowserContext());
TranslateInfoBarDelegate::Create(
- InfoBarService::FromWebContents(web_contents), true,
- TranslateInfoBarDelegate::TRANSLATING, TranslateErrors::NONE,
- profile->GetPrefs(), ShortcutConfig(), source_lang, target_lang);
+ true, InfoBarService::FromWebContents(web_contents),
+ TranslateInfoBarDelegate::TRANSLATING, source_lang, target_lang,
+ TranslateErrors::NONE, profile->GetPrefs(), ShortcutConfig());
DCHECK(script_.get() != NULL);
@@ -604,18 +601,18 @@
PrefService* prefs = Profile::FromBrowserContext(
web_contents->GetBrowserContext())->GetPrefs();
TranslateInfoBarDelegate::Create(
- InfoBarService::FromWebContents(web_contents), true,
+ true, InfoBarService::FromWebContents(web_contents),
(details->error_type == TranslateErrors::NONE) ?
- TranslateInfoBarDelegate::AFTER_TRANSLATE :
- TranslateInfoBarDelegate::TRANSLATION_ERROR,
- details->error_type, prefs, ShortcutConfig(), details->source_language,
- details->target_language);
+ TranslateInfoBarDelegate::AFTER_TRANSLATE :
+ TranslateInfoBarDelegate::TRANSLATION_ERROR,
+ details->source_language, details->target_language, details->error_type,
+ prefs, ShortcutConfig());
if (details->error_type != TranslateErrors::NONE &&
!web_contents->GetBrowserContext()->IsOffTheRecord()) {
TranslateErrorDetails error_details;
error_details.time = base::Time::Now();
- error_details.url = web_contents->GetActiveURL();
+ error_details.url = web_contents->GetLastCommittedURL();
error_details.error = details->error_type;
NotifyTranslateError(error_details);
}
@@ -670,14 +667,10 @@
Profile* profile =
Profile::FromBrowserContext(web_contents->GetBrowserContext());
TranslateInfoBarDelegate::Create(
- InfoBarService::FromWebContents(web_contents),
- true,
- TranslateInfoBarDelegate::TRANSLATION_ERROR,
- TranslateErrors::NETWORK,
- profile->GetPrefs(),
- ShortcutConfig(),
- request.source_lang,
- request.target_lang);
+ true, InfoBarService::FromWebContents(web_contents),
+ TranslateInfoBarDelegate::TRANSLATION_ERROR, request.source_lang,
+ request.target_lang, TranslateErrors::NETWORK, profile->GetPrefs(),
+ ShortcutConfig());
if (!web_contents->GetBrowserContext()->IsOffTheRecord()) {
TranslateErrorDetails error_details;
@@ -720,8 +713,8 @@
ShortcutConfiguration TranslateManager::ShortcutConfig() {
ShortcutConfiguration config;
- // The android implementation does not offer a drop down for space
- // reason so we are more aggressive showing the shortcuts for never translate.
+ // The android implementation does not offer a drop down (for space reasons),
+ // so we are more aggressive about showing the shortcut to never translate.
#if defined(OS_ANDROID)
config.never_translate_min_count = 1;
#else
diff --git a/chrome/browser/translate/translate_manager_browsertest.cc b/chrome/browser/translate/translate_manager_browsertest.cc
index ee3d7ff..7faeda1 100644
--- a/chrome/browser/translate/translate_manager_browsertest.cc
+++ b/chrome/browser/translate/translate_manager_browsertest.cc
@@ -51,7 +51,6 @@
#include "net/url_request/url_fetcher_delegate.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/WebKit/public/web/WebContextMenuData.h"
-#include "third_party/cld/languages/public/languages.h"
using content::NavigationController;
using content::RenderViewHostTester;
@@ -509,7 +508,7 @@
ASSERT_TRUE(infobar != NULL);
EXPECT_EQ(TranslateInfoBarDelegate::TRANSLATION_ERROR,
infobar->infobar_type());
- EXPECT_TRUE(infobar->IsError());
+ EXPECT_TRUE(infobar->is_error());
infobar->MessageInfoBarButtonPressed();
SimulateTranslateScriptURLFetch(true); // This time succeed.
@@ -560,69 +559,36 @@
EXPECT_EQ(TranslateErrors::UNKNOWN_LANGUAGE, infobar->error_type());
}
-// Tests that we show/don't show an info-bar for all languages the CLD can
-// report.
-TEST_F(TranslateManagerBrowserTest, TestAllLanguages) {
- // The index in kExpectation are the Language enum (see languages.pb.h).
- // true if we expect a translate infobar for that language.
- // Note the supported languages are in translation_manager.cc, see
- // kSupportedLanguages.
- bool kExpectations[] = {
- // 0-9
- false, true, true, true, true, true, false, true, true, true,
- // 10-19
- false, true, true, true, true, true, true, true, true, true,
- // 20-29
- true, true, true, true, true, false, false, true, true, true,
- // 30-39
- true, true, false, true, true, true, true, false, true, false,
- // 40-49
- true, false, true, false, false, true, false, true, false, false,
- // 50-59
- false, false, false, true, true, true, true, false, false, false,
- // 60-69
- false, false, true, true, false, true, true, false, true, true,
- // 70-79
- false, false, false, false, false, false, false, true, false, false,
- // 80-89
- false, true, true, false, false, false, false, false, false, false,
- // 90-99
- false, true, false, false, false, false, false, false, false, false,
- // 100-109
- false, true, false, false, false, false, false, false, false, false,
- // 110-119
- false, false, false, false, false, false, false, false, false, false,
- // 120-129
- false, false, false, false, false, false, false, false, false, false,
- // 130-139
- false, false, false, false, false, false, false, false, false, true,
- // 140-149
- false, false, false, false, false, false, false, false, false, false,
- // 150-159
- false, false, false, false, false, false, false, false, false, false,
- // 160
- true
- };
+// Tests that we show/don't show an info-bar for the languages.
+TEST_F(TranslateManagerBrowserTest, TestLanguages) {
+ std::vector<std::string> languages;
+ languages.push_back("en");
+ languages.push_back("ja");
+ languages.push_back("fr");
+ languages.push_back("ht");
+ languages.push_back("xx");
+ languages.push_back("zh");
+ languages.push_back("zh-CN");
+ languages.push_back("und");
GURL url("http://www.google.com");
- for (size_t i = 0; i < arraysize(kExpectations); ++i) {
- ASSERT_LT(i, static_cast<size_t>(NUM_LANGUAGES));
-
- std::string lang = LanguageCodeWithDialects(static_cast<Language>(i));
+ for (size_t i = 0; i < languages.size(); ++i) {
+ std::string lang = languages[i];
SCOPED_TRACE(::testing::Message() << "Iteration " << i <<
- " language=" << lang);
+ " language=" << lang);
// We should not have a translate infobar.
TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
ASSERT_TRUE(infobar == NULL);
// Simulate navigating to a page.
- NavigateAndCommit(url);
- SimulateOnTranslateLanguageDetermined(lang, true);
+ SimulateNavigation(url, lang, true);
// Verify we have/don't have an info-bar as expected.
infobar = GetTranslateInfoBar();
- EXPECT_EQ(kExpectations[i], infobar != NULL);
+ bool expected = TranslateManager::IsSupportedLanguage(lang) &&
+ lang != "en";
+ EXPECT_EQ(expected, infobar != NULL);
// Close the info-bar if applicable.
if (infobar != NULL)
diff --git a/chrome/browser/ui/android/tab_model/tab_model.cc b/chrome/browser/ui/android/tab_model/tab_model.cc
index 4840fde..d21b827 100644
--- a/chrome/browser/ui/android/tab_model/tab_model.cc
+++ b/chrome/browser/ui/android/tab_model/tab_model.cc
@@ -92,7 +92,7 @@
}
ToolbarModel::SecurityLevel TabModel::GetSecurityLevelForCurrentTab() {
- return toolbar_model_->GetSecurityLevel();
+ return toolbar_model_->GetSecurityLevel(false);
}
string16 TabModel::GetSearchTermsForCurrentTab() {
diff --git a/chrome/browser/ui/app_list/app_list_controller_browsertest.cc b/chrome/browser/ui/app_list/app_list_controller_browsertest.cc
index 79c5594..6a7464e 100644
--- a/chrome/browser/ui/app_list/app_list_controller_browsertest.cc
+++ b/chrome/browser/ui/app_list/app_list_controller_browsertest.cc
@@ -42,7 +42,7 @@
IN_PROC_BROWSER_TEST_F(AppListControllerBrowserTest, ShowAndDismiss) {
AppListService* service = AppListService::Get();
ASSERT_FALSE(service->IsAppListVisible());
- service->ShowAppList(browser()->profile());
+ service->ShowForProfile(browser()->profile());
ASSERT_TRUE(service->IsAppListVisible());
service->DismissAppList();
ASSERT_FALSE(service->IsAppListVisible());
@@ -60,10 +60,10 @@
AppListService* service = AppListService::Get();
ASSERT_FALSE(service->IsAppListVisible());
- service->ShowAppList(browser()->profile());
+ service->ShowForProfile(browser()->profile());
ASSERT_TRUE(service->IsAppListVisible());
ASSERT_EQ(browser()->profile(), service->GetCurrentAppListProfile());
- service->ShowAppList(profile2_);
+ service->ShowForProfile(profile2_);
ASSERT_TRUE(service->IsAppListVisible());
ASSERT_EQ(profile2_, service->GetCurrentAppListProfile());
service->DismissAppList();
diff --git a/chrome/browser/ui/app_list/app_list_service.h b/chrome/browser/ui/app_list/app_list_service.h
index ebb8f68..edac211 100644
--- a/chrome/browser/ui/app_list/app_list_service.h
+++ b/chrome/browser/ui/app_list/app_list_service.h
@@ -34,23 +34,27 @@
static void RegisterPrefs(PrefRegistrySimple* registry);
- virtual base::FilePath GetProfilePath(
- const base::FilePath& user_data_dir) = 0;
-
static void RecordShowTimings(const CommandLine& command_line);
- // Show the app list.
- virtual void ShowAppList(Profile* requested_profile) = 0;
+ // Perform Chrome first run logic. This is executed before Chrome's threads
+ // have been created.
+ virtual void HandleFirstRun() = 0;
- // Dismiss the app list.
- virtual void DismissAppList() = 0;
-
- // TODO(koz): Merge this into ShowAppList().
- virtual void SetAppListProfile(const base::FilePath& profile_file_path) = 0;
+ virtual base::FilePath GetProfilePath(
+ const base::FilePath& user_data_dir) = 0;
+ virtual void SetProfilePath(const base::FilePath& profile_path) = 0;
// Show the app list for the profile configured in the user data dir for the
// current browser process.
- virtual void ShowForSavedProfile() = 0;
+ virtual void Show() = 0;
+
+ // Show the app list for the given profile. If it differs from the profile the
+ // app list is currently showing, repopulate the app list and save the new
+ // profile to local prefs as the default app list profile.
+ virtual void ShowForProfile(Profile* requested_profile) = 0;
+
+ // Dismiss the app list.
+ virtual void DismissAppList() = 0;
// Get the profile the app list is currently showing.
virtual Profile* GetCurrentAppListProfile() = 0;
diff --git a/chrome/browser/ui/app_list/app_list_service_disabled.cc b/chrome/browser/ui/app_list/app_list_service_disabled.cc
index 5b46a16..6c1ec63 100644
--- a/chrome/browser/ui/app_list/app_list_service_disabled.cc
+++ b/chrome/browser/ui/app_list/app_list_service_disabled.cc
@@ -21,20 +21,19 @@
AppListServiceDisabled() {}
// AppListService overrides:
+ virtual void HandleFirstRun() OVERRIDE {}
virtual void Init(Profile* initial_profile) OVERRIDE {}
virtual base::FilePath GetProfilePath(
const base::FilePath& user_data_dir) OVERRIDE {
return base::FilePath();
}
+ virtual void SetProfilePath(const base::FilePath& profile_path) OVERRIDE {}
- virtual void ShowForSavedProfile() OVERRIDE {}
- virtual void ShowAppList(Profile* profile) OVERRIDE {}
+ virtual void Show() OVERRIDE {}
+ virtual void ShowForProfile(Profile* profile) OVERRIDE {}
virtual void DismissAppList() OVERRIDE {}
- virtual void SetAppListProfile(
- const base::FilePath& profile_file_path) OVERRIDE {}
-
virtual Profile* GetCurrentAppListProfile() OVERRIDE { return NULL; }
virtual bool IsAppListVisible() const OVERRIDE { return false; }
virtual void EnableAppList(Profile* initial_profile) OVERRIDE {}
diff --git a/chrome/browser/ui/app_list/app_list_service_impl.cc b/chrome/browser/ui/app_list/app_list_service_impl.cc
index 0dcee73..8054e87 100644
--- a/chrome/browser/ui/app_list/app_list_service_impl.cc
+++ b/chrome/browser/ui/app_list/app_list_service_impl.cc
@@ -4,6 +4,8 @@
#include "chrome/browser/ui/app_list/app_list_service_impl.h"
+#include "apps/pref_names.h"
+#include "base/command_line.h"
#include "base/metrics/histogram.h"
#include "base/prefs/pref_service.h"
#include "base/time/time.h"
@@ -11,6 +13,7 @@
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_details.h"
@@ -66,6 +69,11 @@
}
}
+void SetAppListEnabledPreference(bool enabled) {
+ PrefService* local_state = g_browser_process->local_state();
+ local_state->SetBoolean(apps::prefs::kAppLauncherHasBeenEnabled, enabled);
+}
+
} // namespace
// static
@@ -107,6 +115,8 @@
AppListServiceImpl::~AppListServiceImpl() {}
+void AppListServiceImpl::HandleFirstRun() {}
+
void AppListServiceImpl::Init(Profile* initial_profile) {}
base::FilePath AppListServiceImpl::GetProfilePath(
@@ -121,20 +131,28 @@
// If the user has no profile preference for the app launcher, default to the
// last browser profile used.
if (app_list_profile.empty() &&
- local_state->HasPrefPath(prefs::kProfileLastUsed))
+ local_state->HasPrefPath(prefs::kProfileLastUsed)) {
app_list_profile = local_state->GetString(prefs::kProfileLastUsed);
+ }
- std::string profile_path = app_list_profile.empty() ?
- chrome::kInitialProfile :
- app_list_profile;
+ // If there is no last used profile recorded, use the initial profile.
+ if (app_list_profile.empty())
+ app_list_profile = chrome::kInitialProfile;
- return user_data_dir.AppendASCII(profile_path);
+ return user_data_dir.AppendASCII(app_list_profile);
+}
+
+void AppListServiceImpl::SetProfilePath(const base::FilePath& profile_path) {
+ g_browser_process->local_state()->SetString(
+ prefs::kAppListProfile,
+ profile_path.BaseName().MaybeAsASCII());
}
AppListControllerDelegate* AppListServiceImpl::CreateControllerDelegate() {
return NULL;
}
+void AppListServiceImpl::CreateShortcut() {}
void AppListServiceImpl::OnSigninStatusChanged() {}
// We need to watch for profile removal to keep kAppListProfile updated.
@@ -158,16 +176,17 @@
OnSigninStatusChanged();
}
-void AppListServiceImpl::SetAppListProfile(
- const base::FilePath& profile_file_path) {
+void AppListServiceImpl::Show() {
profile_loader_.LoadProfileInvalidatingOtherLoads(
- profile_file_path, base::Bind(&AppListServiceImpl::ShowAppList,
- weak_factory_.GetWeakPtr()));
+ GetProfilePath(g_browser_process->profile_manager()->user_data_dir()),
+ base::Bind(&AppListServiceImpl::ShowForProfile,
+ weak_factory_.GetWeakPtr()));
}
-void AppListServiceImpl::ShowForSavedProfile() {
- SetAppListProfile(GetProfilePath(
- g_browser_process->profile_manager()->user_data_dir()));
+void AppListServiceImpl::EnableAppList(Profile* initial_profile) {
+ SetAppListEnabledPreference(true);
+ SetProfilePath(initial_profile->GetPath());
+ CreateShortcut();
}
Profile* AppListServiceImpl::GetCurrentAppListProfile() {
@@ -192,9 +211,10 @@
profile_loader_.InvalidatePendingProfileLoads();
}
-void AppListServiceImpl::SaveProfilePathToLocalState(
- const base::FilePath& profile_file_path) {
- g_browser_process->local_state()->SetString(
- prefs::kAppListProfile,
- profile_file_path.BaseName().MaybeAsASCII());
+void AppListServiceImpl::HandleCommandLineFlags(Profile* initial_profile) {
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableAppList))
+ EnableAppList(initial_profile);
+
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableAppList))
+ SetAppListEnabledPreference(false);
}
diff --git a/chrome/browser/ui/app_list/app_list_service_impl.h b/chrome/browser/ui/app_list/app_list_service_impl.h
index 01cace7..5f7d70f 100644
--- a/chrome/browser/ui/app_list/app_list_service_impl.h
+++ b/chrome/browser/ui/app_list/app_list_service_impl.h
@@ -46,18 +46,26 @@
ProfileLoader& profile_loader() { return profile_loader_; }
const ProfileLoader& profile_loader() const { return profile_loader_; }
- // Save |profile_file_path| as the app list profile in local state.
- void SaveProfilePathToLocalState(const base::FilePath& profile_file_path);
+ // Process command line flags shared between desktop implementations of the
+ // app list. Currently this allows for enabling or disabling the app list.
+ void HandleCommandLineFlags(Profile* initial_profile);
+
+ // Create a platform-specific shortcut for the app list.
+ virtual void CreateShortcut();
// Called in response to observed successful and unsuccessful signin changes.
virtual void OnSigninStatusChanged();
// AppListService overrides:
+ virtual void HandleFirstRun() OVERRIDE;
virtual void Init(Profile* initial_profile) OVERRIDE;
+
+ // Returns the app list path configured in BrowserProcess::local_state().
virtual base::FilePath GetProfilePath(
const base::FilePath& user_data_dir) OVERRIDE;
-
- virtual void ShowForSavedProfile() OVERRIDE;
+ virtual void SetProfilePath(const base::FilePath& profile_path) OVERRIDE;
+ virtual void Show() OVERRIDE;
+ virtual void EnableAppList(Profile* initial_profile) OVERRIDE;
virtual AppListControllerDelegate* CreateControllerDelegate() OVERRIDE;
private:
@@ -69,12 +77,6 @@
Profile* profile,
Profile::CreateStatus status);
- // AppListService overrides:
- // Update the profile path stored in local prefs, load it (if not already
- // loaded), and show the app list.
- virtual void SetAppListProfile(
- const base::FilePath& profile_file_path) OVERRIDE;
-
virtual Profile* GetCurrentAppListProfile() OVERRIDE;
// ProfileInfoCacheObserver overrides:
diff --git a/chrome/browser/ui/app_list/app_list_service_mac.mm b/chrome/browser/ui/app_list/app_list_service_mac.mm
index 7012d2d..bf64460 100644
--- a/chrome/browser/ui/app_list/app_list_service_mac.mm
+++ b/chrome/browser/ui/app_list/app_list_service_mac.mm
@@ -5,6 +5,7 @@
#include <ApplicationServices/ApplicationServices.h>
#import <Cocoa/Cocoa.h>
+#include "apps/app_launcher.h"
#include "apps/app_shim/app_shim_handler_mac.h"
#include "base/bind.h"
#include "base/command_line.h"
@@ -14,8 +15,10 @@
#include "base/memory/singleton.h"
#include "base/message_loop/message_loop.h"
#include "base/observer_list.h"
+#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
+#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
#include "chrome/browser/ui/app_list/app_list_service.h"
#include "chrome/browser/ui/app_list/app_list_service_impl.h"
@@ -60,13 +63,13 @@
// AppListService overrides:
virtual void Init(Profile* initial_profile) OVERRIDE;
- virtual void ShowAppList(Profile* requested_profile) OVERRIDE;
+ virtual void ShowForProfile(Profile* requested_profile) OVERRIDE;
virtual void DismissAppList() OVERRIDE;
virtual bool IsAppListVisible() const OVERRIDE;
- virtual void EnableAppList(Profile* initial_profile) OVERRIDE;
virtual gfx::NativeWindow GetAppListWindow() OVERRIDE;
- // AppListServiceImpl override:
+ // AppListServiceImpl overrides:
+ virtual void CreateShortcut() OVERRIDE;
virtual void OnSigninStatusChanged() OVERRIDE;
// AppShimHandler overrides:
@@ -85,6 +88,7 @@
AppListServiceMac() {}
base::scoped_nsobject<AppListWindowController> window_controller_;
+ base::scoped_nsobject<NSRunningApplication> previously_active_application_;
// App shim hosts observing when the app list is dismissed. In normal user
// usage there should only be one. However, it can't be guaranteed, so use
@@ -174,7 +178,7 @@
}
// Check that there is an app list shim. If enabling and there is not, make one.
-// If disabling with --enable-app-list-shim=0, and there is one, delete it.
+// If the flag is not present, and there is a shim, delete it.
void CheckAppListShimOnFileThread(const base::FilePath& profile_path) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
const bool enable =
@@ -203,6 +207,21 @@
web_app::ALLOW_DUPLICATE_SHORTCUTS);
}
+NSRunningApplication* ActiveApplicationNotChrome() {
+ NSArray* applications = [[NSWorkspace sharedWorkspace] runningApplications];
+ for (NSRunningApplication* application in applications) {
+ if (![application isActive])
+ continue;
+
+ if ([application isEqual:[NSRunningApplication currentApplication]])
+ return nil; // Chrome is active.
+
+ return application;
+ }
+
+ return nil;
+}
+
AppListControllerDelegateCocoa::AppListControllerDelegateCocoa() {}
AppListControllerDelegateCocoa::~AppListControllerDelegateCocoa() {}
@@ -270,10 +289,12 @@
// browser window open and a new window is opened, and during process startup
// to handle the silent launch case (e.g. for app shims). In the startup case,
// a profile has not yet been determined so |initial_profile| will be NULL.
- if (initial_profile) {
- static bool checked_shim = false;
- if (!checked_shim) {
- checked_shim = true;
+ static bool init_called_with_profile = false;
+ if (initial_profile && !init_called_with_profile) {
+ init_called_with_profile = true;
+ HandleCommandLineFlags(initial_profile);
+ if (!apps::IsAppLauncherEnabled()) {
+ // Not yet enabled via the Web Store. Check for the chrome://flag.
content::BrowserThread::PostTask(
content::BrowserThread::FILE, FROM_HERE,
base::Bind(&CheckAppListShimOnFileThread,
@@ -290,7 +311,7 @@
AppListServiceMac::GetInstance());
}
-void AppListServiceMac::ShowAppList(Profile* requested_profile) {
+void AppListServiceMac::ShowForProfile(Profile* requested_profile) {
InvalidatePendingProfileLoads();
if (IsAppListVisible() && (requested_profile == profile())) {
@@ -298,7 +319,7 @@
return;
}
- SaveProfilePathToLocalState(requested_profile->GetPath());
+ SetProfilePath(requested_profile->GetPath());
DismissAppList();
CreateAppList(requested_profile);
@@ -309,6 +330,22 @@
if (!IsAppListVisible())
return;
+ // If the app list is currently the main window, it will activate the next
+ // Chrome window when dismissed. But if a different application was active
+ // when the app list was shown, activate that instead.
+ base::scoped_nsobject<NSRunningApplication> prior_app;
+ if ([[window_controller_ window] isMainWindow])
+ prior_app.swap(previously_active_application_);
+ else
+ previously_active_application_.reset();
+
+ // If activation is successful, the app list will lose main status and try to
+ // close itself again. It can't be closed in this runloop iteration without
+ // OSX deciding to raise the next Chrome window, and _then_ activating the
+ // application on top. This also occurs if no activation option is given.
+ if ([prior_app activateWithOptions:NSApplicationActivateIgnoringOtherApps])
+ return;
+
[[window_controller_ window] close];
FOR_EACH_OBSERVER(apps::AppShimHandler::Host,
@@ -320,8 +357,9 @@
return [[window_controller_ window] isVisible];
}
-void AppListServiceMac::EnableAppList(Profile* initial_profile) {
- // TODO(tapted): Implement enable logic here for OSX.
+void AppListServiceMac::CreateShortcut() {
+ CreateAppListShim(GetProfilePath(
+ g_browser_process->profile_manager()->user_data_dir()));
}
NSWindow* AppListServiceMac::GetAppListWindow() {
@@ -334,7 +372,7 @@
void AppListServiceMac::OnShimLaunch(apps::AppShimHandler::Host* host,
apps::AppShimLaunchType launch_type) {
- ShowForSavedProfile();
+ Show();
observers_.AddObserver(host);
host->OnAppLaunchComplete(apps::APP_SHIM_LAUNCH_SUCCESS);
}
@@ -457,6 +495,11 @@
NSWindow* window = GetAppListWindow();
DCHECK(window);
[window setFrameOrigin:GetAppListWindowOrigin(window)];
+
+ // Before activating, see if an application other than Chrome is currently the
+ // active application, so that it can be reactivated when dismissing.
+ previously_active_application_.reset([ActiveApplicationNotChrome() retain]);
+
[window makeKeyAndOrderFront:nil];
[NSApp activateIgnoringOtherApps:YES];
}
diff --git a/chrome/browser/ui/app_list/app_list_service_mac_browsertest.mm b/chrome/browser/ui/app_list/app_list_service_mac_browsertest.mm
index 8e96c70..15a5ae9 100644
--- a/chrome/browser/ui/app_list/app_list_service_mac_browsertest.mm
+++ b/chrome/browser/ui/app_list/app_list_service_mac_browsertest.mm
@@ -78,7 +78,7 @@
EXPECT_EQ(0, close_count_);
// With no saved profile, the default profile should be chosen and saved.
- service->ShowForSavedProfile();
+ service->Show();
EXPECT_EQ(browser()->profile(), service->GetCurrentAppListProfile());
EXPECT_TRUE(service->IsAppListVisible());
EXPECT_EQ(0, launch_count_);
@@ -118,7 +118,7 @@
// Verify that observers are correctly removed by ensuring that |close_count_|
// is unchanged when the app list is dismissed again.
- service->ShowAppList(browser()->profile());
+ service->ShowForProfile(browser()->profile());
EXPECT_TRUE(service->IsAppListVisible());
EXPECT_EQ(3, launch_count_);
service->DismissAppList();
diff --git a/chrome/browser/ui/app_list/search/term_break_iterator.cc b/chrome/browser/ui/app_list/search/term_break_iterator.cc
index 071a552..1349683 100644
--- a/chrome/browser/ui/app_list/search/term_break_iterator.cc
+++ b/chrome/browser/ui/app_list/search/term_break_iterator.cc
@@ -7,7 +7,7 @@
#include "base/i18n/char_iterator.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
-#include "third_party/icu/public/common/unicode/uchar.h"
+#include "third_party/icu/source/common/unicode/uchar.h"
namespace app_list {
diff --git a/chrome/browser/ui/app_list/search/tokenized_string_char_iterator.cc b/chrome/browser/ui/app_list/search/tokenized_string_char_iterator.cc
index 5a122b6..6999edd 100644
--- a/chrome/browser/ui/app_list/search/tokenized_string_char_iterator.cc
+++ b/chrome/browser/ui/app_list/search/tokenized_string_char_iterator.cc
@@ -6,7 +6,7 @@
#include "base/i18n/char_iterator.h"
#include "base/logging.h"
-#include "third_party/icu/public/common/unicode/utf16.h"
+#include "third_party/icu/source/common/unicode/utf16.h"
namespace app_list {
diff --git a/chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.cc b/chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.cc
index fc3cc46..965281b 100644
--- a/chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.cc
+++ b/chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.cc
@@ -251,7 +251,7 @@
if (extension_host_) {
const extensions::Extension* extension = extension_host_->
profile()->GetExtensionService()->extensions()->
- GetExtensionOrAppByURL(ExtensionURLInfo(origin_url));
+ GetExtensionOrAppByURL(origin_url);
if (extension) {
return UTF8ToUTF16(base::StringPiece(extension->name()));
}
diff --git a/chrome/browser/ui/ash/app_list/app_list_service_ash.cc b/chrome/browser/ui/ash/app_list/app_list_service_ash.cc
index 4303770..cf10ee6 100644
--- a/chrome/browser/ui/ash/app_list/app_list_service_ash.cc
+++ b/chrome/browser/ui/ash/app_list/app_list_service_ash.cc
@@ -28,7 +28,7 @@
// AppListService overrides:
virtual base::FilePath GetProfilePath(
const base::FilePath& user_data_dir) OVERRIDE;
- virtual void ShowAppList(Profile* default_profile) OVERRIDE;
+ virtual void ShowForProfile(Profile* default_profile) OVERRIDE;
virtual bool IsAppListVisible() const OVERRIDE;
virtual void DismissAppList() OVERRIDE;
virtual void EnableAppList(Profile* initial_profile) OVERRIDE;
@@ -42,7 +42,7 @@
return ChromeLauncherController::instance()->profile()->GetPath();
}
-void AppListServiceAsh::ShowAppList(Profile* default_profile) {
+void AppListServiceAsh::ShowForProfile(Profile* default_profile) {
// This may not work correctly if the profile passed in is different from the
// one the ash Shell is currently using.
// TODO(ananta): Handle profile changes correctly when !defined(OS_CHROMEOS).
diff --git a/chrome/browser/ui/auto_login_infobar_delegate.h b/chrome/browser/ui/auto_login_infobar_delegate.h
index 96bebb7..6b2366b 100644
--- a/chrome/browser/ui/auto_login_infobar_delegate.h
+++ b/chrome/browser/ui/auto_login_infobar_delegate.h
@@ -32,16 +32,13 @@
std::string username;
};
- // Creates an autologin delegate and adds it to |infobar_service|.
+ // Creates an autologin infobar delegate and adds it to |infobar_service|.
static void Create(InfoBarService* infobar_service, const Params& params);
protected:
AutoLoginInfoBarDelegate(InfoBarService* owner, const Params& params);
virtual ~AutoLoginInfoBarDelegate();
- // ConfirmInfoBarDelegate:
- virtual string16 GetMessageText() const OVERRIDE;
-
private:
// Enum values used for UMA histograms.
enum Actions {
@@ -59,6 +56,7 @@
virtual int GetIconID() const OVERRIDE;
virtual Type GetInfoBarType() const OVERRIDE;
virtual AutoLoginInfoBarDelegate* AsAutoLoginInfoBarDelegate() OVERRIDE;
+ virtual string16 GetMessageText() const OVERRIDE;
virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
virtual bool Accept() OVERRIDE;
virtual bool Cancel() OVERRIDE;
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller.h b/chrome/browser/ui/autofill/autofill_dialog_controller.h
index 7662b81..8079a02 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller.h
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller.h
@@ -194,12 +194,14 @@
// A button in the dialog's overlay has been pressed.
virtual void OverlayButtonPressed() = 0;
- // Called when the view has been cancelled.
- virtual void OnCancel() = 0;
+ // Called when the view has been cancelled. Returns true if the dialog should
+ // now close, or false to keep it open.
+ virtual bool OnCancel() = 0;
// Called when the view has been accepted. This could be to submit the payment
- // info or to handle a required action.
- virtual void OnAccept() = 0;
+ // info or to handle a required action. Returns true if the dialog should now
+ // close, or false to keep it open.
+ virtual bool OnAccept() = 0;
// Returns the profile for this dialog.
virtual Profile* profile() = 0;
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_browsertest.cc b/chrome/browser/ui/autofill/autofill_dialog_controller_browsertest.cc
index 60e75c4..916fe15 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller_browsertest.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller_browsertest.cc
@@ -508,6 +508,8 @@
EXPECT_FALSE(controller()->ShouldShowDetailArea());
EXPECT_FALSE(controller()->CurrentAutocheckoutSteps().empty());
EXPECT_TRUE(controller()->ShouldShowProgressBar());
+ controller()->GetTestableView()->CancelForTesting();
+ RunMessageLoop();
}
#if defined(OS_MACOSX)
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
index 6ed07ec..a5e4030 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
@@ -34,6 +34,7 @@
#include "chrome/browser/ui/extensions/native_app_window.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/pref_names.h"
+#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
#include "components/autofill/content/browser/risk/fingerprint.h"
#include "components/autofill/content/browser/risk/proto/fingerprint.pb.h"
@@ -60,6 +61,7 @@
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
+#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#include "content/public/common/url_constants.h"
@@ -68,6 +70,7 @@
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "grit/webkit_resources.h"
+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/cert/cert_status_flags.h"
#include "ui/base/base_window.h"
#include "ui/base/l10n/l10n_util.h"
@@ -375,20 +378,39 @@
return l10n_util::GetStringUTF16(IDS_AUTOFILL_WALLET_BUYER_ACCOUNT_ERROR);
case wallet::WalletClient::BAD_REQUEST:
+ return l10n_util::GetStringFUTF16(
+ IDS_AUTOFILL_WALLET_UPGRADE_CHROME_ERROR,
+ ASCIIToUTF16("71"));
+
case wallet::WalletClient::INVALID_PARAMS:
+ return l10n_util::GetStringFUTF16(
+ IDS_AUTOFILL_WALLET_UPGRADE_CHROME_ERROR,
+ ASCIIToUTF16("42"));
+
case wallet::WalletClient::UNSUPPORTED_API_VERSION:
- return l10n_util::GetStringUTF16(
- IDS_AUTOFILL_WALLET_UPGRADE_CHROME_ERROR);
+ return l10n_util::GetStringFUTF16(
+ IDS_AUTOFILL_WALLET_UPGRADE_CHROME_ERROR,
+ ASCIIToUTF16("43"));
case wallet::WalletClient::SERVICE_UNAVAILABLE:
return l10n_util::GetStringUTF16(
IDS_AUTOFILL_WALLET_SERVICE_UNAVAILABLE_ERROR);
case wallet::WalletClient::INTERNAL_ERROR:
+ return l10n_util::GetStringFUTF16(IDS_AUTOFILL_WALLET_UNKNOWN_ERROR,
+ ASCIIToUTF16("62"));
+
case wallet::WalletClient::MALFORMED_RESPONSE:
+ return l10n_util::GetStringFUTF16(IDS_AUTOFILL_WALLET_UNKNOWN_ERROR,
+ ASCIIToUTF16("72"));
+
case wallet::WalletClient::NETWORK_ERROR:
+ return l10n_util::GetStringFUTF16(IDS_AUTOFILL_WALLET_UNKNOWN_ERROR,
+ ASCIIToUTF16("73"));
+
case wallet::WalletClient::UNKNOWN_ERROR:
- return l10n_util::GetStringUTF16(IDS_AUTOFILL_WALLET_UNKNOWN_ERROR);
+ return l10n_util::GetStringFUTF16(IDS_AUTOFILL_WALLET_UNKNOWN_ERROR,
+ ASCIIToUTF16("74"));
}
NOTREACHED();
@@ -432,6 +454,12 @@
GetMetricLogger().LogDialogInitialUserState(
GetDialogType(), initial_user_state_);
+
+ if (deemphasized_render_view_) {
+ web_contents()->GetRenderViewHost()->Send(
+ new ChromeViewMsg_SetVisuallyDeemphasized(
+ web_contents()->GetRenderViewHost()->GetRoutingID(), false));
+ }
}
// static
@@ -615,10 +643,6 @@
view_->Hide();
}
-bool AutofillDialogControllerImpl::AutocheckoutIsRunning() const {
- return autocheckout_state_ == AUTOCHECKOUT_IN_PROGRESS;
-}
-
void AutofillDialogControllerImpl::OnAutocheckoutError() {
DCHECK_EQ(AUTOCHECKOUT_IN_PROGRESS, autocheckout_state_);
GetMetricLogger().LogAutocheckoutDuration(
@@ -691,14 +715,15 @@
}
string16 AutofillDialogControllerImpl::CancelButtonText() const {
- if (autocheckout_state_ == AUTOCHECKOUT_ERROR)
- return l10n_util::GetStringUTF16(IDS_OK);
- if (autocheckout_state_ == AUTOCHECKOUT_SUCCESS)
- return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_CONTINUE_BUTTON);
return l10n_util::GetStringUTF16(IDS_CANCEL);
}
string16 AutofillDialogControllerImpl::ConfirmButtonText() const {
+ if (autocheckout_state_ == AUTOCHECKOUT_ERROR)
+ return l10n_util::GetStringUTF16(IDS_OK);
+ if (autocheckout_state_ == AUTOCHECKOUT_SUCCESS)
+ return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_CONTINUE_BUTTON);
+
return l10n_util::GetStringUTF16(IsSubmitPausedOn(wallet::VERIFY_CVV) ?
IDS_AUTOFILL_DIALOG_VERIFY_BUTTON : IDS_AUTOFILL_DIALOG_SUBMIT_BUTTON);
}
@@ -762,9 +787,11 @@
}
int AutofillDialogControllerImpl::GetDialogButtons() const {
- if (autocheckout_state_ != AUTOCHECKOUT_NOT_STARTED)
+ if (autocheckout_state_ == AUTOCHECKOUT_IN_PROGRESS)
return ui::DIALOG_BUTTON_CANCEL;
- return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
+ if (autocheckout_state_ == AUTOCHECKOUT_NOT_STARTED)
+ return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
+ return ui::DIALOG_BUTTON_OK;
}
bool AutofillDialogControllerImpl::IsDialogButtonEnabled(
@@ -772,14 +799,20 @@
if (button == ui::DIALOG_BUTTON_OK) {
if (IsSubmitPausedOn(wallet::VERIFY_CVV))
return true;
- if (is_submitting_ || ShouldShowSpinner())
+
+ if (ShouldShowSpinner())
return false;
+
+ if (is_submitting_) {
+ return autocheckout_state_ == AUTOCHECKOUT_SUCCESS ||
+ autocheckout_state_ == AUTOCHECKOUT_ERROR;
+ }
+
return true;
}
DCHECK_EQ(ui::DIALOG_BUTTON_CANCEL, button);
- return !is_submitting_ || autocheckout_state_ != AUTOCHECKOUT_NOT_STARTED ||
- IsSubmitPausedOn(wallet::VERIFY_CVV);
+ return !is_submitting_ || IsSubmitPausedOn(wallet::VERIFY_CVV);
}
DialogOverlayState AutofillDialogControllerImpl::GetDialogOverlay() const {
@@ -808,16 +841,16 @@
cc_number.substr(cc_number.size() - 4));
string.text = l10n_util::GetStringUTF16(
IDS_AUTOFILL_DIALOG_CARD_GENERATION_DONE);
- // TODO(estade): figure out correct color.
- string.text_color = SK_ColorGRAY;
+ string.text_color = SK_ColorBLACK;
+ string.alignment = gfx::ALIGN_CENTER;
state.strings.push_back(DialogOverlayString());
DialogOverlayString& subtext = state.strings.back();
subtext.font = rb.GetFont(ui::ResourceBundle::BaseFont);
- // TODO(estade): figure out correct color.
- subtext.text_color = SK_ColorGRAY;
+ subtext.text_color = SkColorSetRGB(102, 102, 102);
subtext.text = l10n_util::GetStringUTF16(
IDS_AUTOFILL_DIALOG_CARD_GENERATION_EXPLANATION);
+ subtext.alignment = gfx::ALIGN_CENTER;
state.button_text = l10n_util::GetStringUTF16(
IDS_AUTOFILL_DIALOG_CARD_GENERATION_OK_BUTTON);
@@ -829,8 +862,7 @@
// "Submitting" waiting page.
string.text = l10n_util::GetStringUTF16(
IDS_AUTOFILL_DIALOG_CARD_GENERATION_IN_PROGRESS);
- // TODO(estade): figure out correct color.
- string.text_color = SK_ColorGRAY;
+ string.text_color = SK_ColorBLACK;
string.alignment = gfx::ALIGN_CENTER;
}
@@ -1898,7 +1930,7 @@
FinishSubmit();
}
-void AutofillDialogControllerImpl::OnCancel() {
+bool AutofillDialogControllerImpl::OnCancel() {
HidePopup();
if (autocheckout_state_ == AUTOCHECKOUT_NOT_STARTED && !is_submitting_)
LogOnCancelMetrics();
@@ -1908,9 +1940,15 @@
AutofillMetrics::AUTOCHECKOUT_CANCELLED);
}
callback_.Run(NULL, std::string());
+ return true;
}
-void AutofillDialogControllerImpl::OnAccept() {
+bool AutofillDialogControllerImpl::OnAccept() {
+ // If autocheckout has already started, the only thing left to do is to
+ // close the dialog.
+ if (autocheckout_state_ != AUTOCHECKOUT_NOT_STARTED)
+ return true;
+
choose_another_instrument_or_address_ = false;
wallet_server_validation_recoverable_ = true;
HidePopup();
@@ -1929,13 +1967,15 @@
}
}
+ if (GetDialogType() == DIALOG_TYPE_AUTOCHECKOUT)
+ DeemphasizeRenderView();
+
SetIsSubmitting(true);
if (IsSubmitPausedOn(wallet::VERIFY_CVV)) {
DCHECK(!active_instrument_id_.empty());
GetWalletClient()->AuthenticateInstrument(
active_instrument_id_,
- UTF16ToUTF8(view_->GetCvc()),
- wallet_items_->obfuscated_gaia_id());
+ UTF16ToUTF8(view_->GetCvc()));
} else if (IsPayingWithWallet()) {
// TODO(dbeam): disallow interacting with the dialog while submitting.
// http://crbug.com/230932
@@ -1943,6 +1983,8 @@
} else {
FinishSubmit();
}
+
+ return false;
}
Profile* AutofillDialogControllerImpl::profile() {
@@ -2025,6 +2067,20 @@
}
////////////////////////////////////////////////////////////////////////////////
+// content::WebContentsObserver implementation.
+
+void AutofillDialogControllerImpl::DidNavigateMainFrame(
+ const content::LoadCommittedDetails& details,
+ const content::FrameNavigateParams& params) {
+ // Close view if necessary.
+ if (!net::registry_controlled_domains::SameDomainOrHost(
+ details.previous_url, details.entry->GetURL(),
+ net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES)) {
+ Hide();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
// SuggestionsMenuModelDelegate implementation.
void AutofillDialogControllerImpl::SuggestionItemSelected(
@@ -2172,61 +2228,25 @@
OnWalletOrSigninUpdate();
}
-void AutofillDialogControllerImpl::OnDidSaveAddress(
+void AutofillDialogControllerImpl::OnDidSaveToWallet(
+ const std::string& instrument_id,
const std::string& address_id,
const std::vector<wallet::RequiredAction>& required_actions,
const std::vector<wallet::FormFieldError>& form_field_errors) {
DCHECK(is_submitting_ && IsPayingWithWallet());
if (required_actions.empty()) {
- active_address_id_ = address_id;
- GetFullWalletIfReady();
+ if (!address_id.empty())
+ active_address_id_ = address_id;
+ if (!instrument_id.empty())
+ active_instrument_id_ = instrument_id;
+ GetFullWallet();
} else {
OnWalletFormFieldError(form_field_errors);
HandleSaveOrUpdateRequiredActions(required_actions);
}
}
-void AutofillDialogControllerImpl::OnDidSaveInstrument(
- const std::string& instrument_id,
- const std::vector<wallet::RequiredAction>& required_actions,
- const std::vector<wallet::FormFieldError>& form_field_errors) {
- DCHECK(is_submitting_ && IsPayingWithWallet());
-
- if (required_actions.empty()) {
- active_instrument_id_ = instrument_id;
- GetFullWalletIfReady();
- } else {
- OnWalletFormFieldError(form_field_errors);
- HandleSaveOrUpdateRequiredActions(required_actions);
- }
-}
-
-void AutofillDialogControllerImpl::OnDidSaveInstrumentAndAddress(
- const std::string& instrument_id,
- const std::string& address_id,
- const std::vector<wallet::RequiredAction>& required_actions,
- const std::vector<wallet::FormFieldError>& form_field_errors) {
- OnDidSaveInstrument(instrument_id, required_actions, form_field_errors);
- // |is_submitting_| can change while in |OnDidSaveInstrument()|.
- if (is_submitting_)
- OnDidSaveAddress(address_id, required_actions, form_field_errors);
-}
-
-void AutofillDialogControllerImpl::OnDidUpdateAddress(
- const std::string& address_id,
- const std::vector<wallet::RequiredAction>& required_actions,
- const std::vector<wallet::FormFieldError>& form_field_errors) {
- OnDidSaveAddress(address_id, required_actions, form_field_errors);
-}
-
-void AutofillDialogControllerImpl::OnDidUpdateInstrument(
- const std::string& instrument_id,
- const std::vector<wallet::RequiredAction>& required_actions,
- const std::vector<wallet::FormFieldError>& form_field_errors) {
- OnDidSaveInstrument(instrument_id, required_actions, form_field_errors);
-}
-
void AutofillDialogControllerImpl::OnWalletError(
wallet::WalletClient::ErrorType error_type) {
DisableWallet(error_type);
@@ -2294,7 +2314,8 @@
const DialogType dialog_type,
const base::Callback<void(const FormStructure*,
const std::string&)>& callback)
- : profile_(Profile::FromBrowserContext(contents->GetBrowserContext())),
+ : WebContentsObserver(contents),
+ profile_(Profile::FromBrowserContext(contents->GetBrowserContext())),
contents_(contents),
initial_user_state_(AutofillMetrics::DIALOG_USER_STATE_UNKNOWN),
dialog_type_(dialog_type),
@@ -2321,7 +2342,8 @@
choose_another_instrument_or_address_(false),
wallet_server_validation_recoverable_(true),
autocheckout_state_(AUTOCHECKOUT_NOT_STARTED),
- was_ui_latency_logged_(false) {
+ was_ui_latency_logged_(false),
+ deemphasized_render_view_(false) {
// TODO(estade): remove duplicates from |form_structure|?
DCHECK(!callback_.is_null());
}
@@ -3004,17 +3026,16 @@
scoped_ptr<wallet::Instrument> inputted_instrument =
CreateTransientInstrument();
- scoped_ptr<wallet::WalletClient::UpdateInstrumentRequest> update_request =
- CreateUpdateInstrumentRequest(
- inputted_instrument.get(),
- !IsEditingExistingData(SECTION_CC_BILLING) ? std::string() :
- active_instrument->object_id());
+ if (inputted_instrument && IsEditingExistingData(SECTION_CC_BILLING)) {
+ inputted_instrument->set_object_id(active_instrument->object_id());
+ DCHECK(!inputted_instrument->object_id().empty());
+ }
scoped_ptr<wallet::Address> inputted_address;
if (active_address_id_.empty()) {
if (ShouldUseBillingForShipping()) {
const wallet::Address& address = inputted_instrument ?
- inputted_instrument->address() : active_instrument->address();
+ *inputted_instrument->address() : active_instrument->address();
// Try to find an exact matched shipping address and use it for shipping,
// otherwise save it as a new shipping address. http://crbug.com/225442
const wallet::Address* duplicated_address =
@@ -3042,36 +3063,9 @@
return;
}
- // If instrument and address aren't based off of any existing data, save both.
- if (inputted_instrument && inputted_address && !update_request &&
- inputted_address->object_id().empty()) {
- GetWalletClient()->SaveInstrumentAndAddress(
- *inputted_instrument,
- *inputted_address,
- wallet_items_->obfuscated_gaia_id(),
- source_url_);
- return;
- }
-
- if (inputted_instrument) {
- if (update_request) {
- scoped_ptr<wallet::Address> billing_address(
- new wallet::Address(inputted_instrument->address()));
- GetWalletClient()->UpdateInstrument(*update_request,
- billing_address.Pass());
- } else {
- GetWalletClient()->SaveInstrument(*inputted_instrument,
- wallet_items_->obfuscated_gaia_id(),
- source_url_);
- }
- }
-
- if (inputted_address) {
- if (!inputted_address->object_id().empty())
- GetWalletClient()->UpdateAddress(*inputted_address, source_url_);
- else
- GetWalletClient()->SaveAddress(*inputted_address, source_url_);
- }
+ GetWalletClient()->SaveToWallet(inputted_instrument.Pass(),
+ inputted_address.Pass(),
+ source_url_);
}
scoped_ptr<wallet::Instrument> AutofillDialogControllerImpl::
@@ -3091,24 +3085,6 @@
new wallet::Instrument(card, cvc, profile));
}
-scoped_ptr<wallet::WalletClient::UpdateInstrumentRequest>
- AutofillDialogControllerImpl::CreateUpdateInstrumentRequest(
- const wallet::Instrument* instrument,
- const std::string& instrument_id) {
- if (!instrument || instrument_id.empty())
- return scoped_ptr<wallet::WalletClient::UpdateInstrumentRequest>();
-
- scoped_ptr<wallet::WalletClient::UpdateInstrumentRequest> update_request(
- new wallet::WalletClient::UpdateInstrumentRequest(
- instrument_id, source_url_));
- update_request->expiration_month = instrument->expiration_month();
- update_request->expiration_year = instrument->expiration_year();
- update_request->card_verification_number =
- UTF16ToUTF8(instrument->card_verification_number());
- update_request->obfuscated_gaia_id = wallet_items_->obfuscated_gaia_id();
- return update_request.Pass();
-}
-
scoped_ptr<wallet::Address>AutofillDialogControllerImpl::
CreateTransientAddress() {
// If not using billing for shipping, just scrape the view.
@@ -3142,14 +3118,6 @@
capabilities));
}
-void AutofillDialogControllerImpl::GetFullWalletIfReady() {
- DCHECK(is_submitting_);
- DCHECK(IsPayingWithWallet());
-
- if (!active_instrument_id_.empty() && !active_address_id_.empty())
- GetFullWallet();
-}
-
void AutofillDialogControllerImpl::HandleSaveOrUpdateRequiredActions(
const std::vector<wallet::RequiredAction>& required_actions) {
DCHECK(!required_actions.empty());
@@ -3403,6 +3371,13 @@
}
}
+void AutofillDialogControllerImpl::DeemphasizeRenderView() {
+ web_contents()->GetRenderViewHost()->Send(
+ new ChromeViewMsg_SetVisuallyDeemphasized(
+ web_contents()->GetRenderViewHost()->GetRoutingID(), true));
+ deemphasized_render_view_ = true;
+}
+
AutofillMetrics::DialogInitialUserStateMetric
AutofillDialogControllerImpl::GetInitialUserState() const {
// Consider a user to be an Autofill user if the user has any credit cards
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h
index a8c578d..eadf103 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h
@@ -33,6 +33,7 @@
#include "components/autofill/core/browser/personal_data_manager_observer.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
+#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/ssl_status.h"
#include "ui/base/models/simple_menu_model.h"
#include "ui/base/ui_base_types.h"
@@ -69,6 +70,7 @@
class AutofillDialogControllerImpl : public AutofillDialogController,
public AutofillPopupDelegate,
public content::NotificationObserver,
+ public content::WebContentsObserver,
public SuggestionsMenuModelDelegate,
public wallet::WalletClientDelegate,
public wallet::WalletSigninHelperDelegate,
@@ -90,9 +92,6 @@
void Show();
void Hide();
- // Whether Autocheckout is currently running.
- bool AutocheckoutIsRunning() const;
-
// Adds a step in the flow to the Autocheckout UI.
void AddAutocheckoutStep(AutocheckoutStepType step_type);
@@ -173,8 +172,8 @@
bool checked) OVERRIDE;
virtual void LegalDocumentLinkClicked(const ui::Range& range) OVERRIDE;
virtual void OverlayButtonPressed() OVERRIDE;
- virtual void OnCancel() OVERRIDE;
- virtual void OnAccept() OVERRIDE;
+ virtual bool OnCancel() OVERRIDE;
+ virtual bool OnAccept() OVERRIDE;
virtual Profile* profile() OVERRIDE;
virtual content::WebContents* web_contents() OVERRIDE;
@@ -193,6 +192,11 @@
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
+ // content::WebContentsObserver implementation.
+ virtual void DidNavigateMainFrame(
+ const content::LoadCommittedDetails& details,
+ const content::FrameNavigateParams& params) OVERRIDE;
+
// SuggestionsMenuModelDelegate implementation.
virtual void SuggestionItemSelected(SuggestionsMenuModel* model,
size_t index) OVERRIDE;
@@ -208,27 +212,11 @@
scoped_ptr<wallet::FullWallet> full_wallet) OVERRIDE;
virtual void OnDidGetWalletItems(
scoped_ptr<wallet::WalletItems> wallet_items) OVERRIDE;
- virtual void OnDidSaveAddress(
- const std::string& address_id,
- const std::vector<wallet::RequiredAction>& required_actions,
- const std::vector<wallet::FormFieldError>& form_field_errors) OVERRIDE;
- virtual void OnDidSaveInstrument(
- const std::string& instrument_id,
- const std::vector<wallet::RequiredAction>& required_actions,
- const std::vector<wallet::FormFieldError>& form_field_errors) OVERRIDE;
- virtual void OnDidSaveInstrumentAndAddress(
+ virtual void OnDidSaveToWallet(
const std::string& instrument_id,
const std::string& address_id,
const std::vector<wallet::RequiredAction>& required_actions,
const std::vector<wallet::FormFieldError>& form_field_errors) OVERRIDE;
- virtual void OnDidUpdateAddress(
- const std::string& address_id,
- const std::vector<wallet::RequiredAction>& required_actions,
- const std::vector<wallet::FormFieldError>& form_field_errors) OVERRIDE;
- virtual void OnDidUpdateInstrument(
- const std::string& instrument_id,
- const std::vector<wallet::RequiredAction>& required_actions,
- const std::vector<wallet::FormFieldError>& form_field_errors) OVERRIDE;
virtual void OnWalletError(
wallet::WalletClient::ErrorType error_type) OVERRIDE;
@@ -306,6 +294,8 @@
// to the requesting site.
virtual bool TransmissionWillBeSecure() const;
+ AutocheckoutState autocheckout_state() const { return autocheckout_state_; }
+
private:
// Whether or not the current request wants credit info back.
bool RequestingCreditCardInfo() const;
@@ -492,11 +482,6 @@
// Creates an instrument based on |views_|' contents.
scoped_ptr<wallet::Instrument> CreateTransientInstrument();
- // Creates an update request based on |instrument|. May return NULL.
- scoped_ptr<wallet::WalletClient::UpdateInstrumentRequest>
- CreateUpdateInstrumentRequest(const wallet::Instrument* instrument,
- const std::string& instrument_id);
-
// Creates an address based on the contents of |view_|.
scoped_ptr<wallet::Address> CreateTransientAddress();
@@ -504,10 +489,6 @@
// This information is decoded to reveal a fronting (proxy) card.
void GetFullWallet();
- // Calls |GetFullWallet()| if the required members (|risk_data_|,
- // |active_instrument_id_|, and |active_address_id_|) are populated.
- void GetFullWalletIfReady();
-
// Updates the state of the controller and |view_| based on any required
// actions returned by Save or Update calls to Wallet.
void HandleSaveOrUpdateRequiredActions(
@@ -559,6 +540,9 @@
// Sets the state of the autocheckout flow.
void SetAutocheckoutState(AutocheckoutState autocheckout_state);
+ // Obscures the web contents.
+ void DeemphasizeRenderView();
+
// Returns the metric corresponding to the user's initial state when
// interacting with this dialog.
AutofillMetrics::DialogInitialUserStateMetric GetInitialUserState() const;
@@ -707,6 +691,9 @@
// Whether the latency to display to the UI was logged to UMA yet.
bool was_ui_latency_logged_;
+ // Whether or not the render view has been deemphasized.
+ bool deemphasized_render_view_;
+
// State of steps in the current Autocheckout flow, or empty if not an
// Autocheckout use case.
std::vector<DialogAutocheckoutStep> steps_;
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc b/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc
index f12a833..142e7d0 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc
@@ -13,11 +13,14 @@
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/tuple.h"
#include "chrome/browser/ui/autofill/autofill_credit_card_bubble_controller.h"
#include "chrome/browser/ui/autofill/autofill_dialog_controller_impl.h"
#include "chrome/browser/ui/autofill/autofill_dialog_view.h"
#include "chrome/browser/ui/autofill/test_autofill_credit_card_bubble.h"
#include "chrome/common/pref_names.h"
+#include "chrome/common/render_messages.h"
+#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_profile.h"
#include "components/autofill/content/browser/risk/proto/fingerprint.pb.h"
#include "components/autofill/content/browser/wallet/full_wallet.h"
@@ -32,8 +35,7 @@
#include "components/autofill/core/common/autofill_switches.h"
#include "components/autofill/core/common/form_data.h"
#include "content/public/browser/web_contents.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "content/public/test/web_contents_tester.h"
+#include "content/public/test/mock_render_process_host.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -236,6 +238,10 @@
OnWalletSigninError();
}
+ bool AutocheckoutIsRunning() const {
+ return AUTOCHECKOUT_IN_PROGRESS == autocheckout_state();
+ }
+
MOCK_METHOD0(LoadRiskFingerprintData, void());
using AutofillDialogControllerImpl::OnDidLoadRiskFingerprintData;
using AutofillDialogControllerImpl::IsEditingExistingData;
@@ -307,19 +313,18 @@
DISALLOW_COPY_AND_ASSIGN(TestAutofillCreditCardBubbleController);
};
-class AutofillDialogControllerTest : public testing::Test {
+class AutofillDialogControllerTest : public ChromeRenderViewHostTestHarness {
protected:
AutofillDialogControllerTest(): form_structure_(NULL) {}
// testing::Test implementation:
virtual void SetUp() OVERRIDE {
+ ChromeRenderViewHostTestHarness::SetUp();
profile()->CreateRequestContext();
- test_web_contents_.reset(
- content::WebContentsTester::CreateTestWebContents(profile(), NULL));
test_bubble_controller_ =
new testing::NiceMock<TestAutofillCreditCardBubbleController>(
- test_web_contents_.get());
+ web_contents());
// Don't get stuck on the first run wallet interstitial.
profile()->GetPrefs()->SetBoolean(::prefs::kAutofillDialogHasPaidWithWallet,
@@ -331,9 +336,25 @@
virtual void TearDown() OVERRIDE {
if (controller_)
controller_->ViewClosed();
+ ChromeRenderViewHostTestHarness::TearDown();
}
- protected:
+ void Reset() {
+ if (controller_)
+ controller_->ViewClosed();
+ profile()->CreateRequestContext();
+
+ test_bubble_controller_ =
+ new testing::NiceMock<TestAutofillCreditCardBubbleController>(
+ web_contents());
+
+ // Don't get stuck on the first run wallet interstitial.
+ profile()->GetPrefs()->SetBoolean(::prefs::kAutofillDialogHasPaidWithWallet,
+ true);
+
+ SetUpControllerWithFormData(DefaultFormData());
+ }
+
FormData DefaultFormData() {
FormData form_data;
for (size_t i = 0; i < arraysize(kFieldsFromPage); ++i) {
@@ -352,7 +373,7 @@
base::Bind(&AutofillDialogControllerTest::FinishedCallback,
base::Unretained(this));
controller_ = (new testing::NiceMock<TestAutofillDialogController>(
- test_web_contents_.get(),
+ web_contents(),
form_data,
GURL(),
metric_logger_,
@@ -427,16 +448,22 @@
controller()->OnDidLoadRiskFingerprintData(GetFakeFingerprint().Pass());
}
+ bool ReadSetVisuallyDeemphasizedIpc() {
+ EXPECT_EQ(1U, process()->sink().message_count());
+ uint32 kMsgID = ChromeViewMsg_SetVisuallyDeemphasized::ID;
+ const IPC::Message* message =
+ process()->sink().GetFirstMessageMatching(kMsgID);
+ EXPECT_TRUE(message);
+ Tuple1<bool> payload;
+ ChromeViewMsg_SetVisuallyDeemphasized::Read(message, &payload);
+ process()->sink().ClearMessages();
+ return payload.a;
+ }
+
TestAutofillDialogController* controller() { return controller_.get(); }
- TestingProfile* profile() { return &profile_; }
-
const FormStructure* form_structure() { return form_structure_; }
- const content::WebContents* test_web_contents() const {
- return test_web_contents_.get();
- }
-
TestAutofillCreditCardBubbleController* test_bubble_controller() {
return test_bubble_controller_;
}
@@ -449,21 +476,14 @@
EXPECT_TRUE(controller()->AutocheckoutIsRunning());
}
- // Must be first member to ensure TestBrowserThreads outlive other objects.
- content::TestBrowserThreadBundle thread_bundle_;
-
#if defined(OS_WIN)
// http://crbug.com/227221
ui::ScopedOleInitializer ole_initializer_;
#endif
- TestingProfile profile_;
-
// The controller owns itself.
base::WeakPtr<TestAutofillDialogController> controller_;
- scoped_ptr<content::WebContents> test_web_contents_;
-
// Must outlive the controller.
AutofillMetrics metric_logger_;
@@ -471,7 +491,7 @@
const FormStructure* form_structure_;
// Used to monitor if the Autofill credit card bubble is shown. Owned by
- // |test_web_contents_|.
+ // |web_contents()|.
TestAutofillCreditCardBubbleController* test_bubble_controller_;
};
@@ -742,8 +762,7 @@
FillCreditCardInputs();
controller()->OnAccept();
- TearDown();
- SetUp();
+ Reset();
controller()->GetTestingManager()->AddTestingProfile(&full_profile);
controller()->GetTestingManager()->AddTestingProfile(&full_profile2);
shipping_model = static_cast<SuggestionsMenuModel*>(
@@ -756,8 +775,7 @@
shipping_model->ExecuteCommand(2, 0);
FillCreditCardInputs();
controller()->OnAccept();
- TearDown();
- SetUp();
+ Reset();
controller()->GetTestingManager()->AddTestingProfile(&full_profile);
shipping_model = static_cast<SuggestionsMenuModel*>(
controller()->MenuModelForSection(SECTION_SHIPPING));
@@ -815,8 +833,7 @@
FillCreditCardInputs();
controller()->OnAccept();
- TearDown();
- SetUp();
+ Reset();
controller()->GetTestingManager()->AddTestingProfile(&full_profile);
email_suggestions = static_cast<SuggestionsMenuModel*>(
controller()->MenuModelForSection(SECTION_EMAIL));
@@ -1109,7 +1126,9 @@
TEST_F(AutofillDialogControllerTest, SaveAddress) {
EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1);
EXPECT_CALL(*controller()->GetTestingWalletClient(),
- SaveAddress(_, _)).Times(1);
+ SaveToWalletMock(testing::IsNull(),
+ testing::NotNull(),
+ _)).Times(1);
scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
@@ -1126,7 +1145,9 @@
TEST_F(AutofillDialogControllerTest, SaveInstrument) {
EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1);
EXPECT_CALL(*controller()->GetTestingWalletClient(),
- SaveInstrument(_, _, _)).Times(1);
+ SaveToWalletMock(testing::NotNull(),
+ testing::IsNull(),
+ _)).Times(1);
scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
wallet_items->AddAddress(wallet::GetTestShippingAddress());
@@ -1136,7 +1157,9 @@
TEST_F(AutofillDialogControllerTest, SaveInstrumentWithInvalidInstruments) {
EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1);
EXPECT_CALL(*controller()->GetTestingWalletClient(),
- SaveInstrument(_, _, _)).Times(1);
+ SaveToWalletMock(testing::NotNull(),
+ testing::IsNull(),
+ _)).Times(1);
scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
wallet_items->AddAddress(wallet::GetTestShippingAddress());
@@ -1146,17 +1169,25 @@
TEST_F(AutofillDialogControllerTest, SaveInstrumentAndAddress) {
EXPECT_CALL(*controller()->GetTestingWalletClient(),
- SaveInstrumentAndAddress(_, _, _, _)).Times(1);
+ SaveToWalletMock(testing::NotNull(),
+ testing::NotNull(),
+ _)).Times(1);
controller()->OnDidGetWalletItems(wallet::GetTestWalletItems());
AcceptAndLoadFakeFingerprint();
}
+MATCHER(IsUpdatingExistingData, "updating existing Wallet data") {
+ return !arg->object_id().empty();
+}
+
// Tests that editing an address (in wallet mode0 and submitting the dialog
// should update the existing address on the server via WalletClient.
TEST_F(AutofillDialogControllerTest, UpdateAddress) {
EXPECT_CALL(*controller()->GetTestingWalletClient(),
- UpdateAddress(_, _)).Times(1);
+ SaveToWalletMock(testing::IsNull(),
+ IsUpdatingExistingData(),
+ _)).Times(1);
controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
@@ -1167,20 +1198,24 @@
// Tests that editing an instrument (CC + address) in wallet mode updates an
// existing instrument on the server via WalletClient.
TEST_F(AutofillDialogControllerTest, UpdateInstrument) {
+ EXPECT_CALL(*controller()->GetTestingWalletClient(),
+ SaveToWalletMock(IsUpdatingExistingData(),
+ testing::IsNull(),
+ _)).Times(1);
+
controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
controller()->EditClickedForSection(SECTION_CC_BILLING);
AcceptAndLoadFakeFingerprint();
-
- EXPECT_TRUE(
- controller()->GetTestingWalletClient()->updated_billing_address());
}
// Test that a user is able to edit their instrument and add a new address in
// the same submission.
TEST_F(AutofillDialogControllerTest, UpdateInstrumentSaveAddress) {
EXPECT_CALL(*controller()->GetTestingWalletClient(),
- SaveAddress(_, _)).Times(1);
+ SaveToWalletMock(IsUpdatingExistingData(),
+ testing::NotNull(),
+ _)).Times(1);
scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
wallet_items->AddInstrument(wallet::GetTestMaskedInstrument());
@@ -1188,17 +1223,14 @@
controller()->EditClickedForSection(SECTION_CC_BILLING);
AcceptAndLoadFakeFingerprint();
-
- EXPECT_TRUE(
- controller()->GetTestingWalletClient()->updated_billing_address());
}
// Test that saving a new instrument and editing an address works.
TEST_F(AutofillDialogControllerTest, SaveInstrumentUpdateAddress) {
EXPECT_CALL(*controller()->GetTestingWalletClient(),
- SaveInstrument(_, _, _)).Times(1);
- EXPECT_CALL(*controller()->GetTestingWalletClient(),
- UpdateAddress(_, _)).Times(1);
+ SaveToWalletMock(testing::NotNull(),
+ IsUpdatingExistingData(),
+ _)).Times(1);
scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
wallet_items->AddAddress(wallet::GetTestShippingAddress());
@@ -1210,14 +1242,16 @@
}
MATCHER(UsesLocalBillingAddress, "uses the local billing address") {
- return arg.address_line_1() == ASCIIToUTF16(kEditedBillingAddress);
+ return arg->address_line_1() == ASCIIToUTF16(kEditedBillingAddress);
}
// Tests that when using billing address for shipping, and there is no exact
// matched shipping address, then a shipping address should be added.
TEST_F(AutofillDialogControllerTest, BillingForShipping) {
EXPECT_CALL(*controller()->GetTestingWalletClient(),
- SaveAddress(_, _)).Times(1);
+ SaveToWalletMock(testing::IsNull(),
+ testing::NotNull(),
+ _)).Times(1);
controller()->OnDidGetWalletItems(CompleteAndValidWalletItems());
// Select "Same as billing" in the address menu.
@@ -1230,7 +1264,7 @@
// matched shipping address, then a shipping address should not be added.
TEST_F(AutofillDialogControllerTest, BillingForShippingHasMatch) {
EXPECT_CALL(*controller()->GetTestingWalletClient(),
- SaveAddress(_, _)).Times(0);
+ SaveToWalletMock(_, _, _)).Times(0);
scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
scoped_ptr<wallet::WalletItems::MaskedInstrument> instrument =
@@ -1250,22 +1284,6 @@
AcceptAndLoadFakeFingerprint();
}
-// Tests that adding new instrument and also using billing address for shipping,
-// then a shipping address should not be added.
-TEST_F(AutofillDialogControllerTest, BillingForShippingNewInstrument) {
- EXPECT_CALL(*controller()->GetTestingWalletClient(),
- SaveInstrumentAndAddress(_, _, _, _)).Times(1);
-
- scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems();
- wallet_items->AddAddress(wallet::GetTestShippingAddress());
-
- controller()->OnDidGetWalletItems(wallet_items.Pass());
- // Select "Same as billing" in the address menu.
- UseBillingForShipping();
-
- AcceptAndLoadFakeFingerprint();
-}
-
// Test that the local view contents is used when saving a new instrument and
// the user has selected "Same as billing".
TEST_F(AutofillDialogControllerTest, SaveInstrumentSameAsBilling) {
@@ -1287,16 +1305,15 @@
controller()->GetView()->SetUserInput(SECTION_CC_BILLING, outputs);
EXPECT_CALL(*controller()->GetTestingWalletClient(),
- SaveAddress(UsesLocalBillingAddress(), _)).Times(1);
+ SaveToWalletMock(testing::NotNull(),
+ UsesLocalBillingAddress(),
+ _)).Times(1);
AcceptAndLoadFakeFingerprint();
-
- EXPECT_TRUE(
- controller()->GetTestingWalletClient()->updated_billing_address());
}
TEST_F(AutofillDialogControllerTest, CancelNoSave) {
EXPECT_CALL(*controller()->GetTestingWalletClient(),
- SaveInstrumentAndAddress(_, _, _, _)).Times(0);
+ SaveToWalletMock(_, _, _)).Times(0);
EXPECT_CALL(*controller()->GetView(), ModelChanged()).Times(1);
@@ -1488,7 +1505,7 @@
EXPECT_CALL(*controller()->GetTestingWalletClient(),
GetFullWallet(_)).Times(1);
EXPECT_CALL(*controller()->GetTestingWalletClient(),
- AuthenticateInstrument(_, _, _)).Times(1);
+ AuthenticateInstrument(_, _)).Times(1);
SubmitWithWalletItems(CompleteAndValidWalletItems());
@@ -1604,7 +1621,10 @@
wallet::FormFieldError::SHIPPING_ADDRESS));
EXPECT_CALL(*controller()->GetView(), UpdateForErrors()).Times(1);
- controller()->OnDidSaveAddress(std::string(), required_actions, form_errors);
+ controller()->OnDidSaveToWallet(std::string(),
+ std::string(),
+ required_actions,
+ form_errors);
}
// Simulates receiving unrecoverable Wallet server validation errors.
@@ -1622,7 +1642,10 @@
wallet::FormFieldError(wallet::FormFieldError::UNKNOWN_ERROR,
wallet::FormFieldError::UNKNOWN_LOCATION));
- controller()->OnDidSaveAddress(std::string(), required_actions, form_errors);
+ controller()->OnDidSaveToWallet(std::string(),
+ std::string(),
+ required_actions,
+ form_errors);
EXPECT_EQ(1U, NotificationsOfType(
DialogNotification::REQUIRED_ACTION).size());
@@ -1731,14 +1754,18 @@
FillCreditCardInputs();
controller()->OnAccept();
+ EXPECT_TRUE(ReadSetVisuallyDeemphasizedIpc());
controller()->OnAutocheckoutError();
- EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
- EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
+ EXPECT_FALSE(controller()->GetDialogButtons() & ui::DIALOG_BUTTON_CANCEL);
+ EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
EXPECT_EQ(0U, NotificationsOfType(
DialogNotification::AUTOCHECKOUT_SUCCESS).size());
EXPECT_EQ(1U, NotificationsOfType(
DialogNotification::AUTOCHECKOUT_ERROR).size());
+
+ controller()->ViewClosed();
+ EXPECT_FALSE(ReadSetVisuallyDeemphasizedIpc());
}
TEST_F(AutofillDialogControllerTest, OnAutocheckoutSuccess) {
@@ -1762,6 +1789,7 @@
DialogNotification::WALLET_USAGE_CONFIRMATION).size());
AcceptAndLoadFakeFingerprint();
+ EXPECT_TRUE(ReadSetVisuallyDeemphasizedIpc());
controller()->OnDidGetFullWallet(wallet::GetTestFullWallet());
EXPECT_TRUE(controller()->GetDialogOverlay().image.IsEmpty());
@@ -1771,8 +1799,8 @@
controller()->OnAutocheckoutSuccess();
EXPECT_TRUE(controller()->GetDialogOverlay().image.IsEmpty());
- EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL));
- EXPECT_FALSE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
+ EXPECT_FALSE(controller()->GetDialogButtons() & ui::DIALOG_BUTTON_CANCEL);
+ EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
EXPECT_EQ(1U, NotificationsOfType(
DialogNotification::AUTOCHECKOUT_SUCCESS).size());
EXPECT_EQ(0U, NotificationsOfType(
@@ -1781,6 +1809,9 @@
DialogNotification::EXPLANATORY_MESSAGE).size());
EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(
::prefs::kAutofillDialogHasPaidWithWallet));
+
+ controller()->ViewClosed();
+ EXPECT_FALSE(ReadSetVisuallyDeemphasizedIpc());
}
TEST_F(AutofillDialogControllerTest, ViewCancelDoesntSetPref) {
@@ -2156,6 +2187,7 @@
// Initiate flow - should add proxy card step since the user is using wallet
// data.
controller()->OnAccept();
+ EXPECT_TRUE(ReadSetVisuallyDeemphasizedIpc());
controller()->OnDidLoadRiskFingerprintData(GetFakeFingerprint().Pass());
SuggestionState suggestion_state =
@@ -2186,6 +2218,7 @@
// Re-initiate flow.
controller()->OnAccept();
+ EXPECT_TRUE(ReadSetVisuallyDeemphasizedIpc());
// All steps should be initially unstarted.
EXPECT_EQ(3U, controller()->CurrentAutocheckoutSteps().size());
@@ -2225,6 +2258,9 @@
controller()->CurrentAutocheckoutSteps()[2].type());
EXPECT_EQ(AUTOCHECKOUT_STEP_UNSTARTED,
controller()->CurrentAutocheckoutSteps()[2].status());
+
+ controller()->ViewClosed();
+ EXPECT_FALSE(ReadSetVisuallyDeemphasizedIpc());
}
diff --git a/chrome/browser/ui/autofill/autofill_dialog_types.cc b/chrome/browser/ui/autofill/autofill_dialog_types.cc
index 1230c53..6a2a4a2 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_types.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_types.cc
@@ -50,7 +50,7 @@
case DialogNotification::REQUIRED_ACTION:
case DialogNotification::WALLET_ERROR:
case DialogNotification::AUTOCHECKOUT_ERROR:
- return SK_ColorBLACK;
+ return SkColorSetRGB(102, 102, 102);
case DialogNotification::AUTOCHECKOUT_SUCCESS:
case DialogNotification::DEVELOPER_WARNING:
case DialogNotification::EXPLANATORY_MESSAGE:
diff --git a/chrome/browser/ui/autofill/autofill_dialog_types.h b/chrome/browser/ui/autofill/autofill_dialog_types.h
index 26df627..c67a88b 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_types.h
+++ b/chrome/browser/ui/autofill/autofill_dialog_types.h
@@ -173,7 +173,7 @@
AUTOCHECKOUT_ERROR, // There was an error in the flow.
AUTOCHECKOUT_IN_PROGRESS, // The flow is currently in.
AUTOCHECKOUT_NOT_STARTED, // The flow has not been initiated by the user yet.
- AUTOCHECKOUT_SUCCESS, // The flow completed successsfully.
+ AUTOCHECKOUT_SUCCESS, // The flow completed successfully.
};
struct SuggestionState {
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
index 681c2d8..d7bfd83 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
@@ -170,6 +170,62 @@
delegate_->OnPopupShown(this);
}
+void AutofillPopupControllerImpl::UpdateDataListValues(
+ const std::vector<base::string16>& values,
+ const std::vector<base::string16>& labels) {
+ // Remove all the old data list values, which should always be at the top of
+ // the list if they are present.
+ while (!identifiers_.empty() &&
+ identifiers_[0] == WebAutofillClient::MenuItemIDDataListEntry) {
+ names_.erase(names_.begin());
+ subtexts_.erase(subtexts_.begin());
+ icons_.erase(icons_.begin());
+ identifiers_.erase(identifiers_.begin());
+ }
+
+ // If there are no new data list values, exit (clearing the separator if there
+ // is one).
+ if (values.empty()) {
+ if (!identifiers_.empty() &&
+ identifiers_[0] == WebAutofillClient::MenuItemIDSeparator) {
+ names_.erase(names_.begin());
+ subtexts_.erase(subtexts_.begin());
+ icons_.erase(icons_.begin());
+ identifiers_.erase(identifiers_.begin());
+ }
+
+ // The popup contents have changed, so either update the bounds or hide it.
+ if (HasSuggestions())
+ UpdateBoundsAndRedrawPopup();
+ else
+ Hide();
+
+ return;
+ }
+
+ // Add a separator if there are any other values.
+ if (!identifiers_.empty() &&
+ identifiers_[0] != WebAutofillClient::MenuItemIDSeparator) {
+ names_.insert(names_.begin(), string16());
+ subtexts_.insert(subtexts_.begin(), string16());
+ icons_.insert(icons_.begin(), string16());
+ identifiers_.insert(identifiers_.begin(),
+ WebAutofillClient::MenuItemIDSeparator);
+ }
+
+
+ names_.insert(names_.begin(), values.begin(), values.end());
+ subtexts_.insert(subtexts_.begin(), labels.begin(), labels.end());
+
+ // Add the values that are the same for all data list elements.
+ icons_.insert(icons_.begin(), values.size(), base::string16());
+ identifiers_.insert(identifiers_.begin(),
+ values.size(),
+ WebAutofillClient::MenuItemIDDataListEntry);
+
+ UpdateBoundsAndRedrawPopup();
+}
+
void AutofillPopupControllerImpl::Hide() {
if (delegate_.get())
delegate_->OnPopupHidden(this);
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_impl.h b/chrome/browser/ui/autofill/autofill_popup_controller_impl.h
index 8aa1e8f..8509a9f 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller_impl.h
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_impl.h
@@ -50,6 +50,10 @@
const std::vector<string16>& icons,
const std::vector<int>& identifiers);
+ // Updates the data list values currently shown with the popup.
+ void UpdateDataListValues(const std::vector<base::string16>& values,
+ const std::vector<base::string16>& labels);
+
// Hides the popup and destroys the controller. This also invalidates
// |delegate_|.
virtual void Hide() OVERRIDE;
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc b/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc
index 482d838..8cbcdeb 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc
@@ -90,6 +90,9 @@
const std::vector<string16>& subtexts() const {
return AutofillPopupControllerImpl::subtexts();
}
+ const std::vector<int>& identifiers() const {
+ return AutofillPopupControllerImpl::identifiers();
+ }
int selected_line() const {
return AutofillPopupControllerImpl::selected_line();
}
@@ -366,6 +369,91 @@
autofill_popup_controller_->RowWidthWithoutText(3));
}
+TEST_F(AutofillPopupControllerUnitTest, UpdateDataListValues) {
+ std::vector<string16> items;
+ items.push_back(string16());
+ std::vector<int> ids;
+ ids.push_back(1);
+
+ autofill_popup_controller_->Show(items, items, items, ids);
+
+ EXPECT_EQ(items, autofill_popup_controller_->names());
+ EXPECT_EQ(ids, autofill_popup_controller_->identifiers());
+
+ // Add one data list entry.
+ std::vector<string16> data_list_values;
+ data_list_values.push_back(ASCIIToUTF16("data list value 1"));
+
+ autofill_popup_controller_->UpdateDataListValues(data_list_values,
+ data_list_values);
+
+ // Update the expected values.
+ items.insert(items.begin(), data_list_values[0]);
+ items.insert(items.begin() + 1, string16());
+ ids.insert(ids.begin(), WebAutofillClient::MenuItemIDDataListEntry);
+ ids.insert(ids.begin() + 1, WebAutofillClient::MenuItemIDSeparator);
+
+ EXPECT_EQ(items, autofill_popup_controller_->names());
+ EXPECT_EQ(ids, autofill_popup_controller_->identifiers());
+
+ // Add two data list entries (which should replace the current one).
+ data_list_values.push_back(ASCIIToUTF16("data list value 2"));
+
+ autofill_popup_controller_->UpdateDataListValues(data_list_values,
+ data_list_values);
+
+ // Update the expected values.
+ items.insert(items.begin() + 1, data_list_values[1]);
+ ids.insert(ids.begin(), WebAutofillClient::MenuItemIDDataListEntry);
+
+ EXPECT_EQ(items, autofill_popup_controller_->names());
+ EXPECT_EQ(ids, autofill_popup_controller_->identifiers());
+
+ // Clear all data list values.
+ data_list_values.clear();
+
+ autofill_popup_controller_->UpdateDataListValues(data_list_values,
+ data_list_values);
+
+ items.clear();
+ items.push_back(string16());
+ ids.clear();
+ ids.push_back(1);
+
+ EXPECT_EQ(items, autofill_popup_controller_->names());
+ EXPECT_EQ(ids, autofill_popup_controller_->identifiers());
+}
+
+TEST_F(AutofillPopupControllerUnitTest, PopupsWithOnlyDataLists) {
+ // Create the popup with a single datalist element.
+ std::vector<string16> items;
+ items.push_back(string16());
+ std::vector<int> ids;
+ ids.push_back(WebAutofillClient::MenuItemIDDataListEntry);
+
+ autofill_popup_controller_->Show(items, items, items, ids);
+
+ EXPECT_EQ(items, autofill_popup_controller_->names());
+ EXPECT_EQ(ids, autofill_popup_controller_->identifiers());
+
+ // Replace the datalist element with a new one.
+ std::vector<string16> data_list_values;
+ data_list_values.push_back(ASCIIToUTF16("data list value 1"));
+
+ autofill_popup_controller_->UpdateDataListValues(data_list_values,
+ data_list_values);
+
+ EXPECT_EQ(data_list_values, autofill_popup_controller_->names());
+ // The id value should stay the same.
+ EXPECT_EQ(ids, autofill_popup_controller_->identifiers());
+
+ // Clear datalist values and check that the popup becomes hidden.
+ EXPECT_CALL(*autofill_popup_controller_, Hide());
+ data_list_values.clear();
+ autofill_popup_controller_->UpdateDataListValues(data_list_values,
+ data_list_values);
+}
+
TEST_F(AutofillPopupControllerUnitTest, GetOrCreate) {
AutofillDriverImpl* driver =
AutofillDriverImpl::FromWebContents(web_contents());
diff --git a/chrome/browser/ui/autofill/mock_autofill_dialog_controller.cc b/chrome/browser/ui/autofill/mock_autofill_dialog_controller.cc
index 6ca8614..3718086 100644
--- a/chrome/browser/ui/autofill/mock_autofill_dialog_controller.cc
+++ b/chrome/browser/ui/autofill/mock_autofill_dialog_controller.cc
@@ -3,15 +3,32 @@
// found in the LICENSE file.
#include "chrome/browser/ui/autofill/mock_autofill_dialog_controller.h"
+#include "content/public/browser/native_web_keyboard_event.h" // For gmock.
#include "grit/generated_resources.h"
-#include "testing/gmock/include/gmock/gmock.h"
+#include "ui/gfx/rect.h" // Only needed because gmock needs complete types.
namespace autofill {
MockAutofillDialogController::MockAutofillDialogController() {
- testing::DefaultValue<const DetailInputs&>::Set(default_inputs_);
- testing::DefaultValue<ui::ComboboxModel*>::Set(NULL);
- testing::DefaultValue<ValidityData>::Set(ValidityData());
+ using testing::DefaultValue;
+ using testing::_;
+ using testing::Return;
+ using testing::ReturnRef;
+
+ // N.B. Setting DefaultValue in the ctor and deleting it in the dtor will
+ // only work if this Mock is not used together with other mock code that
+ // sets different defaults. If tests utilizing the MockController start
+ // breaking because of this, use ON_CALL instead.
+ DefaultValue<const DetailInputs&>::Set(default_inputs_);
+ DefaultValue<string16>::Set(string16());
+ DefaultValue<ValidityData>::Set(ValidityData());
+ DefaultValue<DialogSignedInState>::Set(REQUIRES_RESPONSE);
+ DefaultValue<gfx::Image>::Set(gfx::Image());
+ DefaultValue<SuggestionState>::Set(SuggestionState(string16(),
+ gfx::Font::NORMAL,
+ gfx::Image(),
+ string16(),
+ gfx::Image()));
// SECTION_CC *must* have a CREDIT_CARD_VERIFICATION_CODE field.
const DetailInput kCreditCardInputs[] = {
@@ -19,172 +36,28 @@
};
cc_default_inputs_.push_back(kCreditCardInputs[0]);
ON_CALL(*this, RequestedFieldsForSection(SECTION_CC))
- .WillByDefault(testing::ReturnRef(cc_default_inputs_));
+ .WillByDefault(ReturnRef(cc_default_inputs_));
+
+ ON_CALL(*this, GetDialogButtons())
+ .WillByDefault(Return(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL));
+ ON_CALL(*this, LegalDocumentLinks()).WillByDefault(ReturnRef(range_));
// Activate all sections but CC_BILLING - default for the real
// controller implementation, too.
- ON_CALL(*this, SectionIsActive(testing::_))
- .WillByDefault(testing::Return(true));
+ ON_CALL(*this, SectionIsActive(_)).WillByDefault(Return(true));
ON_CALL(*this, SectionIsActive(SECTION_CC_BILLING))
- .WillByDefault(testing::Return(false));
+ .WillByDefault(Return(false));
}
MockAutofillDialogController::~MockAutofillDialogController() {
- testing::DefaultValue<ValidityData>::Clear();
- testing::DefaultValue<ui::ComboboxModel*>::Clear();
- testing::DefaultValue<const DetailInputs&>::Clear();
-}
+ using testing::DefaultValue;
-string16 MockAutofillDialogController::DialogTitle() const {
- return string16();
-}
-
-string16 MockAutofillDialogController::AccountChooserText() const {
- return string16();
-}
-
-string16 MockAutofillDialogController::SignInLinkText() const {
- return string16();
-}
-
-string16 MockAutofillDialogController::EditSuggestionText() const {
- return string16();
-}
-
-string16 MockAutofillDialogController::CancelButtonText() const {
- return string16();
-}
-
-string16 MockAutofillDialogController::ConfirmButtonText() const {
- return string16();
-}
-
-string16 MockAutofillDialogController::SaveLocallyText() const {
- return string16();
-}
-
-string16 MockAutofillDialogController::LegalDocumentsText() {
- return string16();
-}
-
-DialogSignedInState MockAutofillDialogController::SignedInState() const {
- return REQUIRES_RESPONSE;
-}
-
-bool MockAutofillDialogController::ShouldShowSpinner() const {
- return false;
-}
-
-gfx::Image MockAutofillDialogController::AccountChooserImage() {
- return gfx::Image();
-}
-
-bool MockAutofillDialogController::ShouldShowDetailArea() const {
- return false;
-}
-
-bool MockAutofillDialogController::ShouldShowProgressBar() const {
- return false;
-}
-
-int MockAutofillDialogController::GetDialogButtons() const {
- return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
-}
-
-bool MockAutofillDialogController::IsDialogButtonEnabled(
- ui::DialogButton button) const {
- return false;
-}
-
-DialogOverlayState MockAutofillDialogController::GetDialogOverlay() const {
- return DialogOverlayState();
-}
-
-const std::vector<ui::Range>&
- MockAutofillDialogController::LegalDocumentLinks() {
- return range_;
-}
-
-string16 MockAutofillDialogController::LabelForSection(
- DialogSection section) const {
- return string16();
-}
-
-SuggestionState MockAutofillDialogController::SuggestionStateForSection(
- DialogSection section) {
- return SuggestionState(string16(),
- gfx::Font::NORMAL,
- gfx::Image(),
- string16(),
- gfx::Image());
-}
-
-void MockAutofillDialogController::EditClickedForSection(
- DialogSection section) {}
-
-void MockAutofillDialogController::EditCancelledForSection(
- DialogSection section) {}
-
-gfx::Image MockAutofillDialogController::IconForField(
- AutofillFieldType type, const string16& user_input) const {
- return gfx::Image();
-}
-
-string16 MockAutofillDialogController::InputValidityMessage(
- DialogSection section,
- AutofillFieldType type,
- const string16& value) {
- return string16();
-}
-
-void MockAutofillDialogController::UserEditedOrActivatedInput(
- DialogSection section,
- const DetailInput* input,
- gfx::NativeView parent_view,
- const gfx::Rect& content_bounds,
- const string16& field_contents,
- bool was_edit) {}
-
-bool MockAutofillDialogController::HandleKeyPressEventInInput(
- const content::NativeWebKeyboardEvent& event) {
- return false;
-}
-
-void MockAutofillDialogController::FocusMoved() {}
-
-gfx::Image MockAutofillDialogController::SplashPageImage() const {
- return gfx::Image();
-}
-
-void MockAutofillDialogController::ViewClosed() {}
-
-std::vector<DialogNotification> MockAutofillDialogController::
- CurrentNotifications() {
- return std::vector<DialogNotification>();
-}
-
-std::vector<DialogAutocheckoutStep> MockAutofillDialogController::
- CurrentAutocheckoutSteps() const {
- return std::vector<DialogAutocheckoutStep>();
-}
-
-void MockAutofillDialogController::SignInLinkClicked() {}
-
-void MockAutofillDialogController::NotificationCheckboxStateChanged(
- DialogNotification::Type type,
- bool checked) {}
-
-void MockAutofillDialogController::LegalDocumentLinkClicked(
- const ui::Range& range) {}
-
-void MockAutofillDialogController::OverlayButtonPressed() {}
-
-void MockAutofillDialogController::OnCancel() {}
-
-void MockAutofillDialogController::OnAccept() {}
-
-content::WebContents* MockAutofillDialogController::web_contents() {
- return NULL;
+ DefaultValue<SuggestionState>::Clear();
+ DefaultValue<gfx::Image>::Clear();
+ DefaultValue<DialogSignedInState>::Clear();
+ DefaultValue<ValidityData>::Clear();
+ DefaultValue<string16>::Clear();
+ DefaultValue<const DetailInputs&>::Clear();
}
} // namespace autofill
diff --git a/chrome/browser/ui/autofill/mock_autofill_dialog_controller.h b/chrome/browser/ui/autofill/mock_autofill_dialog_controller.h
index 61a25d3..511b14b 100644
--- a/chrome/browser/ui/autofill/mock_autofill_dialog_controller.h
+++ b/chrome/browser/ui/autofill/mock_autofill_dialog_controller.h
@@ -15,76 +15,65 @@
MockAutofillDialogController();
virtual ~MockAutofillDialogController();
- virtual string16 DialogTitle() const OVERRIDE;
- virtual string16 AccountChooserText() const OVERRIDE;
- virtual string16 SignInLinkText() const OVERRIDE;
- virtual string16 EditSuggestionText() const OVERRIDE;
- virtual string16 CancelButtonText() const OVERRIDE;
- virtual string16 ConfirmButtonText() const OVERRIDE;
- virtual string16 SaveLocallyText() const OVERRIDE;
- virtual string16 LegalDocumentsText() OVERRIDE;
- virtual DialogSignedInState SignedInState() const OVERRIDE;
- virtual bool ShouldShowSpinner() const OVERRIDE;
+ MOCK_CONST_METHOD0(DialogTitle, string16());
+ MOCK_CONST_METHOD0(AccountChooserText, string16());
+ MOCK_CONST_METHOD0(SignInLinkText, string16());
+ MOCK_CONST_METHOD0(EditSuggestionText, string16());
+ MOCK_CONST_METHOD0(CancelButtonText, string16());
+ MOCK_CONST_METHOD0(ConfirmButtonText, string16());
+ MOCK_CONST_METHOD0(SaveLocallyText, string16());
+ MOCK_METHOD0(LegalDocumentsText, string16());
+ MOCK_CONST_METHOD0(SignedInState, DialogSignedInState());
+ MOCK_CONST_METHOD0(ShouldShowSpinner, bool());
MOCK_CONST_METHOD0(ShouldOfferToSaveInChrome, bool());
MOCK_METHOD0(MenuModelForAccountChooser, ui::MenuModel*());
- virtual gfx::Image AccountChooserImage() OVERRIDE;
- virtual bool ShouldShowProgressBar() const OVERRIDE;
- virtual int GetDialogButtons() const OVERRIDE;
- virtual bool ShouldShowDetailArea() const OVERRIDE;
- virtual bool IsDialogButtonEnabled(ui::DialogButton button) const OVERRIDE;
- virtual DialogOverlayState GetDialogOverlay() const OVERRIDE;
- virtual const std::vector<ui::Range>& LegalDocumentLinks() OVERRIDE;
+ MOCK_METHOD0(AccountChooserImage, gfx::Image());
+ MOCK_CONST_METHOD0(ShouldShowProgressBar, bool());
+ MOCK_CONST_METHOD0(GetDialogButtons, int());
+ MOCK_CONST_METHOD0(ShouldShowDetailArea, bool());
+ MOCK_CONST_METHOD1(IsDialogButtonEnabled, bool(ui::DialogButton button));
+ MOCK_CONST_METHOD0(GetDialogOverlay, DialogOverlayState());
+ MOCK_METHOD0(LegalDocumentLinks, const std::vector<ui::Range>&());
MOCK_CONST_METHOD1(SectionIsActive, bool(DialogSection));
MOCK_CONST_METHOD1(RequestedFieldsForSection,
const DetailInputs&(DialogSection));
MOCK_METHOD1(ComboboxModelForAutofillType,
ui::ComboboxModel*(AutofillFieldType));
MOCK_METHOD1(MenuModelForSection, ui::MenuModel*(DialogSection));
- virtual string16 LabelForSection(DialogSection section) const OVERRIDE;
- virtual SuggestionState SuggestionStateForSection(
- DialogSection section) OVERRIDE;
- virtual void EditClickedForSection(DialogSection section) OVERRIDE;
- virtual void EditCancelledForSection(DialogSection section) OVERRIDE;
- virtual gfx::Image IconForField(AutofillFieldType type,
- const string16& user_input) const OVERRIDE;
- virtual string16 InputValidityMessage(
- DialogSection section,
- AutofillFieldType type,
- const string16& value) OVERRIDE;
+ MOCK_CONST_METHOD1(LabelForSection, string16(DialogSection section));
+ MOCK_METHOD1(SuggestionStateForSection, SuggestionState(DialogSection));
+ MOCK_METHOD1(EditClickedForSection, void(DialogSection section));
+ MOCK_METHOD1(EditCancelledForSection, void(DialogSection section));
+ MOCK_CONST_METHOD2(IconForField,
+ gfx::Image(AutofillFieldType, const string16&));
+ MOCK_METHOD3(InputValidityMessage,
+ string16(DialogSection, AutofillFieldType, const string16&));
MOCK_METHOD3(InputsAreValid, ValidityData(DialogSection,
const DetailOutputMap&,
ValidationType));
- virtual void UserEditedOrActivatedInput(DialogSection section,
- const DetailInput* input,
- gfx::NativeView parent_view,
- const gfx::Rect& content_bounds,
- const string16& field_contents,
- bool was_edit) OVERRIDE;
- virtual bool HandleKeyPressEventInInput(
- const content::NativeWebKeyboardEvent& event) OVERRIDE;
-
- virtual void FocusMoved() OVERRIDE;
-
- virtual gfx::Image SplashPageImage() const OVERRIDE;
-
- virtual void ViewClosed() OVERRIDE;
-
- virtual std::vector<DialogNotification> CurrentNotifications() OVERRIDE;
-
- virtual std::vector<DialogAutocheckoutStep> CurrentAutocheckoutSteps()
- const OVERRIDE;
-
- virtual void SignInLinkClicked() OVERRIDE;
- virtual void NotificationCheckboxStateChanged(DialogNotification::Type type,
- bool checked) OVERRIDE;
-
- virtual void LegalDocumentLinkClicked(const ui::Range& range) OVERRIDE;
- virtual void OverlayButtonPressed() OVERRIDE;
- virtual void OnCancel() OVERRIDE;
- virtual void OnAccept() OVERRIDE;
-
+ MOCK_METHOD6(UserEditedOrActivatedInput,void(DialogSection,
+ const DetailInput*,
+ gfx::NativeView,
+ const gfx::Rect&,
+ const string16&,
+ bool was_edit));
+ MOCK_METHOD1(HandleKeyPressEventInInput,
+ bool(const content::NativeWebKeyboardEvent& event));
+ MOCK_METHOD0(FocusMoved, void());
+ MOCK_CONST_METHOD0(SplashPageImage, gfx::Image());
+ MOCK_METHOD0(ViewClosed, void());
+ MOCK_METHOD0(CurrentNotifications,std::vector<DialogNotification>());
+ MOCK_CONST_METHOD0(CurrentAutocheckoutSteps,
+ std::vector<DialogAutocheckoutStep>());
+ MOCK_METHOD0(SignInLinkClicked, void());
+ MOCK_METHOD2(NotificationCheckboxStateChanged,
+ void(DialogNotification::Type, bool));
+ MOCK_METHOD1(LegalDocumentLinkClicked, void(const ui::Range&));
+ MOCK_METHOD0(OverlayButtonPressed, void());
+ MOCK_METHOD0(OnCancel, bool());
+ MOCK_METHOD0(OnAccept, bool());
MOCK_METHOD0(profile, Profile*());
- virtual content::WebContents* web_contents() OVERRIDE;
+ MOCK_METHOD0(web_contents, content::WebContents*());
private:
DetailInputs default_inputs_;
DetailInputs cc_default_inputs_; // Default inputs for SECTION_CC.
diff --git a/chrome/browser/ui/autofill/tab_autofill_manager_delegate.cc b/chrome/browser/ui/autofill/tab_autofill_manager_delegate.cc
index ffb4546..44603d9 100644
--- a/chrome/browser/ui/autofill/tab_autofill_manager_delegate.cc
+++ b/chrome/browser/ui/autofill/tab_autofill_manager_delegate.cc
@@ -20,6 +20,7 @@
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/chrome_pages.h"
#include "chrome/common/url_constants.h"
+#include "components/autofill/content/browser/autofill_driver_impl.h"
#include "components/autofill/core/common/autofill_pref_names.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h"
@@ -167,6 +168,13 @@
popup_controller_->Show(values, labels, icons, identifiers);
}
+void TabAutofillManagerDelegate::UpdateAutofillPopupDataListValues(
+ const std::vector<base::string16>& values,
+ const std::vector<base::string16>& labels) {
+ if (popup_controller_.get())
+ popup_controller_->UpdateDataListValues(values, labels);
+}
+
void TabAutofillManagerDelegate::HideAutofillPopup() {
if (popup_controller_.get())
popup_controller_->Hide();
@@ -196,17 +204,23 @@
void TabAutofillManagerDelegate::DidNavigateMainFrame(
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) {
- // A redirect immediately after a successful Autocheckout flow shouldn't hide
- // the dialog.
- bool was_redirect = details.entry &&
- content::PageTransitionIsRedirect(details.entry->GetTransitionType());
- if (dialog_controller_.get() &&
- (dialog_controller_->dialog_type() == DIALOG_TYPE_REQUEST_AUTOCOMPLETE ||
- (!dialog_controller_->AutocheckoutIsRunning() && !was_redirect))) {
- HideRequestAutocompleteDialog();
- }
HideAutocheckoutBubble();
+
+ if (!dialog_controller_.get())
+ return;
+
+ // A redirect immediately after a successful Autocheckout flow shouldn't hide
+ // the dialog.
+ bool preserve_dialog = AutofillDriverImpl::FromWebContents(web_contents())->
+ autofill_manager()->autocheckout_manager()->should_preserve_dialog();
+ bool was_redirect = details.entry &&
+ content::PageTransitionIsRedirect(details.entry->GetTransitionType());
+
+ if (dialog_controller_->dialog_type() == DIALOG_TYPE_REQUEST_AUTOCOMPLETE ||
+ (!was_redirect && !preserve_dialog)) {
+ HideRequestAutocompleteDialog();
+ }
}
void TabAutofillManagerDelegate::WebContentsDestroyed(
diff --git a/chrome/browser/ui/autofill/tab_autofill_manager_delegate.h b/chrome/browser/ui/autofill/tab_autofill_manager_delegate.h
index 446721f..75879bd 100644
--- a/chrome/browser/ui/autofill/tab_autofill_manager_delegate.h
+++ b/chrome/browser/ui/autofill/tab_autofill_manager_delegate.h
@@ -69,6 +69,9 @@
const std::vector<string16>& icons,
const std::vector<int>& identifiers,
base::WeakPtr<AutofillPopupDelegate> delegate) OVERRIDE;
+ virtual void UpdateAutofillPopupDataListValues(
+ const std::vector<base::string16>& values,
+ const std::vector<base::string16>& labels) OVERRIDE;
virtual void HideAutofillPopup() OVERRIDE;
virtual bool IsAutocompleteEnabled() OVERRIDE;
diff --git a/chrome/browser/ui/blocked_content/OWNERS b/chrome/browser/ui/blocked_content/OWNERS
new file mode 100644
index 0000000..8c37c31
--- /dev/null
+++ b/chrome/browser/ui/blocked_content/OWNERS
@@ -0,0 +1,2 @@
+bauerb@chromium.org
+jochen@chromium.org
diff --git a/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
index 3c57f87..ddf8415 100644
--- a/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
+++ b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
@@ -14,6 +14,7 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
+#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_finder.h"
@@ -210,10 +211,22 @@
EXPECT_EQ(ASCIIToUTF16(search_string), model->CurrentMatch(NULL).contents);
}
-IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest, BlockWebContentsCreation) {
- CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableBetterPopupBlocking);
+class BetterPopupBlockerBrowserTest : public PopupBlockerBrowserTest {
+ public:
+ BetterPopupBlockerBrowserTest() {}
+ virtual ~BetterPopupBlockerBrowserTest() {}
+ virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+ PopupBlockerBrowserTest::SetUpCommandLine(command_line);
+ command_line->AppendSwitch(switches::kEnableBetterPopupBlocking);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BetterPopupBlockerBrowserTest);
+};
+
+IN_PROC_BROWSER_TEST_F(BetterPopupBlockerBrowserTest,
+ BlockWebContentsCreation) {
CountRenderViewHosts counter;
ui_test_utils::NavigateToURL(browser(), GetTestURL());
@@ -230,11 +243,8 @@
EXPECT_EQ(0, counter.GetRenderViewHostCreatedCount());
}
-IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
+IN_PROC_BROWSER_TEST_F(BetterPopupBlockerBrowserTest,
PopupBlockedFakeClickOnAnchorNoTarget) {
- CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableBetterPopupBlocking);
-
GURL url(ui_test_utils::GetTestUrl(
base::FilePath(kTestDir),
base::FilePath(FILE_PATH_LITERAL("popup-fake-click-on-anchor2.html"))));
@@ -253,6 +263,21 @@
// And no new RVH created.
EXPECT_EQ(0, counter.GetRenderViewHostCreatedCount());
+
+ content::WindowedNotificationObserver observer(
+ chrome::NOTIFICATION_TAB_ADDED,
+ content::NotificationService::AllSources());
+
+ // Launch the blocked popup.
+ PopupBlockerTabHelper* popup_blocker_helper =
+ PopupBlockerTabHelper::FromWebContents(web_contents);
+ EXPECT_EQ(1u, popup_blocker_helper->GetBlockedPopupsCount());
+ IDMap<chrome::NavigateParams, IDMapOwnPointer>::const_iterator iter(
+ &popup_blocker_helper->GetBlockedPopupRequests());
+ ASSERT_FALSE(iter.IsAtEnd());
+ popup_blocker_helper->ShowBlockedPopup(iter.GetCurrentKey());
+
+ observer.Wait();
}
} // namespace
diff --git a/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc b/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc
index a4ad316..41b36ff 100644
--- a/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc
+++ b/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc
@@ -90,7 +90,7 @@
return blocked_popups_.size();
}
-const IDMap<chrome::NavigateParams, IDMapOwnPointer>&
-PopupBlockerTabHelper::GetBlockedPopupRequests() const {
+IDMap<chrome::NavigateParams, IDMapOwnPointer>&
+PopupBlockerTabHelper::GetBlockedPopupRequests() {
return blocked_popups_;
}
diff --git a/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h b/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h
index 3383886..1526054 100644
--- a/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h
+++ b/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h
@@ -31,8 +31,8 @@
size_t GetBlockedPopupsCount() const;
// Returns the mapping from popup IDs to blocked popup requests.
- const IDMap<chrome::NavigateParams, IDMapOwnPointer>&
- GetBlockedPopupRequests() const;
+ IDMap<chrome::NavigateParams, IDMapOwnPointer>&
+ GetBlockedPopupRequests();
// content::WebContentsObserver overrides:
virtual void DidNavigateMainFrame(
diff --git a/chrome/browser/ui/bookmarks/bookmark_bubble_delegate.h b/chrome/browser/ui/bookmarks/bookmark_bubble_delegate.h
new file mode 100644
index 0000000..4927693
--- /dev/null
+++ b/chrome/browser/ui/bookmarks/bookmark_bubble_delegate.h
@@ -0,0 +1,14 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_BUBBLE_DELEGATE_H_
+#define CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_BUBBLE_DELEGATE_H_
+
+class BookmarkBubbleDelegate {
+ public:
+ virtual ~BookmarkBubbleDelegate() {}
+ virtual void OnSignInLinkClicked() = 0;
+};
+
+#endif // CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_BUBBLE_DELEGATE_H_
diff --git a/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.cc b/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.cc
new file mode 100644
index 0000000..9ac9c8c
--- /dev/null
+++ b/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.cc
@@ -0,0 +1,48 @@
+// Copyright 2013 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/ui/bookmarks/bookmark_bubble_sign_in_delegate.h"
+
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/chrome_pages.h"
+#include "chrome/browser/ui/sync/sync_promo_ui.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+
+BookmarkBubbleSignInDelegate::BookmarkBubbleSignInDelegate(Browser* browser)
+ : browser_(browser),
+ profile_(browser->profile()),
+ desktop_type_(browser->host_desktop_type()) {
+ BrowserList::AddObserver(this);
+}
+
+BookmarkBubbleSignInDelegate::~BookmarkBubbleSignInDelegate() {
+ BrowserList::RemoveObserver(this);
+}
+
+void BookmarkBubbleSignInDelegate::OnSignInLinkClicked() {
+ EnsureBrowser();
+ chrome::ShowBrowserSignin(browser_, SyncPromoUI::SOURCE_BOOKMARK_BUBBLE);
+ DCHECK(!browser_->tab_strip_model()->empty());
+ browser_->window()->Show();
+}
+
+void BookmarkBubbleSignInDelegate::OnBrowserRemoved(Browser* browser) {
+ if (browser == browser_)
+ browser_ = NULL;
+}
+
+void BookmarkBubbleSignInDelegate::EnsureBrowser() {
+ if (!browser_) {
+ Profile* original_profile = profile_->GetOriginalProfile();
+ browser_ = chrome::FindLastActiveWithProfile(original_profile,
+ desktop_type_);
+ if (!browser_) {
+ browser_ = new Browser(Browser::CreateParams(original_profile,
+ desktop_type_));
+ }
+ }
+}
diff --git a/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.h b/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.h
new file mode 100644
index 0000000..88e3944
--- /dev/null
+++ b/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.h
@@ -0,0 +1,48 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_BUBBLE_SIGN_IN_DELEGATE_H_
+#define CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_BUBBLE_SIGN_IN_DELEGATE_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "chrome/browser/ui/bookmarks/bookmark_bubble_delegate.h"
+#include "chrome/browser/ui/browser_list_observer.h"
+#include "chrome/browser/ui/host_desktop.h"
+
+class Browser;
+class Profile;
+
+// Delegate of the bookmark bubble to load the sign in page in a browser
+// when the sign in link is clicked.
+class BookmarkBubbleSignInDelegate : public BookmarkBubbleDelegate,
+ public chrome::BrowserListObserver {
+ public:
+ explicit BookmarkBubbleSignInDelegate(Browser* browser);
+
+ private:
+ virtual ~BookmarkBubbleSignInDelegate();
+
+ // BookmarkBubbleDelegate:
+ virtual void OnSignInLinkClicked() OVERRIDE;
+
+ // chrome::BrowserListObserver:
+ virtual void OnBrowserRemoved(Browser* browser) OVERRIDE;
+
+ // Makes sure |browser_| points to a valid browser.
+ void EnsureBrowser();
+
+ // The browser in which the sign in page must be loaded.
+ Browser* browser_;
+
+ // The profile associated with |browser_|.
+ Profile* profile_;
+
+ // The host desktop of |browser_|.
+ chrome::HostDesktopType desktop_type_;
+
+ DISALLOW_COPY_AND_ASSIGN(BookmarkBubbleSignInDelegate);
+};
+
+#endif // CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_BUBBLE_SIGN_IN_DELEGATE_H_
diff --git a/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate_unittest.cc b/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate_unittest.cc
new file mode 100644
index 0000000..f15b007
--- /dev/null
+++ b/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate_unittest.cc
@@ -0,0 +1,62 @@
+// Copyright 2013 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/ui/bookmarks/bookmark_bubble_sign_in_delegate.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/ui/bookmarks/bookmark_bubble_delegate.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/test/base/browser_with_test_window_test.h"
+#include "ui/base/events/event_constants.h"
+#include "ui/base/range/range.h"
+
+typedef BrowserWithTestWindowTest BookmarkBubbleSignInDelegateTest;
+
+TEST_F(BookmarkBubbleSignInDelegateTest, OnSignInLinkClicked) {
+ int starting_tab_count = browser()->tab_strip_model()->count();
+
+ scoped_ptr<BookmarkBubbleDelegate> delegate;
+ delegate.reset(new BookmarkBubbleSignInDelegate(browser()));
+
+ delegate->OnSignInLinkClicked();
+
+ // A new tab should have been opened.
+ int tab_count = browser()->tab_strip_model()->count();
+ EXPECT_EQ(starting_tab_count + 1, tab_count);
+}
+
+// Verifies that the sign in page can be loaded in a different browser
+// if the provided browser is invalidated.
+TEST_F(BookmarkBubbleSignInDelegateTest, BrowserRemoved) {
+ // Create an extra browser.
+ scoped_ptr<BrowserWindow> extra_window;
+ extra_window.reset(CreateBrowserWindow());
+
+ Browser::CreateParams params(browser()->profile(),
+ browser()->host_desktop_type());
+ params.window = extra_window.get();
+ scoped_ptr<Browser> extra_browser;
+ extra_browser.reset(new Browser(params));
+
+ int starting_tab_count = extra_browser->tab_strip_model()->count();
+
+ scoped_ptr<BookmarkBubbleDelegate> delegate;
+ delegate.reset(new BookmarkBubbleSignInDelegate(browser()));
+
+ BrowserList::SetLastActive(extra_browser.get());
+
+ browser()->tab_strip_model()->CloseAllTabs();
+ set_browser(NULL);
+
+ delegate->OnSignInLinkClicked();
+
+ // A new tab should have been opened in the extra browser.
+ int tab_count = extra_browser->tab_strip_model()->count();
+ EXPECT_EQ(starting_tab_count + 1, tab_count);
+
+ // Required to avoid a crash when the browser is deleted.
+ extra_browser->tab_strip_model()->CloseAllTabs();
+}
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index aa2e18f..bd0799f 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -89,6 +89,7 @@
#include "chrome/browser/themes/theme_service_factory.h"
#include "chrome/browser/ui/app_modal_dialogs/javascript_dialog_manager.h"
#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
+#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h"
#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
#include "chrome/browser/ui/browser_command_controller.h"
#include "chrome/browser/ui/browser_commands.h"
@@ -165,10 +166,10 @@
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
-#include "content/public/common/content_restriction.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/page_zoom.h"
#include "content/public/common/renderer_preferences.h"
+#include "content/public/common/webplugininfo.h"
#include "extensions/common/constants.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
@@ -182,7 +183,6 @@
#include "ui/base/window_open_disposition.h"
#include "ui/gfx/point.h"
#include "ui/shell_dialogs/selected_file_info.h"
-#include "webkit/plugins/webplugininfo.h"
#if defined(OS_WIN)
#include "base/win/metro.h"
@@ -678,9 +678,6 @@
DCHECK(num_downloads_blocking);
*num_downloads_blocking = 0;
- if (IsAttemptingToCloseBrowser())
- return DOWNLOAD_CLOSE_OK;
-
// If we're not running a full browser process with a profile manager
// (testing), it's ok to close the browser.
if (!g_browser_process->profile_manager())
@@ -719,7 +716,8 @@
// those downloads would be cancelled by our window (-> profile) close.
DownloadService* download_service =
DownloadServiceFactory::GetForProfile(profile());
- if (profile_window_count == 0 && download_service->DownloadCount() > 0 &&
+ if ((profile_window_count == 0) &&
+ (download_service->DownloadCount() > 0) &&
profile()->IsOffTheRecord()) {
*num_downloads_blocking = download_service->DownloadCount();
return DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE;
@@ -1272,26 +1270,21 @@
nav_params.window_action = chrome::NavigateParams::SHOW_WINDOW;
nav_params.user_gesture = params.user_gesture;
- BlockedContentTabHelper* blocked_content_helper = NULL;
+ PopupBlockerTabHelper* popup_blocker_helper = NULL;
if (source)
- blocked_content_helper = BlockedContentTabHelper::FromWebContents(source);
+ popup_blocker_helper = PopupBlockerTabHelper::FromWebContents(source);
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBetterPopupBlocking) &&
- blocked_content_helper) {
-
- if (blocked_content_helper->all_contents_blocked()) {
- // TODO(jochen): store information about the blocked pop-up in the
- // helper.
- return NULL;
- }
+ popup_blocker_helper) {
if ((params.disposition == NEW_POPUP ||
params.disposition == NEW_FOREGROUND_TAB ||
params.disposition == NEW_BACKGROUND_TAB) &&
!params.user_gesture && !CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisablePopupBlocking)) {
- return NULL;
+ if (popup_blocker_helper->MaybeBlockPopup(nav_params))
+ return NULL;
}
}
@@ -1501,21 +1494,25 @@
return true;
}
- BlockedContentTabHelper* blocked_content_helper =
- BlockedContentTabHelper::FromWebContents(web_contents);
- if (!blocked_content_helper)
+ PopupBlockerTabHelper* popup_blocker_helper =
+ PopupBlockerTabHelper::FromWebContents(web_contents);
+ if (!popup_blocker_helper)
return true;
- if (blocked_content_helper->all_contents_blocked()) {
- // TODO(jochen): store information about the blocked pop-up in the helper.
- return false;
- }
-
if ((disposition == NEW_POPUP || disposition == NEW_FOREGROUND_TAB ||
disposition == NEW_BACKGROUND_TAB) && !user_gesture &&
!CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisablePopupBlocking)) {
- return false;
+ chrome::NavigateParams nav_params(
+ this, target_url, content::PAGE_TRANSITION_LINK);
+ // TODO(jochen): route missing information to here:
+ // referrer, extra_headers, override_encoding
+ nav_params.source_contents = web_contents;
+ nav_params.tabstrip_add_types = TabStripModel::ADD_NONE;
+ nav_params.window_action = chrome::NavigateParams::SHOW_WINDOW;
+ nav_params.user_gesture = user_gesture;
+
+ return !popup_blocker_helper->MaybeBlockPopup(nav_params);
}
return true;
@@ -1545,10 +1542,6 @@
content::Details<RetargetingDetails>(&details));
}
-void Browser::ContentRestrictionsChanged(WebContents* source) {
- command_controller_->ContentRestrictionsChanged();
-}
-
void Browser::RendererUnresponsive(WebContents* source) {
// Ignore hangs if a tab is blocked.
int index = tab_strip_model_->GetIndexOfWebContents(source);
@@ -2211,8 +2204,7 @@
// permission as that is checked in RenderMessageFilter when the CreateWindow
// message is processed.
const Extension* extension =
- extensions_service->extensions()->GetHostedAppByURL(
- ExtensionURLInfo(opener_url));
+ extensions_service->extensions()->GetHostedAppByURL(opener_url);
if (!extension)
return false;
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index af74dbb..61be1dd 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -573,8 +573,6 @@
const string16& frame_name,
const GURL& target_url,
content::WebContents* new_contents) OVERRIDE;
- virtual void ContentRestrictionsChanged(
- content::WebContents* source) OVERRIDE;
virtual void RendererUnresponsive(content::WebContents* source) OVERRIDE;
virtual void RendererResponsive(content::WebContents* source) OVERRIDE;
virtual void WorkerCrashed(content::WebContents* source) OVERRIDE;
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc
index 4603fbd..b2686af 100644
--- a/chrome/browser/ui/browser_browsertest.cc
+++ b/chrome/browser/ui/browser_browsertest.cc
@@ -86,6 +86,10 @@
#include "chrome/browser/browser_process.h"
#endif
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "base/win/windows_version.h"
+#endif
+
using content::InterstitialPage;
using content::HostZoomMap;
using content::NavigationController;
@@ -1949,6 +1953,12 @@
};
IN_PROC_BROWSER_TEST_F(AppModeTest, EnableAppModeTest) {
+#if defined(OS_WIN) && defined(USE_ASH)
+ // Disable this test in Metro+Ash for now (http://crbug.com/262796).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return;
+#endif
+
// Test that an application browser window loads correctly.
// Verify the browser is in application mode.
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc
index 54b8ecc..8726534 100644
--- a/chrome/browser/ui/browser_command_controller.cc
+++ b/chrome/browser/ui/browser_command_controller.cc
@@ -27,6 +27,7 @@
#include "chrome/browser/ui/sync/sync_promo_ui.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/tabs/tab_strip_model_utils.h"
+#include "chrome/common/content_restriction.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/profiling.h"
#include "content/public/browser/native_web_keyboard_event.h"
@@ -35,7 +36,6 @@
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
-#include "content/public/common/content_restriction.h"
#include "content/public/common/url_constants.h"
#include "ui/base/keycodes/keyboard_codes.h"
@@ -1042,11 +1042,11 @@
int restrictions = GetContentRestrictions(browser_);
command_updater_.UpdateCommandEnabled(
- IDC_COPY, !(restrictions & content::CONTENT_RESTRICTION_COPY));
+ IDC_COPY, !(restrictions & CONTENT_RESTRICTION_COPY));
command_updater_.UpdateCommandEnabled(
- IDC_CUT, !(restrictions & content::CONTENT_RESTRICTION_CUT));
+ IDC_CUT, !(restrictions & CONTENT_RESTRICTION_CUT));
command_updater_.UpdateCommandEnabled(
- IDC_PASTE, !(restrictions & content::CONTENT_RESTRICTION_PASTE));
+ IDC_PASTE, !(restrictions & CONTENT_RESTRICTION_PASTE));
UpdateSaveAsState();
UpdatePrintingState();
}
diff --git a/chrome/browser/ui/browser_command_controller_browsertest.cc b/chrome/browser/ui/browser_command_controller_browsertest.cc
index 1f71986..9710148 100644
--- a/chrome/browser/ui/browser_command_controller_browsertest.cc
+++ b/chrome/browser/ui/browser_command_controller_browsertest.cc
@@ -22,7 +22,7 @@
content::WebContents* web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
MockTabModalConfirmDialogDelegate* delegate =
- new MockTabModalConfirmDialogDelegate(web_contents, NULL);
+ new MockTabModalConfirmDialogDelegate(NULL);
TabModalConfirmDialog::Create(delegate, web_contents);
EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_FIND));
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc
index 22f6e1c..c083fba 100644
--- a/chrome/browser/ui/browser_commands.cc
+++ b/chrome/browser/ui/browser_commands.cc
@@ -50,12 +50,14 @@
#include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
#include "chrome/browser/ui/omnibox/location_bar.h"
#include "chrome/browser/ui/status_bubble.h"
+#include "chrome/browser/ui/tab_contents/core_tab_helper.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
#include "chrome/browser/upgrade_detector.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"
+#include "chrome/common/content_restriction.h"
#include "chrome/common/pref_names.h"
#include "components/web_modal/web_contents_modal_dialog_manager.h"
#include "content/public/browser/devtools_agent_host.h"
@@ -67,7 +69,6 @@
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
-#include "content/public/common/content_restriction.h"
#include "content/public/common/renderer_preferences.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
@@ -242,16 +243,18 @@
int content_restrictions = 0;
WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
if (current_tab) {
- content_restrictions = current_tab->GetContentRestrictions();
+ CoreTabHelper* core_tab_helper =
+ CoreTabHelper::FromWebContents(current_tab);
+ content_restrictions = core_tab_helper->content_restrictions();
NavigationEntry* active_entry =
current_tab->GetController().GetActiveEntry();
// See comment in UpdateCommandsForTabState about why we call url().
if (!content::IsSavableURL(
active_entry ? active_entry->GetURL() : GURL()) ||
current_tab->ShowingInterstitialPage())
- content_restrictions |= content::CONTENT_RESTRICTION_SAVE;
+ content_restrictions |= CONTENT_RESTRICTION_SAVE;
if (current_tab->ShowingInterstitialPage())
- content_restrictions |= content::CONTENT_RESTRICTION_PRINT;
+ content_restrictions |= CONTENT_RESTRICTION_PRINT;
}
return content_restrictions;
}
@@ -694,7 +697,7 @@
return false;
}
return !browser->is_devtools() &&
- !(GetContentRestrictions(browser) & content::CONTENT_RESTRICTION_SAVE);
+ !(GetContentRestrictions(browser) & CONTENT_RESTRICTION_SAVE);
}
void ShowFindBar(Browser* browser) {
@@ -726,7 +729,7 @@
// Do not print when a constrained window is showing. It's confusing.
return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
!(IsShowingWebContentsModalDialog(browser) ||
- GetContentRestrictions(browser) & content::CONTENT_RESTRICTION_PRINT);
+ GetContentRestrictions(browser) & CONTENT_RESTRICTION_PRINT);
}
void AdvancedPrint(Browser* browser) {
diff --git a/chrome/browser/ui/browser_commands_mac.cc b/chrome/browser/ui/browser_commands_mac.cc
index 3a18758..5b92019 100644
--- a/chrome/browser/ui/browser_commands_mac.cc
+++ b/chrome/browser/ui/browser_commands_mac.cc
@@ -4,16 +4,23 @@
#include "chrome/browser/ui/browser_commands_mac.h"
+#include "base/command_line.h"
#include "base/mac/mac_util.h"
#include "chrome/browser/fullscreen.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
+#include "chrome/common/chrome_switches.h"
namespace chrome {
void ToggleFullscreenWithChromeOrFallback(Browser* browser) {
- if (chrome::mac::SupportsSystemFullscreen())
+ // In simplified fullscreen mode, the "WithChrome" variant does not exist.
+ // Call into the standard cross-platform fullscreen method instead.
+ const CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kEnableSimplifiedFullscreen))
+ ToggleFullscreenMode(browser);
+ else if (chrome::mac::SupportsSystemFullscreen())
browser->fullscreen_controller()->ToggleFullscreenWithChrome();
else
ToggleFullscreenMode(browser);
diff --git a/chrome/browser/ui/browser_instant_controller.cc b/chrome/browser/ui/browser_instant_controller.cc
index 4adeb91..c36cad8 100644
--- a/chrome/browser/ui/browser_instant_controller.cc
+++ b/chrome/browser/ui/browser_instant_controller.cc
@@ -19,6 +19,7 @@
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/omnibox/location_bar.h"
#include "chrome/browser/ui/omnibox/omnibox_view.h"
+#include "chrome/browser/ui/search/instant_ntp.h"
#include "chrome/browser/ui/search/search_model.h"
#include "chrome/browser/ui/search/search_tab_helper.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -41,21 +42,22 @@
instant_unload_handler_(browser) {
profile_pref_registrar_.Init(profile()->GetPrefs());
profile_pref_registrar_.Add(
- prefs::kSearchSuggestEnabled,
- base::Bind(&BrowserInstantController::ResetInstant,
- base::Unretained(this)));
- profile_pref_registrar_.Add(
prefs::kDefaultSearchProviderID,
base::Bind(&BrowserInstantController::OnDefaultSearchProviderChanged,
base::Unretained(this)));
- ResetInstant(std::string());
browser_->search_model()->AddObserver(this);
- net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
+
+ InstantService* instant_service =
+ InstantServiceFactory::GetForProfile(profile());
+ instant_service->OnBrowserInstantControllerCreated();
}
BrowserInstantController::~BrowserInstantController() {
browser_->search_model()->RemoveObserver(this);
- net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
+
+ InstantService* instant_service =
+ InstantServiceFactory::GetForProfile(profile());
+ instant_service->OnBrowserInstantControllerDestroyed();
}
bool BrowserInstantController::MaybeSwapInInstantNTPContents(
@@ -71,7 +73,10 @@
return false;
}
- scoped_ptr<content::WebContents> instant_ntp = instant_.ReleaseNTPContents();
+ InstantService* instant_service =
+ InstantServiceFactory::GetForProfile(profile());
+ scoped_ptr<content::WebContents> instant_ntp =
+ instant_service->ReleaseNTPContents();
if (!instant_ntp)
return false;
@@ -192,11 +197,6 @@
instant_.ToggleVoiceSearch();
}
-void BrowserInstantController::ResetInstant(const std::string& pref_name) {
- if (chrome::ShouldPreloadInstantNTP(profile()))
- instant_.ReloadStaleNTP();
-}
-
////////////////////////////////////////////////////////////////////////////////
// BrowserInstantController, SearchModelObserver implementation:
@@ -223,15 +223,6 @@
instant_.InstantSupportChanged(new_state.instant_support);
}
-////////////////////////////////////////////////////////////////////////////////
-// BrowserInstantController, net::NetworkChangeNotifier::NetworkChangeObserver
-// implementation:
-
-void BrowserInstantController::OnNetworkChanged(
- net::NetworkChangeNotifier::ConnectionType type) {
- instant_.OnNetworkChanged(type);
-}
-
void BrowserInstantController::OnDefaultSearchProviderChanged(
const std::string& pref_name) {
DCHECK_EQ(pref_name, std::string(prefs::kDefaultSearchProviderID));
@@ -269,5 +260,4 @@
// renderer.
contents->GetController().Reload(false);
}
- instant_.OnDefaultSearchProviderChanged();
}
diff --git a/chrome/browser/ui/browser_instant_controller.h b/chrome/browser/ui/browser_instant_controller.h
index 6f2a025..0d99aaa 100644
--- a/chrome/browser/ui/browser_instant_controller.h
+++ b/chrome/browser/ui/browser_instant_controller.h
@@ -13,7 +13,6 @@
#include "chrome/browser/ui/search/instant_controller.h"
#include "chrome/browser/ui/search/instant_unload_handler.h"
#include "chrome/browser/ui/search/search_model_observer.h"
-#include "net/base/network_change_notifier.h"
#include "ui/base/window_open_disposition.h"
class Browser;
@@ -28,9 +27,7 @@
class Rect;
}
-class BrowserInstantController
- : public SearchModelObserver,
- public net::NetworkChangeNotifier::NetworkChangeObserver {
+class BrowserInstantController : public SearchModelObserver {
public:
explicit BrowserInstantController(Browser* browser);
virtual ~BrowserInstantController();
@@ -83,10 +80,6 @@
void ToggleVoiceSearch();
private:
- // Sets the value of |instant_| based on value from profile. Invoked
- // on pref change.
- void ResetInstant(const std::string& pref_name);
-
// Overridden from search::SearchModelObserver:
virtual void ModelChanged(const SearchModel::State& old_state,
const SearchModel::State& new_state) OVERRIDE;
@@ -97,10 +90,6 @@
// ensures that they are reloaded in a non-privileged renderer process.
void OnDefaultSearchProviderChanged(const std::string& pref_name);
- // Overridden from net::NetworkChangeNotifier::NetworkChangeObserver:
- virtual void OnNetworkChanged(net::NetworkChangeNotifier::ConnectionType type)
- OVERRIDE;
-
// Replaces the contents at tab |index| with |new_contents| and deletes the
// existing contents.
void ReplaceWebContentsAt(int index,
diff --git a/chrome/browser/ui/browser_navigator.cc b/chrome/browser/ui/browser_navigator.cc
index f71625e..5619112 100644
--- a/chrome/browser/ui/browser_navigator.cc
+++ b/chrome/browser/ui/browser_navigator.cc
@@ -247,7 +247,8 @@
load_url_params.referrer = params->referrer;
load_url_params.transition_type = params->transition;
load_url_params.extra_headers = params->extra_headers;
- load_url_params.is_cross_site_redirect = params->is_cross_site_redirect;
+ load_url_params.should_replace_current_entry =
+ params->should_replace_current_entry;
if (params->transferred_global_request_id != GlobalRequestID()) {
load_url_params.is_renderer_initiated = params->is_renderer_initiated;
@@ -392,7 +393,7 @@
browser(a_browser),
initiating_profile(NULL),
host_desktop_type(GetHostDesktop(a_browser)),
- is_cross_site_redirect(false) {
+ should_replace_current_entry(false) {
}
NavigateParams::NavigateParams(Browser* a_browser,
@@ -411,7 +412,7 @@
browser(a_browser),
initiating_profile(NULL),
host_desktop_type(GetHostDesktop(a_browser)),
- is_cross_site_redirect(false) {
+ should_replace_current_entry(false) {
}
NavigateParams::NavigateParams(Profile* a_profile,
@@ -432,7 +433,7 @@
browser(NULL),
initiating_profile(a_profile),
host_desktop_type(chrome::GetActiveDesktop()),
- is_cross_site_redirect(false) {
+ should_replace_current_entry(false) {
}
NavigateParams::~NavigateParams() {}
@@ -446,7 +447,8 @@
nav_params->is_renderer_initiated = params.is_renderer_initiated;
nav_params->transferred_global_request_id =
params.transferred_global_request_id;
- nav_params->is_cross_site_redirect = params.is_cross_site_redirect;
+ nav_params->should_replace_current_entry =
+ params.should_replace_current_entry;
}
void Navigate(NavigateParams* params) {
diff --git a/chrome/browser/ui/browser_navigator.h b/chrome/browser/ui/browser_navigator.h
index 5fbfb8b..1ba38fb 100644
--- a/chrome/browser/ui/browser_navigator.h
+++ b/chrome/browser/ui/browser_navigator.h
@@ -208,9 +208,9 @@
// explicitly or inferred from an existing Browser instance.
chrome::HostDesktopType host_desktop_type;
- // Indicates whether this navigation involves a cross-process redirect,
- // in which case it should replace the current navigation entry.
- bool is_cross_site_redirect;
+ // Indicates whether this navigation should replace the current
+ // navigation entry.
+ bool should_replace_current_entry;
private:
NavigateParams();
diff --git a/chrome/browser/ui/browser_tabrestore.cc b/chrome/browser/ui/browser_tabrestore.cc
index a949fc5..9bb737a 100644
--- a/chrome/browser/ui/browser_tabrestore.cc
+++ b/chrome/browser/ui/browser_tabrestore.cc
@@ -14,6 +14,7 @@
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/session_storage_namespace.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
@@ -44,6 +45,13 @@
content::SessionStorageNamespace* session_storage_namespace,
const std::string& user_agent_override) {
GURL restore_url = navigations.at(selected_navigation).virtual_url();
+ // TODO(ajwong): Remove the temporary session_storage_namespace_map when
+ // we teach session restore to understand that one tab can have multiple
+ // SessionStorageNamespace objects. Also remove the
+ // session_storage_namespace.h include since we only need that to assign
+ // into the map.
+ content::SessionStorageNamespaceMap session_storage_namespace_map;
+ session_storage_namespace_map[std::string()] = session_storage_namespace;
WebContents::CreateParams create_params(
browser->profile(),
tab_util::GetSiteInstanceForNewTab(browser->profile(), restore_url));
@@ -55,7 +63,7 @@
}
WebContents* web_contents = content::WebContents::CreateWithSessionStorage(
create_params,
- session_storage_namespace);
+ session_storage_namespace_map);
extensions::TabHelper::CreateForWebContents(web_contents);
extensions::TabHelper::FromWebContents(web_contents)->
SetExtensionAppById(extension_app_id);
diff --git a/chrome/browser/ui/browser_tabstrip.cc b/chrome/browser/ui/browser_tabstrip.cc
index 9ffa615..38d33e5 100644
--- a/chrome/browser/ui/browser_tabstrip.cc
+++ b/chrome/browser/ui/browser_tabstrip.cc
@@ -76,7 +76,9 @@
if ((disposition == NEW_POPUP || disposition == NEW_FOREGROUND_TAB ||
disposition == NEW_BACKGROUND_TAB) && !user_gesture &&
!CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisablePopupBlocking)) {
+ switches::kDisablePopupBlocking) &&
+ !CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBetterPopupBlocking)) {
// Unrequested popups from normal pages are constrained unless they're in
// the white list. The popup owner will handle checking this.
source_blocked_content->AddPopup(
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_details_container.h b/chrome/browser/ui/cocoa/autofill/autofill_details_container.h
index 5748080..9602169 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_details_container.h
+++ b/chrome/browser/ui/cocoa/autofill/autofill_details_container.h
@@ -24,6 +24,9 @@
: NSViewController<AutofillLayout,
AutofillValidationDisplay> {
@private
+ // Scroll view containing all detail sections.
+ base::scoped_nsobject<NSScrollView> scrollView_;
+
// The individual detail sections.
base::scoped_nsobject<NSMutableArray> details_;
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_details_container.mm b/chrome/browser/ui/cocoa/autofill/autofill_details_container.mm
index f2ce365..1b0de2c 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_details_container.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_details_container.mm
@@ -50,9 +50,17 @@
[self addSection:autofill::SECTION_CC_BILLING];
[self addSection:autofill::SECTION_SHIPPING];
- [self setView:[[NSView alloc] init]];
+ scrollView_.reset([[NSScrollView alloc] initWithFrame:NSZeroRect]);
+ [scrollView_ setHasVerticalScroller:YES];
+ [scrollView_ setHasHorizontalScroller:NO];
+ [scrollView_ setBorderType:NSNoBorder];
+ [scrollView_ setAutohidesScrollers:YES];
+ [self setView:scrollView_];
+
+ [scrollView_ setDocumentView:[[NSView alloc] initWithFrame:NSZeroRect]];
+
for (AutofillSectionContainer* container in details_.get())
- [[self view] addSubview:[container view]];
+ [[scrollView_ documentView] addSubview:[container view]];
infoBubble_.reset([[InfoBubbleView alloc] initWithFrame:NSZeroRect]);
[infoBubble_ setBackgroundColor:
@@ -67,7 +75,7 @@
[label setDrawsBackground:NO];
[infoBubble_ addSubview:label];
- [[self view] addSubview:infoBubble_];
+ [[scrollView_ documentView] addSubview:infoBubble_];
[self performLayout];
}
@@ -93,7 +101,7 @@
}
}
- [[self view] setFrameSize:[self preferredSize]];
+ [[scrollView_ documentView] setFrameSize:[self preferredSize]];
}
- (AutofillSectionContainer*)sectionForId:(autofill::DialogSection)section {
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_details_container_unittest.mm b/chrome/browser/ui/cocoa/autofill/autofill_details_container_unittest.mm
index e003752..2f4d176 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_details_container_unittest.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_details_container_unittest.mm
@@ -32,7 +32,10 @@
TEST_VIEW(AutofillDetailsContainerTest, [container_ view])
TEST_F(AutofillDetailsContainerTest, BasicProperties) {
+ EXPECT_TRUE([[container_ view] isKindOfClass:[NSScrollView class]]);
EXPECT_GT([[[container_ view] subviews] count], 0U);
+
+ [[container_ view] setFrameSize:[container_ preferredSize]];
EXPECT_GT(NSHeight([[container_ view] frame]), 0);
EXPECT_GT(NSWidth([[container_ view] frame]), 0);
}
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm b/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm
index 6ac323b..8e59102 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm
@@ -12,12 +12,15 @@
#include "chrome/browser/ui/chrome_style.h"
#import "chrome/browser/ui/cocoa/autofill/autofill_account_chooser.h"
#import "chrome/browser/ui/cocoa/autofill/autofill_details_container.h"
+#include "chrome/browser/ui/cocoa/autofill/autofill_dialog_constants.h"
#import "chrome/browser/ui/cocoa/autofill/autofill_main_container.h"
#import "chrome/browser/ui/cocoa/autofill/autofill_section_container.h"
#import "chrome/browser/ui/cocoa/autofill/autofill_sign_in_container.h"
#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h"
#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.h"
#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_window.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_view.h"
#import "ui/base/cocoa/flipped_view.h"
#include "ui/base/cocoa/window_size_constants.h"
@@ -54,6 +57,7 @@
initWithCustomWindow:[sheet_controller_ window]]);
constrained_window_.reset(
new ConstrainedWindowMac(this, controller_->web_contents(), sheet));
+ constrained_window_->SetPreventCloseOnLoadStart(true);
}
void AutofillDialogCocoa::Hide() {
@@ -180,6 +184,13 @@
#pragma mark Window Controller
+@interface AutofillDialogWindowController ()
+
+// Notification that the WebContent's view frame has changed.
+- (void)onContentViewFrameDidChange:(NSNotification*)notification;
+
+@end
+
@implementation AutofillDialogWindowController
- (id)initWithWebContents:(content::WebContents*)webContents
@@ -235,10 +246,29 @@
chrome_style::kClientBottomPadding +
chrome_style::kTitleTopPadding;
[self performLayout];
+
+ // Resizing the browser causes the ConstrainedWindow to move.
+ // Observe that to allow resizes based on browser size.
+ NSView* contentView = [[self window] contentView];
+ [contentView setPostsFrameChangedNotifications:YES];
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(onContentViewFrameDidChange:)
+ name:NSWindowDidMoveNotification
+ object:[self window]];
}
return self;
}
+- (void)dealloc {
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+ [super dealloc];
+}
+
+- (void)onContentViewFrameDidChange:(NSNotification*)notification {
+ [self performLayout];
+}
+
- (void)requestRelayout {
[self performLayout];
}
@@ -252,10 +282,21 @@
NSSize headerSize = NSMakeSize(contentSize.width, kAccountChooserHeight);
NSSize size = NSMakeSize(
std::max(contentSize.width, headerSize.width),
- contentSize.height + headerSize.height + kRelatedControlVerticalSpacing);
+ contentSize.height + headerSize.height + kDetailTopPadding);
size.width += 2 * chrome_style::kHorizontalPadding;
size.height += chrome_style::kClientBottomPadding +
chrome_style::kTitleTopPadding;
+
+ // Show as much of the main view as is possible without going past the
+ // bottom of the browser window.
+ NSRect dialogFrameRect = [[self window] frame];
+ NSRect browserFrameRect =
+ [webContents_->GetView()->GetTopLevelNativeWindow() frame];
+ dialogFrameRect.size.height =
+ NSMaxY(dialogFrameRect) - NSMinY(browserFrameRect);
+ dialogFrameRect = [[self window] contentRectForFrameRect:dialogFrameRect];
+ size.height = std::min(NSHeight(dialogFrameRect), size.height);
+
return size;
}
@@ -268,9 +309,11 @@
clientRect.size.height -= chrome_style::kTitleTopPadding +
chrome_style::kClientBottomPadding;
- NSRect headerRect, mainRect;
+ NSRect headerRect, mainRect, dummyRect;
NSDivideRect(clientRect, &headerRect, &mainRect,
kAccountChooserHeight, NSMinYEdge);
+ NSDivideRect(mainRect, &dummyRect, &mainRect,
+ kDetailTopPadding, NSMinYEdge);
[accountChooser_ setFrame:headerRect];
if ([[signInContainer_ view] isHidden]) {
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_dialog_constants.h b/chrome/browser/ui/cocoa/autofill/autofill_dialog_constants.h
index b5d1ba3..98614e9 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_dialog_constants.h
+++ b/chrome/browser/ui/cocoa/autofill/autofill_dialog_constants.h
@@ -25,6 +25,12 @@
// Vertical spacing between legal text and details section.
const int kVerticalSpacing = 8;
+// Padding between top bar and details section.
+const int kDetailTopPadding = 20;
+
+// Padding between the bottom of the details section and the button strip.
+const int kDetailBottomPadding = 30;
+
} // namespace
#endif // CHROME_BROWSER_UI_COCOA_AUTOFILL_AUTOFILL_DIALOG_CONSTANTS__H_
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_main_container.mm b/chrome/browser/ui/cocoa/autofill/autofill_main_container.mm
index 4a9492a..7467810 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_main_container.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_main_container.mm
@@ -104,6 +104,7 @@
NSSize size = NSMakeSize(std::max(buttonSize.width, detailsSize.width),
buttonSize.height + detailsSize.height);
+ size.height += kDetailBottomPadding;
if (![legalDocumentsView_ isHidden]) {
NSSize legalDocumentSize =
@@ -118,12 +119,12 @@
}
- (void)performLayout {
- NSSize preferredContainerSize = [self preferredSize];
+ NSRect bounds = [[self view] bounds];
CGFloat currentY = 0.0;
if (![legalDocumentsView_ isHidden]) {
[legalDocumentsView_ setFrameSize:
- [self preferredLegalDocumentSizeForWidth:preferredContainerSize.width]];
+ [self preferredLegalDocumentSizeForWidth:NSWidth(bounds)]];
currentY = NSMaxY([legalDocumentsView_ frame]) + kVerticalSpacing;
}
@@ -135,15 +136,23 @@
checkboxFrame.origin.y = NSMidY(buttonFrame) - NSHeight(checkboxFrame) / 2.0;
[saveInChromeCheckbox_ setFrameOrigin:checkboxFrame.origin];
- [detailsContainer_ performLayout];
- NSRect containerFrame = [[detailsContainer_ view] frame];
- containerFrame.origin.y = NSMaxY(buttonFrame);
- [[detailsContainer_ view] setFrameOrigin:containerFrame.origin];
+ currentY = NSMaxY(buttonFrame) + kDetailBottomPadding;
- NSRect notificationFrame;
- notificationFrame.origin = NSMakePoint(0, NSMaxY(containerFrame));
+ NSRect notificationFrame = NSZeroRect;
notificationFrame.size = [notificationContainer_ preferredSizeForWidth:
- preferredContainerSize.width];
+ NSWidth(bounds)];
+
+ // Buttons/checkbox/legal take up lower part of view, notifications the
+ // upper part. Adjust the detailsContainer to take up the remainder.
+ CGFloat remainingHeight =
+ NSHeight(bounds) - currentY - NSHeight(notificationFrame);
+ NSRect containerFrame =
+ NSMakeRect(0, currentY, NSWidth(bounds), remainingHeight);
+ [[detailsContainer_ view] setFrame:containerFrame];
+ [detailsContainer_ performLayout];
+
+ notificationFrame.origin =
+ NSMakePoint(0, NSMaxY(containerFrame) + kDetailTopPadding);
[[notificationContainer_ view] setFrame:notificationFrame];
[notificationContainer_ performLayout];
}
diff --git a/chrome/browser/ui/cocoa/autofill/autofill_main_container_unittest.mm b/chrome/browser/ui/cocoa/autofill/autofill_main_container_unittest.mm
index 66ca163..4fd79fb 100644
--- a/chrome/browser/ui/cocoa/autofill/autofill_main_container_unittest.mm
+++ b/chrome/browser/ui/cocoa/autofill/autofill_main_container_unittest.mm
@@ -42,7 +42,9 @@
EXPECT_EQ(5U, [[[container_ view] subviews] count]);
for (NSView* view in [[container_ view] subviews]) {
NSArray* subviews = [view subviews];
- if ([subviews count] == 2) {
+ if ([view isKindOfClass:[NSScrollView class]]) {
+ hasDetailsContainer = true;
+ } else if ([subviews count] == 2) {
EXPECT_TRUE(
[[subviews objectAtIndex:0] isKindOfClass:[NSButton class]]);
EXPECT_TRUE(
@@ -50,10 +52,6 @@
hasButtons = true;
} else if ([view isKindOfClass:[NSTextView class]]) {
hasTextView = true;
- } else if ([subviews count] > 0 &&
- [[subviews objectAtIndex:0] isKindOfClass:
- [AutofillSectionView class]]) {
- hasDetailsContainer = true;
} else if ([view isKindOfClass:[NSButton class]] &&
view == [container_ saveInChromeCheckboxForTesting]) {
hasCheckbox = true;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.mm
index 096e376..3a7cef4 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.mm
@@ -46,7 +46,8 @@
[controller_ isAnimatingFromState:BookmarkBar::DETACHED]) {
[self drawAsDetachedBubble];
} else {
- NSPoint phase = [[self window] themePatternPhase];
+ NSPoint phase = [[self window]
+ themePatternPhaseForAlignment:THEME_PATTERN_ALIGN_WITH_TAB_STRIP];
[[NSGraphicsContext currentContext] cr_setPatternPhase:phase forView:self];
[self drawBackgroundWithOpaque:YES];
}
@@ -76,7 +77,9 @@
CGContextRef cgContext = static_cast<CGContextRef>([context graphicsPort]);
CGContextSetAlpha(cgContext, 1 - morph);
CGContextBeginTransparencyLayer(cgContext, NULL);
- [context cr_setPatternPhase:[[self window] themePatternPhase] forView:self];
+ NSPoint phase = [[self window]
+ themePatternPhaseForAlignment:THEME_PATTERN_ALIGN_WITH_TAB_STRIP];
+ [context cr_setPatternPhase:phase forView:self];
[self drawBackgroundWithOpaque:YES];
CGContextEndTransparencyLayer(cgContext);
}
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h
index c28fd50..3375361 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h
@@ -4,6 +4,7 @@
#import <Cocoa/Cocoa.h>
+#include "base/mac/scoped_nsobject.h"
#include "base/memory/scoped_ptr.h"
#import "chrome/browser/ui/cocoa/base_bubble_controller.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h"
@@ -11,6 +12,7 @@
class BookmarkModel;
class BookmarkNode;
@class BookmarkBubbleController;
+@class BookmarkSyncPromoController;
// Controller for the bookmark bubble. The bookmark bubble is a
// bubble that pops up when clicking on the STAR next to the URL to
@@ -30,9 +32,13 @@
// Ping me when the bookmark model changes out from under us.
scoped_ptr<BookmarkModelObserverForCocoa> bookmarkObserver_;
+ // Sync promo controller, if the sync promo is displayed.
+ base::scoped_nsobject<BookmarkSyncPromoController> syncPromoController_;
+
IBOutlet NSTextField* bigTitle_; // "Bookmark" or "Bookmark Added!"
IBOutlet NSTextField* nameTextField_;
IBOutlet NSPopUpButton* folderPopUpButton_;
+ IBOutlet NSView* syncPromoPlaceholder_;
}
@property(readonly, nonatomic) const BookmarkNode* node;
@@ -62,6 +68,9 @@
// Exposed only for unit testing.
@interface BookmarkBubbleController (ExposedForUnitTesting)
+
+@property(nonatomic, readonly) NSView* syncPromoPlaceholder;
+
- (void)addFolderNodes:(const BookmarkNode*)parent
toPopUpButton:(NSPopUpButton*)button
indentation:(int)indentation;
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm
index b851bad..3886719 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm
@@ -4,14 +4,20 @@
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h"
+#include "base/command_line.h"
#include "base/mac/bundle_locations.h"
#include "base/mac/mac_util.h"
#include "base/strings/sys_string_conversions.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/bookmarks/bookmark_utils.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_finder.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h"
+#import "chrome/browser/ui/cocoa/bookmarks/bookmark_sync_promo_controller.h"
#import "chrome/browser/ui/cocoa/browser_window_controller.h"
#import "chrome/browser/ui/cocoa/info_bubble_view.h"
+#include "chrome/browser/ui/sync/sync_promo_ui.h"
+#include "chrome/common/chrome_switches.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_service.h"
@@ -67,6 +73,32 @@
[super awakeFromNib];
[[nameTextField_ cell] setUsesSingleLineMode:YES];
+
+ Browser* browser = chrome::FindBrowserWithWindow(self.parentWindow);
+ if (SyncPromoUI::ShouldShowSyncPromo(browser->profile()) &&
+ CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBookmarkSyncPromo)) {
+ syncPromoController_.reset(
+ [[BookmarkSyncPromoController alloc] initWithBrowser:browser]);
+ [syncPromoPlaceholder_ addSubview:[syncPromoController_ view]];
+
+ // Resize the sync promo and its placeholder.
+ NSRect syncPromoPlaceholderFrame = [syncPromoPlaceholder_ frame];
+ CGFloat syncPromoHeight = [syncPromoController_
+ preferredHeightForWidth:syncPromoPlaceholderFrame.size.width];
+ syncPromoPlaceholderFrame.size.height = syncPromoHeight;
+
+ [syncPromoPlaceholder_ setFrame:syncPromoPlaceholderFrame];
+ [[syncPromoController_ view] setFrame:syncPromoPlaceholderFrame];
+
+ // Adjust the height of the bubble so that the sync promo fits in it,
+ // except for its bottom border. The xib file hides the left and right
+ // borders of the sync promo.
+ NSRect bubbleFrame = [[self window] frame];
+ bubbleFrame.size.height +=
+ syncPromoHeight - [syncPromoController_ borderWidth];
+ [[self window] setFrame:bubbleFrame display:YES];
+ }
}
// If this is a new bookmark somewhere visible (e.g. on the bookmark
@@ -318,6 +350,10 @@
@implementation BookmarkBubbleController (ExposedForUnitTesting)
+- (NSView*)syncPromoPlaceholder {
+ return syncPromoPlaceholder_;
+}
+
+ (NSString*)chooseAnotherFolderString {
return l10n_util::GetNSStringWithFixup(
IDS_BOOKMARK_BUBBLE_CHOOSER_ANOTHER_FOLDER);
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller_unittest.mm
index 1405f7c..bd8e4ff 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller_unittest.mm
@@ -5,14 +5,20 @@
#import <Cocoa/Cocoa.h>
#include "base/basictypes.h"
+#include "base/command_line.h"
#include "base/mac/scoped_nsobject.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
+#include "chrome/browser/signin/signin_manager.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_window.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.h"
#include "chrome/browser/ui/cocoa/browser_window_controller.h"
#include "chrome/browser/ui/cocoa/cocoa_profile_test.h"
#import "chrome/browser/ui/cocoa/info_bubble_window.h"
+#include "chrome/common/chrome_switches.h"
#include "content/public/browser/notification_service.h"
#include "testing/gtest/include/gtest/gtest.h"
#import "testing/gtest_mac.h"
@@ -57,6 +63,9 @@
namespace {
+// URL of the test bookmark.
+const char kTestBookmarkURL[] = "http://www.google.com";
+
class BookmarkBubbleControllerTest : public CocoaProfileTest {
public:
static int edits_;
@@ -66,7 +75,13 @@
edits_ = 0;
}
- virtual void TearDown() {
+ virtual void SetUp() OVERRIDE {
+ CocoaProfileTest::SetUp();
+ CommandLine* command_line = CommandLine::ForCurrentProcess();
+ command_line->AppendSwitch(switches::kEnableBookmarkSyncPromo);
+ }
+
+ virtual void TearDown() OVERRIDE {
[controller_ close];
CocoaProfileTest::TearDown();
}
@@ -79,11 +94,10 @@
controller_ = nil;
}
controller_ = [[BookmarkBubbleController alloc]
- initWithParentWindow:test_window()
- model:BookmarkModelFactory::GetForProfile(
- profile())
- node:node
- alreadyBookmarked:YES];
+ initWithParentWindow:browser()->window()->GetNativeWindow()
+ model:BookmarkModelFactory::GetForProfile(profile())
+ node:node
+ alreadyBookmarked:YES];
EXPECT_TRUE([controller_ window]);
// The window must be gone or we'll fail a unit test with windows left open.
[static_cast<InfoBubbleWindow*>([controller_ window])
@@ -96,6 +110,14 @@
return BookmarkModelFactory::GetForProfile(profile());
}
+ const BookmarkNode* CreateTestBookmark() {
+ BookmarkModel* model = GetBookmarkModel();
+ return model->AddURL(model->bookmark_bar_node(),
+ 0,
+ ASCIIToUTF16("Bookie markie title"),
+ GURL(kTestBookmarkURL));
+ }
+
bool IsWindowClosing() {
return [static_cast<InfoBubbleWindow*>([controller_ window]) isClosing];
}
@@ -107,32 +129,24 @@
// Confirm basics about the bubble window (e.g. that it is inside the
// parent window)
TEST_F(BookmarkBubbleControllerTest, TestBubbleWindow) {
- BookmarkModel* model = GetBookmarkModel();
- const BookmarkNode* node = model->AddURL(model->bookmark_bar_node(),
- 0,
- ASCIIToUTF16("Bookie markie title"),
- GURL("http://www.google.com"));
+ const BookmarkNode* node = CreateTestBookmark();
BookmarkBubbleController* controller = ControllerForNode(node);
EXPECT_TRUE(controller);
NSWindow* window = [controller window];
EXPECT_TRUE(window);
- EXPECT_TRUE(NSContainsRect([test_window() frame],
+ EXPECT_TRUE(NSContainsRect([browser()->window()->GetNativeWindow() frame],
[window frame]));
}
// Test that we can handle closing the parent window
TEST_F(BookmarkBubbleControllerTest, TestClosingParentWindow) {
- BookmarkModel* model = GetBookmarkModel();
- const BookmarkNode* node = model->AddURL(model->bookmark_bar_node(),
- 0,
- ASCIIToUTF16("Bookie markie title"),
- GURL("http://www.google.com"));
+ const BookmarkNode* node = CreateTestBookmark();
BookmarkBubbleController* controller = ControllerForNode(node);
EXPECT_TRUE(controller);
NSWindow* window = [controller window];
EXPECT_TRUE(window);
base::mac::ScopedNSAutoreleasePool pool;
- [test_window() performClose:NSApp];
+ [browser()->window()->GetNativeWindow() performClose:NSApp];
}
@@ -155,10 +169,10 @@
const BookmarkNode* node4 = model->AddFolder(node2, 0, ASCIIToUTF16("sub"));
EXPECT_TRUE(node4);
const BookmarkNode* node5 = model->AddURL(node1, 0, ASCIIToUTF16("title1"),
- GURL("http://www.google.com"));
+ GURL(kTestBookmarkURL));
EXPECT_TRUE(node5);
const BookmarkNode* node6 = model->AddURL(node3, 0, ASCIIToUTF16("title2"),
- GURL("http://www.google.com"));
+ GURL(kTestBookmarkURL));
EXPECT_TRUE(node6);
const BookmarkNode* node7 = model->AddURL(
node4, 0, ASCIIToUTF16("title3"), GURL("http://www.google.com/reader"));
@@ -204,7 +218,7 @@
ASCIIToUTF16("three"));
EXPECT_TRUE(node3);
const BookmarkNode* node2_1 = model->AddURL(node2, 0, ASCIIToUTF16("title1"),
- GURL("http://www.google.com"));
+ GURL(kTestBookmarkURL));
EXPECT_TRUE(node2_1);
BookmarkBubbleController* controller = ControllerForNode(node1);
@@ -228,11 +242,7 @@
// Click on edit; bubble gets closed.
TEST_F(BookmarkBubbleControllerTest, TestEdit) {
- BookmarkModel* model = GetBookmarkModel();
- const BookmarkNode* node = model->AddURL(model->bookmark_bar_node(),
- 0,
- ASCIIToUTF16("Bookie markie title"),
- GURL("http://www.google.com"));
+ const BookmarkNode* node = CreateTestBookmark();
BookmarkBubbleController* controller = ControllerForNode(node);
EXPECT_TRUE(controller);
@@ -246,10 +256,7 @@
// CallClose; bubble gets closed.
// Also confirm pulse notifications get sent.
TEST_F(BookmarkBubbleControllerTest, TestClose) {
- BookmarkModel* model = GetBookmarkModel();
- const BookmarkNode* node = model->AddURL(
- model->bookmark_bar_node(), 0, ASCIIToUTF16("Bookie markie title"),
- GURL("http://www.google.com"));
+ const BookmarkNode* node = CreateTestBookmark();
EXPECT_EQ(edits_, 0);
base::scoped_nsobject<BookmarkPulseObserver> observer(
@@ -274,7 +281,7 @@
const BookmarkNode* node = model->AddURL(bookmarkBarNode,
0,
ASCIIToUTF16("short-title"),
- GURL("http://www.google.com"));
+ GURL(kTestBookmarkURL));
const BookmarkNode* grandma = model->AddFolder(bookmarkBarNode, 0,
ASCIIToUTF16("grandma"));
EXPECT_TRUE(grandma);
@@ -304,7 +311,7 @@
const BookmarkNode* node = model->AddURL(bookmarkBarNode,
0,
ASCIIToUTF16("short-title"),
- GURL("http://www.google.com"));
+ GURL(kTestBookmarkURL));
EXPECT_TRUE(node);
const BookmarkNode* folder = model->AddFolder(bookmarkBarNode, 0,
ASCIIToUTF16("NAME"));
@@ -353,28 +360,24 @@
// Click the "remove" button
TEST_F(BookmarkBubbleControllerTest, TestRemove) {
- BookmarkModel* model = GetBookmarkModel();
- GURL gurl("http://www.google.com");
- const BookmarkNode* node = model->AddURL(model->bookmark_bar_node(),
- 0,
- ASCIIToUTF16("Bookie markie title"),
- gurl);
+ const BookmarkNode* node = CreateTestBookmark();
BookmarkBubbleController* controller = ControllerForNode(node);
EXPECT_TRUE(controller);
- EXPECT_TRUE(model->IsBookmarked(gurl));
+
+ BookmarkModel* model = GetBookmarkModel();
+ EXPECT_TRUE(model->IsBookmarked(GURL(kTestBookmarkURL)));
[controller remove:controller];
- EXPECT_FALSE(model->IsBookmarked(gurl));
+ EXPECT_FALSE(model->IsBookmarked(GURL(kTestBookmarkURL)));
EXPECT_TRUE(IsWindowClosing());
}
// Confirm picking "choose another folder" caused edit: to be called.
TEST_F(BookmarkBubbleControllerTest, PopUpSelectionChanged) {
BookmarkModel* model = GetBookmarkModel();
- GURL gurl("http://www.google.com");
const BookmarkNode* node = model->AddURL(model->bookmark_bar_node(),
0, ASCIIToUTF16("super-title"),
- gurl);
+ GURL(kTestBookmarkURL));
BookmarkBubbleController* controller = ControllerForNode(node);
EXPECT_TRUE(controller);
@@ -390,38 +393,29 @@
// them pressing escape. The bookmark should not be there.
TEST_F(BookmarkBubbleControllerTest, EscapeRemovesNewBookmark) {
BookmarkModel* model = GetBookmarkModel();
- GURL gurl("http://www.google.com");
- const BookmarkNode* node = model->AddURL(model->bookmark_bar_node(),
- 0,
- ASCIIToUTF16("Bookie markie title"),
- gurl);
+ const BookmarkNode* node = CreateTestBookmark();
BookmarkBubbleController* controller =
[[BookmarkBubbleController alloc]
- initWithParentWindow:test_window()
- model:BookmarkModelFactory::GetForProfile(profile())
+ initWithParentWindow:browser()->window()->GetNativeWindow()
+ model:model
node:node
alreadyBookmarked:NO]; // The last param is the key difference.
EXPECT_TRUE([controller window]);
// Calls release on controller.
[controller cancel:nil];
- EXPECT_FALSE(model->IsBookmarked(gurl));
+ EXPECT_FALSE(model->IsBookmarked(GURL(kTestBookmarkURL)));
}
// Create a controller where the bookmark already existed prior to clicking
// the star and test that sending a cancel command doesn't change the state
// of the bookmark.
TEST_F(BookmarkBubbleControllerTest, EscapeDoesntTouchExistingBookmark) {
- BookmarkModel* model = GetBookmarkModel();
- GURL gurl("http://www.google.com");
- const BookmarkNode* node = model->AddURL(model->bookmark_bar_node(),
- 0,
- ASCIIToUTF16("Bookie markie title"),
- gurl);
+ const BookmarkNode* node = CreateTestBookmark();
BookmarkBubbleController* controller = ControllerForNode(node);
EXPECT_TRUE(controller);
[(id)controller cancel:nil];
- EXPECT_TRUE(model->IsBookmarked(gurl));
+ EXPECT_TRUE(GetBookmarkModel()->IsBookmarked(GURL(kTestBookmarkURL)));
}
// Confirm indentation of items in pop-up menu
@@ -458,6 +452,25 @@
}
}
+// Confirm that the sync promo is displayed when the user is not signed in.
+TEST_F(BookmarkBubbleControllerTest, SyncPromoNotSignedIn) {
+ const BookmarkNode* node = CreateTestBookmark();
+ BookmarkBubbleController* controller = ControllerForNode(node);
+
+ EXPECT_EQ(1u, [[controller.syncPromoPlaceholder subviews] count]);
+}
+
+// Confirm that the sync promo is not displayed when the user is signed in.
+TEST_F(BookmarkBubbleControllerTest, SyncPromoSignedIn) {
+ SigninManager* signin = SigninManagerFactory::GetForProfile(profile());
+ signin->SetAuthenticatedUsername("fake_username");
+
+ const BookmarkNode* node = CreateTestBookmark();
+ BookmarkBubbleController* controller = ControllerForNode(node);
+
+ EXPECT_EQ(0u, [[controller.syncPromoPlaceholder subviews] count]);
+}
+
} // namespace
@implementation NSApplication (BookmarkBubbleUnitTest)
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_sync_promo_controller.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_sync_promo_controller.h
new file mode 100644
index 0000000..fb4fe60
--- /dev/null
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_sync_promo_controller.h
@@ -0,0 +1,37 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_SYNC_PROMO_CONTROLLER_H_
+#define CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_SYNC_PROMO_CONTROLLER_H_
+
+#import <Cocoa/Cocoa.h>
+
+#include "base/mac/scoped_nsobject.h"
+
+class Browser;
+@class HyperlinkTextView;
+
+// Controller of the bookmark sync promo displayed at the bottom of the
+// bookmark bubble.
+@interface BookmarkSyncPromoController : NSViewController<NSTextViewDelegate> {
+ @private
+ // The browser in which the sign in page will be loaded.
+ Browser* browser_; // weak
+
+ // The text view that displays the promo message. Ownership is shared between
+ // the controller and its view.
+ base::scoped_nsobject<HyperlinkTextView> textView_;
+}
+
+@property(nonatomic, readonly) CGFloat borderWidth;
+
+- (id)initWithBrowser:(Browser*)browser;
+
+// Preferred height of the sync promo view for a given width. The border is
+// is included in the provided width and in the returned height.
+- (CGFloat)preferredHeightForWidth:(CGFloat)width;
+
+@end
+
+#endif // CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_SYNC_PROMO_CONTROLLER_H_
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_sync_promo_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_sync_promo_controller.mm
new file mode 100644
index 0000000..ce2ee47
--- /dev/null
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_sync_promo_controller.mm
@@ -0,0 +1,115 @@
+// Copyright 2013 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.
+
+#import "chrome/browser/ui/cocoa/bookmarks/bookmark_sync_promo_controller.h"
+
+#include "base/strings/sys_string_conversions.h"
+#include "chrome/browser/ui/chrome_pages.h"
+#include "chrome/browser/ui/chrome_style.h"
+#import "chrome/browser/ui/cocoa/hyperlink_text_view.h"
+#include "chrome/browser/ui/sync/sync_promo_ui.h"
+#include "grit/generated_resources.h"
+#include "skia/ext/skia_utils_mac.h"
+#include "third_party/skia/include/core/SkColor.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/l10n/l10n_util_mac.h"
+
+namespace {
+
+// Remove underlining from the specified range of characters in a text view.
+void RemoveUnderlining(NSTextView* textView, int offset, int length) {
+ [textView setLinkTextAttributes:nil];
+ NSTextStorage* text = [textView textStorage];
+ NSRange range = NSMakeRange(offset, length);
+ [text addAttribute:NSUnderlineStyleAttributeName
+ value:[NSNumber numberWithInt:NSUnderlineStyleNone]
+ range:range];
+}
+
+const SkColor kTextColor = SkColorSetRGB(0x66, 0x66, 0x66);
+const SkColor kBackgroundColor = SkColorSetRGB(0xf5, 0xf5, 0xf5);
+const SkColor kBorderColor = SkColorSetRGB(0xe5, 0xe5, 0xe5);
+
+// Vertical padding of the promo (dp).
+const CGFloat kVerticalPadding = 15;
+
+// Width of the border (dp).
+const CGFloat kBorderWidth = 1.0;
+
+// Font size of the promo text (pt).
+const int kFontSize = 11;
+
+} // namespace
+
+@implementation BookmarkSyncPromoController
+
+- (id)initWithBrowser:(Browser*)browser {
+ if ((self = [super init])) {
+ browser_ = browser;
+ }
+ return self;
+}
+
+- (CGFloat)borderWidth {
+ return kBorderWidth;
+}
+
+- (CGFloat)preferredHeightForWidth:(CGFloat)width {
+ CGFloat availableWidth =
+ width - (2 * chrome_style::kHorizontalPadding) - (2 * kBorderWidth);
+ NSRect frame = [[textView_ textStorage]
+ boundingRectWithSize:NSMakeSize(availableWidth, 0.0)
+ options:NSStringDrawingUsesLineFragmentOrigin];
+ return frame.size.height + (2 * kVerticalPadding) + (2 * kBorderWidth);
+}
+
+- (void)loadView {
+ NSBox* promoView = [[[NSBox alloc] init] autorelease];
+ [promoView setBoxType:NSBoxCustom];
+ [promoView setFillColor:gfx::SkColorToDeviceNSColor(kBackgroundColor)];
+ [promoView setContentViewMargins:NSMakeSize(chrome_style::kHorizontalPadding,
+ kVerticalPadding)];
+ [promoView setBorderType:NSLineBorder];
+ [promoView setBorderWidth:kBorderWidth];
+ [promoView setBorderColor:gfx::SkColorToDeviceNSColor(kBorderColor)];
+
+ // Add the sync promo text.
+ size_t offset;
+ const string16 linkText = l10n_util::GetStringUTF16(
+ IDS_BOOKMARK_SYNC_PROMO_LINK);
+ const string16 promoText = l10n_util::GetStringFUTF16(
+ IDS_BOOKMARK_SYNC_PROMO_MESSAGE,
+ linkText, &offset);
+ const string16 promoTextWithoutLink =
+ promoText.substr(0, offset) +
+ promoText.substr(offset + linkText.size());
+
+ NSFont* font = [NSFont labelFontOfSize:kFontSize];
+ NSColor* linkColor = gfx::SkColorToCalibratedNSColor(
+ chrome_style::GetLinkColor());
+
+ textView_.reset([[HyperlinkTextView alloc] init]);
+ [textView_ setMessageAndLink:base::SysUTF16ToNSString(promoTextWithoutLink)
+ withLink:base::SysUTF16ToNSString(linkText)
+ atOffset:offset
+ font:font
+ messageColor:gfx::SkColorToDeviceNSColor(kTextColor)
+ linkColor:linkColor];
+ [[textView_ textContainer] setLineFragmentPadding:0.0];
+ RemoveUnderlining(textView_, offset, linkText.size());
+ [textView_ setDelegate:self];
+
+ [promoView setContentView:textView_];
+
+ [self setView:promoView];
+}
+
+- (BOOL)textView:(NSTextView *)textView
+ clickedOnLink:(id)link
+ atIndex:(NSUInteger)charIndex {
+ chrome::ShowBrowserSignin(browser_, SyncPromoUI::SOURCE_BOOKMARK_BUBBLE);
+ return YES;
+}
+
+@end
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_sync_promo_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_sync_promo_controller_unittest.mm
new file mode 100644
index 0000000..3af5003
--- /dev/null
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_sync_promo_controller_unittest.mm
@@ -0,0 +1,34 @@
+// Copyright 2013 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.
+
+#import "chrome/browser/ui/cocoa/bookmarks/bookmark_sync_promo_controller.h"
+
+#import <Cocoa/Cocoa.h>
+
+#include "base/basictypes.h"
+#include "base/mac/scoped_nsobject.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/test/base/browser_with_test_window_test.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+typedef BrowserWithTestWindowTest BookmarkSyncPromoControllerTest;
+
+TEST_F(BookmarkSyncPromoControllerTest, SignInLink) {
+ int starting_tab_count = browser()->tab_strip_model()->count();
+
+ base::scoped_nsobject<BookmarkSyncPromoController> syncPromo(
+ [[BookmarkSyncPromoController alloc] initWithBrowser:browser()]);
+
+ // Simulate clicking the "Sign in" link.
+ [syncPromo textView:nil clickedOnLink:nil atIndex:0u];
+
+ // A new tab should have been opened.
+ int tab_count = browser()->tab_strip_model()->count();
+ EXPECT_EQ(starting_tab_count + 1, tab_count);
+}
+
+} // namespace
\ No newline at end of file
diff --git a/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller_unittest.mm
index 05304e8..b80a2a8 100644
--- a/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller_unittest.mm
@@ -5,6 +5,7 @@
#import "chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.h"
#include "base/mac/scoped_nsobject.h"
+#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_pump_mac.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/prefs/pref_service_syncable.h"
@@ -142,7 +143,7 @@
@interface TestingAvatarMenuItemController : AvatarMenuItemController
<NSAnimationDelegate> {
@private
- scoped_refptr<base::MessagePumpNSRunLoop> pump_;
+ scoped_ptr<base::MessagePumpNSRunLoop> pump_;
}
// After calling |-highlightForEventType:| an animation will possibly be
// started. Since the animation is non-blocking, the run loop will need to be
@@ -152,8 +153,8 @@
@implementation TestingAvatarMenuItemController
- (void)runMessagePump {
- if (!pump_.get())
- pump_ = new base::MessagePumpNSRunLoop;
+ if (!pump_)
+ pump_.reset(new base::MessagePumpNSRunLoop);
pump_->Run(NULL);
}
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
index 796d9ef..f18ab51 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
@@ -49,6 +49,7 @@
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/web_applications/web_app_ui.h"
#include "chrome/browser/web_applications/web_app.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/crash_keys.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/native_web_keyboard_event.h"
@@ -316,8 +317,8 @@
browser_->type(), browser_->app_type(),
browser_->app_name().c_str()));
base::debug::ScopedCrashKey url(crash_keys::mac::kZoomBubbleURL,
- browser_->tab_strip_model()->GetActiveWebContents()->GetActiveURL().
- possibly_invalid_spec());
+ browser_->tab_strip_model()->GetActiveWebContents()->
+ GetLastCommittedURL().possibly_invalid_spec());
[controller_ zoomChangedForActiveTab:can_show_bubble ? YES : NO];
}
@@ -370,6 +371,16 @@
void BrowserWindowCocoa::EnterFullscreen(
const GURL& url, FullscreenExitBubbleType bubble_type) {
+ // When simplified fullscreen is enabled, always enter normal fullscreen.
+ const CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kEnableSimplifiedFullscreen)) {
+ if (url.is_empty())
+ [controller_ enterFullscreen];
+ else
+ [controller_ enterFullscreenForURL:url bubbleType:bubble_type];
+ return;
+ }
+
[controller_ enterPresentationModeForURL:url
bubbleType:bubble_type];
}
@@ -621,6 +632,10 @@
}
void BrowserWindowCocoa::EnterFullscreenWithChrome() {
+ // This method cannot be called if simplified fullscreen is enabled.
+ const CommandLine* command_line = CommandLine::ForCurrentProcess();
+ DCHECK(!command_line->HasSwitch(switches::kEnableSimplifiedFullscreen));
+
CHECK(chrome::mac::SupportsSystemFullscreen());
if ([controller_ inPresentationMode])
[controller_ exitPresentationMode];
@@ -629,10 +644,20 @@
}
bool BrowserWindowCocoa::IsFullscreenWithChrome() {
+ // The WithChrome mode does not exist when simplified fullscreen is enabled.
+ const CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kEnableSimplifiedFullscreen))
+ return false;
return IsFullscreen() && ![controller_ inPresentationMode];
}
bool BrowserWindowCocoa::IsFullscreenWithoutChrome() {
+ // Presentation mode does not exist if simplified fullscreen is enabled. The
+ // WithoutChrome mode simply maps to whether or not the window is fullscreen.
+ const CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kEnableSimplifiedFullscreen))
+ return IsFullscreen();
+
return IsFullscreen() && [controller_ inPresentationMode];
}
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.h b/chrome/browser/ui/cocoa/browser_window_controller.h
index 89f7680..e0dbace 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller.h
+++ b/chrome/browser/ui/cocoa/browser_window_controller.h
@@ -311,8 +311,9 @@
// Gets the window style.
- (ThemedWindowStyle)themedWindowStyle;
-// Gets the pattern phase for the window.
-- (NSPoint)themePatternPhase;
+// Returns the pattern phase for |alignment|. If the window does not have a tab
+// strip, the phase for THEME_PATTERN_ALIGN_WITH_FRAME is always returned.
+- (NSPoint)themePatternPhaseForAlignment:(ThemePatternAlignment)alignment;
// Return the point to which a bubble window's arrow should point, in window
// coordinates.
@@ -409,6 +410,12 @@
bubbleType:(FullscreenExitBubbleType)bubbleType;
- (void)exitPresentationMode;
+// For simplified fullscreen: Enters fullscreen for a tab at a URL. The |url|
+// is guaranteed to be non-empty; see -enterFullscreen for the user-initiated
+// fullscreen mode. Called on Snow Leopard and Lion+.
+- (void)enterFullscreenForURL:(const GURL&)url
+ bubbleType:(FullscreenExitBubbleType)bubbleType;
+
// Returns presentation mode state. This method is safe to call on all OS
// versions.
- (BOOL)inPresentationMode;
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm
index b9aa9e6..bef4fa9 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller.mm
+++ b/chrome/browser/ui/cocoa/browser_window_controller.mm
@@ -1660,10 +1660,13 @@
return style;
}
-- (NSPoint)themePatternPhase {
+- (NSPoint)themePatternPhaseForAlignment:(ThemePatternAlignment)alignment {
NSView* windowChromeView = [[[self window] contentView] superview];
+ NSView* tabStripView = nil;
+ if (alignment == THEME_PATTERN_ALIGN_WITH_TAB_STRIP && [self hasTabStrip])
+ tabStripView = [self tabStripView];
return [BrowserWindowUtils themePatternPhaseFor:windowChromeView
- withTabStrip:[self tabStripView]];
+ withTabStrip:tabStripView];
}
- (NSPoint)bookmarkBubblePoint {
@@ -2010,7 +2013,7 @@
if (!chrome::IsCommandEnabled(browser_.get(), IDC_FULLSCREEN))
return;
- if (chrome::mac::SupportsSystemFullscreen()) {
+ if (chrome::mac::SupportsSystemFullscreen() && !fullscreenWindow_) {
enteredPresentationModeFromFullscreen_ = YES;
if ([[self window] isKindOfClass:[FramedBrowserWindow class]])
[static_cast<FramedBrowserWindow*>([self window]) toggleSystemFullScreen];
@@ -2034,6 +2037,7 @@
bubbleType:(FullscreenExitBubbleType)bubbleType {
fullscreenUrl_ = url;
fullscreenBubbleType_ = bubbleType;
+ [self layoutSubviews];
[self showFullscreenExitBubbleIfNecessary];
}
@@ -2115,6 +2119,16 @@
[self setPresentationMode:NO url:GURL() bubbleType:FEB_TYPE_NONE];
}
+- (void)enterFullscreenForURL:(const GURL&)url
+ bubbleType:(FullscreenExitBubbleType)bubbleType {
+ // This method may only be called in simplified fullscreen mode.
+ const CommandLine* command_line = CommandLine::ForCurrentProcess();
+ DCHECK(command_line->HasSwitch(switches::kEnableSimplifiedFullscreen));
+
+ [self enterFullscreenForSnowLeopard];
+ [self updateFullscreenExitBubbleURL:url bubbleType:bubbleType];
+}
+
- (BOOL)inPresentationMode {
return presentationModeController_.get() &&
[presentationModeController_ inPresentationMode];
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_private.mm b/chrome/browser/ui/cocoa/browser_window_controller_private.mm
index 9ff7da1..382e28a 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller_private.mm
+++ b/chrome/browser/ui/cocoa/browser_window_controller_private.mm
@@ -234,7 +234,7 @@
// If in presentation mode, reset |maxY| to top of screen, so that the
// floating bar slides over the things which appear to be in the content area.
- if (inPresentationMode)
+ if (inPresentationMode || !fullscreenUrl_.is_empty())
maxY = NSMaxY(contentBounds);
// Also place the info bar container immediate below the toolbar, except in
@@ -613,11 +613,9 @@
[self layoutSubviews];
}
+// TODO(rohitrao): This method is misnamed now, since there is a flag that
+// enables 10.6-style fullscreen on newer OSes.
- (void)enterFullscreenForSnowLeopard {
- // TODO(rohitrao): This method is misnamed now, since there is a flag that
- // enables 10.6-style fullscreen on newer OSes.
- DCHECK(!chrome::mac::SupportsSystemFullscreen());
-
// Fade to black.
const CGDisplayReservationInterval kFadeDurationSeconds = 0.6;
Boolean didFadeOut = NO;
@@ -638,8 +636,16 @@
[self moveViewsForFullscreenForSnowLeopard:YES
regularWindow:[self window]
fullscreenWindow:fullscreenWindow_.get()];
- [self adjustUIForPresentationMode:YES];
- [self setPresentationModeInternal:YES forceDropdown:NO];
+
+ // When simplified fullscreen is enabled, do not enter presentation mode.
+ const CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kEnableSimplifiedFullscreen)) {
+ // TODO(rohitrao): Add code to manage the menubar here.
+ } else {
+ [self adjustUIForPresentationMode:YES];
+ [self setPresentationModeInternal:YES forceDropdown:NO];
+ }
+
[self layoutSubviews];
[self windowDidEnterFullScreen:nil];
@@ -668,6 +674,13 @@
kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, /*synchronous=*/true);
}
+ // When simplified fullscreen is enabled, the menubar status is managed
+ // directly by BWC.
+ const CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kEnableSimplifiedFullscreen)) {
+ // TODO(rohitrao): Add code to manage the menubar here.
+ }
+
[self windowWillExitFullScreen:nil];
[self moveViewsForFullscreenForSnowLeopard:NO
diff --git a/chrome/browser/ui/cocoa/chrome_browser_window.mm b/chrome/browser/ui/cocoa/chrome_browser_window.mm
index 24e2623..9855072 100644
--- a/chrome/browser/ui/cocoa/chrome_browser_window.mm
+++ b/chrome/browser/ui/cocoa/chrome_browser_window.mm
@@ -24,11 +24,11 @@
return [delegate themedWindowStyle];
}
-- (NSPoint)themePatternPhase {
+- (NSPoint)themePatternPhaseForAlignment:(ThemePatternAlignment)alignment {
id delegate = [self delegate];
- if (![delegate respondsToSelector:@selector(themePatternPhase)])
+ if (![delegate respondsToSelector:@selector(themePatternPhaseForAlignment:)])
return NSZeroPoint;
- return [delegate themePatternPhase];
+ return [delegate themePatternPhaseForAlignment:alignment];
}
@end
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_animation_unittest.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_animation_unittest.mm
index 5ec022f..1fd2d9e 100644
--- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_animation_unittest.mm
+++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_animation_unittest.mm
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/mac/scoped_nsobject.h"
+#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_pump_mac.h"
#import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_animation.h"
@@ -12,7 +13,7 @@
<NSAnimationDelegate> {
@private
CGFloat frameCount_;
- scoped_refptr<base::MessagePumpNSRunLoop> message_pump_;
+ scoped_ptr<base::MessagePumpNSRunLoop> message_pump_;
}
- (void)runAnimation:(NSAnimation*)animation;
@@ -23,7 +24,7 @@
- (id)init {
if ((self = [super init]))
- message_pump_ = new base::MessagePumpNSRunLoop;
+ message_pump_.reset(new base::MessagePumpNSRunLoop);
return self;
}
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h
index 73202e8..6651e69 100644
--- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h
+++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h
@@ -41,6 +41,8 @@
void PulseWebContentsModalDialog();
web_modal::NativeWebContentsModalDialog GetNativeDialog();
+ void SetPreventCloseOnLoadStart(bool prevent);
+
private:
// Gets the parent window of the dialog.
NSWindow* GetParentWindow() const;
@@ -54,6 +56,9 @@
// This is true if the constrained window has been shown.
bool shown_;
+
+ // This is true while the constrained window is closing.
+ bool closing_;
};
#endif // CHROME_BROWSER_UI_COCOA_CONSTRAINED_WINDOW_CONSTRAINED_WINDOW_MAC_
diff --git a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.mm b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.mm
index df302df..a7cb5be 100644
--- a/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.mm
+++ b/chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.mm
@@ -25,7 +25,8 @@
: delegate_(delegate),
web_contents_(web_contents),
sheet_([sheet retain]),
- shown_(false) {
+ shown_(false),
+ closing_(false) {
DCHECK(web_contents);
DCHECK(sheet_.get());
WebContentsModalDialogManager* web_contents_modal_dialog_manager =
@@ -54,6 +55,10 @@
}
void ConstrainedWindowMac::CloseWebContentsModalDialog() {
+ if (closing_)
+ return;
+
+ closing_ = true;
[[ConstrainedWindowSheetController controllerForSheet:sheet_]
closeSheet:sheet_];
WebContentsModalDialogManager* web_contents_modal_dialog_manager =
@@ -78,6 +83,14 @@
return this;
}
+void ConstrainedWindowMac::SetPreventCloseOnLoadStart(bool prevent) {
+ WebContentsModalDialogManager* web_contents_modal_dialog_manager =
+ WebContentsModalDialogManager::FromWebContents(web_contents_);
+ web_contents_modal_dialog_manager->SetPreventCloseOnLoadStart(
+ GetNativeDialog(),
+ prevent);
+}
+
NSWindow* ConstrainedWindowMac::GetParentWindow() const {
// Tab contents in a tabbed browser may not be inside a window. For this
// reason use a browser window if possible.
diff --git a/chrome/browser/ui/cocoa/content_settings/cookie_details_unittest.mm b/chrome/browser/ui/cocoa/content_settings/cookie_details_unittest.mm
index ce723c9..a7761b1 100644
--- a/chrome/browser/ui/cocoa/content_settings/cookie_details_unittest.mm
+++ b/chrome/browser/ui/cocoa/content_settings/cookie_details_unittest.mm
@@ -142,7 +142,8 @@
content::IndexedDBInfo info(origin,
size,
last_modified,
- file_path);
+ file_path,
+ 0);
details.reset([[CocoaCookieDetails alloc] initWithIndexedDBInfo:&info]);
diff --git a/chrome/browser/ui/cocoa/drag_util.mm b/chrome/browser/ui/cocoa/drag_util.mm
index b991fec..2f5d596 100644
--- a/chrome/browser/ui/cocoa/drag_util.mm
+++ b/chrome/browser/ui/cocoa/drag_util.mm
@@ -8,13 +8,13 @@
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/common/url_constants.h"
+#include "content/public/common/webplugininfo.h"
#include "ipc/ipc_message.h"
#include "net/base/mime_util.h"
#include "net/base/net_util.h"
#import "third_party/mozilla/NSPasteboard+Utils.h"
#import "ui/base/dragdrop/cocoa_dnd_util.h"
#include "url/gurl.h"
-#include "webkit/plugins/webplugininfo.h"
using content::PluginService;
@@ -39,7 +39,7 @@
// TODO(bauerb): This possibly uses stale information, but it's guaranteed not
// to do disk access.
bool allow_wildcard = false;
- webkit::WebPluginInfo plugin;
+ content::WebPluginInfo plugin;
return PluginService::GetInstance()->GetPluginInfo(
-1, // process ID
MSG_ROUTING_NONE, // routing ID
diff --git a/chrome/browser/ui/cocoa/extensions/media_galleries_dialog_cocoa_unittest.mm b/chrome/browser/ui/cocoa/extensions/media_galleries_dialog_cocoa_unittest.mm
index 7217e04..1eb8fb2 100644
--- a/chrome/browser/ui/cocoa/extensions/media_galleries_dialog_cocoa_unittest.mm
+++ b/chrome/browser/ui/cocoa/extensions/media_galleries_dialog_cocoa_unittest.mm
@@ -6,7 +6,6 @@
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/media_galleries/media_galleries_dialog_controller_mock.h"
#include "chrome/browser/storage_monitor/storage_info.h"
-#include "chrome/browser/storage_monitor/test_storage_monitor.h"
#include "chrome/browser/ui/cocoa/extensions/media_galleries_dialog_cocoa.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -29,8 +28,6 @@
}
class MediaGalleriesDialogTest : public testing::Test {
- private:
- test::TestStorageMonitor test_storage_monitor_;
};
// Tests that checkboxes are initialized according to the contents of
diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_view.mm b/chrome/browser/ui/cocoa/find_bar/find_bar_view.mm
index eb7e9d5..2668046 100644
--- a/chrome/browser/ui/cocoa/find_bar/find_bar_view.mm
+++ b/chrome/browser/ui/cocoa/find_bar/find_bar_view.mm
@@ -70,7 +70,8 @@
[path addClip];
// Set the pattern phase
- NSPoint phase = [[self window] themePatternPhase];
+ NSPoint phase = [[self window]
+ themePatternPhaseForAlignment:THEME_PATTERN_ALIGN_WITH_TAB_STRIP];
[context cr_setPatternPhase:phase forView:self];
[super drawBackgroundWithOpaque:YES];
diff --git a/chrome/browser/ui/cocoa/history_overlay_controller_unittest.mm b/chrome/browser/ui/cocoa/history_overlay_controller_unittest.mm
index 96ab915..f92ccb9 100644
--- a/chrome/browser/ui/cocoa/history_overlay_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/history_overlay_controller_unittest.mm
@@ -6,7 +6,7 @@
#import <QuartzCore/QuartzCore.h>
-#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_pump_mac.h"
#import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
#import "third_party/ocmock/gtest_support.h"
@@ -53,7 +53,7 @@
[[HistoryOverlayController alloc] initForMode:kHistoryOverlayModeBack]);
[controller showPanelForView:test_view()];
- scoped_refptr<base::MessagePumpNSRunLoop> message_pump(
+ scoped_ptr<base::MessagePumpNSRunLoop> message_pump(
new base::MessagePumpNSRunLoop);
id mock = [OCMockObject partialMockForObject:controller];
@@ -61,8 +61,9 @@
[[[mock expect] andForwardToRealObject] dismiss];
// Called after |-animationDidStop:finished:|.
+ base::MessagePumpNSRunLoop* weak_message_pump = message_pump.get();
void (^quit_loop)(NSInvocation* invocation) = ^(NSInvocation* invocation) {
- message_pump->Quit();
+ weak_message_pump->Quit();
};
// Set up the mock to first forward to the real implementation and then call
// the above block to quit the run loop.
diff --git a/chrome/browser/ui/cocoa/infobars/translate_infobar_unittest.mm b/chrome/browser/ui/cocoa/infobars/translate_infobar_unittest.mm
index e5ae2a0..2c03aca 100644
--- a/chrome/browser/ui/cocoa/infobars/translate_infobar_unittest.mm
+++ b/chrome/browser/ui/cocoa/infobars/translate_infobar_unittest.mm
@@ -35,13 +35,13 @@
class MockTranslateInfoBarDelegate : public TranslateInfoBarDelegate {
public:
- MockTranslateInfoBarDelegate(TranslateInfoBarDelegate::Type type,
+ MockTranslateInfoBarDelegate(InfoBarService* infobar_service,
+ TranslateInfoBarDelegate::Type type,
TranslateErrors::Type error,
- InfoBarService* infobar_service,
PrefService* prefs,
ShortcutConfiguration config)
- : TranslateInfoBarDelegate(type, error, infobar_service, prefs,
- config, "en", "es") {
+ : TranslateInfoBarDelegate(infobar_service, type, NULL, "en", "es", error,
+ prefs, config) {
}
MOCK_METHOD0(Translate, void());
@@ -86,18 +86,12 @@
config.never_translate_min_count = 3;
config.always_translate_min_count = 3;
infobar_delegate_.reset(new MockTranslateInfoBarDelegate(
- type,
- error,
- infobar_service,
- profile->GetPrefs(),
- config));
+ infobar_service, type, error, profile->GetPrefs(), config));
[[infobar_controller_ view] removeFromSuperview];
- scoped_ptr<InfoBar> infobar(
- static_cast<InfoBarDelegate*>(infobar_delegate_.get())->
- CreateInfoBar(infobar_service));
- infobar_controller_.reset(
- reinterpret_cast<TranslateInfoBarControllerBase*>(
- infobar->controller()));
+ scoped_ptr<InfoBar> infobar(static_cast<InfoBarDelegate*>(
+ infobar_delegate_.get())->CreateInfoBar(infobar_service));
+ infobar_controller_.reset(reinterpret_cast<TranslateInfoBarControllerBase*>(
+ infobar->controller()));
// We need to set the window to be wide so that the options button
// doesn't overlap the other buttons.
[test_window() setContentSize:NSMakeSize(2000, 500)];
diff --git a/chrome/browser/ui/cocoa/keystone_infobar_delegate.mm b/chrome/browser/ui/cocoa/keystone_infobar_delegate.mm
index 4ce489c..5f04437 100644
--- a/chrome/browser/ui/cocoa/keystone_infobar_delegate.mm
+++ b/chrome/browser/ui/cocoa/keystone_infobar_delegate.mm
@@ -75,20 +75,19 @@
// static
void KeystonePromotionInfoBarDelegate::Create() {
Browser* browser = chrome::GetLastActiveBrowser();
- if (browser) {
- content::WebContents* webContents =
- browser->tab_strip_model()->GetActiveWebContents();
-
- if (webContents) {
- InfoBarService* infobar_service =
- InfoBarService::FromWebContents(webContents);
- infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
- new KeystonePromotionInfoBarDelegate(
- infobar_service,
- Profile::FromBrowserContext(
- webContents->GetBrowserContext())->GetPrefs())));
- }
- }
+ if (!browser)
+ return;
+ content::WebContents* webContents =
+ browser->tab_strip_model()->GetActiveWebContents();
+ if (!webContents)
+ return;
+ InfoBarService* infobar_service =
+ InfoBarService::FromWebContents(webContents);
+ infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
+ new KeystonePromotionInfoBarDelegate(
+ infobar_service,
+ Profile::FromBrowserContext(
+ webContents->GetBrowserContext())->GetPrefs())));
}
KeystonePromotionInfoBarDelegate::KeystonePromotionInfoBarDelegate(
diff --git a/chrome/browser/ui/cocoa/location_bar/action_box_menu_bubble_controller.h b/chrome/browser/ui/cocoa/location_bar/action_box_menu_bubble_controller.h
deleted file mode 100644
index f0a38ac..0000000
--- a/chrome/browser/ui/cocoa/location_bar/action_box_menu_bubble_controller.h
+++ /dev/null
@@ -1,107 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_UI_COCOA_LOCATION_BAR_ACTION_BOX_MENU_BUBBLE_CONTROLLER_H_
-#define CHROME_BROWSER_UI_COCOA_LOCATION_BAR_ACTION_BOX_MENU_BUBBLE_CONTROLLER_H_
-
-#import <Cocoa/Cocoa.h>
-
-#include "base/mac/scoped_nsobject.h"
-#include "base/memory/scoped_ptr.h"
-#import "chrome/browser/ui/cocoa/base_bubble_controller.h"
-#import "ui/base/cocoa/tracking_area.h"
-
-class ActionBoxMenuModel;
-class ExtensionIconLoaderBridge;
-class Profile;
-
-// This window controller manages the action box popup menu.
-@interface ActionBoxMenuBubbleController : BaseBubbleController {
- @private
- Profile* profile_;
-
- // The model that contains the data from the backend.
- scoped_ptr<ActionBoxMenuModel> model_;
-
- // Array of the below view controllers.
- base::scoped_nsobject<NSMutableArray> items_;
-}
-
-// Designated initializer. |point| must be in screen coordinates.
-- (id)initWithModel:(scoped_ptr<ActionBoxMenuModel>)model
- parentWindow:(NSWindow*)parent
- anchoredAt:(NSPoint)point
- profile:(Profile*)profile;
-
-// Accesses the model.
-- (ActionBoxMenuModel*)model;
-
-- (NSMutableArray*)items;
-
-// Executes the action of a given menu item.
-- (IBAction)itemSelected:(id)sender;
-
-@end
-
-////////////////////////////////////////////////////////////////////////////////
-
-// This view controller manages the menu item XIB.
-@interface ActionBoxMenuItemController : NSViewController {
- @private
- // The parent menu controller owns this.
- __weak ActionBoxMenuBubbleController* controller_;
-
- size_t modelIndex_;
-
- // Tracks whether this item is currently highlighted.
- BOOL isHighlighted_;
-
- // If the icon comes from an extension, this wraps the extension icon loader.
- scoped_ptr<ExtensionIconLoaderBridge> extensionIconLoaderBridge_;
-
- // Instance variables that back the outlets.
- IBOutlet __weak NSImageView* iconView_;
- IBOutlet __weak NSTextField* nameField_;
-}
-@property(readonly, nonatomic) size_t modelIndex;
-@property(assign, nonatomic) BOOL isHighlighted;
-@property(readonly, nonatomic) NSImageView* iconView;
-@property(assign, nonatomic) NSTextField* nameField;
-
-// Designated initializer.
-- (id)initWithModelIndex:(size_t)modelIndex
- menuController:(ActionBoxMenuBubbleController*)controller
- profile:(Profile*)profile;
-
-// Highlights the subviews appropriately for a given event.
-- (void)highlightForEvent:(NSEvent*)event;
-
-// Execute the action of a given menu item.
-- (IBAction)itemSelected:(id)sender;
-
-// Called when |extensionIconLoaderBridge_| changes, updates |iconView_|.
-- (void)onExtensionIconImageChanged:(NSImage*)image;
-
-@end
-
-////////////////////////////////////////////////////////////////////////////////
-
-// Simple button cell to get tracking and mouse events forwarded back to the
-// view controller for changing highlight style of the item subviews. This is
-// an invisible button that underlays most of the menu item and is responsible
-// for performing the attached action.
-@interface ActionBoxMenuItemView : NSView {
- @private
- // The controller that manages this.
- IBOutlet __weak ActionBoxMenuItemController* viewController_;
-
- // Used to highlight the background on hover.
- ui::ScopedCrTrackingArea trackingArea_;
-}
-
-@property(assign, nonatomic) ActionBoxMenuItemController* viewController;
-
-@end
-
-#endif // CHROME_BROWSER_UI_COCOA_LOCATION_BAR_ACTION_BOX_MENU_BUBBLE_CONTROLLER_H_
diff --git a/chrome/browser/ui/cocoa/location_bar/action_box_menu_bubble_controller.mm b/chrome/browser/ui/cocoa/location_bar/action_box_menu_bubble_controller.mm
deleted file mode 100644
index d65dc50..0000000
--- a/chrome/browser/ui/cocoa/location_bar/action_box_menu_bubble_controller.mm
+++ /dev/null
@@ -1,473 +0,0 @@
-// 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.
-
-#import "chrome/browser/ui/cocoa/location_bar/action_box_menu_bubble_controller.h"
-
-#include "base/mac/bundle_locations.h"
-#include "base/mac/foundation_util.h"
-#include "base/mac/mac_util.h"
-#include "base/strings/sys_string_conversions.h"
-#include "chrome/browser/extensions/extension_icon_image.h"
-#import "chrome/browser/ui/cocoa/browser_window_utils.h"
-#import "chrome/browser/ui/cocoa/info_bubble_view.h"
-#import "chrome/browser/ui/cocoa/info_bubble_window.h"
-#include "chrome/browser/ui/toolbar/action_box_menu_model.h"
-#include "chrome/common/extensions/api/extension_action/action_info.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/extension_constants.h"
-#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#include "skia/ext/skia_utils_mac.h"
-#import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
-#import "ui/base/cocoa/cocoa_event_utils.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/image/image.h"
-#include "ui/gfx/image/image_skia_util_mac.h"
-#include "ui/native_theme/native_theme.h"
-
-@interface ActionBoxMenuBubbleController (Private)
-- (id)highlightedItem;
-- (void)keyDown:(NSEvent*)theEvent;
-- (void)moveDown:(id)sender;
-- (void)moveUp:(id)sender;
-- (void)highlightNextItemByDelta:(NSInteger)delta;
-- (void)highlightItem:(ActionBoxMenuItemController*)newItem;
-@end
-
-@interface ActionBoxMenuItemView (Private)
-- (NSColor*)highlightedMenuItemBackgroundColor;
-@end
-
-namespace {
-
-// Some reasonable values for the menu geometry.
-const CGFloat kBubbleMinWidth = 175;
-const CGFloat kBubbleMaxWidth = 800;
-
-// Distance between the top/bottom of the bubble and the first/last menu item.
-const CGFloat kVerticalPadding = 7.0;
-
-// Minimum distance between the right of a menu item and the right border.
-const CGFloat kRightMargin = 20.0;
-
-// Alpha of the black rectangle overlayed on the item hovered over.
-const CGFloat kSelectionAlpha = 0.06;
-
-} // namespace
-
-// extension Icon Loader Bridge ////////////////////////////////////////////////
-
-class ExtensionIconLoaderBridge : public extensions::IconImage::Observer {
- public:
- ExtensionIconLoaderBridge(Profile* profile,
- const extensions::Extension* extension,
- ActionBoxMenuItemController* controller)
- : controller_(controller) {
- const extensions::ActionInfo* page_launcher_info =
- extensions::ActionInfo::GetPageLauncherInfo(extension);
- DCHECK(page_launcher_info);
- icon_loader_.reset(new extensions::IconImage(
- profile,
- extension,
- page_launcher_info->default_icon,
- extension_misc::EXTENSION_ICON_ACTION,
- extensions::IconsInfo::GetDefaultAppIcon(),
- this));
- OnExtensionIconImageChanged(icon_loader_.get());
- }
-
- private:
- virtual void OnExtensionIconImageChanged(
- extensions::IconImage* image) OVERRIDE {
- [controller_ onExtensionIconImageChanged:
- gfx::NSImageFromImageSkia(image->image_skia())];
- }
-
- scoped_ptr<extensions::IconImage> icon_loader_;
- ActionBoxMenuItemController* controller_; // Weak.
-
- DISALLOW_COPY_AND_ASSIGN(ExtensionIconLoaderBridge);
-};
-
-@implementation ActionBoxMenuBubbleController
-
-- (id)initWithModel:(scoped_ptr<ActionBoxMenuModel>)model
- parentWindow:(NSWindow*)parent
- anchoredAt:(NSPoint)point
- profile:(Profile*)profile {
- // Use an arbitrary height because it will reflect the size of the content.
- NSRect contentRect = NSMakeRect(0, 0, kBubbleMinWidth, 150);
- // Create an empty window into which content is placed.
- base::scoped_nsobject<InfoBubbleWindow> window(
- [[InfoBubbleWindow alloc] initWithContentRect:contentRect
- styleMask:NSBorderlessWindowMask
- backing:NSBackingStoreBuffered
- defer:NO]);
- [window setAllowedAnimations:info_bubble::kAnimateNone];
- if (self = [super initWithWindow:window
- parentWindow:parent
- anchoredAt:point]) {
- profile_ = profile;
- model_.reset(model.release());
-
- [[self bubble] setAlignment:info_bubble::kAlignRightEdgeToAnchorEdge];
- [[self bubble] setArrowLocation:info_bubble::kNoArrow];
- ui::NativeTheme* nativeTheme = ui::NativeTheme::instance();
- [[self bubble] setBackgroundColor:
- gfx::SkColorToCalibratedNSColor(nativeTheme->GetSystemColor(
- ui::NativeTheme::kColorId_DialogBackground))];
- [self performLayout];
- }
- return self;
-}
-
-- (ActionBoxMenuModel*)model {
- return model_.get();
-}
-
-- (NSMutableArray*)items {
- return items_;
-}
-
-- (IBAction)itemSelected:(id)sender {
- // If Enter is pressed but nothing is highlighted, don't activate anything.
- if (!sender)
- return;
-
- // Close the current window and activate the parent browser window, otherwise
- // the bookmark popup refuses to show.
- [self close];
- [BrowserWindowUtils
- activateWindowForController:[[self parentWindow] windowController]];
- size_t modelIndex = [sender modelIndex];
- DCHECK(model_.get());
- int eventFlags = ui::EventFlagsFromNSEvent([NSApp currentEvent]);
- model_->ActivatedAt(modelIndex, eventFlags);
-}
-
-// Private /////////////////////////////////////////////////////////////////////
-
-- (void)performLayout {
- NSView* contentView = [[self window] contentView];
-
- // Reset the array of controllers and remove all the views.
- items_.reset([[NSMutableArray alloc] init]);
- [contentView setSubviews:[NSArray array]];
-
- // Leave some space at the bottom of the menu.
- CGFloat yOffset = kVerticalPadding;
-
- // Keep track of a potential separator to resize it when we know the width.
- base::scoped_nsobject<NSBox> separatorView;
-
- // Loop over the items in reverse, constructing the menu items.
- CGFloat width = kBubbleMinWidth;
- CGFloat minX = NSMinX([contentView bounds]);
- for (int i = model_->GetItemCount() - 1; i >= 0; --i) {
- if (model_->GetTypeAt(i) == ui::MenuModel::TYPE_SEPARATOR) {
- const CGFloat kSeparatorHeight = 1.0;
- // Only supports one separator.
- DCHECK(!separatorView);
- yOffset += kVerticalPadding + kSeparatorHeight;
- separatorView.reset([[NSBox alloc]
- initWithFrame:NSMakeRect(0, yOffset, width, kSeparatorHeight)]);
- [separatorView setBoxType:NSBoxCustom];
- ui::NativeTheme* nativeTheme = ui::NativeTheme::instance();
- [separatorView setBorderColor:
- gfx::SkColorToCalibratedNSColor(nativeTheme->GetSystemColor(
- ui::NativeTheme::kColorId_MenuSeparatorColor))];
- [contentView addSubview:separatorView];
- yOffset += kVerticalPadding;
- } else {
- // Create the item controller. Autorelease it because it will be owned
- // by the |items_| array.
- base::scoped_nsobject<ActionBoxMenuItemController> itemController(
- [[ActionBoxMenuItemController alloc] initWithModelIndex:i
- menuController:self
- profile:profile_]);
-
- // Adjust the name field to fit the string.
- [GTMUILocalizerAndLayoutTweaker sizeToFitView:[itemController nameField]];
-
- // Expand the size of the window if required to fit the menu item.
- width = std::max(width,
- NSMaxX([[itemController nameField] frame]) - minX + kRightMargin);
-
- // Add the item to the content view.
- [[itemController view] setFrameOrigin:NSMakePoint(0, yOffset)];
- [contentView addSubview:[itemController view]];
- yOffset += NSHeight([[itemController view] frame]);
-
- // Keep track of the view controller.
- [items_ addObject:itemController.get()];
- }
- }
-
- // Leave some space at the top of the menu.
- yOffset += kVerticalPadding;
-
- // Set the window frame, clamping the width at a sensible max.
- NSRect frame = [[self window] frame];
- frame.size.height = yOffset;
- frame.size.width = std::min(width, kBubbleMaxWidth);
-
- // Resize the separator to full width.
- if (separatorView) {
- NSRect separatorFrame = [separatorView frame];
- separatorFrame.size.width = width;
- [separatorView setFrame:separatorFrame];
- }
-
- [[self window] setFrame:frame display:YES];
-}
-
-- (id)highlightedItem {
- for (ActionBoxMenuItemController* item in items_.get()) {
- if ([item isHighlighted]) {
- return item;
- }
- }
- return nil;
-}
-
-- (void)keyDown:(NSEvent*)theEvent {
- // Interpret all possible key events. In particular, this will answer
- // moveDown, moveUp and insertNewline so that the menu can be navigated
- // with keystrokes.
- [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
-}
-
-- (void)moveDown:(id)sender {
- [self highlightNextItemByDelta:-1];
-}
-
-- (void)moveUp:(id)sender {
- [self highlightNextItemByDelta:1];
-}
-
-- (void)insertNewline:(id)sender {
- [self itemSelected:[self highlightedItem]];
-}
-
-- (void)highlightNextItemByDelta:(NSInteger)delta {
- NSUInteger count = [items_ count];
- if (count == 0)
- return;
-
- // If nothing is selected, select the first (resp. last) item when going up
- // (resp. going down). Otherwise selects the next (resp. previous) item.
- // This code does not wrap around if something is already selected.
-
- // First assumes nothing is selected.
- NSUInteger newIndex = delta < 0 ? (count - 1) : 0;
- NSUInteger oldIndex = [items_ indexOfObject:[self highlightedItem]];
- // oldIndex will be NSNotFound when [self highlightedItem] returns nil.
- if (oldIndex != NSNotFound) {
- // Something is selected, move only if not already at top/bottom.
- newIndex = oldIndex;
- if (newIndex != (delta < 0 ? 0 : count - 1))
- newIndex += delta;
- }
-
- [self highlightItem:[items_ objectAtIndex:newIndex]];
-}
-
-- (void)highlightItem:(ActionBoxMenuItemController*)newItem {
- ActionBoxMenuItemController* oldItem = [self highlightedItem];
- if (oldItem == newItem)
- return;
- [oldItem setIsHighlighted:NO];
- [newItem setIsHighlighted:YES];
-}
-
-@end
-
-// Menu Item Controller ////////////////////////////////////////////////////////
-
-@implementation ActionBoxMenuItemController
-
-@synthesize modelIndex = modelIndex_;
-@synthesize isHighlighted = isHighlighted_;
-@synthesize iconView = iconView_;
-@synthesize nameField = nameField_;
-
-- (id)initWithModelIndex:(size_t)modelIndex
- menuController:(ActionBoxMenuBubbleController*)controller
- profile:(Profile*)profile {
- if ((self = [super initWithNibName:@"ActionBoxMenuItem"
- bundle:base::mac::FrameworkBundle()])) {
- modelIndex_ = modelIndex;
- controller_ = controller;
-
- [self loadView];
-
- gfx::Image icon = gfx::Image();
- ActionBoxMenuModel* model = [controller model];
- if (model->GetIconAt(modelIndex_, &icon)) {
- extensionIconLoaderBridge_.reset();
- [iconView_ setImage:icon.ToNSImage()];
- } else if (model->GetTypeAt(modelIndex_) == ui::MenuModel::TYPE_COMMAND &&
- model->IsItemExtension(modelIndex_)) {
- // Creating an ExtensionIconLoaderBridge will call
- // onExtensionIconImageChanged and set the |iconView_|.
- [iconView_ setImage:nil];
- extensionIconLoaderBridge_.reset(new ExtensionIconLoaderBridge(
- profile,
- model->GetExtensionAt(modelIndex_),
- self));
- } else {
- extensionIconLoaderBridge_.reset();
- [iconView_ setImage:nil];
- }
-
- nameField_.stringValue = base::SysUTF16ToNSString(
- controller.model->GetLabelAt(modelIndex_));
- }
- return self;
-}
-
-- (void)dealloc {
- base::mac::ObjCCastStrict<ActionBoxMenuItemView>(
- self.view).viewController = nil;
- [super dealloc];
-}
-
-- (void)highlightForEvent:(NSEvent*)event {
- switch ([event type]) {
- case NSMouseEntered:
- [controller_ highlightItem:self];
- break;
-
- case NSMouseExited:
- [controller_ highlightItem:nil];
- break;
-
- default:
- NOTREACHED();
- };
-}
-
-- (IBAction)itemSelected:(id)sender {
- [controller_ itemSelected:self];
-}
-
-- (void)setIsHighlighted:(BOOL)isHighlighted {
- if (isHighlighted_ == isHighlighted)
- return;
-
- isHighlighted_ = isHighlighted;
- [[self view] setNeedsDisplay:YES];
-}
-
-- (void)onExtensionIconImageChanged:(NSImage*)image {
- [iconView_ setImage:image];
-}
-
-@end
-
-// Items from the action box menu //////////////////////////////////////////////
-
-@implementation ActionBoxMenuItemView
-
-@synthesize viewController = viewController_;
-
-- (void)updateTrackingAreas {
- if (trackingArea_.get())
- [self removeTrackingArea:trackingArea_.get()];
-
- trackingArea_.reset(
- [[CrTrackingArea alloc] initWithRect:[self bounds]
- options:NSTrackingMouseEnteredAndExited |
- NSTrackingActiveInKeyWindow
- owner:self
- userInfo:nil]);
- [self addTrackingArea:trackingArea_.get()];
-
- [super updateTrackingAreas];
-}
-
-- (BOOL)acceptsFirstResponder {
- return YES;
-}
-
-- (void)mouseUp:(NSEvent*)theEvent {
- [viewController_ itemSelected:self];
-}
-
-- (void)mouseEntered:(NSEvent*)theEvent {
- [viewController_ highlightForEvent:theEvent];
-}
-
-- (void)mouseExited:(NSEvent*)theEvent {
- [viewController_ highlightForEvent:theEvent];
-}
-
-- (void)drawRect:(NSRect)dirtyRect {
- NSColor* backgroundColor = nil;
- if ([viewController_ isHighlighted]) {
- ui::NativeTheme* nativeTheme = ui::NativeTheme::instance();
- backgroundColor = gfx::SkColorToCalibratedNSColor(
- nativeTheme->GetSystemColor(
- ui::NativeTheme::kColorId_FocusedMenuItemBackgroundColor));
- } else {
- backgroundColor = [NSColor clearColor];
- }
-
- [backgroundColor set];
- [NSBezierPath fillRect:[self bounds]];
-}
-
-// Make sure the element is focusable for accessibility.
-- (BOOL)canBecomeKeyView {
- return YES;
-}
-
-- (BOOL)accessibilityIsIgnored {
- return NO;
-}
-
-- (NSArray*)accessibilityAttributeNames {
- NSMutableArray* attributes =
- [[[super accessibilityAttributeNames] mutableCopy] autorelease];
- [attributes addObject:NSAccessibilityTitleAttribute];
- [attributes addObject:NSAccessibilityEnabledAttribute];
-
- return attributes;
-}
-
-- (NSArray*)accessibilityActionNames {
- NSArray* parentActions = [super accessibilityActionNames];
- return [parentActions arrayByAddingObject:NSAccessibilityPressAction];
-}
-
-- (id)accessibilityAttributeValue:(NSString*)attribute {
- if ([attribute isEqual:NSAccessibilityRoleAttribute])
- return NSAccessibilityButtonRole;
-
- if ([attribute isEqual:NSAccessibilityRoleDescriptionAttribute])
- return NSAccessibilityRoleDescription(NSAccessibilityButtonRole, nil);
-
- if ([attribute isEqual:NSAccessibilityEnabledAttribute])
- return [NSNumber numberWithBool:YES];
-
- return [super accessibilityAttributeValue:attribute];
-}
-
-- (void)accessibilityPerformAction:(NSString*)action {
- if ([action isEqual:NSAccessibilityPressAction]) {
- [viewController_ itemSelected:self];
- return;
- }
-
- [super accessibilityPerformAction:action];
-}
-
-- (NSColor*)highlightedMenuItemBackgroundColor {
- ui::NativeTheme* nativeTheme = ui::NativeTheme::instance();
- return gfx::SkColorToCalibratedNSColor(nativeTheme->GetSystemColor(
- ui::NativeTheme::kColorId_FocusedMenuItemBackgroundColor));
-}
-
-@end
diff --git a/chrome/browser/ui/cocoa/location_bar/action_box_menu_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/location_bar/action_box_menu_bubble_controller_unittest.mm
deleted file mode 100644
index 7399ac5..0000000
--- a/chrome/browser/ui/cocoa/location_bar/action_box_menu_bubble_controller_unittest.mm
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import "chrome/browser/ui/cocoa/location_bar/action_box_menu_bubble_controller.h"
-
-#include "base/command_line.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/values.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_system.h"
-#include "chrome/browser/extensions/test_extension_system.h"
-#include "chrome/browser/ui/cocoa/cocoa_profile_test.h"
-#include "chrome/browser/ui/toolbar/action_box_menu_model.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/extension_builder.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-const CGFloat kAnchorPointX = 400;
-const CGFloat kAnchorPointY = 300;
-
-class MenuDelegate : public ui::SimpleMenuModel::Delegate {
- public:
- // Methods for determining the state of specific command ids.
- virtual bool IsCommandIdChecked(int command_id) const OVERRIDE {
- return false;
- }
-
- virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE {
- return true;
- }
-
- virtual bool GetAcceleratorForCommandId(
- int command_id,
- ui::Accelerator* accelerator) OVERRIDE {
- return false;
- }
-
- // Performs the action associated with the specified command id.
- virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE {
- }
-};
-
-class ActionBoxMenuBubbleControllerTest : public CocoaProfileTest {
- public:
- ActionBoxMenuBubbleControllerTest() {
- }
-
- virtual void SetUp() OVERRIDE {
- CocoaProfileTest::SetUp();
- ASSERT_TRUE(browser());
-
- // Create a test extension service.
- CommandLine command_line(CommandLine::NO_PROGRAM);
- extensions::TestExtensionSystem* test_ext_system =
- static_cast<extensions::TestExtensionSystem*>(
- extensions::ExtensionSystem::Get(profile()));
- service_ = test_ext_system->CreateExtensionService(
- &command_line, base::FilePath(), false);
- EXPECT_TRUE(service_->extensions_enabled());
- service_->Init();
- }
-
- virtual void TearDown() OVERRIDE {
- // Close our windows.
- [controller_ close];
- CocoaProfileTest::TearDown();
- }
-
- // Add an extension with a page_launcher to the model and the extension
- // service. Call this before calling CreateController.
- scoped_refptr<extensions::Extension> AddPageLauncherExtension(
- ActionBoxMenuModel* model,
- const std::string& page_launcher_title,
- int command_id) {
- scoped_refptr<extensions::Extension> extension =
- extensions::ExtensionBuilder()
- .SetManifest(extensions::DictionaryBuilder()
- .Set("name", "Extension with page launcher")
- .Set("version", "1.0.0")
- .Set("manifest_version", 2)
- .Set("page_launcher", extensions::DictionaryBuilder()
- .Set("default_title", page_launcher_title))
- .Set("app", extensions::DictionaryBuilder()
- .Set("background", extensions::DictionaryBuilder()
- .Set("page", ""))))
- .Build();
- service_->AddExtension(extension.get());
- model->AddExtension(*extension.get(), command_id);
- return extension;
- }
-
- // Creates a controller based on |model|. Takes ownership of |model|.
- void CreateController(scoped_ptr<ActionBoxMenuModel> model) {
- // The bubble controller will release itself when the window closes.
- controller_ = [[ActionBoxMenuBubbleController alloc]
- initWithModel:model.Pass()
- parentWindow:test_window()
- anchoredAt:NSMakePoint(kAnchorPointX, kAnchorPointY)
- profile:profile()];
-
- [controller_ showWindow:nil];
- }
-
- // Checks that the controller's view contains at least one separator subview
- // and that it has full width.
- void EnsureSeparatorHasCorrectWidth() {
- bool found = false;
- for (id view in [[[controller_ window] contentView] subviews]) {
- // Assume all NSBox subviews are separators.
- if ([view isKindOfClass:[NSBox class]]) {
- found = true;
- ASSERT_EQ(NSWidth([[controller_ window] frame]),
- NSWidth([view bounds]));
- }
- }
- ASSERT_TRUE(found);
- }
-
- protected:
- ActionBoxMenuBubbleController* controller_;
- MenuDelegate menu_delegate_;
- ExtensionService* service_;
-};
-
-TEST_F(ActionBoxMenuBubbleControllerTest, CreateMenuWithExtensions) {
- scoped_ptr<ActionBoxMenuModel> model(new ActionBoxMenuModel(
- profile(), &menu_delegate_));
- AddPageLauncherExtension(model.get(), "Launch extension 1", 0);
- AddPageLauncherExtension(model.get(), "Launch extension 2", 1);
- CreateController(model.Pass());
-
- // Ensure extensions are there and in the right order.
- int extension1Index = -1;
- int extension2Index = -1;
- for (id actionBoxMenuItemController in [controller_ items]) {
- NSString* label = [[actionBoxMenuItemController nameField] stringValue];
- int index = [actionBoxMenuItemController modelIndex];
- NSImage* image = [[actionBoxMenuItemController iconView] image];
- if ([label isEqualToString:@"Launch extension 1"]) {
- ASSERT_EQ(-1, extension1Index);
- ASSERT_EQ(19, [image size].width);
- ASSERT_EQ(19, [image size].height);
- extension1Index = index;
- }
- if ([label isEqualToString:@"Launch extension 2"]) {
- ASSERT_EQ(-1, extension2Index);
- ASSERT_EQ(19, [image size].width);
- ASSERT_EQ(19, [image size].height);
- extension2Index = index;
- }
- }
-
- ASSERT_NE(-1, extension1Index);
- ASSERT_NE(-1, extension2Index);
- ASSERT_EQ(extension1Index, extension2Index - 1);
-}
-
-TEST_F(ActionBoxMenuBubbleControllerTest, CheckSeparatorWithShortExtensions) {
- scoped_ptr<ActionBoxMenuModel> model(new ActionBoxMenuModel(
- profile(), &menu_delegate_));
- model->AddItem(0, ASCIIToUTF16("Bookmark this page"));
- AddPageLauncherExtension(model.get(), "Short", 1);
- CreateController(model.Pass());
-
- // The width of the menu is dictated by the widest item which in this case
- // is going to be "Bookmark this page", which comes before the separator.
- // Ensure that, in this case, the separator has the full width.
- EnsureSeparatorHasCorrectWidth();
-}
-
-TEST_F(ActionBoxMenuBubbleControllerTest, CheckSeparatorWithLongExtensions) {
- scoped_ptr<ActionBoxMenuModel> model(new ActionBoxMenuModel(
- profile(), &menu_delegate_));
- model->AddItem(0, ASCIIToUTF16("Bookmark this page"));
- AddPageLauncherExtension(model.get(),
- "This is a long page launcher extension title...", 1);
- CreateController(model.Pass());
-
- // The width of the menu is dictated by the widest item which in this case
- // is going to be the extension, which comes after the separator. Ensure that,
- // in this case, the separator has the full width.
- EnsureSeparatorHasCorrectWidth();
-}
-
-} // namespace
diff --git a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h
index 69af462..d682305 100644
--- a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h
+++ b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h
@@ -28,7 +28,6 @@
class LocationBarDecoration;
class LocationIconDecoration;
class PageActionDecoration;
-class PlusDecoration;
class Profile;
class SelectedKeywordDecoration;
class StarDecoration;
@@ -77,7 +76,6 @@
virtual ExtensionAction* GetPageAction(size_t index) OVERRIDE;
virtual ExtensionAction* GetVisiblePageAction(size_t index) OVERRIDE;
virtual void TestPageActionPressed(size_t index) OVERRIDE;
- virtual void TestActionBoxMenuItemSelected(int command_id) OVERRIDE;
virtual bool GetBookmarkStarVisibility() OVERRIDE;
// Set/Get the editable state of the field.
@@ -87,10 +85,6 @@
// Set the starred state of the bookmark star.
void SetStarred(bool starred);
- // Set (or resets) the icon image resource for the action box plus decoration.
- void ResetActionBoxIcon();
- void SetActionBoxIcon(int image_id);
-
// Happens when the zoom changes for the active tab. |can_show_bubble| is
// false when the change in zoom for the active tab wasn't an explicit user
// action (e.g. switching tabs, creating a new tab, creating a new browser).
@@ -102,10 +96,6 @@
// aim at.
NSPoint GetBookmarkBubblePoint() const;
- // Get the point in window coordinates on the Action Box icon for
- // anchoring its bubbles.
- NSPoint GetActionBoxAnchorPoint() const;
-
// Get the point in window coordinates in the security icon at which the page
// info bubble aims.
NSPoint GetPageInfoBubblePoint() const;
@@ -211,9 +201,6 @@
// Ensures the star decoration is visible or hidden, as required.
void UpdateStarDecorationVisibility();
- // Ensures the plus decoration is visible or hidden, as required.
- void UpdatePlusDecorationVisibility();
-
scoped_ptr<OmniboxViewMac> omnibox_view_;
CommandUpdater* command_updater_; // Weak, owned by Browser.
@@ -238,9 +225,6 @@
// on the left.
scoped_ptr<EVBubbleDecoration> ev_bubble_decoration_;
- // Action "plus" button right of bookmark star.
- scoped_ptr<PlusDecoration> plus_decoration_;
-
// Bookmark star right of page actions.
scoped_ptr<StarDecoration> star_decoration_;
diff --git a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm
index 8a7f095..ec510a6 100644
--- a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm
+++ b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm
@@ -39,7 +39,6 @@
#import "chrome/browser/ui/cocoa/location_bar/keyword_hint_decoration.h"
#import "chrome/browser/ui/cocoa/location_bar/location_icon_decoration.h"
#import "chrome/browser/ui/cocoa/location_bar/page_action_decoration.h"
-#import "chrome/browser/ui/cocoa/location_bar/plus_decoration.h"
#import "chrome/browser/ui/cocoa/location_bar/selected_keyword_decoration.h"
#import "chrome/browser/ui/cocoa/location_bar/star_decoration.h"
#import "chrome/browser/ui/cocoa/location_bar/zoom_decoration.h"
@@ -104,9 +103,6 @@
content::PAGE_TRANSITION_TYPED |
content::PAGE_TRANSITION_FROM_ADDRESS_BAR)),
weak_ptr_factory_(this) {
- if (extensions::FeatureSwitch::action_box()->IsEnabled()) {
- plus_decoration_.reset(new PlusDecoration(this, browser_));
- }
for (size_t i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) {
DCHECK_EQ(i, content_setting_decorations_.size());
@@ -238,7 +234,6 @@
command_updater_->UpdateCommandEnabled(IDC_BOOKMARK_PAGE_FROM_STAR,
IsStarEnabled());
UpdateStarDecorationVisibility();
- UpdatePlusDecorationVisibility();
UpdateZoomDecoration();
RefreshPageActionDecorations();
RefreshContentSettingsDecorations();
@@ -467,11 +462,6 @@
page_action_decorations_[index]->OnMousePressed(NSZeroRect);
}
-void LocationBarViewMac::TestActionBoxMenuItemSelected(int command_id) {
- plus_decoration_->action_box_button_controller()->ExecuteCommand(
- command_id, 0);
-}
-
bool LocationBarViewMac::GetBookmarkStarVisibility() {
DCHECK(star_decoration_.get());
return star_decoration_->IsVisible();
@@ -480,7 +470,6 @@
void LocationBarViewMac::SetEditable(bool editable) {
[field_ setEditable:editable ? YES : NO];
UpdateStarDecorationVisibility();
- UpdatePlusDecorationVisibility();
UpdateZoomDecoration();
UpdatePageActions();
Layout();
@@ -504,16 +493,6 @@
OnDecorationsChanged();
}
-void LocationBarViewMac::ResetActionBoxIcon() {
- plus_decoration_->ResetIcon();
- OnDecorationsChanged();
-}
-
-void LocationBarViewMac::SetActionBoxIcon(int image_id) {
- plus_decoration_->SetTemporaryIcon(image_id);
- OnDecorationsChanged();
-}
-
void LocationBarViewMac::ZoomChangedForActiveTab(bool can_show_bubble) {
UpdateZoomDecoration();
OnDecorationsChanged();
@@ -522,10 +501,6 @@
zoom_decoration_->ToggleBubble(YES);
}
-NSPoint LocationBarViewMac::GetActionBoxAnchorPoint() const {
- return plus_decoration_->GetActionBoxAnchorPoint();
-}
-
NSPoint LocationBarViewMac::GetBookmarkBubblePoint() const {
AutocompleteTextFieldCell* cell = [field_ cell];
const NSRect frame = [cell frameForDecoration:star_decoration_.get()
@@ -667,8 +642,6 @@
[cell addLeftDecoration:location_icon_decoration_.get()];
[cell addLeftDecoration:selected_keyword_decoration_.get()];
[cell addLeftDecoration:ev_bubble_decoration_.get()];
- if (plus_decoration_.get())
- [cell addRightDecoration:plus_decoration_.get()];
[cell addRightDecoration:star_decoration_.get()];
[cell addRightDecoration:zoom_decoration_.get()];
@@ -704,7 +677,8 @@
selected_keyword_decoration_->SetVisible(true);
selected_keyword_decoration_->SetKeyword(short_name, is_extension_keyword);
selected_keyword_decoration_->SetImage(GetKeywordImage(keyword));
- } else if (toolbar_model_->GetSecurityLevel() == ToolbarModel::EV_SECURE) {
+ } else if (toolbar_model_->GetSecurityLevel(false) ==
+ ToolbarModel::EV_SECURE) {
// Switch from location icon to show the EV bubble instead.
location_icon_decoration_->SetVisible(false);
ev_bubble_decoration_->SetVisible(true);
@@ -748,17 +722,5 @@
}
void LocationBarViewMac::UpdateStarDecorationVisibility() {
- // If the action box is enabled, only show the star if it's lit.
- bool visible = IsStarEnabled();
- if (!star_decoration_->starred() &&
- extensions::FeatureSwitch::action_box()->IsEnabled())
- visible = false;
- star_decoration_->SetVisible(visible);
-}
-
-void LocationBarViewMac::UpdatePlusDecorationVisibility() {
- if (extensions::FeatureSwitch::action_box()->IsEnabled()) {
- // If the action box is enabled, hide it when input is in progress.
- plus_decoration_->SetVisible(!toolbar_model_->GetInputInProgress());
- }
+ star_decoration_->SetVisible(IsStarEnabled());
}
diff --git a/chrome/browser/ui/cocoa/location_bar/plus_decoration.h b/chrome/browser/ui/cocoa/location_bar/plus_decoration.h
deleted file mode 100644
index 64bcf70..0000000
--- a/chrome/browser/ui/cocoa/location_bar/plus_decoration.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_UI_COCOA_LOCATION_BAR_PLUS_DECORATION_H_
-#define CHROME_BROWSER_UI_COCOA_LOCATION_BAR_PLUS_DECORATION_H_
-
-#import <Cocoa/Cocoa.h>
-
-#include "base/mac/scoped_nsobject.h"
-#include "chrome/browser/ui/cocoa/location_bar/button_decoration.h"
-#include "chrome/browser/ui/toolbar/action_box_button_controller.h"
-
-@class ActionBoxMenuBubbleController;
-class Browser;
-class LocationBarViewMac;
-
-// Note: this file is under development (see crbug.com/138118).
-
-// Plus icon on the right side of the location bar.
-class PlusDecoration : public ButtonDecoration,
- public ActionBoxButtonController::Delegate {
- public:
- PlusDecoration(LocationBarViewMac* owner, Browser* browser);
- virtual ~PlusDecoration();
-
- // Helper to get where the action box menu and bubble point should be
- // anchored. Similar to |PageActionDecoration| or |StarDecoration|.
- NSPoint GetActionBoxAnchorPoint();
-
- // Sets or clears a temporary icon for the button.
- void ResetIcon();
- void SetTemporaryIcon(int image_id);
-
- // Implement |LocationBarDecoration|.
- virtual bool AcceptsMousePress() OVERRIDE;
- virtual bool OnMousePressed(NSRect frame) OVERRIDE;
- virtual NSString* GetToolTip() OVERRIDE;
-
- ActionBoxButtonController* action_box_button_controller() {
- return &controller_;
- }
-
- private:
- // Implement |ActionBoxButtonController::Delegate|.
- virtual void ShowMenu(scoped_ptr<ActionBoxMenuModel> model) OVERRIDE;
-
- // Owner of the decoration, used to obtain the menu.
- LocationBarViewMac* owner_;
-
- Browser* browser_;
-
- ActionBoxButtonController controller_;
-
- void SetIcons(int normal_id, int hover_id, int pressed_id);
-
- base::scoped_nsobject<ActionBoxMenuBubbleController> menu_controller_;
-
- DISALLOW_COPY_AND_ASSIGN(PlusDecoration);
-};
-
-#endif // CHROME_BROWSER_UI_COCOA_LOCATION_BAR_PLUS_DECORATION_H_
diff --git a/chrome/browser/ui/cocoa/location_bar/plus_decoration.mm b/chrome/browser/ui/cocoa/location_bar/plus_decoration.mm
deleted file mode 100644
index c8cb131..0000000
--- a/chrome/browser/ui/cocoa/location_bar/plus_decoration.mm
+++ /dev/null
@@ -1,87 +0,0 @@
-// 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.
-
-#import "chrome/browser/ui/cocoa/location_bar/plus_decoration.h"
-
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_window.h"
-#import "chrome/browser/ui/cocoa/location_bar/action_box_menu_bubble_controller.h"
-#import "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.h"
-#import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
-#import "chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h"
-#include "chrome/browser/ui/toolbar/action_box_menu_model.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#include "ui/base/l10n/l10n_util_mac.h"
-
-namespace {
-// The offset to apply to the menu so that it appears just attached to the
-// right-hand side of the omnibox while slightly overlapping vertically.
-const CGFloat kAnchorPointXOffset = 1.0;
-const CGFloat kAnchorPointYOffset = 2.0;
-} // namespace
-
-PlusDecoration::PlusDecoration(LocationBarViewMac* owner,
- Browser* browser)
- : owner_(owner),
- browser_(browser),
- controller_(browser, this) {
- SetVisible(true);
- ResetIcon();
-}
-
-PlusDecoration::~PlusDecoration() {
-}
-
-NSPoint PlusDecoration::GetActionBoxAnchorPoint() {
- AutocompleteTextField* field = owner_->GetAutocompleteTextField();
- NSRect bounds = [field bounds];
- NSPoint anchor = NSMakePoint(NSMaxX(bounds) - kAnchorPointXOffset,
- NSMaxY(bounds) - kAnchorPointYOffset);
- return [field convertPoint:anchor toView:nil];
-}
-
-void PlusDecoration::ResetIcon() {
- SetIcons(
- IDR_ACTION_BOX_BUTTON_NORMAL,
- IDR_ACTION_BOX_BUTTON_HOVER,
- IDR_ACTION_BOX_BUTTON_PRESSED);
-}
-
-void PlusDecoration::SetTemporaryIcon(int image_id) {
- SetIcons(image_id, image_id, image_id);
-}
-
-bool PlusDecoration::AcceptsMousePress() {
- return true;
-}
-
-bool PlusDecoration::OnMousePressed(NSRect frame) {
- controller_.OnButtonClicked();
- return true;
-}
-
-NSString* PlusDecoration::GetToolTip() {
- return l10n_util::GetNSStringWithFixup(IDS_TOOLTIP_ACTION_BOX_BUTTON);
-}
-
-void PlusDecoration::ShowMenu(scoped_ptr<ActionBoxMenuModel> menu_model) {
- // Controller for the menu attached to the plus decoration.
- // |menu_controller| will automatically release itself on close.
- NSWindow* parent = browser_->window()->GetNativeWindow();
- ActionBoxMenuBubbleController* menu_controller =
- [[ActionBoxMenuBubbleController alloc]
- initWithModel:menu_model.Pass()
- parentWindow:parent
- anchoredAt:[parent convertBaseToScreen:GetActionBoxAnchorPoint()]
- profile:browser_->profile()];
-
- [menu_controller showWindow:nil];
-}
-
-void PlusDecoration::SetIcons(int normal_id, int hover_id, int pressed_id) {
- SetNormalImage(OmniboxViewMac::ImageForResource(normal_id));
- SetHoverImage(OmniboxViewMac::ImageForResource(hover_id));
- SetPressedImage(OmniboxViewMac::ImageForResource(pressed_id));
-}
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm
index e0bc46d..de73f1e 100644
--- a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm
+++ b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm
@@ -465,7 +465,7 @@
// [Could it be to not change if no change? If so, I'm guessing
// AppKit may already handle that.]
const ToolbarModel::SecurityLevel security_level =
- toolbar_model()->GetSecurityLevel();
+ toolbar_model()->GetSecurityLevel(false);
// Emphasize the scheme for security UI display purposes (if necessary).
if (!model()->user_input_in_progress() && model()->CurrentTextIsURL() &&
@@ -867,7 +867,7 @@
// this method could call the OmniboxView version.
bool OmniboxViewMac::ShouldEnableCopyURL() {
return !model()->user_input_in_progress() &&
- toolbar_model()->WouldReplaceSearchURLWithSearchTerms();
+ toolbar_model()->WouldReplaceSearchURLWithSearchTerms(false);
}
bool OmniboxViewMac::CanPasteAndGo() {
diff --git a/chrome/browser/ui/cocoa/run_loop_testing.mm b/chrome/browser/ui/cocoa/run_loop_testing.mm
index f79aa53..927e440 100644
--- a/chrome/browser/ui/cocoa/run_loop_testing.mm
+++ b/chrome/browser/ui/cocoa/run_loop_testing.mm
@@ -7,6 +7,7 @@
#import <Foundation/Foundation.h>
#include "base/mac/scoped_nsobject.h"
+#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_pump_mac.h"
// This class is scheduled with a delayed selector to quit the message pump.
@@ -37,7 +38,7 @@
namespace testing {
void NSRunLoopRunAllPending() {
- scoped_refptr<base::MessagePumpNSRunLoop> message_pump(
+ scoped_ptr<base::MessagePumpNSRunLoop> message_pump(
new base::MessagePumpNSRunLoop);
// Put a delayed selector on the queue. All other pending delayed selectors
diff --git a/chrome/browser/ui/cocoa/status_icons/status_tray_mac.h b/chrome/browser/ui/cocoa/status_icons/status_tray_mac.h
index 34aac19..2bb19c4 100644
--- a/chrome/browser/ui/cocoa/status_icons/status_tray_mac.h
+++ b/chrome/browser/ui/cocoa/status_icons/status_tray_mac.h
@@ -14,7 +14,7 @@
protected:
// Factory method for creating a status icon.
- virtual StatusIcon* CreatePlatformStatusIcon() OVERRIDE;
+ virtual StatusIcon* CreatePlatformStatusIcon(StatusIconType type) OVERRIDE;
private:
DISALLOW_COPY_AND_ASSIGN(StatusTrayMac);
diff --git a/chrome/browser/ui/cocoa/status_icons/status_tray_mac.mm b/chrome/browser/ui/cocoa/status_icons/status_tray_mac.mm
index 5d6c3e2..7a4324d 100644
--- a/chrome/browser/ui/cocoa/status_icons/status_tray_mac.mm
+++ b/chrome/browser/ui/cocoa/status_icons/status_tray_mac.mm
@@ -13,6 +13,6 @@
StatusTrayMac::StatusTrayMac() {
}
-StatusIcon* StatusTrayMac::CreatePlatformStatusIcon() {
+StatusIcon* StatusTrayMac::CreatePlatformStatusIcon(StatusIconType type) {
return new StatusIconMac();
}
diff --git a/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.h b/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.h
index 0ead38a..85aea22 100644
--- a/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.h
+++ b/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.h
@@ -38,8 +38,9 @@
virtual void AcceptTabModalDialog() OVERRIDE;
virtual void CancelTabModalDialog() OVERRIDE;
- // TabModalConfirmDialogCloseDelegate:
+ // TabModalConfirmDialogOperationsDelegate:
virtual void CloseDialog() OVERRIDE;
+ virtual void SetPreventCloseOnLoadStart(bool prevent) OVERRIDE;
// ConstrainedWindowMacDelegate:
virtual void OnConstrainedWindowClosed(
diff --git a/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.mm b/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.mm
index bdca853..6966adc 100644
--- a/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.mm
+++ b/chrome/browser/ui/cocoa/tab_modal_confirm_dialog_mac.mm
@@ -88,7 +88,7 @@
[[CustomConstrainedWindowSheet alloc]
initWithCustomWindow:[alert_ window]]);
window_.reset(new ConstrainedWindowMac(this, web_contents, sheet));
- delegate_->set_close_delegate(this);
+ delegate_->set_operations_delegate(this);
}
TabModalConfirmDialogMac::~TabModalConfirmDialogMac() {
@@ -106,7 +106,14 @@
window_->CloseWebContentsModalDialog();
}
+void TabModalConfirmDialogMac::SetPreventCloseOnLoadStart(bool prevent) {
+ window_->SetPreventCloseOnLoadStart(prevent);
+}
+
void TabModalConfirmDialogMac::OnConstrainedWindowClosed(
ConstrainedWindowMac* window) {
+ // Provide a disposition in case the dialog was closed without accepting or
+ // cancelling.
+ delegate_->Cancel();
delete this;
}
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_view.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_view.mm
index 9748eb0..e62eb67 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_strip_view.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_strip_view.mm
@@ -56,7 +56,9 @@
if (NSMinY(dirtyRect) < backgroundHeight) {
gfx::ScopedNSGraphicsContextSaveGState scopedGState;
NSGraphicsContext *context = [NSGraphicsContext currentContext];
- [context cr_setPatternPhase:[[self window] themePatternPhase] forView:self];
+ NSPoint phase = [[self window] themePatternPhaseForAlignment:
+ THEME_PATTERN_ALIGN_WITH_TAB_STRIP];
+ [context cr_setPatternPhase:phase forView:self];
// Themes don't have an inactive image so only look for one if there's no
// theme.
diff --git a/chrome/browser/ui/cocoa/tabs/tab_view.mm b/chrome/browser/ui/cocoa/tabs/tab_view.mm
index d7ff32f..99985d9 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_view.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_view.mm
@@ -301,6 +301,21 @@
bitmapResources[active][selected], true);
}
+// Draws the active tab background.
+- (void)drawFillForActiveTab:(NSRect)dirtyRect {
+ NSColor* backgroundImageColor = [self backgroundColorForSelected:YES];
+ [backgroundImageColor set];
+
+ // Themes can have partially transparent images. NSRectFill() is measurably
+ // faster though, so call it for the known-safe default theme.
+ ThemeService* themeProvider =
+ static_cast<ThemeService*>([[self window] themeProvider]);
+ if (themeProvider && themeProvider->UsingDefaultTheme())
+ NSRectFill(dirtyRect);
+ else
+ NSRectFillUsingOperation(dirtyRect, NSCompositeSourceOver);
+}
+
// Draws the tab background.
- (void)drawFill:(NSRect)dirtyRect {
gfx::ScopedNSGraphicsContextSaveGState scopedGState;
@@ -309,65 +324,51 @@
ThemeService* themeProvider =
static_cast<ThemeService*>([[self window] themeProvider]);
- [context cr_setPatternPhase:[[self window] themePatternPhase] forView:self];
-
+ NSPoint phase = [[self window]
+ themePatternPhaseForAlignment: THEME_PATTERN_ALIGN_WITH_TAB_STRIP];
+ [context cr_setPatternPhase:phase forView:self];
CGImageRef mask([self tabClippingMask]);
CGRect maskBounds = CGRectMake(0, 0, maskCacheWidth_, kMaskHeight);
CGContextClipToMask(cgContext, maskBounds, mask);
bool selected = [self state];
+ if (selected) {
+ [self drawFillForActiveTab:dirtyRect];
+ return;
+ }
// Background tabs should not paint over the tab strip separator, which is
// two pixels high in both lodpi and hidpi.
- if (!selected && dirtyRect.origin.y < 1)
+ if (dirtyRect.origin.y < 1)
dirtyRect.origin.y = 2 * [self cr_lineWidth];
+ // Draw the tab background.
+ NSColor* backgroundImageColor = [self backgroundColorForSelected:NO];
+ [backgroundImageColor set];
+
+ // Themes can have partially transparent images. NSRectFill() is measurably
+ // faster though, so call it for the known-safe default theme.
bool usingDefaultTheme = themeProvider && themeProvider->UsingDefaultTheme();
- NSColor* backgroundImageColor = [self backgroundColorForSelected:selected];
+ if (usingDefaultTheme)
+ NSRectFill(dirtyRect);
+ else
+ NSRectFillUsingOperation(dirtyRect, NSCompositeSourceOver);
- // Don't draw the window/tab bar background when selected, since the tab
- // background overlay drawn over it (see below) will be fully opaque.
- if (!selected) {
- [backgroundImageColor set];
- // Themes can have partially transparent images. NSRectFill() is measurably
- // faster though, so call it for the known-safe default theme.
- if (usingDefaultTheme)
- NSRectFill(dirtyRect);
- else
- NSRectFillUsingOperation(dirtyRect, NSCompositeSourceOver);
- }
-
- // Use the same overlay for the selected state and for hover and alert
- // glows; for the selected state, it's fully opaque.
+ // Draw the glow for hover and the overlay for alerts.
CGFloat hoverAlpha = [self hoverAlpha];
CGFloat alertAlpha = [self alertAlpha];
- if (selected || hoverAlpha > 0 || alertAlpha > 0) {
+ if (hoverAlpha > 0 || alertAlpha > 0) {
gfx::ScopedNSGraphicsContextSaveGState contextSave;
-
- // Draw the selected background / glow overlay.
CGContextBeginTransparencyLayer(cgContext, 0);
- if (!selected) {
- // The alert glow overlay is like the selected state but at most at most
- // 80% opaque. The hover glow brings up the overlay's opacity at most
- // 50%.
- CGFloat backgroundAlpha = 0.8 * alertAlpha;
- backgroundAlpha += (1 - backgroundAlpha) * 0.5 * hoverAlpha;
- CGContextSetAlpha(cgContext, backgroundAlpha);
- }
- // For background tabs, this branch is taken to draw a highlight. The
- // highlight is drawn using the foreground tab bitmap.
- if (!selected && themeProvider)
- backgroundImageColor = [self backgroundColorForSelected:YES];
+ // The alert glow overlay is like the selected state but at most at most 80%
+ // opaque. The hover glow brings up the overlay's opacity at most 50%.
+ CGFloat backgroundAlpha = 0.8 * alertAlpha;
+ backgroundAlpha += (1 - backgroundAlpha) * 0.5 * hoverAlpha;
+ CGContextSetAlpha(cgContext, backgroundAlpha);
- [backgroundImageColor set];
- // Themes can have partially transparent images. NSRectFill() is measurably
- // faster though, so call it for the known-safe default theme.
- if (usingDefaultTheme)
- NSRectFill(dirtyRect);
- else
- NSRectFillUsingOperation(dirtyRect, NSCompositeSourceOver);
+ [self drawFillForActiveTab:dirtyRect];
// ui::ThemeProvider::HasCustomImage is true only if the theme provides the
// image. However, even if the theme doesn't provide a tab background, the
@@ -377,7 +378,7 @@
(themeProvider->HasCustomImage(IDR_THEME_TAB_BACKGROUND) ||
themeProvider->HasCustomImage(IDR_THEME_FRAME));
// Draw a mouse hover gradient for the default themes.
- if (!selected && hoverAlpha > 0) {
+ if (hoverAlpha > 0) {
if (themeProvider && !hasCustomTheme) {
base::scoped_nsobject<NSGradient> glow([NSGradient alloc]);
[glow initWithStartingColor:[NSColor colorWithCalibratedWhite:1.0
diff --git a/chrome/browser/ui/cocoa/tabs/tab_window_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_window_controller.mm
index e49c875..7978772 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_window_controller.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_window_controller.mm
@@ -33,9 +33,11 @@
return NO;
}
-- (NSPoint)themePatternPhase {
- if ([self parentWindow])
- return [[[self parentWindow] windowController] themePatternPhase];
+- (NSPoint)themePatternPhaseForAlignment:(ThemePatternAlignment)alignment {
+ if ([self parentWindow]) {
+ return [[[self parentWindow] windowController]
+ themePatternPhaseForAlignment:alignment];
+ }
return NSZeroPoint;
}
diff --git a/chrome/browser/ui/cocoa/themed_window.h b/chrome/browser/ui/cocoa/themed_window.h
index c35db6d..f553795 100644
--- a/chrome/browser/ui/cocoa/themed_window.h
+++ b/chrome/browser/ui/cocoa/themed_window.h
@@ -21,12 +21,22 @@
};
typedef NSUInteger ThemedWindowStyle;
+// Indicates how the theme image should be aligned.
+enum ThemePatternAlignment {
+ // Aligns the top of the theme image with the top of the frame. Use this
+ // for IDR_THEME_THEME_FRAME.*
+ THEME_PATTERN_ALIGN_WITH_FRAME,
+ // Aligns the top of the theme image with the top of the tab
+ // strip. Use this for IDR_THEME_TAB_BACKGROUND and IDR_THEME_TOOLBAR.
+ THEME_PATTERN_ALIGN_WITH_TAB_STRIP
+};
+
// Implemented by windows that support theming.
@interface NSWindow (ThemeProvider)
- (ThemeProvider*)themeProvider;
- (ThemedWindowStyle)themedWindowStyle;
-- (NSPoint)themePatternPhase;
+- (NSPoint)themePatternPhaseForAlignment:(ThemePatternAlignment)alignment;
@end
#endif // CHROME_BROWSER_UI_COCOA_THEMED_WINDOW_H_
diff --git a/chrome/browser/ui/cocoa/themed_window.mm b/chrome/browser/ui/cocoa/themed_window.mm
index 911bf8a..6696464 100644
--- a/chrome/browser/ui/cocoa/themed_window.mm
+++ b/chrome/browser/ui/cocoa/themed_window.mm
@@ -16,7 +16,7 @@
return THEMED_NORMAL;
}
-- (NSPoint)themePatternPhase {
+- (NSPoint)themePatternPhaseForAlignment:(ThemePatternAlignment)alignment {
return NSZeroPoint;
}
diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_view.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_view.mm
index 5b9cb46..a4ec3fd 100644
--- a/chrome/browser/ui/cocoa/toolbar/toolbar_view.mm
+++ b/chrome/browser/ui/cocoa/toolbar/toolbar_view.mm
@@ -18,9 +18,8 @@
}
- (void)drawRect:(NSRect)rect {
- // The toolbar's background pattern is phased relative to the
- // tab strip view's background pattern.
- NSPoint phase = [[self window] themePatternPhase];
+ NSPoint phase = [[self window]
+ themePatternPhaseForAlignment:THEME_PATTERN_ALIGN_WITH_TAB_STRIP];
[[NSGraphicsContext currentContext] cr_setPatternPhase:phase forView:self];
[self drawBackgroundWithOpaque:YES];
}
diff --git a/chrome/browser/ui/collected_cookies_infobar_delegate.cc b/chrome/browser/ui/collected_cookies_infobar_delegate.cc
index e335e4d..b60761e 100644
--- a/chrome/browser/ui/collected_cookies_infobar_delegate.cc
+++ b/chrome/browser/ui/collected_cookies_infobar_delegate.cc
@@ -11,6 +11,7 @@
#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
+
// static
void CollectedCookiesInfoBarDelegate::Create(InfoBarService* infobar_service) {
infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
diff --git a/chrome/browser/ui/collected_cookies_infobar_delegate.h b/chrome/browser/ui/collected_cookies_infobar_delegate.h
index 2c0e1a7..2023026 100644
--- a/chrome/browser/ui/collected_cookies_infobar_delegate.h
+++ b/chrome/browser/ui/collected_cookies_infobar_delegate.h
@@ -16,7 +16,8 @@
// the reload right from the infobar.
class CollectedCookiesInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
- // Creates a collected cookies delegate and adds it to |infobar_service|.
+ // Creates a collected cookies infobar delegate and adds it to
+ // |infobar_service|.
static void Create(InfoBarService* infobar_service);
private:
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
index d73ffb3..b2bd578 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"
+#include "base/command_line.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chrome_notification_types.h"
@@ -19,9 +20,12 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper_delegate.h"
+#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h"
+#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/collected_cookies_infobar_delegate.h"
#include "chrome/browser/ui/content_settings/content_setting_bubble_model_delegate.h"
#include "chrome/browser/ui/content_settings/content_setting_changed_infobar_delegate.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/content_settings.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/render_messages.h"
@@ -33,8 +37,10 @@
#include "content/public/browser/web_contents_delegate.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
+#include "grit/ui_resources.h"
#include "net/base/net_util.h"
#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
using content::UserMetricsAction;
using content::WebContents;
@@ -454,7 +460,7 @@
ContentSettingCookiesBubbleModel::~ContentSettingCookiesBubbleModel() {
// On some plattforms e.g. MacOS X it is possible to close a tab while the
- // cookies settubgs bubble is open. This resets the web contents to NULL.
+ // cookies settings bubble is open. This resets the web contents to NULL.
if (settings_changed() && web_contents()) {
CollectedCookiesInfoBarDelegate::Create(
InfoBarService::FromWebContents(web_contents()));
@@ -539,6 +545,29 @@
void ContentSettingPopupBubbleModel::SetPopups() {
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBetterPopupBlocking)) {
+ IDMap<chrome::NavigateParams, IDMapOwnPointer>& blocked_popups =
+ PopupBlockerTabHelper::FromWebContents(web_contents())
+ ->GetBlockedPopupRequests();
+ for (IDMap<chrome::NavigateParams, IDMapOwnPointer>::const_iterator
+ iter(&blocked_popups);
+ !iter.IsAtEnd();
+ iter.Advance()) {
+
+ std::string title(iter.GetCurrentValue()->url.spec());
+ // The popup may not have a valid URL.
+ if (title.empty())
+ title = l10n_util::GetStringUTF8(IDS_TAB_LOADING_TITLE);
+ PopupItem popup_item(
+ ui::ResourceBundle::GetSharedInstance().GetImageNamed(
+ IDR_DEFAULT_FAVICON),
+ title,
+ iter.GetCurrentKey());
+ add_popup(popup_item);
+ }
+ return;
+ }
std::vector<WebContents*> blocked_contents;
BlockedContentTabHelper::FromWebContents(web_contents())->
GetBlockedContents(&blocked_contents);
@@ -549,18 +578,22 @@
// have a URL or title.
if (title.empty())
title = l10n_util::GetStringUTF8(IDS_TAB_LOADING_TITLE);
- PopupItem popup_item;
- popup_item.title = title;
- popup_item.image = FaviconTabHelper::FromWebContents(*i)->GetFavicon();
- popup_item.web_contents = *i;
+ PopupItem popup_item(
+ FaviconTabHelper::FromWebContents(*i)->GetFavicon(), title, *i);
add_popup(popup_item);
}
}
void ContentSettingPopupBubbleModel::OnPopupClicked(int index) {
if (web_contents()) {
- BlockedContentTabHelper::FromWebContents(web_contents())->
- LaunchForContents(bubble_content().popup_items[index].web_contents);
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBetterPopupBlocking)) {
+ PopupBlockerTabHelper::FromWebContents(web_contents())->
+ ShowBlockedPopup(bubble_content().popup_items[index].popup_id);
+ } else {
+ BlockedContentTabHelper::FromWebContents(web_contents())->
+ LaunchForContents(bubble_content().popup_items[index].web_contents);
+ }
}
}
@@ -920,11 +953,11 @@
void ContentSettingDomainListBubbleModel::SetDomainsAndCustomLink() {
TabSpecificContentSettings* content_settings =
TabSpecificContentSettings::FromWebContents(web_contents());
- const GeolocationSettingsState& settings =
- content_settings->geolocation_settings_state();
- GeolocationSettingsState::FormattedHostsPerState formatted_hosts_per_state;
+ const ContentSettingsUsagesState& usages =
+ content_settings->geolocation_usages_state();
+ ContentSettingsUsagesState::FormattedHostsPerState formatted_hosts_per_state;
unsigned int tab_state_flags = 0;
- settings.GetDetailedInfo(&formatted_hosts_per_state, &tab_state_flags);
+ usages.GetDetailedInfo(&formatted_hosts_per_state, &tab_state_flags);
// Divide the tab's current geolocation users into sets according to their
// permission state.
MaybeAddDomainList(formatted_hosts_per_state[CONTENT_SETTING_ALLOW],
@@ -933,12 +966,12 @@
MaybeAddDomainList(formatted_hosts_per_state[CONTENT_SETTING_BLOCK],
IDS_GEOLOCATION_BUBBLE_SECTION_DENIED);
- if (tab_state_flags & GeolocationSettingsState::TABSTATE_HAS_EXCEPTION) {
+ if (tab_state_flags & ContentSettingsUsagesState::TABSTATE_HAS_EXCEPTION) {
set_custom_link(l10n_util::GetStringUTF8(
IDS_GEOLOCATION_BUBBLE_CLEAR_LINK));
set_custom_link_enabled(true);
} else if (tab_state_flags &
- GeolocationSettingsState::TABSTATE_HAS_CHANGED) {
+ ContentSettingsUsagesState::TABSTATE_HAS_CHANGED) {
set_custom_link(l10n_util::GetStringUTF8(
IDS_GEOLOCATION_BUBBLE_REQUIRE_RELOAD_TO_CLEAR));
}
@@ -952,12 +985,12 @@
const GURL& embedder_url = web_contents()->GetURL();
TabSpecificContentSettings* content_settings =
TabSpecificContentSettings::FromWebContents(web_contents());
- const GeolocationSettingsState::StateMap& state_map =
- content_settings->geolocation_settings_state().state_map();
+ const ContentSettingsUsagesState::StateMap& state_map =
+ content_settings->geolocation_usages_state().state_map();
HostContentSettingsMap* settings_map =
profile()->GetHostContentSettingsMap();
- for (GeolocationSettingsState::StateMap::const_iterator it =
+ for (ContentSettingsUsagesState::StateMap::const_iterator it =
state_map.begin(); it != state_map.end(); ++it) {
settings_map->SetContentSetting(
ContentSettingsPattern::FromURLNoWildcard(it->first),
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.h b/chrome/browser/ui/content_settings/content_setting_bubble_model.h
index fbb19c1..89c7bef 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model.h
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.h
@@ -34,9 +34,20 @@
typedef ContentSettingBubbleModelDelegate Delegate;
struct PopupItem {
+ PopupItem(const gfx::Image& image,
+ const std::string& title,
+ content::WebContents* web_contents)
+ : image(image),
+ title(title),
+ web_contents(web_contents),
+ popup_id(-1) {}
+ PopupItem(const gfx::Image& image, const std::string& title, int32 popup_id)
+ : image(image), title(title), web_contents(NULL), popup_id(popup_id) {}
+
gfx::Image image;
std::string title;
content::WebContents* web_contents;
+ int32 popup_id;
};
typedef std::vector<PopupItem> PopupItems;
diff --git a/chrome/browser/ui/content_settings/content_setting_image_model.cc b/chrome/browser/ui/content_settings/content_setting_image_model.cc
index 97e881a..c49163b 100644
--- a/chrome/browser/ui/content_settings/content_setting_image_model.cc
+++ b/chrome/browser/ui/content_settings/content_setting_image_model.cc
@@ -174,18 +174,18 @@
TabSpecificContentSettings::FromWebContents(web_contents);
if (!content_settings)
return;
- const GeolocationSettingsState& settings_state = content_settings->
- geolocation_settings_state();
- if (settings_state.state_map().empty())
+ const ContentSettingsUsagesState& usages_state = content_settings->
+ geolocation_usages_state();
+ if (usages_state.state_map().empty())
return;
set_visible(true);
// If any embedded site has access the allowed icon takes priority over the
// blocked icon.
- unsigned int tab_state_flags = 0;
- settings_state.GetDetailedInfo(NULL, &tab_state_flags);
+ unsigned int state_flags = 0;
+ usages_state.GetDetailedInfo(NULL, &state_flags);
bool allowed =
- !!(tab_state_flags & GeolocationSettingsState::TABSTATE_HAS_ANY_ALLOWED);
+ !!(state_flags & ContentSettingsUsagesState::TABSTATE_HAS_ANY_ALLOWED);
set_icon(allowed ? IDR_ALLOWED_LOCATION : IDR_BLOCKED_LOCATION);
set_tooltip(l10n_util::GetStringUTF8(allowed ?
IDS_GEOLOCATION_ALLOWED_TOOLTIP : IDS_GEOLOCATION_BLOCKED_TOOLTIP));
diff --git a/chrome/browser/ui/extensions/extension_install_ui_default.cc b/chrome/browser/ui/extensions/extension_install_ui_default.cc
index 54e6a8a..abc00b6 100644
--- a/chrome/browser/ui/extensions/extension_install_ui_default.cc
+++ b/chrome/browser/ui/extensions/extension_install_ui_default.cc
@@ -82,7 +82,7 @@
// Helper class to put up an infobar when installation fails.
class ErrorInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
- // Creates an error delegate and adds it to |infobar_service|.
+ // Creates an error infobar delegate and adds it to |infobar_service|.
static void Create(InfoBarService* infobar_service,
const extensions::CrxInstallerError& error);
@@ -155,7 +155,7 @@
void ExtensionInstallUI::OpenAppInstalledUI(Profile* profile,
const std::string& app_id) {
#if defined(OS_CHROMEOS)
- AppListService::Get()->ShowAppList(profile);
+ AppListService::Get()->ShowForProfile(profile);
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_APP_INSTALLED_TO_APPLIST,
@@ -255,7 +255,7 @@
#endif
if (apps::IsAppLauncherEnabled()) {
- AppListService::Get()->ShowAppList(current_profile);
+ AppListService::Get()->ShowForProfile(current_profile);
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_APP_INSTALLED_TO_APPLIST,
@@ -284,7 +284,7 @@
Browser* browser = chrome::FindLastActiveWithProfile(profile_,
chrome::GetActiveDesktop());
- if (!browser) // unit tests
+ if (!browser) // Can be NULL in unittests.
return;
WebContents* web_contents =
browser->tab_strip_model()->GetActiveWebContents();
diff --git a/chrome/browser/ui/fullscreen/fullscreen_controller.cc b/chrome/browser/ui/fullscreen/fullscreen_controller.cc
index df306d6..7c1621e 100644
--- a/chrome/browser/ui/fullscreen/fullscreen_controller.cc
+++ b/chrome/browser/ui/fullscreen/fullscreen_controller.cc
@@ -142,6 +142,9 @@
if (state_prior_to_tab_fullscreen_ ==
STATE_BROWSER_FULLSCREEN_WITH_CHROME) {
EnterFullscreenModeInternal(BROWSER_WITH_CHROME);
+ } else {
+ // Clear the bubble URL, which forces the Mac UI to redraw.
+ UpdateFullscreenExitBubbleContent();
}
#endif
// If currently there is a tab in "tab fullscreen" mode and fullscreen
@@ -191,6 +194,9 @@
#if defined(OS_MACOSX)
void FullscreenController::ToggleFullscreenWithChrome() {
+ // This method cannot be called if simplified fullscreen is enabled.
+ const CommandLine* command_line = CommandLine::ForCurrentProcess();
+ DCHECK(!command_line->HasSwitch(switches::kEnableSimplifiedFullscreen));
ToggleFullscreenModeInternal(BROWSER_WITH_CHROME);
}
#endif
diff --git a/chrome/browser/ui/fullscreen/fullscreen_exit_bubble_type.cc b/chrome/browser/ui/fullscreen/fullscreen_exit_bubble_type.cc
index 6c06423..9cd835d 100644
--- a/chrome/browser/ui/fullscreen/fullscreen_exit_bubble_type.cc
+++ b/chrome/browser/ui/fullscreen/fullscreen_exit_bubble_type.cc
@@ -23,7 +23,7 @@
const ExtensionSet* extensions = extension_service->extensions();
DCHECK(extensions);
const extensions::Extension* extension =
- extensions->GetExtensionOrAppByURL(ExtensionURLInfo(url));
+ extensions->GetExtensionOrAppByURL(url);
if (extension) {
host = UTF8ToUTF16(extension->name());
} else if (url.SchemeIs(extensions::kExtensionScheme)) {
@@ -130,4 +130,4 @@
}
}
-} // namespace
+} // namespace fullscreen_bubble
diff --git a/chrome/browser/ui/gtk/action_box_button_gtk.cc b/chrome/browser/ui/gtk/action_box_button_gtk.cc
deleted file mode 100644
index cd87e8a..0000000
--- a/chrome/browser/ui/gtk/action_box_button_gtk.cc
+++ /dev/null
@@ -1,164 +0,0 @@
-// 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/ui/gtk/action_box_button_gtk.h"
-
-#include <gtk/gtk.h>
-
-#include "base/logging.h"
-#include "chrome/browser/extensions/extension_icon_image.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/gtk/custom_button.h"
-#include "chrome/browser/ui/gtk/view_id_util.h"
-#include "chrome/browser/ui/toolbar/action_box_menu_model.h"
-#include "chrome/browser/ui/view_ids.h"
-#include "chrome/common/extensions/api/extension_action/action_info.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/extension_constants.h"
-#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/layout.h"
-#include "ui/gfx/gtk_util.h"
-#include "ui/gfx/image/image_skia.h"
-#include "ui/gfx/image/image_skia_rep.h"
-
-using extensions::ActionInfo;
-using extensions::Extension;
-using extensions::IconImage;
-
-namespace {
-
-// This class provides a GtkWidget that shows an Extension's page launcher icon.
-// We can't use GtkImage directly because loading the icon from the extension
-// must be done asynchronously. The lifetime of this object is tied to its
-// GtkWidget, and it will delete itself upon receiving a "destroy" signal from
-// the widget.
-class ExtensionIcon : public IconImage::Observer {
- public:
- ExtensionIcon(Profile* profile, const Extension* extension);
-
- GtkWidget* GetWidget();
-
- private:
- virtual ~ExtensionIcon() {}
-
- virtual void OnExtensionIconImageChanged(IconImage* image) OVERRIDE;
- void UpdateIcon();
-
- CHROMEGTK_CALLBACK_0(ExtensionIcon, void, OnDestroyed);
-
- GtkWidget* image_;
-
- scoped_ptr<IconImage> icon_;
-
- DISALLOW_COPY_AND_ASSIGN(ExtensionIcon);
-};
-
-ExtensionIcon::ExtensionIcon(Profile* profile, const Extension* extension)
- : image_(NULL) {
- const ActionInfo* page_launcher_info =
- ActionInfo::GetPageLauncherInfo(extension);
- icon_.reset(new IconImage(profile,
- extension,
- page_launcher_info->default_icon,
- extension_misc::EXTENSION_ICON_ACTION,
- extensions::IconsInfo::GetDefaultAppIcon(),
- this));
- UpdateIcon();
-}
-
-GtkWidget* ExtensionIcon::GetWidget() {
- return image_;
-}
-
-void ExtensionIcon::OnExtensionIconImageChanged(IconImage* image) {
- DCHECK_EQ(image, icon_.get());
- UpdateIcon();
-}
-
-void ExtensionIcon::UpdateIcon() {
- const gfx::ImageSkiaRep& rep =
- icon_->image_skia().GetRepresentation(ui::SCALE_FACTOR_NONE);
- GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(rep.sk_bitmap());
-
- if (!image_) {
- image_ = gtk_image_new_from_pixbuf(pixbuf);
- g_signal_connect(image_, "destroy", G_CALLBACK(OnDestroyedThunk), this);
- } else {
- gtk_image_set_from_pixbuf(GTK_IMAGE(image_), pixbuf);
- }
- g_object_unref(pixbuf);
-}
-
-void ExtensionIcon::OnDestroyed(GtkWidget* sender) {
- DCHECK_EQ(sender, image_);
- delete this;
-}
-
-} // namespace
-
-ActionBoxButtonGtk::ActionBoxButtonGtk(Browser* browser)
- : controller_(browser, this),
- browser_(browser) {
- button_.reset(new CustomDrawButton(
- IDR_ACTION_BOX_BUTTON_NORMAL,
- IDR_ACTION_BOX_BUTTON_PRESSED,
- IDR_ACTION_BOX_BUTTON_HOVER,
- 0)); // TODO: disabled?
- gtk_widget_set_tooltip_text(widget(),
- l10n_util::GetStringUTF8(IDS_TOOLTIP_ACTION_BOX_BUTTON).c_str());
-
- g_signal_connect(widget(), "button-press-event",
- G_CALLBACK(OnButtonPressThunk), this);
-
- ViewIDUtil::SetID(widget(), VIEW_ID_ACTION_BOX_BUTTON);
-}
-
-ActionBoxButtonGtk::~ActionBoxButtonGtk() {
-}
-
-void ActionBoxButtonGtk:: StoppedShowing() {
- button_->UnsetPaintOverride();
-}
-
-bool ActionBoxButtonGtk::AlwaysShowIconForCmd(int command_id) const {
- return true;
-}
-
-GtkWidget* ActionBoxButtonGtk::GetImageForCommandId(int command_id) const {
- int index = model_->GetIndexOfCommandId(command_id);
- if (model_->IsItemExtension(index)) {
- const Extension* extension = model_->GetExtensionAt(index);
- return (new ExtensionIcon(browser_->profile(), extension))->GetWidget();
- }
-
- return GetDefaultImageForCommandId(command_id);
-}
-
-GtkWidget* ActionBoxButtonGtk::widget() {
- return button_->widget();
-}
-
-void ActionBoxButtonGtk::ShowMenu(scoped_ptr<ActionBoxMenuModel> model) {
- button_->SetPaintOverride(GTK_STATE_ACTIVE);
- model_ = model.Pass();
- menu_.reset(new MenuGtk(this, model_.get()));
- menu_->PopupForWidget(
- button_->widget(),
- // The mouse button. This is 1 because currently it can only be generated
- // from a mouse click, but if ShowMenu can be called in other situations
- // (e.g. other mouse buttons, or without any click at all) then it will
- // need to be that button or 0.
- 1,
- gtk_get_current_event_time());
-}
-
-gboolean ActionBoxButtonGtk::OnButtonPress(GtkWidget* widget,
- GdkEventButton* event) {
- if (event->button == 1)
- controller_.OnButtonClicked();
- return FALSE;
-}
diff --git a/chrome/browser/ui/gtk/action_box_button_gtk.h b/chrome/browser/ui/gtk/action_box_button_gtk.h
deleted file mode 100644
index 423b0cb..0000000
--- a/chrome/browser/ui/gtk/action_box_button_gtk.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_UI_GTK_ACTION_BOX_BUTTON_GTK_H_
-#define CHROME_BROWSER_UI_GTK_ACTION_BOX_BUTTON_GTK_H_
-
-#include "base/compiler_specific.h"
-#include "base/memory/scoped_ptr.h"
-#include "chrome/browser/ui/gtk/menu_gtk.h"
-#include "chrome/browser/ui/toolbar/action_box_button_controller.h"
-#include "ui/base/gtk/gtk_signal.h"
-
-class ActionBoxMenuModel;
-class Browser;
-class CustomDrawButton;
-
-typedef struct _GtkWidget GtkWidget;
-
-// This class displays the action box button with an associated menu. This is
-// where extension actions and the bookmark star live.
-class ActionBoxButtonGtk : public MenuGtk::Delegate,
- public ActionBoxButtonController::Delegate {
- public:
- explicit ActionBoxButtonGtk(Browser* browser);
- virtual ~ActionBoxButtonGtk();
-
- // MenuGtk::Delegate implementation.
- virtual void StoppedShowing() OVERRIDE;
- virtual bool AlwaysShowIconForCmd(int command_id) const OVERRIDE;
- virtual GtkWidget* GetImageForCommandId(int command_id) const OVERRIDE;
-
- GtkWidget* widget();
-
- ActionBoxButtonController* action_box_button_controller() {
- return &controller_;
- }
-
- private:
- // ActionBoxButtonController::Delegate implementation.
- virtual void ShowMenu(scoped_ptr<ActionBoxMenuModel> model) OVERRIDE;
-
- // Show the action box menu.
- CHROMEGTK_CALLBACK_1(ActionBoxButtonGtk, gboolean, OnButtonPress,
- GdkEventButton*);
-
- ActionBoxButtonController controller_;
-
- scoped_ptr<CustomDrawButton> button_;
-
- // The browser to which we will send commands.
- Browser* browser_;
-
- // The model and menu displayed when the button is clicked. The menu is
- // recreated every time it is displayed.
- scoped_ptr<ActionBoxMenuModel> model_;
- scoped_ptr<MenuGtk> menu_;
-
- DISALLOW_COPY_AND_ASSIGN(ActionBoxButtonGtk);
-};
-
-#endif // CHROME_BROWSER_UI_GTK_ACTION_BOX_BUTTON_GTK_H_
diff --git a/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.cc b/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.cc
index f854da6..c74edca 100644
--- a/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.cc
@@ -8,6 +8,7 @@
#include "base/basictypes.h"
#include "base/bind.h"
+#include "base/command_line.h"
#include "base/i18n/rtl.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
@@ -18,32 +19,63 @@
#include "chrome/browser/bookmarks/bookmark_utils.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/themes/theme_properties.h"
#include "chrome/browser/ui/bookmarks/bookmark_editor.h"
#include "chrome/browser/ui/bookmarks/recently_used_folders_combo_model.h"
#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/chrome_pages.h"
#include "chrome/browser/ui/gtk/gtk_theme_service.h"
#include "chrome/browser/ui/gtk/gtk_util.h"
+#include "chrome/browser/ui/sync/sync_promo_ui.h"
+#include "chrome/common/chrome_switches.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/user_metrics.h"
#include "grit/generated_resources.h"
#include "ui/base/gtk/gtk_hig_constants.h"
#include "ui/base/l10n/l10n_util.h"
+#include "ui/gfx/canvas_paint_gtk.h"
using content::UserMetricsAction;
namespace {
-// We basically have a singleton, since a bubble is sort of app-modal. This
-// keeps track of the currently open bubble, or NULL if none is open.
-BookmarkBubbleGtk* g_bubble = NULL;
-
enum {
COLUMN_NAME,
COLUMN_IS_SEPARATOR,
COLUMN_COUNT
};
+// Thickness of the bubble's border.
+const int kBubbleBorderThickness = 1;
+
+// Color of the bubble's border.
+const SkColor kBubbleBorderColor = SkColorSetRGB(0x63, 0x63, 0x63);
+
+// Background color of the sync promo.
+const GdkColor kPromoBackgroundColor = GDK_COLOR_RGB(0xf5, 0xf5, 0xf5);
+
+// Color of the border of the sync promo.
+const SkColor kPromoBorderColor = SkColorSetRGB(0xe5, 0xe5, 0xe5);
+
+// Color of the text in the sync promo.
+const GdkColor kPromoTextColor = GDK_COLOR_RGB(0x66, 0x66, 0x66);
+
+// Vertical padding inside the sync promo.
+const int kPromoVerticalPadding = 15;
+
+// Pango markup for the "Sign in" link in the sync promo.
+const char kPromoLinkMarkup[] =
+ "<a href='signin'><span underline='none'>%s</span></a>";
+
+// Style to make the sync promo link blue.
+const char kPromoLinkStyle[] =
+ "style \"sign-in-link\" {\n"
+ " GtkWidget::link-color=\"blue\"\n"
+ "}\n"
+ "widget \"*sign-in-link\" style \"sign-in-link\"\n";
+
gboolean IsSeparator(GtkTreeModel* model, GtkTreeIter* iter, gpointer data) {
gboolean is_separator;
gtk_tree_model_get(model, iter, COLUMN_IS_SEPARATOR, &is_separator, -1);
@@ -52,6 +84,8 @@
} // namespace
+BookmarkBubbleGtk* BookmarkBubbleGtk::bookmark_bubble_ = NULL;
+
// static
void BookmarkBubbleGtk::Show(GtkWidget* anchor,
Profile* profile,
@@ -59,9 +93,12 @@
bool newly_bookmarked) {
// Sometimes Ctrl+D may get pressed more than once on top level window
// before the bookmark bubble window is shown and takes the keyboad focus.
- if (g_bubble)
+ if (bookmark_bubble_)
return;
- g_bubble = new BookmarkBubbleGtk(anchor, profile, url, newly_bookmarked);
+ bookmark_bubble_ = new BookmarkBubbleGtk(anchor,
+ profile,
+ url,
+ newly_bookmarked);
}
void BookmarkBubbleGtk::BubbleClosing(BubbleGtk* bubble,
@@ -88,6 +125,8 @@
gtk_widget_modify_fg(*it, GTK_STATE_NORMAL, &ui::kGdkBlack);
}
}
+
+ UpdatePromoColors();
}
BookmarkBubbleGtk::BookmarkBubbleGtk(GtkWidget* anchor,
@@ -99,6 +138,8 @@
model_(BookmarkModelFactory::GetForProfile(profile)),
theme_service_(GtkThemeService::GetFrom(profile_)),
anchor_(anchor),
+ promo_(NULL),
+ promo_label_(NULL),
name_entry_(NULL),
folder_combo_(NULL),
bubble_(NULL),
@@ -117,13 +158,20 @@
GtkWidget* close_button = gtk_button_new_with_label(
l10n_util::GetStringUTF8(IDS_DONE).c_str());
+ GtkWidget* bubble_container = gtk_vbox_new(FALSE, 0);
+
+ // Prevent the content of the bubble to be drawn on the border.
+ gtk_container_set_border_width(GTK_CONTAINER(bubble_container),
+ kBubbleBorderThickness);
+
// Our content is arranged in 3 rows. |top| contains a left justified
// message, and a right justified remove link button. |table| is the middle
// portion with the name entry and the folder combo. |bottom| is the final
// row with a spacer, and the edit... and close buttons on the right.
GtkWidget* content = gtk_vbox_new(FALSE, 5);
- gtk_container_set_border_width(GTK_CONTAINER(content),
- ui::kContentAreaBorder);
+ gtk_container_set_border_width(
+ GTK_CONTAINER(content),
+ ui::kContentAreaBorder - kBubbleBorderThickness);
GtkWidget* top = gtk_hbox_new(FALSE, 0);
gtk_misc_set_alignment(GTK_MISC(label), 0, 1);
@@ -164,9 +212,57 @@
// We want the focus to start on the entry, not on the remove button.
gtk_container_set_focus_child(GTK_CONTAINER(content), table);
+ gtk_box_pack_start(GTK_BOX(bubble_container), content, TRUE, TRUE, 0);
+
+ const CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kEnableBookmarkSyncPromo) &&
+ SyncPromoUI::ShouldShowSyncPromo(profile_)) {
+ std::string link_text =
+ l10n_util::GetStringUTF8(IDS_BOOKMARK_SYNC_PROMO_LINK);
+ char* link_markup = g_markup_printf_escaped(kPromoLinkMarkup,
+ link_text.c_str());
+ string16 link_markup_utf16;
+ base::UTF8ToUTF16(link_markup, strlen(link_markup), &link_markup_utf16);
+ g_free(link_markup);
+
+ std::string promo_markup = l10n_util::GetStringFUTF8(
+ IDS_BOOKMARK_SYNC_PROMO_MESSAGE,
+ link_markup_utf16);
+
+ promo_ = gtk_event_box_new();
+ gtk_widget_set_app_paintable(promo_, TRUE);
+
+ promo_label_ = gtk_label_new(NULL);
+ gtk_label_set_markup(GTK_LABEL(promo_label_), promo_markup.c_str());
+ gtk_misc_set_alignment(GTK_MISC(promo_label_), 0.0, 0.0);
+ gtk_misc_set_padding(GTK_MISC(promo_label_),
+ ui::kContentAreaBorder,
+ kPromoVerticalPadding);
+
+ // Custom link color.
+ gtk_rc_parse_string(kPromoLinkStyle);
+
+ UpdatePromoColors();
+
+ gtk_container_add(GTK_CONTAINER(promo_), promo_label_);
+ gtk_box_pack_start(GTK_BOX(bubble_container), promo_, TRUE, TRUE, 0);
+ g_signal_connect(promo_,
+ "realize",
+ G_CALLBACK(&OnSyncPromoRealizeThunk),
+ this);
+ g_signal_connect(promo_,
+ "expose-event",
+ G_CALLBACK(&OnSyncPromoExposeThunk),
+ this);
+ g_signal_connect(promo_label_,
+ "activate-link",
+ G_CALLBACK(&OnSignInClickedThunk),
+ this);
+ }
+
bubble_ = BubbleGtk::Show(anchor_,
NULL,
- content,
+ bubble_container,
BubbleGtk::ANCHOR_TOP_RIGHT,
BubbleGtk::MATCH_SYSTEM_THEME |
BubbleGtk::POPUP_WINDOW |
@@ -197,8 +293,8 @@
}
BookmarkBubbleGtk::~BookmarkBubbleGtk() {
- DCHECK(g_bubble);
- g_bubble = NULL;
+ DCHECK(bookmark_bubble_);
+ bookmark_bubble_ = NULL;
if (apply_edits_) {
ApplyEdits();
@@ -251,6 +347,70 @@
bubble_->Close();
}
+gboolean BookmarkBubbleGtk::OnSignInClicked(GtkWidget* widget, gchar* uri) {
+ GtkWindow* window = GTK_WINDOW(gtk_widget_get_toplevel(anchor_));
+ Browser* browser = chrome::FindBrowserWithWindow(window);
+ chrome::ShowBrowserSignin(browser, SyncPromoUI::SOURCE_BOOKMARK_BUBBLE);
+ bubble_->Close();
+ return TRUE;
+}
+
+void BookmarkBubbleGtk::OnSyncPromoRealize(GtkWidget* widget) {
+ int width = gtk_util::GetWidgetSize(widget).width();
+ gtk_util::SetLabelWidth(promo_label_, width);
+}
+
+gboolean BookmarkBubbleGtk::OnSyncPromoExpose(GtkWidget* widget,
+ GdkEventExpose* event) {
+ GtkAllocation allocation;
+ gtk_widget_get_allocation(widget, &allocation);
+
+ gfx::CanvasSkiaPaint canvas(event);
+
+ // Draw a border on top of the promo.
+ canvas.DrawLine(gfx::Point(0, 0),
+ gfx::Point(allocation.width + 1, 0),
+ kPromoBorderColor);
+
+ // Redraw the rounded corners of the bubble that are hidden by the
+ // background of the promo.
+ SkPaint points_paint;
+ points_paint.setColor(kBubbleBorderColor);
+ points_paint.setStrokeWidth(SkIntToScalar(1));
+ canvas.DrawPoint(gfx::Point(0, allocation.height - 1), points_paint);
+ canvas.DrawPoint(gfx::Point(allocation.width - 1, allocation.height - 1),
+ points_paint);
+
+ return FALSE; // Propagate expose to children.
+}
+
+void BookmarkBubbleGtk::UpdatePromoColors() {
+ if (!promo_)
+ return;
+
+ GdkColor promo_background_color;
+
+ if (!theme_service_->UsingNativeTheme()) {
+ promo_background_color = kPromoBackgroundColor;
+ gtk_widget_set_name(promo_label_, "sign-in-link");
+ gtk_util::SetLabelColor(promo_label_, &kPromoTextColor);
+ } else {
+ promo_background_color = theme_service_->GetGdkColor(
+ ThemeProperties::COLOR_TOOLBAR);
+ gtk_widget_set_name(promo_label_, "sign-in-link-theme-color");
+ }
+
+ gtk_widget_modify_bg(promo_, GTK_STATE_NORMAL, &promo_background_color);
+
+ // No visible highlight color when the mouse is over the link.
+ gtk_widget_modify_base(promo_label_,
+ GTK_STATE_ACTIVE,
+ &promo_background_color);
+ gtk_widget_modify_base(promo_label_,
+ GTK_STATE_PRELIGHT,
+ &promo_background_color);
+}
+
void BookmarkBubbleGtk::ApplyEdits() {
// Set this to make sure we don't attempt to apply edits again.
apply_edits_ = false;
diff --git a/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.h b/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.h
index 22e7f4a..6452f87 100644
--- a/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.h
+++ b/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.h
@@ -17,6 +17,7 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/ui/gtk/bubble/bubble_gtk.h"
@@ -50,6 +51,11 @@
const content::NotificationDetails& details) OVERRIDE;
private:
+ friend class BookmarkBubbleGtkBrowserTest;
+ FRIEND_TEST_ALL_PREFIXES(BookmarkBubbleGtkBrowserTest, SyncPromoSignedIn);
+ FRIEND_TEST_ALL_PREFIXES(BookmarkBubbleGtkBrowserTest, SyncPromoNotSignedIn);
+ FRIEND_TEST_ALL_PREFIXES(BookmarkBubbleGtkBrowserTest, SyncPromoLink);
+
BookmarkBubbleGtk(GtkWidget* anchor,
Profile* profile,
const GURL& url,
@@ -63,6 +69,18 @@
CHROMEGTK_CALLBACK_0(BookmarkBubbleGtk, void, OnEditClicked);
CHROMEGTK_CALLBACK_0(BookmarkBubbleGtk, void, OnCloseClicked);
CHROMEGTK_CALLBACK_0(BookmarkBubbleGtk, void, OnRemoveClicked);
+ CHROMEGTK_CALLBACK_1(BookmarkBubbleGtk,
+ gboolean,
+ OnSignInClicked,
+ gchar*);
+ CHROMEGTK_CALLBACK_0(BookmarkBubbleGtk, void, OnSyncPromoRealize);
+ CHROMEGTK_CALLBACK_1(BookmarkBubbleGtk,
+ gboolean,
+ OnSyncPromoExpose,
+ GdkEventExpose*);
+
+ // Sets the colors used in the sync promo according to the current theme.
+ void UpdatePromoColors();
// Update the bookmark with any edits that have been made.
void ApplyEdits();
@@ -75,6 +93,10 @@
void InitFolderComboModel();
+ // We basically have a singleton, since a bubble is sort of app-modal. This
+ // keeps track of the currently open bubble, or NULL if none is open.
+ static BookmarkBubbleGtk* bookmark_bubble_;
+
// The URL of the bookmark.
GURL url_;
@@ -93,6 +115,12 @@
// The button that removes the bookmark.
GtkWidget* remove_button_;
+ // The bookmark sync promo, if shown.
+ GtkWidget* promo_;
+
+ // The label in the bookmark sync promo, if shown.
+ GtkWidget* promo_label_;
+
// The various labels in the interface. We keep track of them for theme
// changes.
std::vector<GtkWidget*> labels_;
diff --git a/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk_browsertest.cc b/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk_browsertest.cc
new file mode 100644
index 0000000..f1fb093
--- /dev/null
+++ b/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk_browsertest.cc
@@ -0,0 +1,85 @@
+// Copyright 2013 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/ui/gtk/bookmarks/bookmark_bubble_gtk.h"
+
+#include "base/command_line.h"
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/bookmarks/bookmark_model_factory.h"
+#include "chrome/browser/bookmarks/bookmark_utils.h"
+#include "chrome/browser/signin/signin_manager.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "content/public/browser/web_contents.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+const char kTestBookmarkURL[] = "http://www.google.com";
+} // namespace
+
+class BookmarkBubbleGtkBrowserTest : public InProcessBrowserTest {
+ public:
+ BookmarkBubbleGtkBrowserTest() {}
+
+ // content::BrowserTestBase:
+ virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+ command_line->AppendSwitch(switches::kEnableBookmarkSyncPromo);
+ }
+
+ virtual void SetUpOnMainThread() OVERRIDE {
+ bookmark_utils::AddIfNotBookmarked(
+ BookmarkModelFactory::GetForProfile(browser()->profile()),
+ GURL(kTestBookmarkURL),
+ string16());
+ }
+
+ protected:
+ // Creates a bookmark bubble.
+ void CreateBookmarkBubble() {
+ BookmarkBubbleGtk::Show(GTK_WIDGET(browser()->window()->GetNativeWindow()),
+ browser()->profile(),
+ GURL(kTestBookmarkURL),
+ true);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BookmarkBubbleGtkBrowserTest);
+};
+
+// Verifies that the sync promo is not displayed for a signed in user.
+IN_PROC_BROWSER_TEST_F(BookmarkBubbleGtkBrowserTest, SyncPromoSignedIn) {
+ SigninManager* signin = SigninManagerFactory::GetForProfile(
+ browser()->profile());
+ signin->SetAuthenticatedUsername("fake_username");
+
+ CreateBookmarkBubble();
+ EXPECT_FALSE(BookmarkBubbleGtk::bookmark_bubble_->promo_);
+}
+
+// Verifies that the sync promo is displayed for a user that is not signed in.
+IN_PROC_BROWSER_TEST_F(BookmarkBubbleGtkBrowserTest, SyncPromoNotSignedIn) {
+ CreateBookmarkBubble();
+ EXPECT_TRUE(BookmarkBubbleGtk::bookmark_bubble_->promo_);
+}
+
+// Verifies that a new tab is opened when the "Sign in" link is clicked.
+IN_PROC_BROWSER_TEST_F(BookmarkBubbleGtkBrowserTest, SyncPromoLink) {
+ GURL initial_url =
+ browser()->tab_strip_model()->GetActiveWebContents()->GetVisibleURL();
+ CreateBookmarkBubble();
+
+ // Simulate clicking the "Sign in" link.
+ BookmarkBubbleGtk::bookmark_bubble_->OnSignInClicked(NULL, NULL);
+
+ EXPECT_NE(
+ initial_url,
+ browser()->tab_strip_model()->GetActiveWebContents()->GetVisibleURL());
+}
+
diff --git a/chrome/browser/ui/gtk/extensions/media_galleries_dialog_gtk_unittest.cc b/chrome/browser/ui/gtk/extensions/media_galleries_dialog_gtk_unittest.cc
index 5490cec..089cf89 100644
--- a/chrome/browser/ui/gtk/extensions/media_galleries_dialog_gtk_unittest.cc
+++ b/chrome/browser/ui/gtk/extensions/media_galleries_dialog_gtk_unittest.cc
@@ -6,7 +6,6 @@
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/media_galleries/media_galleries_dialog_controller_mock.h"
#include "chrome/browser/storage_monitor/storage_info.h"
-#include "chrome/browser/storage_monitor/test_storage_monitor.h"
#include "chrome/browser/ui/gtk/extensions/media_galleries_dialog_gtk.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -33,8 +32,6 @@
} // namespace
class MediaGalleriesDialogTest : public testing::Test {
- private:
- test::TestStorageMonitor test_storage_monitor_;
};
// Tests that checkboxes are initialized according to the contents of
diff --git a/chrome/browser/ui/gtk/extensions/native_app_window_gtk.cc b/chrome/browser/ui/gtk/extensions/native_app_window_gtk.cc
index e96e322..4154834 100644
--- a/chrome/browser/ui/gtk/extensions/native_app_window_gtk.cc
+++ b/chrome/browser/ui/gtk/extensions/native_app_window_gtk.cc
@@ -4,6 +4,10 @@
#include "chrome/browser/ui/gtk/extensions/native_app_window_gtk.h"
+#include <gdk/gdkx.h>
+#include <vector>
+
+#include "base/message_loop/message_pump_gtk.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/gtk/extensions/extension_keybinding_registry_gtk.h"
@@ -28,6 +32,12 @@
// gtk_window_get_position() after the last GTK configure-event signal.
const int kDebounceTimeoutMilliseconds = 100;
+const char* kAtomsToCache[] = {
+ "_NET_WM_STATE",
+ "_NET_WM_STATE_HIDDEN",
+ NULL
+};
+
} // namespace
NativeAppWindowGtk::NativeAppWindowGtk(ShellWindow* shell_window,
@@ -38,7 +48,9 @@
is_active_(false),
content_thinks_its_fullscreen_(false),
frameless_(params.frame == ShellWindow::FRAME_NONE),
- frame_cursor_(NULL) {
+ frame_cursor_(NULL),
+ atom_cache_(base::MessagePumpGtk::GetDefaultXDisplay(), kAtomsToCache),
+ is_x_event_listened_(false) {
window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
gfx::NativeView native_view =
@@ -128,6 +140,25 @@
G_CALLBACK(OnMouseMoveEventThunk), this);
}
+ // If _NET_WM_STATE_HIDDEN is in _NET_SUPPORTED, listen for XEvent to work
+ // around GTK+ not reporting minimization state changes. See comment in the
+ // |OnXEvent|.
+ std::vector< ::Atom> supported_atoms;
+ if (ui::GetAtomArrayProperty(ui::GetX11RootWindow(),
+ "_NET_SUPPORTED",
+ &supported_atoms)) {
+ if (std::find(supported_atoms.begin(),
+ supported_atoms.end(),
+ atom_cache_.GetAtom("_NET_WM_STATE_HIDDEN")) !=
+ supported_atoms.end()) {
+ GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(window_));
+ gdk_window_add_filter(window,
+ &NativeAppWindowGtk::OnXEventThunk,
+ this);
+ is_x_event_listened_ = true;
+ }
+ }
+
// Add the keybinding registry.
extension_keybinding_registry_.reset(new ExtensionKeybindingRegistryGtk(
shell_window_->profile(),
@@ -140,6 +171,11 @@
NativeAppWindowGtk::~NativeAppWindowGtk() {
ui::ActiveWindowWatcherX::RemoveObserver(this);
+ if (is_x_event_listened_) {
+ gdk_window_remove_filter(NULL,
+ &NativeAppWindowGtk::OnXEventThunk,
+ this);
+ }
}
bool NativeAppWindowGtk::IsActive() const {
@@ -224,6 +260,10 @@
}
void NativeAppWindowGtk::Maximize() {
+ // Represent the window first in order to keep the maximization behavior
+ // consistency with Windows platform. Otherwise the window will be hidden if
+ // it has been minimized.
+ gtk_window_present(window_);
gtk_window_maximize(window_);
}
@@ -236,6 +276,12 @@
gtk_window_unmaximize(window_);
else if (IsMinimized())
gtk_window_deiconify(window_);
+
+ // Represent the window to keep restoration behavior consistency with Windows
+ // platform.
+ // TODO(zhchbin): verify whether we need this until http://crbug.com/261013 is
+ // fixed.
+ gtk_window_present(window_);
}
void NativeAppWindowGtk::SetBounds(const gfx::Rect& bounds) {
@@ -257,6 +303,33 @@
}
}
+GdkFilterReturn NativeAppWindowGtk::OnXEvent(GdkXEvent* gdk_x_event,
+ GdkEvent* gdk_event) {
+ // Work around GTK+ not reporting minimization state changes. Listen
+ // for _NET_WM_STATE property changes and use _NET_WM_STATE_HIDDEN's
+ // presence to set or clear the iconified bit if _NET_WM_STATE_HIDDEN
+ // is supported. http://crbug.com/162794.
+ XEvent* x_event = static_cast<XEvent*>(gdk_x_event);
+ std::vector< ::Atom> atom_list;
+
+ if (x_event->type == PropertyNotify &&
+ x_event->xproperty.atom == atom_cache_.GetAtom("_NET_WM_STATE") &&
+ ui::GetAtomArrayProperty(GDK_WINDOW_XWINDOW(GTK_WIDGET(window_)->window),
+ "_NET_WM_STATE",
+ &atom_list)) {
+ std::vector< ::Atom>::iterator it =
+ std::find(atom_list.begin(),
+ atom_list.end(),
+ atom_cache_.GetAtom("_NET_WM_STATE_HIDDEN"));
+ state_ = (it != atom_list.end()) ? GDK_WINDOW_STATE_ICONIFIED :
+ static_cast<GdkWindowState>(state_ & ~GDK_WINDOW_STATE_ICONIFIED);
+
+ shell_window_->OnNativeWindowChanged();
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
void NativeAppWindowGtk::FlashFrame(bool flash) {
gtk_window_set_urgency_hint(window_, flash);
}
diff --git a/chrome/browser/ui/gtk/extensions/native_app_window_gtk.h b/chrome/browser/ui/gtk/extensions/native_app_window_gtk.h
index 2b71243..ce5ece9 100644
--- a/chrome/browser/ui/gtk/extensions/native_app_window_gtk.h
+++ b/chrome/browser/ui/gtk/extensions/native_app_window_gtk.h
@@ -15,6 +15,7 @@
#include "third_party/skia/include/core/SkRegion.h"
#include "ui/base/gtk/gtk_signal.h"
#include "ui/base/x/active_window_watcher_x_observer.h"
+#include "ui/base/x/x11_atom_cache.h"
#include "ui/gfx/rect.h"
class ExtensionKeybindingRegistryGtk;
@@ -102,6 +103,9 @@
GdkEventMotion*);
CHROMEGTK_CALLBACK_1(NativeAppWindowGtk, gboolean, OnButtonPress,
GdkEventButton*);
+ // Callback for PropertyChange XEvents.
+ CHROMEG_CALLBACK_1(NativeAppWindowGtk, GdkFilterReturn,
+ OnXEvent, GdkXEvent*, GdkEvent*);
void OnConfigureDebounced();
@@ -155,6 +159,11 @@
// updating its dimensions.
ObserverList<web_modal::WebContentsModalDialogHostObserver> observer_list_;
+ ui::X11AtomCache atom_cache_;
+
+ // True if we listen for the XEvent.
+ bool is_x_event_listened_;
+
DISALLOW_COPY_AND_ASSIGN(NativeAppWindowGtk);
};
diff --git a/chrome/browser/ui/gtk/infobars/extension_infobar_gtk.cc b/chrome/browser/ui/gtk/infobars/extension_infobar_gtk.cc
index bb87abb..c12d975 100644
--- a/chrome/browser/ui/gtk/infobars/extension_infobar_gtk.cc
+++ b/chrome/browser/ui/gtk/infobars/extension_infobar_gtk.cc
@@ -47,15 +47,15 @@
icon_(NULL),
alignment_(NULL),
weak_ptr_factory_(this) {
- delegate->set_observer(this);
+ GetDelegate()->set_observer(this);
- int height = delegate->height();
+ int height = GetDelegate()->height();
SetBarTargetHeight((height > 0) ? (height + kSeparatorLineHeight) : 0);
}
ExtensionInfoBarGtk::~ExtensionInfoBarGtk() {
- if (delegate_)
- delegate_->set_observer(NULL);
+ if (GetDelegate())
+ GetDelegate()->set_observer(NULL);
}
void ExtensionInfoBarGtk::PlatformSpecificHide(bool animate) {
@@ -75,42 +75,6 @@
*r = *g = *b = 218.0 / 255.0;
}
-void ExtensionInfoBarGtk::OnImageLoaded(const gfx::Image& image) {
-
- DCHECK(icon_);
- // TODO(erg): IDR_EXTENSIONS_SECTION should have an IDR_INFOBAR_EXTENSIONS
- // icon of the correct size with real subpixel shading and such.
- const gfx::ImageSkia* icon = NULL;
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- if (image.IsEmpty())
- icon = rb.GetImageSkiaNamed(IDR_EXTENSIONS_SECTION);
- else
- icon = image.ToImageSkia();
-
- SkBitmap bitmap;
- if (button_) {
- gfx::ImageSkia* drop_image = rb.GetImageSkiaNamed(IDR_APP_DROPARROW);
-
- int image_size = extension_misc::EXTENSION_ICON_BITTY;
- // The margin between the extension icon and the drop-down arrow bitmap.
- static const int kDropArrowLeftMargin = 3;
- scoped_ptr<gfx::Canvas> canvas(new gfx::Canvas(
- gfx::Size(image_size + kDropArrowLeftMargin + drop_image->width(),
- image_size), ui::SCALE_FACTOR_100P, false));
- canvas->DrawImageInt(*icon, 0, 0, icon->width(), icon->height(), 0, 0,
- image_size, image_size, false);
- canvas->DrawImageInt(*drop_image, image_size + kDropArrowLeftMargin,
- image_size / 2);
- bitmap = canvas->ExtractImageRep().sk_bitmap();
- } else {
- bitmap = *icon->bitmap();
- }
-
- GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(bitmap);
- gtk_image_set_from_pixbuf(GTK_IMAGE(icon_), pixbuf);
- g_object_unref(pixbuf);
-}
-
void ExtensionInfoBarGtk::InitWidgets() {
InfoBarGtk::InitWidgets();
@@ -124,7 +88,7 @@
icon_ = gtk_image_new();
gtk_misc_set_alignment(GTK_MISC(icon_), 0.5, 0.5);
- extensions::ExtensionHost* extension_host = delegate_->extension_host();
+ extensions::ExtensionHost* extension_host = GetDelegate()->extension_host();
const extensions::Extension* extension = extension_host->extension();
if (extension->ShowConfigureContextMenus()) {
@@ -147,7 +111,7 @@
ExtensionIconSet::MATCH_EXACTLY);
// Load image asynchronously, calling back OnImageLoaded.
extensions::ImageLoader* loader =
- extensions::ImageLoader::Get(delegate_->extension_host()->profile());
+ extensions::ImageLoader::Get(extension_host->profile());
loader->LoadImageAsync(extension, icon_resource,
gfx::Size(extension_misc::EXTENSION_ICON_BITTY,
extension_misc::EXTENSION_ICON_BITTY),
@@ -186,6 +150,46 @@
delegate_ = NULL;
}
+void ExtensionInfoBarGtk::OnImageLoaded(const gfx::Image& image) {
+
+ DCHECK(icon_);
+ // TODO(erg): IDR_EXTENSIONS_SECTION should have an IDR_INFOBAR_EXTENSIONS
+ // icon of the correct size with real subpixel shading and such.
+ const gfx::ImageSkia* icon = NULL;
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ if (image.IsEmpty())
+ icon = rb.GetImageSkiaNamed(IDR_EXTENSIONS_SECTION);
+ else
+ icon = image.ToImageSkia();
+
+ SkBitmap bitmap;
+ if (button_) {
+ gfx::ImageSkia* drop_image = rb.GetImageSkiaNamed(IDR_APP_DROPARROW);
+
+ int image_size = extension_misc::EXTENSION_ICON_BITTY;
+ // The margin between the extension icon and the drop-down arrow bitmap.
+ static const int kDropArrowLeftMargin = 3;
+ scoped_ptr<gfx::Canvas> canvas(new gfx::Canvas(
+ gfx::Size(image_size + kDropArrowLeftMargin + drop_image->width(),
+ image_size), ui::SCALE_FACTOR_100P, false));
+ canvas->DrawImageInt(*icon, 0, 0, icon->width(), icon->height(), 0, 0,
+ image_size, image_size, false);
+ canvas->DrawImageInt(*drop_image, image_size + kDropArrowLeftMargin,
+ image_size / 2);
+ bitmap = canvas->ExtractImageRep().sk_bitmap();
+ } else {
+ bitmap = *icon->bitmap();
+ }
+
+ GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(bitmap);
+ gtk_image_set_from_pixbuf(GTK_IMAGE(icon_), pixbuf);
+ g_object_unref(pixbuf);
+}
+
+ExtensionInfoBarDelegate* ExtensionInfoBarGtk::GetDelegate() {
+ return delegate_ ? delegate_->AsExtensionInfoBarDelegate() : NULL;
+}
+
Browser* ExtensionInfoBarGtk::GetBrowser() {
DCHECK(icon_);
// Get the Browser object this infobar is attached to.
@@ -196,7 +200,7 @@
}
ExtensionContextMenuModel* ExtensionInfoBarGtk::BuildMenuModel() {
- const extensions::Extension* extension = delegate_->extension();
+ const extensions::Extension* extension = GetDelegate()->extension();
if (!extension->ShowConfigureContextMenus())
return NULL;
@@ -211,7 +215,7 @@
GtkAllocation* allocation) {
gfx::Size new_size(allocation->width, allocation->height);
- delegate_->extension_host()->view()->render_view_host()->GetView()->
+ GetDelegate()->extension_host()->view()->render_view_host()->GetView()->
SetSize(new_size);
}
diff --git a/chrome/browser/ui/gtk/infobars/extension_infobar_gtk.h b/chrome/browser/ui/gtk/infobars/extension_infobar_gtk.h
index 3cd73d8..71c9c2a 100644
--- a/chrome/browser/ui/gtk/infobars/extension_infobar_gtk.h
+++ b/chrome/browser/ui/gtk/infobars/extension_infobar_gtk.h
@@ -42,6 +42,8 @@
void OnImageLoaded(const gfx::Image& image);
+ ExtensionInfoBarDelegate* GetDelegate();
+
// Looks at the window the infobar is in and gets the browser. Can return
// NULL if we aren't attached.
Browser* GetBrowser();
@@ -59,7 +61,10 @@
CHROMEGTK_CALLBACK_1(ExtensionInfoBarGtk, gboolean, OnExpose,
GdkEventExpose*);
- ExtensionInfoBarDelegate* delegate_;
+ // TODO(pkasting): This shadows InfoBarView::delegate_. Get rid of this once
+ // InfoBars own their delegates (and thus we don't need the DelegateObserver
+ // functionality). For now, almost everyone should use GetDelegate() instead.
+ InfoBarDelegate* delegate_;
ExtensionViewGtk* view_;
diff --git a/chrome/browser/ui/gtk/infobars/infobar_gtk.cc b/chrome/browser/ui/gtk/infobars/infobar_gtk.cc
index 49907ea..ab2417b 100644
--- a/chrome/browser/ui/gtk/infobars/infobar_gtk.cc
+++ b/chrome/browser/ui/gtk/infobars/infobar_gtk.cc
@@ -7,7 +7,6 @@
#include "base/debug/trace_event.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/themes/theme_properties.h"
#include "chrome/browser/ui/gtk/browser_window_gtk.h"
diff --git a/chrome/browser/ui/gtk/infobars/translate_infobar_base_gtk.cc b/chrome/browser/ui/gtk/infobars/translate_infobar_base_gtk.cc
index a31fc6f..1d06498 100644
--- a/chrome/browser/ui/gtk/infobars/translate_infobar_base_gtk.cc
+++ b/chrome/browser/ui/gtk/infobars/translate_infobar_base_gtk.cc
@@ -52,7 +52,7 @@
background_color_animation_->Hide();
}
} else {
- background_error_percent_ = delegate->IsError() ? 1 : 0;
+ background_error_percent_ = delegate->is_error() ? 1 : 0;
}
}
@@ -127,7 +127,7 @@
return;
// The options button sits outside the translate_box so that it can be end
- // packed in hbox_.
+ // packed in hbox().
GtkWidget* options_menu_button = CreateMenuButton(
l10n_util::GetStringUTF8(IDS_TRANSLATE_INFOBAR_OPTIONS));
signals()->Connect(options_menu_button, "clicked",
diff --git a/chrome/browser/ui/gtk/location_bar_view_gtk.cc b/chrome/browser/ui/gtk/location_bar_view_gtk.cc
index 3a012b8..13adaa0 100644
--- a/chrome/browser/ui/gtk/location_bar_view_gtk.cc
+++ b/chrome/browser/ui/gtk/location_bar_view_gtk.cc
@@ -47,7 +47,6 @@
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"
#include "chrome/browser/ui/content_settings/content_setting_image_model.h"
-#include "chrome/browser/ui/gtk/action_box_button_gtk.h"
#include "chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.h"
#include "chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h"
#include "chrome/browser/ui/gtk/browser_window_gtk.h"
@@ -487,19 +486,6 @@
// doesn't work, someone is probably calling show_all on our parent box.
gtk_box_pack_end(GTK_BOX(entry_box_), tab_to_search_hint_, FALSE, FALSE, 0);
- if (extensions::FeatureSwitch::action_box()->IsEnabled()) {
- // TODO(mpcomplete): should we hide this if ShouldOnlyShowLocation()==true?
- action_box_button_.reset(new ActionBoxButtonGtk(browser_));
-
- GtkWidget* alignment = gtk_alignment_new(0, 0, 1, 1);
- gtk_alignment_set_padding(GTK_ALIGNMENT(alignment),
- 0, 0, 0, InnerPadding());
- gtk_container_add(GTK_CONTAINER(alignment), action_box_button_->widget());
-
- gtk_box_pack_end(GTK_BOX(hbox_.get()), alignment,
- FALSE, FALSE, 0);
- }
-
if (browser_defaults::bookmarks_enabled && !ShouldOnlyShowLocation()) {
// Hide the star icon in popups, app windows, etc.
CreateStarButton();
@@ -1029,11 +1015,6 @@
page_action_views_[index]->TestActivatePageAction();
}
-void LocationBarViewGtk::TestActionBoxMenuItemSelected(int command_id) {
- action_box_button_->action_box_button_controller()->
- ExecuteCommand(command_id, 0);
-}
-
bool LocationBarViewGtk::GetBookmarkStarVisibility() {
return starred_;
}
@@ -1216,7 +1197,7 @@
GTK_IMAGE(location_icon_image_),
theme_service_->GetImageNamed(resource_id).ToGdkPixbuf());
- if (toolbar_model_->GetSecurityLevel() == ToolbarModel::EV_SECURE) {
+ if (toolbar_model_->GetSecurityLevel(false) == ToolbarModel::EV_SECURE) {
if (!gtk_util::IsActingAsRoundedWindow(site_type_event_box_)) {
// Fun fact: If wee try to make |site_type_event_box_| act as a
// rounded window while it doesn't have a visible window, GTK interprets
@@ -1622,9 +1603,6 @@
command_updater_->UpdateCommandEnabled(IDC_BOOKMARK_PAGE, star_enabled);
command_updater_->UpdateCommandEnabled(IDC_BOOKMARK_PAGE_FROM_STAR,
star_enabled);
- if (extensions::FeatureSwitch::action_box()->IsEnabled() && !starred_) {
- star_enabled = false;
- }
if (star_enabled) {
gtk_widget_show_all(star_.get());
int id = starred_ ? IDR_STAR_LIT : IDR_STAR;
diff --git a/chrome/browser/ui/gtk/location_bar_view_gtk.h b/chrome/browser/ui/gtk/location_bar_view_gtk.h
index c046b53..c886f32 100644
--- a/chrome/browser/ui/gtk/location_bar_view_gtk.h
+++ b/chrome/browser/ui/gtk/location_bar_view_gtk.h
@@ -36,7 +36,6 @@
#include "ui/base/window_open_disposition.h"
#include "url/gurl.h"
-class ActionBoxButtonGtk;
class Browser;
class CommandUpdater;
class ContentSettingImageModel;
@@ -150,7 +149,6 @@
virtual ExtensionAction* GetPageAction(size_t index) OVERRIDE;
virtual ExtensionAction* GetVisiblePageAction(size_t index) OVERRIDE;
virtual void TestPageActionPressed(size_t index) OVERRIDE;
- virtual void TestActionBoxMenuItemSelected(int command_id) OVERRIDE;
virtual bool GetBookmarkStarVisibility() OVERRIDE;
// content::NotificationObserver:
@@ -484,8 +482,6 @@
// Alignment used to wrap |location_entry_|.
GtkWidget* location_entry_alignment_;
- scoped_ptr<ActionBoxButtonGtk> action_box_button_;
-
CommandUpdater* command_updater_;
ToolbarModel* toolbar_model_;
Browser* browser_;
diff --git a/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.cc b/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.cc
index 5cc63a8..c931846 100644
--- a/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.cc
+++ b/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.cc
@@ -457,7 +457,7 @@
model()->UpdatePermanentText(toolbar_model()->GetText(true));
ToolbarModel::SecurityLevel security_level =
- toolbar_model()->GetSecurityLevel();
+ toolbar_model()->GetSecurityLevel(false);
bool changed_security_level = (security_level != security_level_);
security_level_ = security_level;
@@ -1261,7 +1261,7 @@
G_CALLBACK(HandleCopyURLClipboardThunk), this);
gtk_widget_set_sensitive(
copy_url_menuitem,
- toolbar_model()->WouldReplaceSearchURLWithSearchTerms() &&
+ toolbar_model()->WouldReplaceSearchURLWithSearchTerms(false) &&
!model()->user_input_in_progress());
gtk_widget_show(copy_url_menuitem);
}
diff --git a/chrome/browser/ui/gtk/status_icons/status_tray_gtk.cc b/chrome/browser/ui/gtk/status_icons/status_tray_gtk.cc
index 04bc250..ecff525 100644
--- a/chrome/browser/ui/gtk/status_icons/status_tray_gtk.cc
+++ b/chrome/browser/ui/gtk/status_icons/status_tray_gtk.cc
@@ -12,7 +12,7 @@
StatusTrayGtk::~StatusTrayGtk() {
}
-StatusIcon* StatusTrayGtk::CreatePlatformStatusIcon() {
+StatusIcon* StatusTrayGtk::CreatePlatformStatusIcon(StatusIconType type) {
return new StatusIconGtk();
}
diff --git a/chrome/browser/ui/gtk/status_icons/status_tray_gtk.h b/chrome/browser/ui/gtk/status_icons/status_tray_gtk.h
index cd7a0b4..3e010d7 100644
--- a/chrome/browser/ui/gtk/status_icons/status_tray_gtk.h
+++ b/chrome/browser/ui/gtk/status_icons/status_tray_gtk.h
@@ -15,7 +15,7 @@
protected:
// Overriden from StatusTray:
- virtual StatusIcon* CreatePlatformStatusIcon() OVERRIDE;
+ virtual StatusIcon* CreatePlatformStatusIcon(StatusIconType type) OVERRIDE;
private:
DISALLOW_COPY_AND_ASSIGN(StatusTrayGtk);
diff --git a/chrome/browser/ui/gtk/status_icons/status_tray_gtk_unittest.cc b/chrome/browser/ui/gtk/status_icons/status_tray_gtk_unittest.cc
index 8d96513..3cf40d0 100644
--- a/chrome/browser/ui/gtk/status_icons/status_tray_gtk_unittest.cc
+++ b/chrome/browser/ui/gtk/status_icons/status_tray_gtk_unittest.cc
@@ -29,7 +29,7 @@
TEST(StatusTrayGtkTest, CreateIcon) {
// Create an icon, set the images and tooltip, then shut it down.
StatusTrayGtk tray;
- StatusIcon* icon = tray.CreateStatusIcon();
+ StatusIcon* icon = tray.CreateStatusIcon(StatusTray::OTHER_ICON);
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
gfx::ImageSkia* image = rb.GetImageSkiaNamed(IDR_STATUS_TRAY_ICON);
icon->SetImage(*image);
@@ -43,7 +43,8 @@
TEST(StatusTrayGtkTest, ClickOnIcon) {
// Create an icon, send a fake click event, make sure observer is called.
StatusTrayGtk tray;
- StatusIconGtk* icon = static_cast<StatusIconGtk*>(tray.CreateStatusIcon());
+ StatusIconGtk* icon = static_cast<StatusIconGtk*>(
+ tray.CreateStatusIcon(StatusTray::OTHER_ICON));
MockStatusIconObserver observer;
icon->AddObserver(&observer);
EXPECT_CALL(observer, OnStatusIconClicked());
diff --git a/chrome/browser/ui/gtk/tab_modal_confirm_dialog_gtk.cc b/chrome/browser/ui/gtk/tab_modal_confirm_dialog_gtk.cc
index 9b98a30..7f419a3 100644
--- a/chrome/browser/ui/gtk/tab_modal_confirm_dialog_gtk.cc
+++ b/chrome/browser/ui/gtk/tab_modal_confirm_dialog_gtk.cc
@@ -31,7 +31,8 @@
TabModalConfirmDialogGtk::TabModalConfirmDialogGtk(
TabModalConfirmDialogDelegate* delegate,
content::WebContents* web_contents)
- : delegate_(delegate),
+ : web_contents_(web_contents),
+ delegate_(delegate),
window_(NULL) {
dialog_ = gtk_vbox_new(FALSE, ui::kContentAreaSpacing);
GtkWidget* label = gtk_label_new(
@@ -100,7 +101,7 @@
g_signal_connect(dialog_, "destroy", G_CALLBACK(OnDestroyThunk), this);
window_ = CreateWebContentsModalDialogGtk(dialog_, cancel_);
- delegate_->set_close_delegate(this);
+ delegate_->set_operations_delegate(this);
WebContentsModalDialogManager* web_contents_modal_dialog_manager =
WebContentsModalDialogManager::FromWebContents(web_contents);
@@ -108,6 +109,10 @@
}
TabModalConfirmDialogGtk::~TabModalConfirmDialogGtk() {
+ // Provide a disposition in case the dialog was closed without accepting or
+ // cancelling.
+ delegate_->Cancel();
+
gtk_widget_destroy(dialog_);
}
@@ -123,6 +128,13 @@
gtk_widget_destroy(window_);
}
+void TabModalConfirmDialogGtk::SetPreventCloseOnLoadStart(bool prevent) {
+ WebContentsModalDialogManager* web_contents_modal_dialog_manager =
+ WebContentsModalDialogManager::FromWebContents(web_contents_);
+ web_contents_modal_dialog_manager->SetPreventCloseOnLoadStart(window_,
+ prevent);
+}
+
void TabModalConfirmDialogGtk::OnAccept(GtkWidget* widget) {
delegate_->Accept();
}
diff --git a/chrome/browser/ui/gtk/tab_modal_confirm_dialog_gtk.h b/chrome/browser/ui/gtk/tab_modal_confirm_dialog_gtk.h
index 8c7104a..bdbff19 100644
--- a/chrome/browser/ui/gtk/tab_modal_confirm_dialog_gtk.h
+++ b/chrome/browser/ui/gtk/tab_modal_confirm_dialog_gtk.h
@@ -38,8 +38,9 @@
virtual void AcceptTabModalDialog() OVERRIDE;
virtual void CancelTabModalDialog() OVERRIDE;
- // TabModalConfirmDialogCloseDelegate:
+ // TabModalConfirmDialogOperationsDelegate:
virtual void CloseDialog() OVERRIDE;
+ virtual void SetPreventCloseOnLoadStart(bool prevent) OVERRIDE;
// Callbacks:
CHROMEGTK_CALLBACK_0(TabModalConfirmDialogGtk, void, OnAccept);
@@ -47,6 +48,8 @@
CHROMEGTK_CALLBACK_0(TabModalConfirmDialogGtk, void, OnDestroy);
CHROMEGTK_CALLBACK_0(TabModalConfirmDialogGtk, void, OnLinkClicked);
+ content::WebContents* web_contents_;
+
scoped_ptr<TabModalConfirmDialogDelegate> delegate_;
GtkWidget* dialog_;
diff --git a/chrome/browser/ui/hung_plugin_tab_helper.cc b/chrome/browser/ui/hung_plugin_tab_helper.cc
index 648cba4..1428d1a 100644
--- a/chrome/browser/ui/hung_plugin_tab_helper.cc
+++ b/chrome/browser/ui/hung_plugin_tab_helper.cc
@@ -131,8 +131,8 @@
class HungPluginInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
- // Creates a hung plugin delegate and adds it to |infobar_service|. Returns
- // the delegate if it was successfully added.
+ // Creates a hung plugin infobar delegate and adds it to |infobar_service|.
+ // Returns the delegate if it was successfully added.
static HungPluginInfoBarDelegate* Create(InfoBarService* infobar_service,
HungPluginTabHelper* helper,
int plugin_child_id,
@@ -234,8 +234,7 @@
base::Timer timer;
private:
- // Delay in seconds before re-showing the hung plugin message. This will be
- // increased each time.
+ // Initial delay in seconds before re-showing the hung plugin message.
static const int kInitialReshowDelaySec;
// Since the scope of the timer manages our callback, this struct should
@@ -329,7 +328,6 @@
const content::NotificationSource& source,
const content::NotificationDetails& details) {
DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type);
-
// Note: do not dereference. The InfoBarContainer will delete the object when
// it gets this notification, we only remove our tracking info, if we have
// any.
@@ -338,7 +336,6 @@
// InfoBars own their delegates.
InfoBarDelegate* infobar =
content::Details<InfoBarRemovedDetails>(details)->first;
-
for (PluginStateMap::iterator i = hung_plugins_.begin();
i != hung_plugins_.end(); ++i) {
PluginState* state = i->second.get();
@@ -421,9 +418,8 @@
return;
DCHECK(!state->infobar);
- state->infobar =
- HungPluginInfoBarDelegate::Create(infobar_service, this, child_id,
- state->name);
+ state->infobar = HungPluginInfoBarDelegate::Create(infobar_service, this,
+ child_id, state->name);
}
void HungPluginTabHelper::CloseBar(PluginState* state) {
diff --git a/chrome/browser/ui/libgtk2ui/app_indicator_icon.cc b/chrome/browser/ui/libgtk2ui/app_indicator_icon.cc
new file mode 100644
index 0000000..ff4b79f
--- /dev/null
+++ b/chrome/browser/ui/libgtk2ui/app_indicator_icon.cc
@@ -0,0 +1,383 @@
+// Copyright 2013 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/ui/libgtk2ui/app_indicator_icon.h"
+
+#include <gtk/gtk.h>
+#include <dlfcn.h>
+
+#include "base/bind.h"
+#include "base/file_util.h"
+#include "base/memory/ref_counted_memory.h"
+#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/threading/sequenced_worker_pool.h"
+#include "chrome/browser/ui/libgtk2ui/menu_util.h"
+#include "content/public/browser/browser_thread.h"
+#include "ui/base/models/menu_model.h"
+#include "ui/gfx/image/image_skia.h"
+
+namespace {
+
+typedef enum {
+ APP_INDICATOR_CATEGORY_APPLICATION_STATUS,
+ APP_INDICATOR_CATEGORY_COMMUNICATIONS,
+ APP_INDICATOR_CATEGORY_SYSTEM_SERVICES,
+ APP_INDICATOR_CATEGORY_HARDWARE,
+ APP_INDICATOR_CATEGORY_OTHER
+} AppIndicatorCategory;
+
+typedef enum {
+ APP_INDICATOR_STATUS_PASSIVE,
+ APP_INDICATOR_STATUS_ACTIVE,
+ APP_INDICATOR_STATUS_ATTENTION
+} AppIndicatorStatus;
+
+typedef AppIndicator* (*app_indicator_new_func)(const gchar* id,
+ const gchar* icon_name,
+ AppIndicatorCategory category);
+
+typedef AppIndicator* (*app_indicator_new_with_path_func)(
+ const gchar* id,
+ const gchar* icon_name,
+ AppIndicatorCategory category,
+ const gchar* icon_theme_path);
+
+typedef void (*app_indicator_set_status_func)(AppIndicator* self,
+ AppIndicatorStatus status);
+
+typedef void (*app_indicator_set_attention_icon_full_func)(
+ AppIndicator* self,
+ const gchar* icon_name,
+ const gchar* icon_desc);
+
+typedef void (*app_indicator_set_menu_func)(AppIndicator* self, GtkMenu* menu);
+
+typedef void (*app_indicator_set_icon_full_func)(AppIndicator* self,
+ const gchar* icon_name,
+ const gchar* icon_desc);
+
+typedef void (*app_indicator_set_icon_theme_path_func)(
+ AppIndicator* self,
+ const gchar* icon_theme_path);
+
+bool attempted_load = false;
+bool opened = false;
+
+// Retrieved functions from libappindicator.
+app_indicator_new_func app_indicator_new = NULL;
+app_indicator_new_with_path_func app_indicator_new_with_path = NULL;
+app_indicator_set_status_func app_indicator_set_status = NULL;
+app_indicator_set_attention_icon_full_func
+ app_indicator_set_attention_icon_full = NULL;
+app_indicator_set_menu_func app_indicator_set_menu = NULL;
+app_indicator_set_icon_full_func app_indicator_set_icon_full = NULL;
+app_indicator_set_icon_theme_path_func app_indicator_set_icon_theme_path = NULL;
+
+void EnsureMethodsLoaded() {
+
+ if (attempted_load)
+ return;
+ attempted_load = true;
+
+ void* indicator_lib = dlopen("libappindicator.so", RTLD_LAZY);
+ if (!indicator_lib) {
+ indicator_lib = dlopen("libappindicator.so.1", RTLD_LAZY);
+ }
+ if (!indicator_lib) {
+ indicator_lib = dlopen("libappindicator.so.0", RTLD_LAZY);
+ }
+ if (!indicator_lib) {
+ return;
+ }
+
+ opened = true;
+
+ app_indicator_new = reinterpret_cast<app_indicator_new_func>(
+ dlsym(indicator_lib, "app_indicator_new"));
+
+ app_indicator_new_with_path =
+ reinterpret_cast<app_indicator_new_with_path_func>(
+ dlsym(indicator_lib, "app_indicator_new_with_path"));
+
+ app_indicator_set_status = reinterpret_cast<app_indicator_set_status_func>(
+ dlsym(indicator_lib, "app_indicator_set_status"));
+
+ app_indicator_set_attention_icon_full =
+ reinterpret_cast<app_indicator_set_attention_icon_full_func>(
+ dlsym(indicator_lib, "app_indicator_set_attention_icon_full"));
+
+ app_indicator_set_menu = reinterpret_cast<app_indicator_set_menu_func>(
+ dlsym(indicator_lib, "app_indicator_set_menu"));
+
+ app_indicator_set_icon_full =
+ reinterpret_cast<app_indicator_set_icon_full_func>(
+ dlsym(indicator_lib, "app_indicator_set_icon_full"));
+
+ app_indicator_set_icon_theme_path =
+ reinterpret_cast<app_indicator_set_icon_theme_path_func>(
+ dlsym(indicator_lib, "app_indicator_set_icon_theme_path"));
+}
+
+} // namespace
+
+namespace libgtk2ui {
+
+AppIndicatorIcon::AppIndicatorIcon(std::string id)
+ : id_(id),
+ icon_(NULL),
+ gtk_menu_(NULL),
+ menu_model_(NULL),
+ icon_change_count_(0),
+ block_activation_(false),
+ has_click_action_replacement_(false) {
+ EnsureMethodsLoaded();
+}
+AppIndicatorIcon::~AppIndicatorIcon() {
+ if (icon_) {
+ app_indicator_set_status(icon_, APP_INDICATOR_STATUS_PASSIVE);
+ if (menu_model_)
+ menu_model_->MenuClosed();
+ if (gtk_menu_)
+ DestroyMenu();
+ g_object_unref(icon_);
+ content::BrowserThread::GetBlockingPool()->PostTask(
+ FROM_HERE,
+ base::Bind(&AppIndicatorIcon::DeletePath, icon_file_path_.DirName()));
+ }
+}
+
+bool AppIndicatorIcon::CouldOpen() {
+ EnsureMethodsLoaded();
+ return opened;
+}
+
+void AppIndicatorIcon::SetImage(const gfx::ImageSkia& image) {
+ if (opened) {
+ ++icon_change_count_;
+ gfx::ImageSkia safe_image = gfx::ImageSkia(image);
+ safe_image.MakeThreadSafe();
+ base::PostTaskAndReplyWithResult(
+ content::BrowserThread::GetBlockingPool()
+ ->GetTaskRunnerWithShutdownBehavior(
+ base::SequencedWorkerPool::SKIP_ON_SHUTDOWN).get(),
+ FROM_HERE,
+ base::Bind(&AppIndicatorIcon::CreateTempImageFile,
+ safe_image,
+ icon_change_count_,
+ id_),
+ base::Bind(&AppIndicatorIcon::SetImageFromFile,
+ base::Unretained(this)));
+ }
+}
+
+void AppIndicatorIcon::SetPressedImage(const gfx::ImageSkia& image) {
+ // Ignore pressed images, since the standard on Linux is to not highlight
+ // pressed status icons.
+}
+
+void AppIndicatorIcon::SetToolTip(const string16& tool_tip) {
+ // App-indicators don't support tool-tips. Ignore call.
+}
+
+void AppIndicatorIcon::SetClickActionLabel(const string16& label) {
+ click_action_label_ = UTF16ToUTF8(label);
+
+ // If the menu item has already been created, then find the menu item and
+ // change it's label.
+ if (has_click_action_replacement_) {
+ GList* children = gtk_container_get_children(GTK_CONTAINER(gtk_menu_));
+ for (GList* child = children; child; child = g_list_next(child))
+ if (g_object_get_data(G_OBJECT(child->data), "click-action-item") !=
+ NULL) {
+ gtk_menu_item_set_label(GTK_MENU_ITEM(child->data),
+ click_action_label_.c_str());
+ break;
+ }
+ g_list_free(children);
+ } else if (icon_) {
+ CreateClickActionReplacement();
+ app_indicator_set_menu(icon_, GTK_MENU(gtk_menu_));
+ }
+}
+
+void AppIndicatorIcon::UpdatePlatformContextMenu(ui::MenuModel* model) {
+ if (!opened)
+ return;
+
+ if (gtk_menu_) {
+ DestroyMenu();
+ has_click_action_replacement_ = false;
+ }
+ menu_model_ = model;
+
+ // If icon doesn't exist now it's okay, the menu will be set later along with
+ // the image. Both an icon and a menu are required to show an app indicator.
+ if (model && icon_)
+ SetMenu();
+}
+
+void AppIndicatorIcon::SetImageFromFile(base::FilePath icon_file_path) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ if (!icon_file_path.empty()) {
+ base::FilePath old_path = icon_file_path_;
+ icon_file_path_ = icon_file_path;
+
+ std::string icon_name =
+ icon_file_path_.BaseName().RemoveExtension().value();
+ std::string icon_dir = icon_file_path_.DirName().value();
+ if (!icon_) {
+ icon_ =
+ app_indicator_new_with_path(id_.c_str(),
+ icon_name.c_str(),
+ APP_INDICATOR_CATEGORY_APPLICATION_STATUS,
+ icon_dir.c_str());
+ app_indicator_set_status(icon_, APP_INDICATOR_STATUS_ACTIVE);
+ if (menu_model_) {
+ SetMenu();
+ } else if (!click_action_label_.empty()) {
+ CreateClickActionReplacement();
+ app_indicator_set_menu(icon_, GTK_MENU(gtk_menu_));
+ }
+ } else {
+ // Currently we are creating a new temp directory every time the icon is
+ // set. So we need to set the directory each time.
+ app_indicator_set_icon_theme_path(icon_, icon_dir.c_str());
+ app_indicator_set_icon_full(icon_, icon_name.c_str(), "icon");
+
+ // Delete previous icon directory.
+ content::BrowserThread::GetBlockingPool()->PostTask(
+ FROM_HERE,
+ base::Bind(&AppIndicatorIcon::DeletePath, old_path.DirName()));
+ }
+ }
+}
+
+void AppIndicatorIcon::SetMenu() {
+ gtk_menu_ = gtk_menu_new();
+ BuildSubmenuFromModel(menu_model_,
+ gtk_menu_,
+ G_CALLBACK(OnMenuItemActivatedThunk),
+ &block_activation_,
+ this);
+ if (!click_action_label_.empty())
+ CreateClickActionReplacement();
+ UpdateMenu();
+ menu_model_->MenuWillShow();
+ app_indicator_set_menu(icon_, GTK_MENU(gtk_menu_));
+}
+
+void AppIndicatorIcon::CreateClickActionReplacement() {
+ GtkWidget* menu_item = NULL;
+
+ // If a menu doesn't exist create one just for the click action replacement.
+ if (!gtk_menu_) {
+ gtk_menu_ = gtk_menu_new();
+ } else {
+ // Add separator before the other menu items.
+ menu_item = gtk_separator_menu_item_new();
+ gtk_widget_show(menu_item);
+ gtk_menu_shell_prepend(GTK_MENU_SHELL(gtk_menu_), menu_item);
+ }
+
+ // Add "click replacement menu item".
+ menu_item = gtk_menu_item_new_with_mnemonic(click_action_label_.c_str());
+ g_object_set_data(
+ G_OBJECT(menu_item), "click-action-item", GINT_TO_POINTER(1));
+ g_signal_connect(menu_item, "activate", G_CALLBACK(OnClickThunk), this);
+ gtk_widget_show(menu_item);
+ gtk_menu_shell_prepend(GTK_MENU_SHELL(gtk_menu_), menu_item);
+
+ has_click_action_replacement_ = true;
+}
+
+void AppIndicatorIcon::DestroyMenu() {
+ if (menu_model_)
+ menu_model_->MenuClosed();
+ gtk_widget_destroy(gtk_menu_);
+ gtk_menu_ = NULL;
+ menu_model_ = NULL;
+}
+
+base::FilePath AppIndicatorIcon::CreateTempImageFile(gfx::ImageSkia image,
+ int icon_change_count,
+ std::string id) {
+ scoped_refptr<base::RefCountedMemory> png_data =
+ gfx::Image(image).As1xPNGBytes();
+ if (png_data->size() == 0) {
+ // If the bitmap could not be encoded to PNG format, skip it.
+ LOG(WARNING) << "Could not encode icon";
+ return base::FilePath();
+ }
+
+ base::FilePath temp_dir;
+ base::FilePath new_file_path;
+
+ // Create a new temporary directory for each image since using a single
+ // temporary directory seems to have issues when changing icons in quick
+ // succession.
+ if (!file_util::CreateNewTempDirectory("", &temp_dir))
+ return base::FilePath();
+ new_file_path =
+ temp_dir.Append(id + base::StringPrintf("_%d.png", icon_change_count));
+ int bytes_written =
+ file_util::WriteFile(new_file_path,
+ reinterpret_cast<const char*>(png_data->front()),
+ png_data->size());
+
+ if (bytes_written != static_cast<int>(png_data->size())) {
+ return base::FilePath();
+ }
+
+ return new_file_path;
+}
+
+void AppIndicatorIcon::DeletePath(base::FilePath icon_file_path) {
+ if (!icon_file_path.empty()) {
+ base::DeleteFile(icon_file_path, true);
+ }
+}
+
+void AppIndicatorIcon::UpdateMenu() {
+ gtk_container_foreach(
+ GTK_CONTAINER(gtk_menu_), SetMenuItemInfo, &block_activation_);
+}
+
+void AppIndicatorIcon::OnClick(GtkWidget* menu_item) {
+ if (delegate())
+ delegate()->OnClick();
+}
+
+void AppIndicatorIcon::OnMenuItemActivated(GtkWidget* menu_item) {
+ if (block_activation_)
+ return;
+
+ ui::MenuModel* model = ModelForMenuItem(GTK_MENU_ITEM(menu_item));
+
+ if (!model) {
+ // There won't be a model for "native" submenus like the "Input Methods"
+ // context menu. We don't need to handle activation messages for submenus
+ // anyway, so we can just return here.
+ DCHECK(gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu_item)));
+ return;
+ }
+
+ // The activate signal is sent to radio items as they get deselected;
+ // ignore it in this case.
+ if (GTK_IS_RADIO_MENU_ITEM(menu_item) &&
+ !gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_item))) {
+ return;
+ }
+
+ int id;
+ if (!GetMenuItemID(menu_item, &id))
+ return;
+
+ // The menu item can still be activated by hotkeys even if it is disabled.
+ if (menu_model_->IsEnabledAt(id))
+ ExecuteCommand(model, id);
+ UpdateMenu();
+}
+
+} // namespace libgtk2ui
diff --git a/chrome/browser/ui/libgtk2ui/app_indicator_icon.h b/chrome/browser/ui/libgtk2ui/app_indicator_icon.h
new file mode 100644
index 0000000..33bfd5e
--- /dev/null
+++ b/chrome/browser/ui/libgtk2ui/app_indicator_icon.h
@@ -0,0 +1,83 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_UI_LIBGTK2UI_APP_INDICATOR_ICON_H_
+#define CHROME_BROWSER_UI_LIBGTK2UI_APP_INDICATOR_ICON_H_
+
+#include "base/files/file_path.h"
+#include "chrome/browser/ui/libgtk2ui/gtk2_signal.h"
+#include "ui/linux_ui/status_icon_linux.h"
+
+typedef struct _AppIndicator AppIndicator;
+typedef struct _GtkWidget GtkWidget;
+
+namespace gfx {
+class ImageSkia;
+}
+
+namespace libgtk2ui {
+
+class AppIndicatorIcon : public StatusIconLinux {
+ public:
+ // The id uniquely identifies the new status icon from other chrome status
+ // icons.
+ explicit AppIndicatorIcon(std::string id);
+ virtual ~AppIndicatorIcon();
+
+ // Indicates whether libappindicator so could be opened.
+ static bool CouldOpen();
+
+ // Overridden from StatusIcon:
+ virtual void SetImage(const gfx::ImageSkia& image) OVERRIDE;
+ virtual void SetPressedImage(const gfx::ImageSkia& image) OVERRIDE;
+ virtual void SetToolTip(const string16& tool_tip) OVERRIDE;
+ virtual void SetClickActionLabel(const string16& label) OVERRIDE;
+
+ protected:
+ // Overridden from StatusIcon.
+ virtual void UpdatePlatformContextMenu(ui::MenuModel* menu) OVERRIDE;
+
+ private:
+ void SetImageFromFile(base::FilePath icon_file_path);
+ void SetMenu();
+
+ // Adds a menu item to the top of the existing gtk_menu as a replacement for
+ // the status icon click action or creates a new gtk menu with the menu item
+ // if a menu doesn't exist. Clicking on this menu item should simulate a
+ // status icon click by despatching a click event.
+ void CreateClickActionReplacement();
+ void DestroyMenu();
+
+ static base::FilePath CreateTempImageFile(gfx::ImageSkia image,
+ int icon_change_count,
+ std::string id);
+ static void DeletePath(base::FilePath icon_file_path);
+
+ // Updates all the enabled/checked states and the dynamic labels.
+ void UpdateMenu();
+
+ // Callback for when the status icon click replacement menu item is clicked.
+ CHROMEGTK_CALLBACK_0(AppIndicatorIcon, void, OnClick);
+
+ // Callback for when a menu item is clicked.
+ CHROMEGTK_CALLBACK_0(AppIndicatorIcon, void, OnMenuItemActivated);
+
+ std::string id_;
+ std::string click_action_label_;
+
+ // Gtk status icon wrapper
+ AppIndicator* icon_;
+
+ GtkWidget* gtk_menu_;
+ ui::MenuModel* menu_model_;
+
+ base::FilePath icon_file_path_;
+ int icon_change_count_;
+ bool block_activation_;
+ bool has_click_action_replacement_;
+};
+
+} // namespace libgtk2ui
+
+#endif // CHROME_BROWSER_UI_LIBGTK2UI_APP_INDICATOR_ICON_H_
diff --git a/chrome/browser/ui/libgtk2ui/gtk2_ui.cc b/chrome/browser/ui/libgtk2ui/gtk2_ui.cc
index de66141..4167edc 100644
--- a/chrome/browser/ui/libgtk2ui/gtk2_ui.cc
+++ b/chrome/browser/ui/libgtk2ui/gtk2_ui.cc
@@ -12,7 +12,9 @@
#include "base/logging.h"
#include "base/nix/mime_util_xdg.h"
#include "base/stl_util.h"
+#include "base/strings/stringprintf.h"
#include "chrome/browser/themes/theme_properties.h"
+#include "chrome/browser/ui/libgtk2ui/app_indicator_icon.h"
#include "chrome/browser/ui/libgtk2ui/chrome_gtk_frame.h"
#include "chrome/browser/ui/libgtk2ui/gtk2_util.h"
#include "chrome/browser/ui/libgtk2ui/native_theme_gtk2.h"
@@ -49,6 +51,12 @@
namespace {
+// Prefix for app indicator ids
+const char kAppIndicatorIdPrefix[] = "chrome_app_indicator_";
+
+// Number of app indicators used (used as part of app-indicator id).
+int indicators_count;
+
// The size of the rendered toolbar image.
const int kToolbarImageWidth = 64;
const int kToolbarImageHeight = 128;
@@ -304,6 +312,8 @@
// style-set signal handler.
LoadGtkValues();
SetXDGIconTheme();
+
+ indicators_count = 0;
}
Gtk2UI::~Gtk2UI() {
@@ -381,6 +391,20 @@
unity::SetProgressFraction(percentage);
}
+bool Gtk2UI::IsStatusIconSupported() const {
+ return AppIndicatorIcon::CouldOpen();
+}
+
+scoped_ptr<StatusIconLinux> Gtk2UI::CreateLinuxStatusIcon() const {
+ if (AppIndicatorIcon::CouldOpen()) {
+ ++indicators_count;
+ return scoped_ptr<StatusIconLinux>(new AppIndicatorIcon(
+ base::StringPrintf("%s%d", kAppIndicatorIdPrefix, indicators_count)));
+ } else {
+ return scoped_ptr<StatusIconLinux>();
+ }
+}
+
ui::SelectFileDialog* Gtk2UI::CreateSelectFileDialog(
ui::SelectFileDialog::Listener* listener,
ui::SelectFilePolicy* policy) const {
diff --git a/chrome/browser/ui/libgtk2ui/gtk2_ui.h b/chrome/browser/ui/libgtk2ui/gtk2_ui.h
index b1db13a..69a7dde 100644
--- a/chrome/browser/ui/libgtk2ui/gtk2_ui.h
+++ b/chrome/browser/ui/libgtk2ui/gtk2_ui.h
@@ -47,6 +47,8 @@
virtual bool GetDefaultUsesSystemTheme() const OVERRIDE;
virtual void SetDownloadCount(int count) const OVERRIDE;
virtual void SetProgressFraction(float percentage) const OVERRIDE;
+ virtual bool IsStatusIconSupported() const OVERRIDE;
+ virtual scoped_ptr<StatusIconLinux> CreateLinuxStatusIcon() const OVERRIDE;
private:
typedef std::map<int, SkColor> ColorMap;
diff --git a/chrome/browser/ui/libgtk2ui/gtk2_util.cc b/chrome/browser/ui/libgtk2ui/gtk2_util.cc
index eec6b1a..107f2ee 100644
--- a/chrome/browser/ui/libgtk2ui/gtk2_util.cc
+++ b/chrome/browser/ui/libgtk2ui/gtk2_util.cc
@@ -8,11 +8,10 @@
#include "base/command_line.h"
#include "base/environment.h"
-#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
-#include "skia/ext/platform_canvas.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/gfx/canvas.h"
+#include "ui/base/accelerators/accelerator.h"
+#include "ui/base/events/event_constants.h"
+#include "ui/base/keycodes/keyboard_code_conversion_x.cc"
#include "ui/gfx/size.h"
namespace {
@@ -36,6 +35,33 @@
}
}
+// Replaces all ampersands (as used in our grd files to indicate mnemonics)
+// to |target|, except ampersands appearing in pairs which are replaced by
+// a single ampersand. Any underscores get replaced with two underscores as
+// is needed by GTK.
+std::string ConvertAmpersandsTo(const std::string& label,
+ const std::string& target) {
+ std::string ret;
+ ret.reserve(label.length() * 2);
+ for (size_t i = 0; i < label.length(); ++i) {
+ if ('_' == label[i]) {
+ ret.push_back('_');
+ ret.push_back('_');
+ } else if ('&' == label[i]) {
+ if (i + 1 < label.length() && '&' == label[i + 1]) {
+ ret.push_back('&');
+ ++i;
+ } else {
+ ret.append(target);
+ }
+ } else {
+ ret.push_back(label[i]);
+ }
+ }
+
+ return ret;
+}
+
} // namespace
namespace libgtk2ui {
@@ -61,60 +87,45 @@
#endif
}
-const SkBitmap GdkPixbufToImageSkia(GdkPixbuf* pixbuf) {
- // TODO(erg): What do we do in the case where the pixbuf fails these dchecks?
- // I would prefer to use our gtk based canvas, but that would require
- // recompiling half of our skia extensions with gtk support, which we can't
- // do in this build.
- DCHECK_EQ(GDK_COLORSPACE_RGB, gdk_pixbuf_get_colorspace(pixbuf));
+void SetAlwaysShowImage(GtkWidget* image_menu_item) {
+ gtk_image_menu_item_set_always_show_image(
+ GTK_IMAGE_MENU_ITEM(image_menu_item), TRUE);
+}
- int n_channels = gdk_pixbuf_get_n_channels(pixbuf);
- int w = gdk_pixbuf_get_width(pixbuf);
- int h = gdk_pixbuf_get_height(pixbuf);
+std::string ConvertAcceleratorsFromWindowsStyle(const std::string& label) {
+ return ConvertAmpersandsTo(label, "_");
+}
- SkBitmap ret;
- ret.setConfig(SkBitmap::kARGB_8888_Config, w, h);
- ret.allocPixels();
- ret.eraseColor(0);
+guint GetGdkKeyCodeForAccelerator(const ui::Accelerator& accelerator) {
+ // The second parameter is false because accelerator keys are expressed in
+ // terms of the non-shift-modified key.
+ return XKeysymForWindowsKeyCode(accelerator.key_code(), false);
+}
- uint32_t* skia_data = static_cast<uint32_t*>(ret.getAddr(0, 0));
+GdkModifierType GetGdkModifierForAccelerator(
+ const ui::Accelerator& accelerator) {
+ int event_flag = accelerator.modifiers();
+ int modifier = 0;
+ if (event_flag & ui::EF_SHIFT_DOWN)
+ modifier |= GDK_SHIFT_MASK;
+ if (event_flag & ui::EF_CONTROL_DOWN)
+ modifier |= GDK_CONTROL_MASK;
+ if (event_flag & ui::EF_ALT_DOWN)
+ modifier |= GDK_MOD1_MASK;
+ return static_cast<GdkModifierType>(modifier);
+}
- if (n_channels == 4) {
- int total_length = w * h;
- guchar* gdk_pixels = gdk_pixbuf_get_pixels(pixbuf);
-
- // Now here's the trick: we need to convert the gdk data (which is RGBA and
- // isn't premultiplied) to skia (which can be anything and premultiplied).
- for (int i = 0; i < total_length; ++i, gdk_pixels += 4) {
- const unsigned char& red = gdk_pixels[0];
- const unsigned char& green = gdk_pixels[1];
- const unsigned char& blue = gdk_pixels[2];
- const unsigned char& alpha = gdk_pixels[3];
-
- skia_data[i] = SkPreMultiplyARGB(alpha, red, green, blue);
- }
- } else if (n_channels == 3) {
- // Because GDK makes rowstrides word aligned, we need to do something a bit
- // more complex when a pixel isn't perfectly a word of memory.
- int rowstride = gdk_pixbuf_get_rowstride(pixbuf);
- guchar* gdk_pixels = gdk_pixbuf_get_pixels(pixbuf);
- for (int y = 0; y < h; ++y) {
- int row = y * rowstride;
-
- for (int x = 0; x < w; ++x) {
- guchar* pixel = gdk_pixels + row + (x * 3);
- const unsigned char& red = pixel[0];
- const unsigned char& green = pixel[1];
- const unsigned char& blue = pixel[2];
-
- skia_data[y * w + x] = SkPreMultiplyARGB(255, red, green, blue);
- }
- }
- } else {
- NOTREACHED();
- }
-
- return ret;
+int EventFlagsFromGdkState(guint state) {
+ int flags = ui::EF_NONE;
+ flags |= (state & GDK_LOCK_MASK) ? ui::EF_CAPS_LOCK_DOWN : ui::EF_NONE;
+ flags |= (state & GDK_CONTROL_MASK) ? ui::EF_CONTROL_DOWN : ui::EF_NONE;
+ flags |= (state & GDK_SHIFT_MASK) ? ui::EF_SHIFT_DOWN : ui::EF_NONE;
+ flags |= (state & GDK_MOD1_MASK) ? ui::EF_ALT_DOWN : ui::EF_NONE;
+ flags |= (state & GDK_BUTTON1_MASK) ? ui::EF_LEFT_MOUSE_BUTTON : ui::EF_NONE;
+ flags |=
+ (state & GDK_BUTTON2_MASK) ? ui::EF_MIDDLE_MOUSE_BUTTON : ui::EF_NONE;
+ flags |= (state & GDK_BUTTON3_MASK) ? ui::EF_RIGHT_MOUSE_BUTTON : ui::EF_NONE;
+ return flags;
}
} // namespace libgtk2ui
diff --git a/chrome/browser/ui/libgtk2ui/gtk2_util.h b/chrome/browser/ui/libgtk2ui/gtk2_util.h
index 77a1cbf..ca5274c 100644
--- a/chrome/browser/ui/libgtk2ui/gtk2_util.h
+++ b/chrome/browser/ui/libgtk2ui/gtk2_util.h
@@ -5,10 +5,9 @@
#ifndef CHROME_BROWSER_UI_LIBGTK2UI_GTK2_UTIL_H_
#define CHROME_BROWSER_UI_LIBGTK2UI_GTK2_UTIL_H_
+#include <gtk/gtk.h>
#include <string>
-typedef struct _GdkPixbuf GdkPixbuf;
-
class CommandLine;
class SkBitmap;
@@ -16,6 +15,10 @@
class Environment;
}
+namespace ui {
+class Accelerator;
+}
+
namespace libgtk2ui {
void GtkInitFromCommandLine(const CommandLine& command_line);
@@ -23,7 +26,22 @@
// Returns the name of the ".desktop" file associated with our running process.
std::string GetDesktopName(base::Environment* env);
-const SkBitmap GdkPixbufToImageSkia(GdkPixbuf* pixbuf);
+// Show the image for the given menu item, even if the user's default is to not
+// show images. Only to be used for favicons or other menus where the image is
+// crucial to its functionality.
+void SetAlwaysShowImage(GtkWidget* image_menu_item);
+
+// Change windows accelerator style to GTK style. (GTK uses _ for
+// accelerators. Windows uses & with && as an escape for &.)
+std::string ConvertAcceleratorsFromWindowsStyle(const std::string& label);
+
+guint GetGdkKeyCodeForAccelerator(const ui::Accelerator& accelerator);
+
+GdkModifierType GetGdkModifierForAccelerator(
+ const ui::Accelerator& accelerator);
+
+// Translates event flags into plaform independent event flags.
+int EventFlagsFromGdkState(guint state);
} // namespace libgtk2ui
diff --git a/chrome/browser/ui/libgtk2ui/libgtk2ui.gyp b/chrome/browser/ui/libgtk2ui/libgtk2ui.gyp
index efa61e9..d204857 100644
--- a/chrome/browser/ui/libgtk2ui/libgtk2ui.gyp
+++ b/chrome/browser/ui/libgtk2ui/libgtk2ui.gyp
@@ -33,6 +33,8 @@
# the normal, global gtk exclusion rules, as we are otherwise using gtk
# in a non-gtk build.
'sources': [
+ 'app_indicator_icon.cc',
+ 'app_indicator_icon.h',
'chrome_gtk_frame.cc',
'chrome_gtk_frame.h',
'gtk2_ui.cc',
@@ -40,6 +42,8 @@
'gtk2_util.cc',
'gtk2_util.h',
'libgtk2ui_export.h',
+ 'menu_util.cc',
+ 'menu_util.h',
'native_theme_gtk2.cc',
'native_theme_gtk2.h',
'owned_widget_gtk2.cc',
diff --git a/chrome/browser/ui/libgtk2ui/menu_util.cc b/chrome/browser/ui/libgtk2ui/menu_util.cc
new file mode 100644
index 0000000..90bb54e
--- /dev/null
+++ b/chrome/browser/ui/libgtk2ui/menu_util.cc
@@ -0,0 +1,260 @@
+// Copyright 2013 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/ui/libgtk2ui/menu_util.h"
+
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/ui/libgtk2ui/gtk2_util.h"
+#include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h"
+#include "ui/base/accelerators/accelerator.h"
+#include "ui/base/models/menu_model.h"
+
+namespace libgtk2ui {
+
+GtkWidget* BuildMenuItemWithImage(const std::string& label, GtkWidget* image) {
+ GtkWidget* menu_item = gtk_image_menu_item_new_with_mnemonic(label.c_str());
+ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item), image);
+ return menu_item;
+}
+
+GtkWidget* BuildMenuItemWithImage(const std::string& label,
+ const gfx::Image& icon) {
+ GdkPixbuf* pixbuf = GdkPixbufFromSkBitmap(*icon.ToSkBitmap());
+
+ GtkWidget* menu_item =
+ BuildMenuItemWithImage(label, gtk_image_new_from_pixbuf(pixbuf));
+ g_object_unref(pixbuf);
+ return menu_item;
+}
+
+GtkWidget* BuildMenuItemWithLabel(const std::string& label) {
+ return gtk_menu_item_new_with_mnemonic(label.c_str());
+}
+
+ui::MenuModel* ModelForMenuItem(GtkMenuItem* menu_item) {
+ return reinterpret_cast<ui::MenuModel*>(
+ g_object_get_data(G_OBJECT(menu_item), "model"));
+}
+
+GtkWidget* AppendMenuItemToMenu(int index,
+ ui::MenuModel* model,
+ GtkWidget* menu_item,
+ GtkWidget* menu,
+ bool connect_to_activate,
+ GCallback item_activated_cb,
+ void* this_ptr) {
+ // Set the ID of a menu item.
+ // Add 1 to the menu_id to avoid setting zero (null) to "menu-id".
+ g_object_set_data(G_OBJECT(menu_item), "menu-id", GINT_TO_POINTER(index + 1));
+
+ // Native menu items do their own thing, so only selectively listen for the
+ // activate signal.
+ if (connect_to_activate) {
+ g_signal_connect(menu_item, "activate", item_activated_cb, this_ptr);
+ }
+
+ // AppendMenuItemToMenu is used both internally when we control menu creation
+ // from a model (where the model can choose to hide certain menu items), and
+ // with immediate commands which don't provide the option.
+ if (model) {
+ if (model->IsVisibleAt(index))
+ gtk_widget_show(menu_item);
+ } else {
+ gtk_widget_show(menu_item);
+ }
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+ return menu_item;
+}
+
+bool GetMenuItemID(GtkWidget* menu_item, int* menu_id) {
+ gpointer id_ptr = g_object_get_data(G_OBJECT(menu_item), "menu-id");
+ if (id_ptr != NULL) {
+ *menu_id = GPOINTER_TO_INT(id_ptr) - 1;
+ return true;
+ }
+
+ return false;
+}
+
+void ExecuteCommand(ui::MenuModel* model, int id) {
+ GdkEvent* event = gtk_get_current_event();
+ int event_flags = 0;
+
+ if (event && event->type == GDK_BUTTON_RELEASE)
+ event_flags = EventFlagsFromGdkState(event->button.state);
+ model->ActivatedAt(id, event_flags);
+
+ if (event)
+ gdk_event_free(event);
+}
+
+void BuildSubmenuFromModel(ui::MenuModel* model,
+ GtkWidget* menu,
+ GCallback item_activated_cb,
+ bool* block_activation,
+ void* this_ptr) {
+ std::map<int, GtkWidget*> radio_groups;
+ GtkWidget* menu_item = NULL;
+ for (int i = 0; i < model->GetItemCount(); ++i) {
+ gfx::Image icon;
+ std::string label =
+ ConvertAcceleratorsFromWindowsStyle(UTF16ToUTF8(model->GetLabelAt(i)));
+
+ bool connect_to_activate = true;
+
+ switch (model->GetTypeAt(i)) {
+ case ui::MenuModel::TYPE_SEPARATOR:
+ menu_item = gtk_separator_menu_item_new();
+ break;
+
+ case ui::MenuModel::TYPE_CHECK:
+ menu_item = gtk_check_menu_item_new_with_mnemonic(label.c_str());
+ break;
+
+ case ui::MenuModel::TYPE_RADIO: {
+ std::map<int, GtkWidget*>::iterator iter =
+ radio_groups.find(model->GetGroupIdAt(i));
+
+ if (iter == radio_groups.end()) {
+ menu_item =
+ gtk_radio_menu_item_new_with_mnemonic(NULL, label.c_str());
+ radio_groups[model->GetGroupIdAt(i)] = menu_item;
+ } else {
+ menu_item = gtk_radio_menu_item_new_with_mnemonic_from_widget(
+ GTK_RADIO_MENU_ITEM(iter->second), label.c_str());
+ }
+ break;
+ }
+ case ui::MenuModel::TYPE_BUTTON_ITEM: {
+ NOTIMPLEMENTED();
+ break;
+ }
+ case ui::MenuModel::TYPE_SUBMENU:
+ case ui::MenuModel::TYPE_COMMAND: {
+ if (model->GetIconAt(i, &icon))
+ menu_item = BuildMenuItemWithImage(label, icon);
+ else
+ menu_item = BuildMenuItemWithLabel(label);
+ if (GTK_IS_IMAGE_MENU_ITEM(menu_item)) {
+ SetAlwaysShowImage(menu_item);
+ }
+ break;
+ }
+
+ default:
+ NOTREACHED();
+ }
+
+ if (model->GetTypeAt(i) == ui::MenuModel::TYPE_SUBMENU) {
+ GtkWidget* submenu = gtk_menu_new();
+ ui::MenuModel* submenu_model = model->GetSubmenuModelAt(i);
+ BuildSubmenuFromModel(submenu_model,
+ submenu,
+ item_activated_cb,
+ block_activation,
+ this_ptr);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), submenu);
+
+ // Update all the menu item info in the newly-generated menu.
+ gtk_container_foreach(
+ GTK_CONTAINER(submenu), SetMenuItemInfo, block_activation);
+ submenu_model->MenuWillShow();
+ connect_to_activate = false;
+ }
+
+ ui::Accelerator accelerator;
+ if (model->GetAcceleratorAt(i, &accelerator)) {
+ gtk_widget_add_accelerator(menu_item,
+ "activate",
+ NULL,
+ GetGdkKeyCodeForAccelerator(accelerator),
+ GetGdkModifierForAccelerator(accelerator),
+ GTK_ACCEL_VISIBLE);
+ }
+
+ g_object_set_data(G_OBJECT(menu_item), "model", model);
+ AppendMenuItemToMenu(i,
+ model,
+ menu_item,
+ menu,
+ connect_to_activate,
+ item_activated_cb,
+ this_ptr);
+
+ menu_item = NULL;
+ }
+}
+
+void SetMenuItemInfo(GtkWidget* widget, void* block_activation_ptr) {
+ if (GTK_IS_SEPARATOR_MENU_ITEM(widget)) {
+ // We need to explicitly handle this case because otherwise we'll ask the
+ // menu delegate about something with an invalid id.
+ return;
+ }
+
+ int id;
+ if (!GetMenuItemID(widget, &id))
+ return;
+
+ ui::MenuModel* model = ModelForMenuItem(GTK_MENU_ITEM(widget));
+ if (!model) {
+ // If we're not providing the sub menu, then there's no model. For
+ // example, the IME submenu doesn't have a model.
+ return;
+ }
+ bool* block_activation = static_cast<bool*>(block_activation_ptr);
+
+ if (GTK_IS_CHECK_MENU_ITEM(widget)) {
+ GtkCheckMenuItem* item = GTK_CHECK_MENU_ITEM(widget);
+
+ // gtk_check_menu_item_set_active() will send the activate signal. Touching
+ // the underlying "active" property will also call the "activate" handler
+ // for this menu item. So we prevent the "activate" handler from
+ // being called while we set the checkbox.
+ // Why not use one of the glib signal-blocking functions? Because when we
+ // toggle a radio button, it will deactivate one of the other radio buttons,
+ // which we don't have a pointer to.
+ *block_activation = true;
+ gtk_check_menu_item_set_active(item, model->IsItemCheckedAt(id));
+ *block_activation = false;
+ }
+
+ if (GTK_IS_MENU_ITEM(widget)) {
+ gtk_widget_set_sensitive(widget, model->IsEnabledAt(id));
+
+ if (model->IsVisibleAt(id)) {
+ // Update the menu item label if it is dynamic.
+ if (model->IsItemDynamicAt(id)) {
+ std::string label = ConvertAcceleratorsFromWindowsStyle(
+ UTF16ToUTF8(model->GetLabelAt(id)));
+
+ gtk_menu_item_set_label(GTK_MENU_ITEM(widget), label.c_str());
+ if (GTK_IS_IMAGE_MENU_ITEM(widget)) {
+ gfx::Image icon;
+ if (model->GetIconAt(id, &icon)) {
+ gtk_image_menu_item_set_image(
+ GTK_IMAGE_MENU_ITEM(widget),
+ gtk_image_new_from_pixbuf(
+ GdkPixbufFromSkBitmap(*icon.ToSkBitmap())));
+ } else {
+ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(widget), NULL);
+ }
+ }
+ }
+
+ gtk_widget_show(widget);
+ } else {
+ gtk_widget_hide(widget);
+ }
+
+ GtkWidget* submenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(widget));
+ if (submenu) {
+ gtk_container_foreach(
+ GTK_CONTAINER(submenu), &SetMenuItemInfo, block_activation_ptr);
+ }
+ }
+}
+
+} // namespace libgtk2ui
diff --git a/chrome/browser/ui/libgtk2ui/menu_util.h b/chrome/browser/ui/libgtk2ui/menu_util.h
new file mode 100644
index 0000000..c81d32d
--- /dev/null
+++ b/chrome/browser/ui/libgtk2ui/menu_util.h
@@ -0,0 +1,56 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_UI_LIBGTK2UI_MENU_UTIL_H_
+#define CHROME_BROWSER_UI_LIBGTK2UI_MENU_UTIL_H_
+
+#include <gtk/gtk.h>
+
+#include "ui/gfx/image/image.h"
+
+namespace ui {
+class MenuModel;
+}
+
+namespace libgtk2ui {
+// Builds GtkImageMenuItems.
+GtkWidget* BuildMenuItemWithImage(const std::string& label, GtkWidget* image);
+GtkWidget* BuildMenuItemWithImage(const std::string& label,
+ const gfx::Image& icon);
+GtkWidget* BuildMenuItemWithLabel(const std::string& label);
+
+ui::MenuModel* ModelForMenuItem(GtkMenuItem* menu_item);
+
+// This method is used to build the menu dynamically. The return value is the
+// new menu item.
+GtkWidget* AppendMenuItemToMenu(int index,
+ ui::MenuModel* model,
+ GtkWidget* menu_item,
+ GtkWidget* menu,
+ bool connect_to_activate,
+ GCallback item_activated_cb,
+ void* this_ptr);
+
+// Gets the ID of a menu item.
+// Returns true if the menu item has an ID.
+bool GetMenuItemID(GtkWidget* menu_item, int* menu_id);
+
+// Execute command associated with specified id.
+void ExecuteCommand(ui::MenuModel* model, int id);
+
+// Creates a GtkMenu from |model_|. block_activation_ptr is used to disable
+// the item_activated_callback while we set up the set up the menu items.
+// See comments in definition of SetMenuItemInfo for more info.
+void BuildSubmenuFromModel(ui::MenuModel* model,
+ GtkWidget* menu,
+ GCallback item_activated_cb,
+ bool* block_activation,
+ void* this_ptr);
+
+// Sets the check mark, enabled/disabled state and dynamic labels on menu items.
+void SetMenuItemInfo(GtkWidget* widget, void* block_activation_ptr);
+
+} // namespace libgtk2ui
+
+#endif // CHROME_BROWSER_UI_LIBGTK2UI_MENU_UTIL_H_
diff --git a/chrome/browser/ui/libgtk2ui/skia_utils_gtk2.cc b/chrome/browser/ui/libgtk2ui/skia_utils_gtk2.cc
index 44f03f5..88731b8 100644
--- a/chrome/browser/ui/libgtk2ui/skia_utils_gtk2.cc
+++ b/chrome/browser/ui/libgtk2ui/skia_utils_gtk2.cc
@@ -6,6 +6,11 @@
#include <gdk/gdk.h>
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkUnPreMultiply.h"
+
namespace libgtk2ui {
const int kSkiaToGDKMultiplier = 257;
@@ -29,4 +34,104 @@
return gdk_color;
}
+const SkBitmap GdkPixbufToImageSkia(GdkPixbuf* pixbuf) {
+ // TODO(erg): What do we do in the case where the pixbuf fails these dchecks?
+ // I would prefer to use our gtk based canvas, but that would require
+ // recompiling half of our skia extensions with gtk support, which we can't
+ // do in this build.
+ DCHECK_EQ(GDK_COLORSPACE_RGB, gdk_pixbuf_get_colorspace(pixbuf));
+
+ int n_channels = gdk_pixbuf_get_n_channels(pixbuf);
+ int w = gdk_pixbuf_get_width(pixbuf);
+ int h = gdk_pixbuf_get_height(pixbuf);
+
+ SkBitmap ret;
+ ret.setConfig(SkBitmap::kARGB_8888_Config, w, h);
+ ret.allocPixels();
+ ret.eraseColor(0);
+
+ uint32_t* skia_data = static_cast<uint32_t*>(ret.getAddr(0, 0));
+
+ if (n_channels == 4) {
+ int total_length = w * h;
+ guchar* gdk_pixels = gdk_pixbuf_get_pixels(pixbuf);
+
+ // Now here's the trick: we need to convert the gdk data (which is RGBA and
+ // isn't premultiplied) to skia (which can be anything and premultiplied).
+ for (int i = 0; i < total_length; ++i, gdk_pixels += 4) {
+ const unsigned char& red = gdk_pixels[0];
+ const unsigned char& green = gdk_pixels[1];
+ const unsigned char& blue = gdk_pixels[2];
+ const unsigned char& alpha = gdk_pixels[3];
+
+ skia_data[i] = SkPreMultiplyARGB(alpha, red, green, blue);
+ }
+ } else if (n_channels == 3) {
+ // Because GDK makes rowstrides word aligned, we need to do something a bit
+ // more complex when a pixel isn't perfectly a word of memory.
+ int rowstride = gdk_pixbuf_get_rowstride(pixbuf);
+ guchar* gdk_pixels = gdk_pixbuf_get_pixels(pixbuf);
+ for (int y = 0; y < h; ++y) {
+ int row = y * rowstride;
+
+ for (int x = 0; x < w; ++x) {
+ guchar* pixel = gdk_pixels + row + (x * 3);
+ const unsigned char& red = pixel[0];
+ const unsigned char& green = pixel[1];
+ const unsigned char& blue = pixel[2];
+
+ skia_data[y * w + x] = SkPreMultiplyARGB(255, red, green, blue);
+ }
+ }
+ } else {
+ NOTREACHED();
+ }
+
+ return ret;
+}
+
+GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap& bitmap) {
+ if (bitmap.isNull())
+ return NULL;
+
+ SkAutoLockPixels lock_pixels(bitmap);
+
+ int width = bitmap.width();
+ int height = bitmap.height();
+
+ GdkPixbuf* pixbuf =
+ gdk_pixbuf_new(GDK_COLORSPACE_RGB, // The only colorspace gtk supports.
+ TRUE, // There is an alpha channel.
+ 8,
+ width,
+ height);
+
+ // SkBitmaps are premultiplied, we need to unpremultiply them.
+ const int kBytesPerPixel = 4;
+ uint8* divided = gdk_pixbuf_get_pixels(pixbuf);
+
+ for (int y = 0, i = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ uint32 pixel = bitmap.getAddr32(0, y)[x];
+
+ int alpha = SkColorGetA(pixel);
+ if (alpha != 0 && alpha != 255) {
+ SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel);
+ divided[i + 0] = SkColorGetR(unmultiplied);
+ divided[i + 1] = SkColorGetG(unmultiplied);
+ divided[i + 2] = SkColorGetB(unmultiplied);
+ divided[i + 3] = alpha;
+ } else {
+ divided[i + 0] = SkColorGetR(pixel);
+ divided[i + 1] = SkColorGetG(pixel);
+ divided[i + 2] = SkColorGetB(pixel);
+ divided[i + 3] = alpha;
+ }
+ i += kBytesPerPixel;
+ }
+ }
+
+ return pixbuf;
+}
+
} // namespace libgtk2ui
diff --git a/chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h b/chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h
index 18a1075..1ce81a5 100644
--- a/chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h
+++ b/chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h
@@ -8,6 +8,9 @@
#include "third_party/skia/include/core/SkColor.h"
typedef struct _GdkColor GdkColor;
+typedef struct _GdkPixbuf GdkPixbuf;
+
+class SkBitmap;
namespace libgtk2ui {
@@ -17,6 +20,13 @@
// Converts ARGB to GdkColor.
GdkColor SkColorToGdkColor(SkColor color);
+const SkBitmap GdkPixbufToImageSkia(GdkPixbuf* pixbuf);
+
+// Convert and copy a SkBitmap to a GdkPixbuf. NOTE: this uses BGRAToRGBA, so
+// it is an expensive operation. The returned GdkPixbuf will have a refcount of
+// 1, and the caller is responsible for unrefing it when done.
+GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap& bitmap);
+
} // namespace libgtk2ui
#endif // CHROME_BROWSER_UI_LIBGTK2UI_SKIA_UTILS_GTK2_H_
diff --git a/chrome/browser/ui/omnibox/action_box_browsertest.cc b/chrome/browser/ui/omnibox/action_box_browsertest.cc
deleted file mode 100644
index 869a641..0000000
--- a/chrome/browser/ui/omnibox/action_box_browsertest.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-// 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 "base/command_line.h"
-#include "base/message_loop/message_loop.h"
-#include "base/strings/string16.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/app/chrome_command_ids.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_utils.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_commands.h"
-#include "chrome/browser/ui/browser_tabstrip.h"
-#include "chrome/browser/ui/browser_window.h"
-#include "chrome/browser/ui/omnibox/location_bar.h"
-#include "chrome/browser/ui/toolbar/action_box_menu_model.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/url_constants.h"
-#include "chrome/test/base/in_process_browser_test.h"
-#include "chrome/test/base/interactive_test_utils.h"
-#include "chrome/test/base/testing_profile.h"
-#include "chrome/test/base/ui_test_utils.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/web_contents.h"
-
-class ActionBoxTest : public InProcessBrowserTest,
- public content::NotificationObserver {
- protected:
- ActionBoxTest() {}
-
- virtual void SetUpOnMainThread() OVERRIDE {
- ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
- ASSERT_NO_FATAL_FAILURE(SetupComponents());
- chrome::FocusLocationBar(browser());
- ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX));
- }
-
- virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
- // Enable Action Box UI for the test.
- command_line->AppendSwitchASCII(switches::kActionBox, "1");
- }
-
- void SetupComponents() {}
-
- virtual void Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) OVERRIDE {
- switch (type) {
- case content::NOTIFICATION_WEB_CONTENTS_DESTROYED:
- case chrome::NOTIFICATION_TAB_PARENTED:
- case chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY:
- case chrome::NOTIFICATION_HISTORY_LOADED:
- case chrome::NOTIFICATION_HISTORY_URLS_MODIFIED:
- case chrome::NOTIFICATION_TEMPLATE_URL_SERVICE_LOADED:
- break;
- default:
- FAIL() << "Unexpected notification type";
- }
- base::MessageLoop::current()->Quit();
- }
-
- DISALLOW_COPY_AND_ASSIGN(ActionBoxTest);
-};
-
-// Test if Bookmark star appears after bookmarking a page in the action box, and
-// disappears after unbookmarking a page.
-IN_PROC_BROWSER_TEST_F(ActionBoxTest, BookmarkAPageTest) {
- LocationBarTesting* loc_bar =
- browser()->window()->GetLocationBar()->GetLocationBarForTesting();
-
- // Navigate somewhere we can bookmark.
- ui_test_utils::NavigateToURL(browser(), GURL("http://www.google.com"));
-
- // Make sure the bookmarking system is up and running.
- BookmarkModel* model =
- BookmarkModelFactory::GetForProfile(browser()->profile());
- ui_test_utils::WaitForBookmarkModelToLoad(model);
-
- // Page is not bookmarked yet.
- ASSERT_FALSE(loc_bar->GetBookmarkStarVisibility());
-
- // Simulate an action box click and menu item selection.
- chrome::ExecuteCommand(browser(), IDC_BOOKMARK_PAGE_FROM_STAR);
-
- // Page is now bookmarked.
- ASSERT_TRUE(loc_bar->GetBookmarkStarVisibility());
-
- // Get the BookmarkModel to unbookmark the bookmark.
- bookmark_utils::RemoveAllBookmarks(model, GURL("http://www.google.com"));
-
- // Page is now unbookmarked.
- ASSERT_FALSE(loc_bar->GetBookmarkStarVisibility());
-
-}
diff --git a/chrome/browser/ui/omnibox/alternate_nav_infobar_delegate.h b/chrome/browser/ui/omnibox/alternate_nav_infobar_delegate.h
index 5b5f594..90b8fd1 100644
--- a/chrome/browser/ui/omnibox/alternate_nav_infobar_delegate.h
+++ b/chrome/browser/ui/omnibox/alternate_nav_infobar_delegate.h
@@ -12,7 +12,7 @@
class AlternateNavInfoBarDelegate : public InfoBarDelegate {
public:
- // Creates an alternate nav delegate and adds it to |infobar_service|.
+ // Creates an alternate nav infobar delegate and adds it to |infobar_service|.
static void Create(InfoBarService* infobar_service,
const GURL& alternate_nav_url);
diff --git a/chrome/browser/ui/omnibox/location_bar.h b/chrome/browser/ui/omnibox/location_bar.h
index eeeb843..6a759b1 100644
--- a/chrome/browser/ui/omnibox/location_bar.h
+++ b/chrome/browser/ui/omnibox/location_bar.h
@@ -104,10 +104,6 @@
// Simulates a left mouse pressed on the visible page action at |index|.
virtual void TestPageActionPressed(size_t index) = 0;
- // Simulates a left mouse pressed on the action box decoration, followed by
- // a menu item selection.
- virtual void TestActionBoxMenuItemSelected(int command_id) = 0;
-
// Returns whether or not the bookmark star decoration is visible.
virtual bool GetBookmarkStarVisibility() = 0;
diff --git a/chrome/browser/ui/omnibox/omnibox_controller.cc b/chrome/browser/ui/omnibox/omnibox_controller.cc
index 196fef7..b5b7117 100644
--- a/chrome/browser/ui/omnibox/omnibox_controller.cc
+++ b/chrome/browser/ui/omnibox/omnibox_controller.cc
@@ -69,21 +69,6 @@
const AutocompleteResult::const_iterator match(result.default_match());
if (match != result.end()) {
current_match_ = *match;
- // TODO(beaudoin): This code could be made simpler if AutocompleteMatch
- // had an |inline_autocompletion| instead of |inline_autocomplete_offset|.
- // The |fill_into_edit| we get may not match what we have in the view at
- // that time. We're only interested in the inline_autocomplete part, so
- // update this here.
- current_match_.fill_into_edit = omnibox_edit_model_->user_text();
- if (match->inline_autocomplete_offset < match->fill_into_edit.length()) {
- current_match_.inline_autocomplete_offset =
- current_match_.fill_into_edit.length();
- current_match_.fill_into_edit += match->fill_into_edit.substr(
- match->inline_autocomplete_offset);
- } else {
- current_match_.inline_autocomplete_offset = string16::npos;
- }
-
if (!prerender::IsOmniboxEnabled(profile_))
DoPreconnect(*match);
omnibox_edit_model_->OnCurrentMatchChanged();
diff --git a/chrome/browser/ui/omnibox/omnibox_current_page_delegate.h b/chrome/browser/ui/omnibox/omnibox_current_page_delegate.h
index faf2135..e91aa2d 100644
--- a/chrome/browser/ui/omnibox/omnibox_current_page_delegate.h
+++ b/chrome/browser/ui/omnibox/omnibox_current_page_delegate.h
@@ -32,6 +32,9 @@
// Returns the URL of the current page.
virtual const GURL& GetURL() const = 0;
+ // Returns true if the visible entry is a New Tab Page rendered by Instant.
+ virtual bool IsInstantNTP() const = 0;
+
// Returns whether the current page is loading.
virtual bool IsLoading() const = 0;
diff --git a/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc b/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc
index 80d2cdf..7868c8c 100644
--- a/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc
+++ b/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.cc
@@ -10,6 +10,7 @@
#include "chrome/browser/predictors/autocomplete_action_predictor.h"
#include "chrome/browser/predictors/autocomplete_action_predictor_factory.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/search/search.h"
#include "chrome/browser/sessions/session_tab_helper.h"
#include "chrome/browser/ui/omnibox/omnibox_edit_controller.h"
#include "chrome/browser/ui/search/search_tab_helper.h"
@@ -35,6 +36,10 @@
return controller_->GetWebContents()->GetURL();
}
+bool OmniboxCurrentPageDelegateImpl::IsInstantNTP() const {
+ return chrome::IsInstantNTP(controller_->GetWebContents());
+}
+
bool OmniboxCurrentPageDelegateImpl::IsLoading() const {
return controller_->GetWebContents()->IsLoading();
}
@@ -88,6 +93,6 @@
predictors::AutocompleteActionPredictorFactory::GetForProfile(profile_)->
StartPrerendering(
match.destination_url,
- web_contents->GetController().GetSessionStorageNamespace(),
+ web_contents->GetController().GetSessionStorageNamespaceMap(),
container_bounds.size());
}
diff --git a/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.h b/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.h
index 496f746..9ef4581 100644
--- a/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.h
+++ b/chrome/browser/ui/omnibox/omnibox_current_page_delegate_impl.h
@@ -20,6 +20,7 @@
// OmniboxCurrentPageDelegate.
virtual bool CurrentPageExists() const OVERRIDE;
virtual const GURL& GetURL() const OVERRIDE;
+ virtual bool IsInstantNTP() const OVERRIDE;
virtual bool IsLoading() const OVERRIDE;
virtual content::NavigationController&
GetNavigationController() const OVERRIDE;
diff --git a/chrome/browser/ui/omnibox/omnibox_edit_model.cc b/chrome/browser/ui/omnibox/omnibox_edit_model.cc
index 6ba8740..7ade221 100644
--- a/chrome/browser/ui/omnibox/omnibox_edit_model.cc
+++ b/chrome/browser/ui/omnibox/omnibox_edit_model.cc
@@ -347,7 +347,7 @@
}
bool OmniboxEditModel::CurrentTextIsURL() const {
- if (view_->toolbar_model()->WouldReplaceSearchURLWithSearchTerms())
+ if (view_->toolbar_model()->WouldReplaceSearchURLWithSearchTerms(false))
return false;
// If current text is not composed of replaced search terms and
@@ -375,7 +375,7 @@
// Do not adjust if selection did not start at the beginning of the field, or
// if the URL was replaced by search terms.
if ((sel_min != 0) ||
- view_->toolbar_model()->WouldReplaceSearchURLWithSearchTerms())
+ view_->toolbar_model()->WouldReplaceSearchURLWithSearchTerms(false))
return;
if (!user_input_in_progress_ && is_all_selected) {
@@ -625,10 +625,9 @@
autocomplete_controller()->input().type(),
popup_model()->selected_line(),
-1, // don't yet know tab ID; set later if appropriate
- delegate_->CurrentPageExists() ? ClassifyPage(delegate_->GetURL()) :
- metrics::OmniboxEventProto_PageClassification_OTHER,
+ ClassifyPage(),
elapsed_time_since_user_first_modified_omnibox,
- string16::npos, // completed_length; possibly set later
+ match.inline_autocompletion.length(),
elapsed_time_since_last_change_to_default_match,
result());
@@ -646,12 +645,6 @@
if (index != OmniboxPopupModel::kNoMatch)
log.selected_index = index;
- if (match.inline_autocomplete_offset != string16::npos) {
- DCHECK_GE(match.fill_into_edit.length(),
- match.inline_autocomplete_offset);
- log.completed_length =
- match.fill_into_edit.length() - match.inline_autocomplete_offset;
- }
if ((disposition == CURRENT_TAB) && delegate_->CurrentPageExists()) {
// If we know the destination is being opened in the current tab,
@@ -702,6 +695,9 @@
TemplateURLPrepopulateData::kMaxPrepopulatedEngineID);
}
+ // Get the current text before we call RevertAll() which will clear it.
+ string16 current_text = GetViewText();
+
if (disposition != NEW_BACKGROUND_TAB) {
base::AutoReset<bool> tmp(&in_revert_, true);
view_->RevertAll(); // Revert the box to its unedited state
@@ -716,8 +712,8 @@
GetDestinationURL(match, query_formulation_time);
RecordPercentageMatchHistogram(
- permanent_text_, match.contents,
- view_->toolbar_model()->WouldReplaceSearchURLWithSearchTerms(),
+ permanent_text_, current_text,
+ view_->toolbar_model()->WouldReplaceSearchURLWithSearchTerms(false),
match.transition);
// Track whether the destination URL sends us to a search results page
@@ -726,8 +722,8 @@
TemplateURLServiceFactory::GetForProfile(profile_)->
GetDefaultSearchProvider();
if (default_provider && default_provider->IsSearchURL(destination_url))
- content::RecordAction(UserMetricsAction(
- "OmniboxDestinationURLMatchesDefaultSearchProvider"));
+ content::RecordAction(
+ UserMetricsAction("OmniboxDestinationURLIsSearchOnDSP"));
// This calls RevertAll again.
base::AutoReset<bool> tmp(&in_revert_, true);
@@ -1100,6 +1096,8 @@
MaybeAcceptKeywordBySpace(user_text_));
}
+// TODO(beaudoin): Merge OnPopupDataChanged with this method once the popup
+// handling has completely migrated to omnibox_controller.
void OmniboxEditModel::OnCurrentMatchChanged() {
has_temporary_text_ = false;
@@ -1110,17 +1108,12 @@
string16 keyword;
bool is_keyword_hint;
match.GetKeywordUIState(profile_, &keyword, &is_keyword_hint);
- string16 inline_autocomplete_text;
- if (match.inline_autocomplete_offset < match.fill_into_edit.length()) {
- // We have blue text, go through OnPopupDataChanged.
- // TODO(beaudoin): Merge OnPopupDataChanged with this method once the
- // popup handling has completely migrated to omnibox_controller.
- inline_autocomplete_text =
- match.fill_into_edit.substr(match.inline_autocomplete_offset);
- }
popup_model()->OnResultChanged();
- OnPopupDataChanged(inline_autocomplete_text, NULL, keyword,
- is_keyword_hint);
+ // OnPopupDataChanged() resets OmniboxController's |current_match_| early
+ // on. Therefore, copy match.inline_autocompletion to a temp to preserve
+ // its value across the entire call.
+ const string16 inline_autocompletion(match.inline_autocompletion);
+ OnPopupDataChanged(inline_autocompletion, NULL, keyword, is_keyword_hint);
}
string16 OmniboxEditModel::GetViewText() const {
@@ -1163,7 +1156,7 @@
DCHECK(match != NULL);
if (!user_input_in_progress_ &&
- view_->toolbar_model()->WouldReplaceSearchURLWithSearchTerms()) {
+ view_->toolbar_model()->WouldReplaceSearchURLWithSearchTerms(false)) {
// Any time the user hits enter on the unchanged omnibox, we should reload.
// When we're not extracting search terms, AcceptInput() will take care of
// this (see code referring to PAGE_TRANSITION_RELOAD there), but when we're
@@ -1266,17 +1259,26 @@
}
metrics::OmniboxEventProto::PageClassification
- OmniboxEditModel::ClassifyPage(const GURL& gurl) const {
+ OmniboxEditModel::ClassifyPage() const {
+ if (!delegate_->CurrentPageExists())
+ return metrics::OmniboxEventProto::OTHER;
+ if (delegate_->IsInstantNTP())
+ return metrics::OmniboxEventProto::INSTANT_NEW_TAB_PAGE;
+ const GURL& gurl = delegate_->GetURL();
if (!gurl.is_valid())
- return metrics::OmniboxEventProto_PageClassification_INVALID_SPEC;
+ return metrics::OmniboxEventProto::INVALID_SPEC;
const std::string& url = gurl.spec();
if (url == chrome::kChromeUINewTabURL)
- return metrics::OmniboxEventProto_PageClassification_NEW_TAB_PAGE;
+ return metrics::OmniboxEventProto::NEW_TAB_PAGE;
if (url == content::kAboutBlankURL)
- return metrics::OmniboxEventProto_PageClassification_BLANK;
+ return metrics::OmniboxEventProto::BLANK;
if (url == profile()->GetPrefs()->GetString(prefs::kHomePage))
- return metrics::OmniboxEventProto_PageClassification_HOMEPAGE;
- return metrics::OmniboxEventProto_PageClassification_OTHER;
+ return metrics::OmniboxEventProto::HOMEPAGE;
+ if (view_->toolbar_model()->WouldReplaceSearchURLWithSearchTerms(true)) {
+ return metrics::
+ OmniboxEventProto::SEARCH_RESULT_PAGE_DOING_SEARCH_TERM_REPLACEMENT;
+ }
+ return metrics::OmniboxEventProto::OTHER;
}
void OmniboxEditModel::ClassifyStringForPasteAndGo(
diff --git a/chrome/browser/ui/omnibox/omnibox_edit_model.h b/chrome/browser/ui/omnibox/omnibox_edit_model.h
index 4dff4ef..4087b4d 100644
--- a/chrome/browser/ui/omnibox/omnibox_edit_model.h
+++ b/chrome/browser/ui/omnibox/omnibox_edit_model.h
@@ -299,8 +299,6 @@
// Access the current view text.
string16 GetViewText() const;
- string16 user_text() const { return user_text_; }
-
// TODO(beaudoin): We need this to allow OmniboxController access the
// InstantController via OmniboxEditController, because the only valid pointer
// to InstantController is kept in Browser. We should try to get rid of this,
@@ -389,8 +387,7 @@
// page or a normal web page. Used for logging omnibox events for
// UMA opted-in users. Examines the user's profile to determine if the
// current page is the user's home page.
- metrics::OmniboxEventProto::PageClassification ClassifyPage(
- const GURL& gurl) const;
+ metrics::OmniboxEventProto::PageClassification ClassifyPage() const;
// Sets |match| and |alternate_nav_url| based on classifying |text|.
// |alternate_nav_url| may be NULL.
diff --git a/chrome/browser/ui/omnibox/omnibox_popup_model.cc b/chrome/browser/ui/omnibox/omnibox_popup_model.cc
index 30d1825..09102d1 100644
--- a/chrome/browser/ui/omnibox/omnibox_popup_model.cc
+++ b/chrome/browser/ui/omnibox/omnibox_popup_model.cc
@@ -16,7 +16,7 @@
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/ui/omnibox/omnibox_popup_model_observer.h"
#include "chrome/browser/ui/omnibox/omnibox_popup_view.h"
-#include "third_party/icu/public/common/unicode/ubidi.h"
+#include "third_party/icu/source/common/unicode/ubidi.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/rect.h"
@@ -111,13 +111,7 @@
match.GetKeywordUIState(edit_model_->profile(), &keyword, &is_keyword_hint);
if (reset_to_default) {
- string16 inline_autocomplete_text;
- if ((match.inline_autocomplete_offset != string16::npos) &&
- (match.inline_autocomplete_offset < match.fill_into_edit.length())) {
- inline_autocomplete_text =
- match.fill_into_edit.substr(match.inline_autocomplete_offset);
- }
- edit_model_->OnPopupDataChanged(inline_autocomplete_text, NULL,
+ edit_model_->OnPopupDataChanged(match.inline_autocompletion, NULL,
keyword, is_keyword_hint);
} else {
edit_model_->OnPopupDataChanged(match.fill_into_edit, ¤t_destination,
diff --git a/chrome/browser/ui/pdf/pdf_tab_helper.cc b/chrome/browser/ui/pdf/pdf_tab_helper.cc
index 3e3bfcb..d78bb81 100644
--- a/chrome/browser/ui/pdf/pdf_tab_helper.cc
+++ b/chrome/browser/ui/pdf/pdf_tab_helper.cc
@@ -4,12 +4,14 @@
#include "chrome/browser/ui/pdf/pdf_tab_helper.h"
+#include "chrome/browser/download/download_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/omnibox/location_bar.h"
#include "chrome/browser/ui/pdf/open_pdf_in_reader_prompt_delegate.h"
#include "chrome/browser/ui/pdf/pdf_unsupported_feature.h"
+#include "chrome/browser/ui/tab_contents/core_tab_helper.h"
#include "chrome/common/render_messages.h"
#include "content/public/browser/navigation_details.h"
@@ -32,7 +34,10 @@
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(PDFTabHelper, message)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_PDFHasUnsupportedFeature,
- OnPDFHasUnsupportedFeature)
+ OnHasUnsupportedFeature)
+ IPC_MESSAGE_HANDLER(ChromeViewHostMsg_PDFSaveURLAs, OnSaveURLAs)
+ IPC_MESSAGE_HANDLER(ChromeViewHostMsg_PDFUpdateContentRestrictions,
+ OnUpdateContentRestrictions)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -64,6 +69,18 @@
location_bar->UpdateOpenPDFInReaderPrompt();
}
-void PDFTabHelper::OnPDFHasUnsupportedFeature() {
+void PDFTabHelper::OnHasUnsupportedFeature() {
PDFHasUnsupportedFeature(web_contents());
}
+
+void PDFTabHelper::OnSaveURLAs(const GURL& url,
+ const content::Referrer& referrer) {
+ download_util::RecordDownloadSource(download_util::INITIATED_BY_PDF_SAVE);
+ web_contents()->SaveFrame(url, referrer);
+}
+
+void PDFTabHelper::OnUpdateContentRestrictions(int content_restrictions) {
+ CoreTabHelper* core_tab_helper =
+ CoreTabHelper::FromWebContents(web_contents());
+ core_tab_helper->UpdateContentRestrictions(content_restrictions);
+}
diff --git a/chrome/browser/ui/pdf/pdf_tab_helper.h b/chrome/browser/ui/pdf/pdf_tab_helper.h
index d50c86f..978c605 100644
--- a/chrome/browser/ui/pdf/pdf_tab_helper.h
+++ b/chrome/browser/ui/pdf/pdf_tab_helper.h
@@ -41,7 +41,10 @@
void UpdateLocationBar();
// Message handlers.
- void OnPDFHasUnsupportedFeature();
+ void OnHasUnsupportedFeature();
+ void OnSaveURLAs(const GURL& url,
+ const content::Referrer& referrer);
+ void OnUpdateContentRestrictions(int content_restrictions);
// The model for the confirmation prompt to open a PDF in Adobe Reader.
scoped_ptr<OpenPDFInReaderPromptDelegate> open_in_reader_prompt_;
diff --git a/chrome/browser/ui/pdf/pdf_unsupported_feature.cc b/chrome/browser/ui/pdf/pdf_unsupported_feature.cc
index d6c9638..fde1364 100644
--- a/chrome/browser/ui/pdf/pdf_unsupported_feature.cc
+++ b/chrome/browser/ui/pdf/pdf_unsupported_feature.cc
@@ -50,7 +50,7 @@
using content::Referrer;
using content::UserMetricsAction;
using content::WebContents;
-using webkit::WebPluginInfo;
+using content::WebPluginInfo;
namespace {
@@ -243,7 +243,7 @@
public:
// |reader| is NULL if Adobe Reader isn't installed.
PDFUnsupportedFeaturePromptDelegate(WebContents* web_contents,
- const webkit::WebPluginInfo* reader,
+ const content::WebPluginInfo* reader,
PluginFinder* plugin_finder);
virtual ~PDFUnsupportedFeaturePromptDelegate();
@@ -267,7 +267,7 @@
PDFUnsupportedFeaturePromptDelegate::PDFUnsupportedFeaturePromptDelegate(
WebContents* web_contents,
- const webkit::WebPluginInfo* reader,
+ const content::WebPluginInfo* reader,
PluginFinder* plugin_finder)
: web_contents_(web_contents),
reader_installed_(!!reader),
@@ -358,13 +358,13 @@
#if defined(OS_WIN) && defined(ENABLE_PLUGIN_INSTALLATION)
void GotPluginsCallback(int process_id,
int routing_id,
- const std::vector<webkit::WebPluginInfo>& plugins) {
+ const std::vector<content::WebPluginInfo>& plugins) {
WebContents* web_contents =
tab_util::GetWebContentsByID(process_id, routing_id);
if (!web_contents)
return;
- const webkit::WebPluginInfo* reader = NULL;
+ const content::WebPluginInfo* reader = NULL;
PluginFinder* plugin_finder = PluginFinder::GetInstance();
for (size_t i = 0; i < plugins.size(); ++i) {
scoped_ptr<PluginMetadata> plugin_metadata(
diff --git a/chrome/browser/ui/prefs/prefs_tab_helper.cc b/chrome/browser/ui/prefs/prefs_tab_helper.cc
index 30feabb..3e3f718 100644
--- a/chrome/browser/ui/prefs/prefs_tab_helper.cc
+++ b/chrome/browser/ui/prefs/prefs_tab_helper.cc
@@ -25,8 +25,8 @@
#include "content/public/browser/web_contents.h"
#include "grit/locale_settings.h"
#include "grit/platform_locale_settings.h"
-#include "third_party/icu/public/common/unicode/uchar.h"
-#include "third_party/icu/public/common/unicode/uscript.h"
+#include "third_party/icu/source/common/unicode/uchar.h"
+#include "third_party/icu/source/common/unicode/uscript.h"
#include "webkit/common/webpreferences.h"
#if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(ENABLE_THEMES)
diff --git a/chrome/browser/ui/search/instant_controller.cc b/chrome/browser/ui/search/instant_controller.cc
index 6203445..28ce7fa 100644
--- a/chrome/browser/ui/search/instant_controller.cc
+++ b/chrome/browser/ui/search/instant_controller.cc
@@ -19,7 +19,6 @@
#include "chrome/browser/search_engines/template_url_service.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/ui/browser_instant_controller.h"
-#include "chrome/browser/ui/search/instant_ntp.h"
#include "chrome/browser/ui/search/instant_tab.h"
#include "chrome/browser/ui/search/search_tab_helper.h"
#include "chrome/common/chrome_switches.h"
@@ -102,16 +101,6 @@
SearchTabHelper::FromWebContents(contents)->NavigationEntryUpdated();
}
-template <typename T>
-void DeletePageSoon(scoped_ptr<T> page) {
- if (page->contents()) {
- base::MessageLoop::current()->DeleteSoon(
- FROM_HERE, page->ReleaseContents().release());
- }
-
- base::MessageLoop::current()->DeleteSoon(FROM_HERE, page.release());
-}
-
} // namespace
InstantController::InstantController(BrowserInstantController* browser,
@@ -121,41 +110,9 @@
omnibox_focus_state_(OMNIBOX_FOCUS_NONE),
omnibox_focus_change_reason_(OMNIBOX_FOCUS_CHANGE_EXPLICIT),
omnibox_bounds_(-1, -1, 0, 0) {
-
- // When the InstantController lives, the InstantService should live.
- // InstantService sets up profile-level facilities such as the ThemeSource for
- // the NTP.
- // However, in some tests, browser_ may be null.
- if (browser_) {
- InstantService* instant_service = GetInstantService();
- instant_service->AddObserver(this);
- }
}
InstantController::~InstantController() {
- if (browser_) {
- InstantService* instant_service = GetInstantService();
- instant_service->RemoveObserver(this);
- }
-}
-
-scoped_ptr<content::WebContents> InstantController::ReleaseNTPContents() {
- if (!extended_enabled() || !browser_->profile() ||
- browser_->profile()->IsOffTheRecord() ||
- !chrome::ShouldShowInstantNTP())
- return scoped_ptr<content::WebContents>();
-
- LOG_INSTANT_DEBUG_EVENT(this, "ReleaseNTPContents");
-
- if (ShouldSwitchToLocalNTP())
- ResetNTP(GetLocalInstantURL());
-
- scoped_ptr<content::WebContents> ntp_contents = ntp_->ReleaseContents();
-
- // Preload a new Instant NTP.
- ResetNTP(GetInstantURL());
-
- return ntp_contents.Pass();
}
void InstantController::SetOmniboxBounds(const gfx::Rect& bounds) {
@@ -163,19 +120,10 @@
return;
omnibox_bounds_ = bounds;
- if (ntp_)
- ntp_->sender()->SetOmniboxBounds(omnibox_bounds_);
if (instant_tab_)
instant_tab_->sender()->SetOmniboxBounds(omnibox_bounds_);
}
-void InstantController::OnDefaultSearchProviderChanged() {
- if (ntp_ && extended_enabled()) {
- ntp_.reset();
- ResetNTP(GetInstantURL());
- }
-}
-
void InstantController::ToggleVoiceSearch() {
if (instant_tab_)
instant_tab_->sender()->ToggleVoiceSearch();
@@ -190,36 +138,26 @@
return;
}
- if (IsContentsFrom(instant_tab(), contents)) {
- // Verify we're not already on a local page and that the URL precisely
- // equals the instant_url (minus the query params, as those will be filled
- // in by template values). This check is necessary to make sure we don't
- // inadvertently redirect to the local NTP if someone, say, reloads a SRP
- // while offline, as a committed results page still counts as an instant
- // url. We also check to make sure there's no forward history, as if
- // someone hits the back button a lot when offline and returns to a NTP
- // we don't want to redirect and nuke their forward history stack.
- const GURL& current_url = contents->GetURL();
- if (instant_tab_->IsLocal() ||
- !chrome::MatchesOriginAndPath(GURL(GetInstantURL()), current_url) ||
- !current_url.ref().empty() ||
- contents->GetController().CanGoForward())
- return;
- LOG_INSTANT_DEBUG_EVENT(this, "InstantPageLoadFailed: instant_tab");
- RedirectToLocalNTP(contents);
- } else if (IsContentsFrom(ntp(), contents)) {
- LOG_INSTANT_DEBUG_EVENT(this, "InstantPageLoadFailed: ntp");
- bool is_local = ntp_->IsLocal();
- DeletePageSoon(ntp_.Pass());
- if (!is_local)
- ResetNTP(GetLocalInstantURL());
- } else {
- NOTREACHED();
- }
-}
+ DCHECK(IsContentsFrom(instant_tab(), contents));
-content::WebContents* InstantController::GetNTPContents() const {
- return ntp_ ? ntp_->contents() : NULL;
+ // Verify we're not already on a local page and that the URL precisely
+ // equals the instant_url (minus the query params, as those will be filled
+ // in by template values). This check is necessary to make sure we don't
+ // inadvertently redirect to the local NTP if someone, say, reloads a SRP
+ // while offline, as a committed results page still counts as an instant
+ // url. We also check to make sure there's no forward history, as if
+ // someone hits the back button a lot when offline and returns to a NTP
+ // we don't want to redirect and nuke their forward history stack.
+ const GURL& current_url = contents->GetURL();
+ GURL instant_url = chrome::GetInstantURL(profile(),
+ chrome::kDisableStartMargin);
+ if (instant_tab_->IsLocal() ||
+ !chrome::MatchesOriginAndPath(instant_url, current_url) ||
+ !current_url.ref().empty() ||
+ contents->GetController().CanGoForward())
+ return;
+ LOG_INSTANT_DEBUG_EVENT(this, "InstantPageLoadFailed: instant_tab");
+ RedirectToLocalNTP(contents);
}
bool InstantController::SubmitQuery(const string16& search_terms) {
@@ -291,17 +229,6 @@
InstantTab::EmitMouseoverCount(contents);
}
-void InstantController::ThemeInfoChanged(
- const ThemeBackgroundInfo& theme_info) {
- if (!extended_enabled())
- return;
-
- if (ntp_)
- ntp_->sender()->SendThemeBackgroundInfo(theme_info);
- if (instant_tab_)
- instant_tab_->sender()->SendThemeBackgroundInfo(theme_info);
-}
-
void InstantController::LogDebugEvent(const std::string& info) const {
DVLOG(1) << info;
@@ -316,19 +243,6 @@
debug_events_.clear();
}
-void InstantController::MostVisitedItemsChanged(
- const std::vector<InstantMostVisitedItem>& items) {
- if (ntp_)
- ntp_->sender()->SendMostVisitedItems(items);
- if (instant_tab_)
- instant_tab_->sender()->SendMostVisitedItems(items);
-
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_INSTANT_SENT_MOST_VISITED_ITEMS,
- content::Source<InstantController>(this),
- content::NotificationService::NoDetails());
-}
-
void InstantController::DeleteMostVisitedItem(const GURL& url) {
DCHECK(!url.is_empty());
InstantService* instant_service = GetInstantService();
@@ -363,45 +277,6 @@
return instant_tab_.get();
}
-InstantNTP* InstantController::ntp() const {
- return ntp_.get();
-}
-
-void InstantController::OnNetworkChanged(
- net::NetworkChangeNotifier::ConnectionType type) {
- // Not interested in events conveying change to offline
- if (type == net::NetworkChangeNotifier::CONNECTION_NONE)
- return;
- if (!extended_enabled_)
- return;
- if (!ntp_ || ntp_->IsLocal())
- ResetNTP(GetInstantURL());
-}
-
-// TODO(shishir): We assume that the WebContent's current RenderViewHost is the
-// RenderViewHost being created which is not always true. Fix this.
-void InstantController::InstantPageRenderViewCreated(
- const content::WebContents* contents) {
- if (!extended_enabled())
- return;
-
- // Update theme info so that the page picks it up.
- InstantService* instant_service = GetInstantService();
- if (instant_service) {
- instant_service->UpdateThemeInfo();
- instant_service->UpdateMostVisitedItemsInfo();
- }
-
- // Ensure the searchbox API has the correct initial state.
- if (IsContentsFrom(ntp(), contents)) {
- ntp_->sender()->SetOmniboxBounds(omnibox_bounds_);
- ntp_->InitializeFonts();
- ntp_->InitializePromos();
- } else {
- NOTREACHED();
- }
-}
-
void InstantController::InstantSupportChanged(
InstantSupportState instant_support) {
// Handle INSTANT_SUPPORT_YES here because InstantPage is not hooked up to the
@@ -416,53 +291,25 @@
void InstantController::InstantSupportDetermined(
const content::WebContents* contents,
bool supports_instant) {
- if (IsContentsFrom(instant_tab(), contents)) {
- if (!supports_instant)
- base::MessageLoop::current()->DeleteSoon(FROM_HERE,
- instant_tab_.release());
+ DCHECK(IsContentsFrom(instant_tab(), contents));
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
- content::Source<InstantController>(this),
- content::NotificationService::NoDetails());
- } else if (IsContentsFrom(ntp(), contents)) {
- if (!supports_instant) {
- bool is_local = ntp_->IsLocal();
- DeletePageSoon(ntp_.Pass());
- // Preload a local NTP in place of the broken online one.
- if (!is_local)
- ResetNTP(GetLocalInstantURL());
- }
+ if (!supports_instant)
+ base::MessageLoop::current()->DeleteSoon(FROM_HERE, instant_tab_.release());
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_INSTANT_NTP_SUPPORT_DETERMINED,
- content::Source<InstantController>(this),
- content::NotificationService::NoDetails());
-
- } else {
- NOTREACHED();
- }
-}
-
-void InstantController::InstantPageRenderProcessGone(
- const content::WebContents* contents) {
- if (IsContentsFrom(ntp(), contents)) {
- DeletePageSoon(ntp_.Pass());
- } else {
- NOTREACHED();
- }
+ content::NotificationService::current()->Notify(
+ chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
+ content::Source<InstantController>(this),
+ content::NotificationService::NoDetails());
}
void InstantController::InstantPageAboutToNavigateMainFrame(
const content::WebContents* contents,
const GURL& url) {
- if (IsContentsFrom(instant_tab(), contents)) {
- // The Instant tab navigated. Send it the data it needs to display
- // properly.
- UpdateInfoForInstantTab();
- } else {
- NOTREACHED();
- }
+ DCHECK(IsContentsFrom(instant_tab(), contents));
+
+ // The Instant tab navigated. Send it the data it needs to display
+ // properly.
+ UpdateInfoForInstantTab();
}
void InstantController::FocusOmnibox(const content::WebContents* contents,
@@ -518,88 +365,15 @@
browser_->OpenURL(url, transition, disposition);
}
-std::string InstantController::GetLocalInstantURL() const {
- return chrome::GetLocalInstantURL(profile()).spec();
-}
-
-std::string InstantController::GetInstantURL() const {
- if (extended_enabled() && net::NetworkChangeNotifier::IsOffline())
- return GetLocalInstantURL();
-
- const GURL instant_url = chrome::GetInstantURL(profile(),
- omnibox_bounds_.x());
- if (instant_url.is_valid())
- return instant_url.spec();
-
- // Only extended mode has a local fallback.
- return extended_enabled() ? GetLocalInstantURL() : std::string();
-}
-
bool InstantController::extended_enabled() const {
return extended_enabled_;
}
-bool InstantController::PageIsCurrent(const InstantPage* page) const {
-
- const std::string& instant_url = GetInstantURL();
- if (instant_url.empty() ||
- !chrome::MatchesOriginAndPath(GURL(page->instant_url()),
- GURL(instant_url)))
- return false;
-
- return page->supports_instant();
-}
-
-void InstantController::ResetNTP(const std::string& instant_url) {
- // Never load the Instant NTP if it is disabled.
- if (!chrome::ShouldShowInstantNTP())
- return;
-
- // Instant NTP is only used in extended mode so we should always have a
- // non-empty URL to use.
- DCHECK(!instant_url.empty());
- ntp_.reset(new InstantNTP(this, instant_url,
- browser_->profile()->IsOffTheRecord()));
- ntp_->InitContents(profile(), browser_->GetActiveWebContents(),
- base::Bind(&InstantController::ReloadStaleNTP,
- base::Unretained(this)));
- LOG_INSTANT_DEBUG_EVENT(this, base::StringPrintf(
- "ResetNTP: instant_url='%s'", instant_url.c_str()));
-}
-
-void InstantController::ReloadStaleNTP() {
- if (extended_enabled())
- ResetNTP(GetInstantURL());
-}
-
-bool InstantController::ShouldSwitchToLocalNTP() const {
- if (!ntp())
- return true;
-
- // Assume users with Javascript disabled do not want the online experience.
- if (!IsJavascriptEnabled())
- return true;
-
- // Already a local page. Not calling IsLocal() because we want to distinguish
- // between the Google-specific and generic local NTP.
- if (extended_enabled() && ntp()->instant_url() == GetLocalInstantURL())
- return false;
-
- if (PageIsCurrent(ntp()))
- return false;
-
- // The preloaded NTP does not support instant yet. If we're not in startup,
- // always fall back to the local NTP. If we are in startup, use the local NTP
- // (unless the finch flag to use the remote NTP is set).
- return !(InStartup() && chrome::ShouldPreferRemoteNTPOnStartup());
-}
-
void InstantController::ResetInstantTab() {
if (!search_mode_.is_origin_default()) {
content::WebContents* active_tab = browser_->GetActiveWebContents();
if (!instant_tab_ || active_tab != instant_tab_->contents()) {
- instant_tab_.reset(
- new InstantTab(this, browser_->profile()->IsOffTheRecord()));
+ instant_tab_.reset(new InstantTab(this, browser_->profile()));
instant_tab_->Init(active_tab);
UpdateInfoForInstantTab();
}
@@ -638,39 +412,15 @@
void InstantController::RedirectToLocalNTP(content::WebContents* contents) {
contents->GetController().LoadURL(
- chrome::GetLocalInstantURL(browser_->profile()),
- content::Referrer(),
- content::PAGE_TRANSITION_SERVER_REDIRECT,
- std::string()); // No extra headers.
+ GURL(chrome::kChromeSearchLocalNtpUrl),
+ content::Referrer(),
+ content::PAGE_TRANSITION_SERVER_REDIRECT,
+ std::string()); // No extra headers.
// TODO(dcblack): Remove extraneous history entry caused by 404s.
// Note that the base case of a 204 being returned doesn't push a history
// entry.
}
-bool InstantController::IsJavascriptEnabled() const {
- GURL instant_url(GetInstantURL());
- GURL origin(instant_url.GetOrigin());
- ContentSetting js_setting = profile()->GetHostContentSettingsMap()->
- GetContentSetting(origin, origin, CONTENT_SETTINGS_TYPE_JAVASCRIPT,
- NO_RESOURCE_IDENTIFIER);
- // Javascript can be disabled either in content settings or via a WebKit
- // preference, so check both. Disabling it through the Settings page affects
- // content settings. I'm not sure how to disable the WebKit preference, but
- // it's theoretically possible some users have it off.
- bool js_content_enabled =
- js_setting == CONTENT_SETTING_DEFAULT ||
- js_setting == CONTENT_SETTING_ALLOW;
- bool js_webkit_enabled = profile()->GetPrefs()->GetBoolean(
- prefs::kWebKitJavascriptEnabled);
- return js_content_enabled && js_webkit_enabled;
-}
-
-bool InstantController::InStartup() const {
- // TODO(shishir): This is not completely reliable. Find a better way to detect
- // startup time.
- return !browser_->GetActiveWebContents();
-}
-
InstantService* InstantController::GetInstantService() const {
return InstantServiceFactory::GetForProfile(profile());
}
diff --git a/chrome/browser/ui/search/instant_controller.h b/chrome/browser/ui/search/instant_controller.h
index 7964d87..b204ba0 100644
--- a/chrome/browser/ui/search/instant_controller.h
+++ b/chrome/browser/ui/search/instant_controller.h
@@ -14,20 +14,17 @@
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
-#include "chrome/browser/search/instant_service_observer.h"
#include "chrome/browser/ui/search/instant_page.h"
#include "chrome/common/instant_types.h"
#include "chrome/common/omnibox_focus_state.h"
#include "chrome/common/search_types.h"
#include "content/public/common/page_transition_types.h"
-#include "net/base/network_change_notifier.h"
#include "ui/base/window_open_disposition.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/rect.h"
#include "url/gurl.h"
class BrowserInstantController;
-class InstantNTP;
class InstantService;
class InstantTab;
class Profile;
@@ -43,49 +40,29 @@
// InstantController drives Chrome Instant, i.e., the browser implementation of
// the Embedded Search API (see http://dev.chromium.org/embeddedsearch).
//
-// In extended mode, InstantController maintains and coordinates two
-// instances of InstantPage:
-// (1) An InstantNTP instance which is a preloaded search page that will be
-// swapped-in the next time the user navigates to the New Tab Page. It is
-// never shown to the user in an uncommitted state.
-// (2) An InstantTab instance which points to the currently active tab, if it
-// supports the Embedded Search API.
-//
-// Both are backed by a WebContents. InstantNTP owns its WebContents and
-// InstantTab does not.
+// In extended mode, InstantController maintains and coordinates an InstantTab
+// instance of InstantPage. An InstantTab instance points to the currently
+// active tab, if it supports the Embedded Search API. InstantTab is backed by a
+// WebContents and it does not own that WebContents.
//
// InstantController is owned by Browser via BrowserInstantController.
-class InstantController : public InstantPage::Delegate,
- public InstantServiceObserver {
+class InstantController : public InstantPage::Delegate {
public:
InstantController(BrowserInstantController* browser,
bool extended_enabled);
virtual ~InstantController();
- // Releases and returns the NTP WebContents. May be NULL. Loads a new
- // WebContents for the NTP.
- scoped_ptr<content::WebContents> ReleaseNTPContents() WARN_UNUSED_RESULT;
-
// Sets the stored start-edge margin and width of the omnibox.
void SetOmniboxBounds(const gfx::Rect& bounds);
- // Called when the default search provider changes. Resets InstantNTP.
- void OnDefaultSearchProviderChanged();
-
// Notifies |instant_Tab_| to toggle voice search.
void ToggleVoiceSearch();
- // The ntp WebContents. May be NULL. InstantController retains ownership.
- content::WebContents* GetNTPContents() const;
-
// Called if the browser is navigating to a search URL for |search_terms| with
// search-term-replacement enabled. If |instant_tab_| can be used to process
// the search, this does so and returns true. Else, returns false.
bool SubmitQuery(const string16& search_terms);
- // If the network status changes, try to reset NTP and Overlay.
- void OnNetworkChanged(net::NetworkChangeNotifier::ConnectionType type);
-
// Called to indicate that the omnibox focus state changed with the given
// |reason|. If |focus_state| is FOCUS_NONE, |view_gaining_focus| is set to
// the view gaining focus.
@@ -112,16 +89,6 @@
// Resets list of debug events.
void ClearDebugEvents();
- // Loads a new NTP to replace |ntp_|.
- void ReloadStaleNTP();
-
- // Returns the correct Instant URL to use from the following possibilities:
- // o The default search engine's Instant URL
- // o The local page (see GetLocalInstantURL())
- // Returns empty string if no valid Instant URL is available (this is only
- // possible in non-extended mode where we don't have a local page fall-back).
- virtual std::string GetInstantURL() const;
-
// See comments for |debug_events_| below.
const std::list<std::pair<int64, std::string> >& debug_events() {
return debug_events_;
@@ -136,31 +103,13 @@
virtual bool extended_enabled() const;
virtual InstantTab* instant_tab() const;
- virtual InstantNTP* ntp() const;
virtual Profile* profile() const;
- // Returns true if Javascript is enabled and false otherwise.
- virtual bool IsJavascriptEnabled() const;
-
- // Returns true if the browser is in startup.
- virtual bool InStartup() const;
-
private:
friend class InstantExtendedManualTest;
friend class InstantTestBase;
-#define UNIT_F(test) FRIEND_TEST_ALL_PREFIXES(InstantControllerTest, test)
- UNIT_F(DoesNotSwitchToLocalNTPIfOnCurrentNTP);
- UNIT_F(DoesNotSwitchToLocalNTPIfOnLocalNTP);
- UNIT_F(IsJavascriptEnabled);
- UNIT_F(IsJavascriptEnabledChecksContentSettings);
- UNIT_F(IsJavascriptEnabledChecksPrefs);
- UNIT_F(PrefersRemoteNTPOnStartup);
- UNIT_F(SwitchesToLocalNTPIfJSDisabled);
- UNIT_F(SwitchesToLocalNTPIfNoInstantSupport);
- UNIT_F(SwitchesToLocalNTPIfNoNTPReady);
- UNIT_F(SwitchesToLocalNTPIfPathBad);
-#undef UNIT_F
+
FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, ExtendedModeIsOn);
FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, MostVisited);
FRIEND_TEST_ALL_PREFIXES(InstantExtendedTest, NTPIsPreloaded);
@@ -195,13 +144,9 @@
// Overridden from InstantPage::Delegate:
// TODO(shishir): We assume that the WebContent's current RenderViewHost is
// the RenderViewHost being created which is not always true. Fix this.
- virtual void InstantPageRenderViewCreated(
- const content::WebContents* contents) OVERRIDE;
virtual void InstantSupportDetermined(
const content::WebContents* contents,
bool supports_instant) OVERRIDE;
- virtual void InstantPageRenderProcessGone(
- const content::WebContents* contents) OVERRIDE;
virtual void InstantPageAboutToNavigateMainFrame(
const content::WebContents* contents,
const GURL& url) OVERRIDE;
@@ -215,11 +160,6 @@
bool is_search_type) OVERRIDE;
virtual void InstantPageLoadFailed(content::WebContents* contents) OVERRIDE;
- // Overridden from InstantServiceObserver:
- virtual void ThemeInfoChanged(const ThemeBackgroundInfo& theme_info) OVERRIDE;
- virtual void MostVisitedItemsChanged(
- const std::vector<InstantMostVisitedItem>& items) OVERRIDE;
-
// Invoked by the InstantLoader when the Instant page wants to delete a
// Most Visited item.
virtual void DeleteMostVisitedItem(const GURL& url) OVERRIDE;
@@ -239,20 +179,6 @@
// Helper for OmniboxFocusChanged. Commit or discard the overlay.
void OmniboxLostFocus(gfx::NativeView view_gaining_focus);
- // Returns the local Instant URL. (Just a convenience wrapper around
- // chrome::GetLocalInstantURL.)
- virtual std::string GetLocalInstantURL() const;
-
- // Returns true if |page| has an up-to-date Instant URL and supports Instant.
- // Note that local URLs will not pass this check.
- bool PageIsCurrent(const InstantPage* page) const;
-
- // Recreates |ntp_| using |instant_url|.
- void ResetNTP(const std::string& instant_url);
-
- // Returns true if we should switch to using the local NTP.
- bool ShouldSwitchToLocalNTP() const;
-
// If the active tab is an Instant search results page, sets |instant_tab_| to
// point to it. Else, deletes any existing |instant_tab_|.
void ResetInstantTab();
@@ -276,8 +202,7 @@
// Instant is effectively disabled.
const bool extended_enabled_;
- // The instances of InstantPage maintained by InstantController.
- scoped_ptr<InstantNTP> ntp_;
+ // The instance of InstantPage maintained by InstantController.
scoped_ptr<InstantTab> instant_tab_;
// Omnibox focus state.
diff --git a/chrome/browser/ui/search/instant_controller_unittest.cc b/chrome/browser/ui/search/instant_controller_unittest.cc
deleted file mode 100644
index b96540b..0000000
--- a/chrome/browser/ui/search/instant_controller_unittest.cc
+++ /dev/null
@@ -1,289 +0,0 @@
-// Copyright (c) 2013 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 "base/memory/scoped_ptr.h"
-#include "base/metrics/histogram.h"
-#include "base/metrics/histogram_samples.h"
-#include "base/metrics/statistics_recorder.h"
-#include "base/prefs/pref_service.h"
-#include "chrome/browser/content_settings/host_content_settings_map.h"
-#include "chrome/browser/search/search.h"
-#include "chrome/browser/ui/search/instant_controller.h"
-#include "chrome/browser/ui/search/instant_ntp.h"
-#include "chrome/common/content_settings.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/test/base/testing_profile.h"
-#include "content/public/test/test_browser_thread.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using base::HistogramBase;
-using base::HistogramSamples;
-using base::StatisticsRecorder;
-
-class TestableInstantNTP : public InstantNTP {
- public:
- TestableInstantNTP(InstantController* controller,
- const std::string& instant_url)
- : InstantNTP(controller, instant_url, false) {
- }
-
- // Overrides from InstantPage
- virtual bool supports_instant() const OVERRIDE {
- return test_supports_instant_;
- }
-
- virtual bool IsLocal() const OVERRIDE {
- return test_is_local_;
- };
-
- virtual const std::string& instant_url() const OVERRIDE {
- return test_instant_url_;
- }
-
- void set_instant_url(const std::string& instant_url) {
- test_instant_url_ = instant_url;
- }
-
- void set_supports_instant(bool supports_instant) {
- test_supports_instant_ = supports_instant;
- }
-
- void set_is_local(bool is_local) {
- test_is_local_ = is_local;
- }
-
- private:
- std::string test_instant_url_;
- bool test_supports_instant_;
- bool test_is_local_;
-};
-
-class TestableInstantController : public InstantController {
- public:
- TestableInstantController()
- : InstantController(NULL, true),
- test_instant_url_("http://test_url"),
- test_extended_enabled_(true),
- override_javascript_enabled_(true),
- test_javascript_enabled_(true),
- test_in_startup_(false),
- test_ntp_(NULL) {}
-
- // Overrides from InstantController
- virtual std::string GetInstantURL() const OVERRIDE {
- return test_instant_url_;
- }
-
- virtual std::string GetLocalInstantURL() const OVERRIDE {
- return "http://local_instant_url";
- }
-
- virtual bool extended_enabled() const OVERRIDE {
- return test_extended_enabled_;
- }
-
- virtual InstantNTP* ntp() const OVERRIDE {
- return test_ntp_;
- }
-
- void set_instant_url(std::string instant_url) {
- test_instant_url_ = instant_url;
- }
-
- void set_extended_enabled(bool extended_enabled) {
- test_extended_enabled_ = extended_enabled;
- }
-
- void set_ntp(InstantNTP* ntp) {
- test_ntp_ = ntp;
- }
-
- void set_javascript_enabled(bool javascript_enabled) {
- override_javascript_enabled_ = true;
- test_javascript_enabled_ = javascript_enabled;
- }
-
- void set_override_javascript_enabled(bool override_javascript_enabled) {
- override_javascript_enabled_ = override_javascript_enabled;
- }
-
- void set_in_startup(bool in_startup) {
- test_in_startup_ = in_startup;
- }
-
- virtual bool IsJavascriptEnabled() const OVERRIDE {
- if (override_javascript_enabled_)
- return test_javascript_enabled_;
- else
- return InstantController::IsJavascriptEnabled();
- }
-
- virtual bool InStartup() const OVERRIDE {
- return test_in_startup_;
- }
-
- virtual Profile* profile() const OVERRIDE {
- return &profile_;
- }
-
-private:
- std::string test_instant_url_;
- bool test_extended_enabled_;
- bool override_javascript_enabled_;
- bool test_javascript_enabled_;
- bool test_in_startup_;
- InstantNTP* test_ntp_;
- mutable TestingProfile profile_;
-};
-
-class InstantControllerTest : public testing::Test {
- public:
- InstantControllerTest()
- : ui_thread_(content::BrowserThread::UI),
- instant_controller_(new TestableInstantController()) {
- }
-
- virtual void SetUp() OVERRIDE {
- base::StatisticsRecorder::Initialize();
- }
-
- TestableInstantController* instant_controller() {
- return instant_controller_.get();
- }
-
- private:
- content::TestBrowserThread ui_thread_;
- scoped_ptr<TestableInstantController> instant_controller_;
-};
-
-TEST_F(InstantControllerTest, PrefersRemoteNTPOnStartup) {
- std::string instant_url("http://instant_url");
- scoped_ptr<TestableInstantNTP> ntp(new TestableInstantNTP(
- instant_controller(), instant_url));
- ntp->set_is_local(false);
- instant_controller()->set_ntp(ntp.get());
- instant_controller()->set_javascript_enabled(true);
- instant_controller()->set_extended_enabled(true);
- instant_controller()->set_instant_url(instant_url);
- ntp->set_instant_url(instant_url);
- ntp->set_supports_instant(false);
- instant_controller()->set_in_startup(true);
- EXPECT_EQ(!chrome::ShouldPreferRemoteNTPOnStartup(),
- instant_controller()->ShouldSwitchToLocalNTP());
-}
-
-TEST_F(InstantControllerTest, SwitchesToLocalNTPIfNoInstantSupport) {
- std::string instant_url("http://instant_url");
- scoped_ptr<TestableInstantNTP> ntp(new TestableInstantNTP(
- instant_controller(), instant_url));
- ntp.reset(new TestableInstantNTP(instant_controller(), instant_url));
- ntp->set_is_local(false);
- instant_controller()->set_ntp(ntp.get());
- instant_controller()->set_javascript_enabled(true);
- instant_controller()->set_extended_enabled(true);
- instant_controller()->set_instant_url(instant_url);
- ntp->set_instant_url(instant_url);
- ntp->set_supports_instant(false);
- instant_controller()->set_in_startup(false);
- EXPECT_TRUE(instant_controller()->ShouldSwitchToLocalNTP());
-}
-
-TEST_F(InstantControllerTest, SwitchesToLocalNTPIfPathBad) {
- std::string instant_url("http://instant_url");
- scoped_ptr<TestableInstantNTP> ntp(new TestableInstantNTP(
- instant_controller(), instant_url));
- ntp.reset(new TestableInstantNTP(instant_controller(), instant_url));
- ntp->set_is_local(false);
- instant_controller()->set_ntp(ntp.get());
- instant_controller()->set_javascript_enabled(true);
- instant_controller()->set_extended_enabled(true);
- instant_controller()->set_instant_url("http://bogus_url");
- ntp->set_instant_url(instant_url);
- ntp->set_supports_instant(true);
- instant_controller()->set_in_startup(false);
- EXPECT_TRUE(instant_controller()->ShouldSwitchToLocalNTP());
-}
-
-TEST_F(InstantControllerTest, DoesNotSwitchToLocalNTPIfOnCurrentNTP) {
- std::string instant_url("http://instant_url");
- scoped_ptr<TestableInstantNTP> ntp(new TestableInstantNTP(
- instant_controller(), instant_url));
- ntp.reset(new TestableInstantNTP(instant_controller(), instant_url));
- ntp->set_is_local(false);
- instant_controller()->set_ntp(ntp.get());
- instant_controller()->set_javascript_enabled(true);
- instant_controller()->set_extended_enabled(true);
- instant_controller()->set_instant_url(instant_url);
- ntp->set_instant_url(instant_url);
- ntp->set_supports_instant(true);
- instant_controller()->set_in_startup(false);
- EXPECT_FALSE(instant_controller()->ShouldSwitchToLocalNTP());
-}
-
-TEST_F(InstantControllerTest, DoesNotSwitchToLocalNTPIfOnLocalNTP) {
- std::string instant_url("http://instant_url");
- scoped_ptr<TestableInstantNTP> ntp(new TestableInstantNTP(
- instant_controller(), instant_url));
- ntp.reset(new TestableInstantNTP(instant_controller(), instant_url));
- ntp->set_is_local(false);
- instant_controller()->set_ntp(ntp.get());
- instant_controller()->set_javascript_enabled(true);
- instant_controller()->set_extended_enabled(true);
- instant_controller()->set_instant_url(instant_url);
- ntp->set_instant_url("http://local_instant_url");
- ntp->set_supports_instant(true);
- instant_controller()->set_in_startup(false);
- EXPECT_FALSE(instant_controller()->ShouldSwitchToLocalNTP());
-}
-
-TEST_F(InstantControllerTest, SwitchesToLocalNTPIfJSDisabled) {
- std::string instant_url("http://instant_url");
- scoped_ptr<TestableInstantNTP> ntp(new TestableInstantNTP(
- instant_controller(), instant_url));
- ntp.reset(new TestableInstantNTP(instant_controller(), instant_url));
- ntp->set_is_local(false);
- instant_controller()->set_ntp(ntp.get());
- instant_controller()->set_javascript_enabled(false);
- instant_controller()->set_extended_enabled(true);
- instant_controller()->set_instant_url(instant_url);
- ntp->set_instant_url("http://local_instant_url");
- ntp->set_supports_instant(true);
- instant_controller()->set_in_startup(false);
- EXPECT_TRUE(instant_controller()->ShouldSwitchToLocalNTP());
-}
-
-TEST_F(InstantControllerTest, SwitchesToLocalNTPIfNoNTPReady) {
- EXPECT_TRUE(instant_controller()->ShouldSwitchToLocalNTP());
-}
-
-TEST_F(InstantControllerTest, IsJavascriptEnabled) {
- instant_controller()->set_override_javascript_enabled(false);
- EXPECT_TRUE(instant_controller()->IsJavascriptEnabled());
-}
-
-TEST_F(InstantControllerTest, IsJavascriptEnabledChecksContentSettings) {
- instant_controller()->set_override_javascript_enabled(false);
- instant_controller()->profile()->GetHostContentSettingsMap()
- ->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT,
- CONTENT_SETTING_DEFAULT);
- EXPECT_TRUE(instant_controller()->IsJavascriptEnabled());
- instant_controller()->profile()->GetHostContentSettingsMap()
- ->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT,
- CONTENT_SETTING_ALLOW);
- EXPECT_TRUE(instant_controller()->IsJavascriptEnabled());
- instant_controller()->profile()->GetHostContentSettingsMap()
- ->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT,
- CONTENT_SETTING_BLOCK);
- EXPECT_FALSE(instant_controller()->IsJavascriptEnabled());
-}
-
-TEST_F(InstantControllerTest, IsJavascriptEnabledChecksPrefs) {
- instant_controller()->set_override_javascript_enabled(false);
- instant_controller()->profile()->GetPrefs()->SetBoolean(
- prefs::kWebKitJavascriptEnabled, true);
- EXPECT_TRUE(instant_controller()->IsJavascriptEnabled());
- instant_controller()->profile()->GetPrefs()->SetBoolean(
- prefs::kWebKitJavascriptEnabled, false);
- EXPECT_FALSE(instant_controller()->IsJavascriptEnabled());
-}
diff --git a/chrome/browser/ui/search/instant_extended_interactive_uitest.cc b/chrome/browser/ui/search/instant_extended_interactive_uitest.cc
index f9f51f4..7d2f2c8 100644
--- a/chrome/browser/ui/search/instant_extended_interactive_uitest.cc
+++ b/chrome/browser/ui/search/instant_extended_interactive_uitest.cc
@@ -45,6 +45,7 @@
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/omnibox/omnibox_view.h"
#include "chrome/browser/ui/search/instant_ntp.h"
+#include "chrome/browser/ui/search/instant_ntp_prerenderer.h"
#include "chrome/browser/ui/search/instant_tab.h"
#include "chrome/browser/ui/search/instant_test_utils.h"
#include "chrome/browser/ui/search/search_tab_helper.h"
@@ -350,26 +351,33 @@
ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
FocusOmniboxAndWaitForInstantNTPSupport();
+ InstantService* instant_service =
+ InstantServiceFactory::GetForProfile(browser()->profile());
+ ASSERT_NE(static_cast<InstantService*>(NULL), instant_service);
+
// The setup first initializes the platform specific NetworkChangeNotifier.
// The InstantExtendedNetworkTest replaces it with a fake, but by the time,
- // instant controller has already registered itself. So the instant controller
- // needs to register itself as NetworkChangeObserver again.
- net::NetworkChangeNotifier::AddNetworkChangeObserver(browser_instant());
+ // InstantNTPPrerenderer has already registered itself. So the
+ // InstantNTPPrerenderer needs to register itself as NetworkChangeObserver
+ // again.
+ net::NetworkChangeNotifier::AddNetworkChangeObserver(
+ instant_service->ntp_prerenderer());
// The fake network change notifier will provide the network state to be
// offline, so the ntp will be local.
- ASSERT_NE(static_cast<InstantNTP*>(NULL), instant()->ntp());
- EXPECT_TRUE(instant()->ntp()->IsLocal());
+ ASSERT_NE(static_cast<InstantNTP*>(NULL),
+ instant_service->ntp_prerenderer()->ntp());
+ EXPECT_TRUE(instant_service->ntp_prerenderer()->ntp()->IsLocal());
// Change the connect state, and wait for the notifications to be run, and NTP
// support to be determined.
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_ETHERNET);
FocusOmniboxAndWaitForInstantNTPSupport();
- // Verify the network state is fine, and instant controller doesn't want to
- // switch to local NTP anymore.
+ // Verify the network state is fine, and InstantNTPPrerenderer doesn't want
+ // to switch to local NTP anymore.
EXPECT_FALSE(net::NetworkChangeNotifier::IsOffline());
- EXPECT_FALSE(instant()->ShouldSwitchToLocalNTP());
+ EXPECT_FALSE(instant_service->ntp_prerenderer()->ShouldSwitchToLocalNTP());
// Open new tab.
ui_test_utils::NavigateToURLWithDisposition(
@@ -382,17 +390,19 @@
// Verify new NTP is not local.
EXPECT_TRUE(chrome::IsInstantNTP(active_tab));
- EXPECT_NE(instant()->GetLocalInstantURL(), active_tab->GetURL().spec());
- ASSERT_NE(static_cast<InstantNTP*>(NULL), instant()->ntp());
- EXPECT_FALSE(instant()->ntp()->IsLocal());
+ EXPECT_NE(instant_service->ntp_prerenderer()->GetLocalInstantURL(),
+ active_tab->GetURL().spec());
+ ASSERT_NE(static_cast<InstantNTP*>(NULL),
+ instant_service->ntp_prerenderer()->ntp());
+ EXPECT_FALSE(instant_service->ntp_prerenderer()->ntp()->IsLocal());
SetConnectionType(net::NetworkChangeNotifier::CONNECTION_NONE);
FocusOmniboxAndWaitForInstantNTPSupport();
- // Verify the network state is fine, and instant controller doesn't want to
- // switch to local NTP anymore.
+ // Verify the network state is fine, and InstantNTPPrerenderer doesn't want
+ // to switch to local NTP anymore.
EXPECT_TRUE(net::NetworkChangeNotifier::IsOffline());
- EXPECT_TRUE(instant()->ShouldSwitchToLocalNTP());
+ EXPECT_TRUE(instant_service->ntp_prerenderer()->ShouldSwitchToLocalNTP());
// Open new tab. Preloaded NTP contents should have been used.
ui_test_utils::NavigateToURLWithDisposition(
@@ -404,9 +414,11 @@
// Verify new NTP is not local.
EXPECT_TRUE(chrome::IsInstantNTP(active_tab));
- EXPECT_EQ(instant()->GetLocalInstantURL(), active_tab->GetURL().spec());
- ASSERT_NE(static_cast<InstantNTP*>(NULL), instant()->ntp());
- EXPECT_TRUE(instant()->ntp()->IsLocal());
+ EXPECT_EQ(instant_service->ntp_prerenderer()->GetLocalInstantURL(),
+ active_tab->GetURL().spec());
+ ASSERT_NE(static_cast<InstantNTP*>(NULL),
+ instant_service->ntp_prerenderer()->ntp());
+ EXPECT_TRUE(instant_service->ntp_prerenderer()->ntp()->IsLocal());
}
#if defined(HTML_INSTANT_EXTENDED_POPUP)
diff --git a/chrome/browser/ui/search/instant_extended_manual_interactive_uitest.cc b/chrome/browser/ui/search/instant_extended_manual_interactive_uitest.cc
index 6035c1b..af3206f 100644
--- a/chrome/browser/ui/search/instant_extended_manual_interactive_uitest.cc
+++ b/chrome/browser/ui/search/instant_extended_manual_interactive_uitest.cc
@@ -4,6 +4,8 @@
#include "base/strings/string_util.h"
#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/search/instant_service.h"
+#include "chrome/browser/search/instant_service_factory.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/task_manager/task_manager.h"
#include "chrome/browser/task_manager/task_manager_browsertest_util.h"
@@ -11,7 +13,7 @@
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/host_desktop.h"
#include "chrome/browser/ui/omnibox/omnibox_view.h"
-#include "chrome/browser/ui/search/instant_ntp.h"
+#include "chrome/browser/ui/search/instant_ntp_prerenderer.h"
#include "chrome/browser/ui/search/instant_test_utils.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/omnibox_focus_state.h"
@@ -93,9 +95,12 @@
IN_PROC_BROWSER_TEST_F(InstantExtendedManualTest, MANUAL_ShowsGoogleNTP) {
set_browser(browser());
- instant()->ReloadStaleNTP();
- FocusOmniboxAndWaitForInstantNTPSupport();
+ InstantService* instant_service =
+ InstantServiceFactory::GetForProfile(browser()->profile());
+ ASSERT_NE(static_cast<InstantService*>(NULL), instant_service);
+ instant_service->ntp_prerenderer()->ReloadStaleNTP();
+ FocusOmniboxAndWaitForInstantNTPSupport();
content::WindowedNotificationObserver observer(
content::NOTIFICATION_NAV_ENTRY_COMMITTED,
content::NotificationService::AllSources());
@@ -112,9 +117,12 @@
IN_PROC_BROWSER_TEST_F(InstantExtendedManualTest, MANUAL_SearchesFromFakebox) {
set_browser(browser());
- instant()->ReloadStaleNTP();
- FocusOmniboxAndWaitForInstantNTPSupport();
+ InstantService* instant_service =
+ InstantServiceFactory::GetForProfile(browser()->profile());
+ ASSERT_NE(static_cast<InstantService*>(NULL), instant_service);
+ instant_service->ntp_prerenderer()->ReloadStaleNTP();
+ FocusOmniboxAndWaitForInstantNTPSupport();
// Open a new tab page.
content::WindowedNotificationObserver observer(
content::NOTIFICATION_NAV_ENTRY_COMMITTED,
diff --git a/chrome/browser/ui/search/instant_loader.cc b/chrome/browser/ui/search/instant_loader.cc
index c50b7fb..d6d467d 100644
--- a/chrome/browser/ui/search/instant_loader.cc
+++ b/chrome/browser/ui/search/instant_loader.cc
@@ -7,7 +7,6 @@
#include "chrome/browser/content_settings/tab_specific_content_settings.h"
#include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h"
#include "chrome/browser/favicon/favicon_tab_helper.h"
-#include "chrome/browser/history/history_tab_helper.h"
#include "chrome/browser/safe_browsing/safe_browsing_tab_observer.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/tab_contents/tab_util.h"
@@ -42,7 +41,6 @@
void InstantLoader::Init(const GURL& instant_url,
Profile* profile,
- const content::WebContents* active_tab,
const base::Closure& on_stale_callback) {
content::WebContents::CreateParams create_params(profile);
create_params.site_instance = content::SiteInstance::CreateForURL(
@@ -104,9 +102,7 @@
CoreTabHelper::CreateForWebContents(contents());
CoreTabHelper::FromWebContents(contents())->set_delegate(this);
- // Tab helpers used when committing an overlay.
SearchTabHelper::CreateForWebContents(contents());
- HistoryTabHelper::CreateForWebContents(contents());
// Observers.
extensions::WebNavigationTabObserver::CreateForWebContents(contents());
@@ -127,11 +123,6 @@
content::Source<content::NavigationController>(
&contents_->GetController()));
#endif
-
- // When the WebContents finishes loading it should be checked to ensure that
- // it is in the instant process.
- registrar_.Add(this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
- content::Source<content::WebContents>(contents_.get()));
}
scoped_ptr<content::WebContents> InstantLoader::ReleaseContents() {
@@ -155,23 +146,12 @@
content::Source<content::NavigationController>(
&contents_->GetController()));
#endif
- registrar_.Remove(this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
- content::Source<content::WebContents>(contents_.get()));
-
return contents_.Pass();
}
void InstantLoader::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
- if (type == content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME) {
- const content::WebContents* web_contents =
- content::Source<content::WebContents>(source).ptr();
- DCHECK_EQ(contents_.get(), web_contents);
- delegate_->LoadCompletedMainFrame();
- return;
- }
-
#if defined(OS_MACOSX)
if (type == content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED) {
if (content::RenderWidgetHostView* rwhv =
@@ -202,14 +182,6 @@
return false;
}
-void InstantLoader::LostCapture() {
- delegate_->OnMouseUp();
-}
-
-void InstantLoader::WebContentsFocused(content::WebContents* /* contents */) {
- delegate_->OnFocus();
-}
-
void InstantLoader::CanDownload(content::RenderViewHost* /* render_view_host */,
int /* request_id */,
const std::string& /* request_method */,
@@ -218,29 +190,6 @@
callback.Run(false);
}
-void InstantLoader::HandleMouseDown() {
- delegate_->OnMouseDown();
-}
-
-void InstantLoader::HandleMouseUp() {
- delegate_->OnMouseUp();
-}
-
-void InstantLoader::HandlePointerActivate() {
- delegate_->OnMouseDown();
-}
-
-void InstantLoader::HandleGestureEnd() {
- delegate_->OnMouseUp();
-}
-
-void InstantLoader::DragEnded() {
- // If the user drags, we won't get a mouse up (at least on Linux). Commit
- // the Instant result when the drag ends, so that during the drag the page
- // won't move around.
- delegate_->OnMouseUp();
-}
-
bool InstantLoader::OnGoToEntryOffset(int /* offset */) {
return false;
}
diff --git a/chrome/browser/ui/search/instant_loader.h b/chrome/browser/ui/search/instant_loader.h
index e0ec012..36aef11 100644
--- a/chrome/browser/ui/search/instant_loader.h
+++ b/chrome/browser/ui/search/instant_loader.h
@@ -24,8 +24,7 @@
}
// InstantLoader is used to create and maintain a WebContents where we can
-// preload a page into. It is used by InstantOverlay and InstantNTP to
-// preload an Instant page.
+// preload a page into. It is used by InstantNTP to preload an Instant page.
class InstantLoader : public content::NotificationObserver,
public content::WebContentsDelegate,
public CoreTabHelperDelegate {
@@ -37,15 +36,6 @@
// Called after someone has swapped in a different WebContents for ours.
virtual void OnSwappedContents() = 0;
- // Called when the underlying contents receive focus.
- virtual void OnFocus() = 0;
-
- // Called when the mouse pointer is down.
- virtual void OnMouseDown() = 0;
-
- // Called when the mouse pointer is released (or a drag event ends).
- virtual void OnMouseUp() = 0;
-
// Called to open a URL using the underlying contents (see
// WebContentsDelegate::OpenURLFromTab). The Delegate should return the
// WebContents the URL is opened in, or NULL if the URL wasn't opened
@@ -54,9 +44,6 @@
content::WebContents* source,
const content::OpenURLParams& params) = 0;
- // Called when a main frame load is complete.
- virtual void LoadCompletedMainFrame() = 0;
-
protected:
~Delegate();
};
@@ -66,12 +53,10 @@
// Creates a new WebContents in the context of |profile| that will be used to
// load |instant_url|. The page is not actually loaded until Load() is
- // called. Uses |active_contents|, if non-NULL, to initialize the size of the
- // new contents. |on_stale_callback| will be called after kStalePageTimeoutMS
+ // called. |on_stale_callback| will be called after kStalePageTimeoutMS
// has elapsed after Load() being called.
void Init(const GURL& instant_url,
Profile* profile,
- const content::WebContents* active_contents,
const base::Closure& on_stale_callback);
// Loads |instant_url_| in |contents_|.
@@ -101,17 +86,10 @@
// Overridden from content::WebContentsDelegate:
virtual bool ShouldSuppressDialogs() OVERRIDE;
virtual bool ShouldFocusPageAfterCrash() OVERRIDE;
- virtual void LostCapture() OVERRIDE;
- virtual void WebContentsFocused(content::WebContents* contents) OVERRIDE;
virtual void CanDownload(content::RenderViewHost* render_view_host,
int request_id,
const std::string& request_method,
const base::Callback<void(bool)>& callback) OVERRIDE;
- virtual void HandleMouseDown() OVERRIDE;
- virtual void HandleMouseUp() OVERRIDE;
- virtual void HandlePointerActivate() OVERRIDE;
- virtual void HandleGestureEnd() OVERRIDE;
- virtual void DragEnded() OVERRIDE;
virtual bool OnGoToEntryOffset(int offset) OVERRIDE;
virtual content::WebContents* OpenURLFromTab(
content::WebContents* source,
diff --git a/chrome/browser/ui/search/instant_ntp.cc b/chrome/browser/ui/search/instant_ntp.cc
index 0ccc9b0..08274f6 100644
--- a/chrome/browser/ui/search/instant_ntp.cc
+++ b/chrome/browser/ui/search/instant_ntp.cc
@@ -5,27 +5,31 @@
#include "chrome/browser/ui/search/instant_ntp.h"
#include "base/metrics/histogram.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/search/instant_ntp_prerenderer.h"
#include "chrome/browser/ui/search/search_tab_helper.h"
#include "chrome/browser/ui/webui/ntp/ntp_user_data_logger.h"
#include "content/public/browser/web_contents.h"
#include "url/gurl.h"
-InstantNTP::InstantNTP(InstantPage::Delegate* delegate,
+InstantNTP::InstantNTP(InstantNTPPrerenderer* ntp_prerenderer,
const std::string& instant_url,
- bool is_incognito)
- : InstantPage(delegate, instant_url, is_incognito),
- loader_(this) {
- DCHECK(delegate);
+ Profile* profile)
+ : InstantPage(ntp_prerenderer, instant_url, profile,
+ profile->IsOffTheRecord()),
+ loader_(this),
+ ntp_prerenderer_(ntp_prerenderer) {
}
InstantNTP::~InstantNTP() {
+ if (contents())
+ ReleaseContents().reset();
}
-void InstantNTP::InitContents(Profile* profile,
- const content::WebContents* active_tab,
- const base::Closure& on_stale_callback) {
+void InstantNTP::InitContents(const base::Closure& on_stale_callback) {
+ DCHECK(!contents());
GURL instantNTP_url(instant_url());
- loader_.Init(instantNTP_url, profile, active_tab, on_stale_callback);
+ loader_.Init(instantNTP_url, profile(), on_stale_callback);
SetContents(loader_.contents());
content::WebContents* content = contents();
SearchTabHelper::FromWebContents(content)->InitForPreloadedNTP();
@@ -42,34 +46,20 @@
}
void InstantNTP::RenderViewCreated(content::RenderViewHost* render_view_host) {
- delegate()->InstantPageRenderViewCreated(contents());
+ InitializeFonts();
+ InitializePromos();
}
void InstantNTP::RenderProcessGone(base::TerminationStatus /* status */) {
- delegate()->InstantPageRenderProcessGone(contents());
+ ntp_prerenderer_->RenderProcessGone();
}
void InstantNTP::OnSwappedContents() {
SetContents(loader_.contents());
}
-void InstantNTP::OnFocus() {
- NOTREACHED();
-}
-
-void InstantNTP::OnMouseDown() {
- NOTREACHED();
-}
-
-void InstantNTP::OnMouseUp() {
- NOTREACHED();
-}
-
content::WebContents* InstantNTP::OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) {
return NULL;
}
-
-void InstantNTP::LoadCompletedMainFrame() {
-}
diff --git a/chrome/browser/ui/search/instant_ntp.h b/chrome/browser/ui/search/instant_ntp.h
index 152451a..0505f25 100644
--- a/chrome/browser/ui/search/instant_ntp.h
+++ b/chrome/browser/ui/search/instant_ntp.h
@@ -9,15 +9,18 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/process_util.h"
#include "chrome/browser/ui/search/instant_loader.h"
#include "chrome/browser/ui/search/instant_page.h"
+class InstantNTPPrerenderer;
class Profile;
namespace content {
class RenderViewHost;
+class WebContents;
}
// InstantNTP is used to preload an Instant page that will be swapped in when a
@@ -26,40 +29,38 @@
class InstantNTP : public InstantPage,
public InstantLoader::Delegate {
public:
- InstantNTP(InstantPage::Delegate* delegate, const std::string& instant_url,
- bool is_incognito);
+ InstantNTP(InstantNTPPrerenderer* delegate,
+ const std::string& instant_url,
+ Profile* profile);
virtual ~InstantNTP();
- // Creates a new WebContents and loads |instant_url_| into it. Uses
- // |active_tab|, if non-NULL, to initialize the size of the WebContents.
+ // Creates a new WebContents and loads |instant_url_| into it.
// |on_stale_callback| will be called when |loader_| determines the page to
// be stale.
- void InitContents(Profile* profile,
- const content::WebContents* active_tab,
- const base::Closure& on_stale_callback);
+ void InitContents(const base::Closure& on_stale_callback);
// Releases the WebContents for the Instant page. This should be called when
// the page is about to be committed.
scoped_ptr<content::WebContents> ReleaseContents();
private:
+ FRIEND_TEST_ALL_PREFIXES(InstantExtendedNetworkTest,
+ NTPReactsToNetworkChanges);
+
// Overridden from content::WebContentsObserver:
virtual void RenderViewCreated(
content::RenderViewHost* render_view_host) OVERRIDE;
virtual void RenderProcessGone(
base::TerminationStatus status) OVERRIDE;
- // Overriden from InstantLoader::Delegate:
+ // Overridden from InstantLoader::Delegate:
virtual void OnSwappedContents() OVERRIDE;
- virtual void OnFocus() OVERRIDE;
- virtual void OnMouseDown() OVERRIDE;
- virtual void OnMouseUp() OVERRIDE;
virtual content::WebContents* OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) OVERRIDE;
- virtual void LoadCompletedMainFrame() OVERRIDE;
InstantLoader loader_;
+ InstantNTPPrerenderer* const ntp_prerenderer_;
DISALLOW_COPY_AND_ASSIGN(InstantNTP);
};
diff --git a/chrome/browser/ui/search/instant_ntp_prerenderer.cc b/chrome/browser/ui/search/instant_ntp_prerenderer.cc
new file mode 100644
index 0000000..7a4c131
--- /dev/null
+++ b/chrome/browser/ui/search/instant_ntp_prerenderer.cc
@@ -0,0 +1,284 @@
+// Copyright 2013 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/ui/search/instant_ntp_prerenderer.h"
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "base/prefs/pref_service.h"
+#include "build/build_config.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/content_settings/content_settings_provider.h"
+#include "chrome/browser/content_settings/host_content_settings_map.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/search/instant_service.h"
+#include "chrome/browser/search/instant_service_factory.h"
+#include "chrome/browser/search/search.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/host_desktop.h"
+#include "chrome/browser/ui/search/instant_ntp.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/content_settings.h"
+#include "chrome/common/pref_names.h"
+#include "content/public/browser/notification_service.h"
+#include "net/base/network_change_notifier.h"
+
+namespace {
+
+void DeleteNTPSoon(scoped_ptr<InstantNTP> ntp) {
+ if (!ntp)
+ return;
+
+ if (ntp->contents()) {
+ base::MessageLoop::current()->DeleteSoon(
+ FROM_HERE, ntp->ReleaseContents().release());
+ }
+ base::MessageLoop::current()->DeleteSoon(FROM_HERE, ntp.release());
+}
+
+} // namespace
+
+
+InstantNTPPrerenderer::InstantNTPPrerenderer(Profile* profile,
+ PrefService* prefs)
+ : profile_(profile),
+ extended_enabled_(chrome::IsInstantExtendedAPIEnabled()) {
+ DCHECK(profile);
+
+ // In unit tests, prefs may be NULL.
+ if (prefs) {
+ profile_pref_registrar_.Init(prefs);
+ profile_pref_registrar_.Add(
+ prefs::kSearchSuggestEnabled,
+ base::Bind(&InstantNTPPrerenderer::ReloadStaleNTP,
+ base::Unretained(this)));
+ profile_pref_registrar_.Add(
+ prefs::kDefaultSearchProviderID,
+ base::Bind(&InstantNTPPrerenderer::OnDefaultSearchProviderChanged,
+ base::Unretained(this)));
+ }
+ net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
+}
+
+InstantNTPPrerenderer::~InstantNTPPrerenderer() {
+ net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
+}
+
+void InstantNTPPrerenderer::PreloadInstantNTP() {
+ DCHECK(!ntp());
+ ReloadStaleNTP();
+}
+
+scoped_ptr<content::WebContents> InstantNTPPrerenderer::ReleaseNTPContents() {
+ if (!extended_enabled() || !profile_ || profile_->IsOffTheRecord() ||
+ !chrome::ShouldShowInstantNTP())
+ return scoped_ptr<content::WebContents>();
+
+ if (ShouldSwitchToLocalNTP())
+ ResetNTP(GetLocalInstantURL());
+
+ scoped_ptr<content::WebContents> ntp_contents = ntp_->ReleaseContents();
+
+ // Preload a new InstantNTP.
+ ResetNTP(GetInstantURL());
+ return ntp_contents.Pass();
+}
+
+content::WebContents* InstantNTPPrerenderer::GetNTPContents() const {
+ return ntp() ? ntp()->contents() : NULL;
+}
+
+void InstantNTPPrerenderer::DeleteNTPContents() {
+ if (ntp_)
+ ntp_.reset();
+}
+
+void InstantNTPPrerenderer::RenderProcessGone() {
+ DeleteNTPSoon(ntp_.Pass());
+}
+
+std::string InstantNTPPrerenderer::GetLocalInstantURL() const {
+ return chrome::GetLocalInstantURL(profile_).spec();
+}
+
+std::string InstantNTPPrerenderer::GetInstantURL() const {
+ if (net::NetworkChangeNotifier::IsOffline())
+ return GetLocalInstantURL();
+
+ // TODO(kmadhusu): Remove start margin param from chrome::GetInstantURL().
+ const GURL instant_url = chrome::GetInstantURL(profile_,
+ chrome::kDisableStartMargin);
+ if (!instant_url.is_valid())
+ return GetLocalInstantURL();
+
+ return instant_url.spec();
+}
+
+bool InstantNTPPrerenderer::IsJavascriptEnabled() const {
+ GURL instant_url(GetInstantURL());
+ GURL origin(instant_url.GetOrigin());
+ ContentSetting js_setting = profile_->GetHostContentSettingsMap()->
+ GetContentSetting(origin, origin, CONTENT_SETTINGS_TYPE_JAVASCRIPT,
+ NO_RESOURCE_IDENTIFIER);
+ // Javascript can be disabled either in content settings or via a WebKit
+ // preference, so check both. Disabling it through the Settings page affects
+ // content settings. I'm not sure how to disable the WebKit preference, but
+ // it's theoretically possible some users have it off.
+ bool js_content_enabled =
+ js_setting == CONTENT_SETTING_DEFAULT ||
+ js_setting == CONTENT_SETTING_ALLOW;
+ bool js_webkit_enabled = profile_->GetPrefs()->GetBoolean(
+ prefs::kWebKitJavascriptEnabled);
+ return js_content_enabled && js_webkit_enabled;
+}
+
+bool InstantNTPPrerenderer::InStartup() const {
+#if !defined(OS_ANDROID)
+ // TODO(kmadhusu): This is not completely reliable. Find a better way to
+ // detect startup time.
+ Browser* browser = chrome::FindBrowserWithProfile(profile_,
+ chrome::GetActiveDesktop());
+ return !browser || !browser->tab_strip_model()->GetActiveWebContents();
+#endif
+ return false;
+}
+
+InstantNTP* InstantNTPPrerenderer::ntp() const {
+ return ntp_.get();
+}
+
+bool InstantNTPPrerenderer::extended_enabled() const {
+ return extended_enabled_;
+}
+
+void InstantNTPPrerenderer::OnNetworkChanged(
+ net::NetworkChangeNotifier::ConnectionType type) {
+ // Not interested in events conveying change to offline.
+ if (type == net::NetworkChangeNotifier::CONNECTION_NONE)
+ return;
+
+ if (!extended_enabled())
+ return;
+
+ if (!ntp() || ntp()->IsLocal())
+ ResetNTP(GetInstantURL());
+}
+
+void InstantNTPPrerenderer::InstantSupportDetermined(
+ const content::WebContents* contents,
+ bool supports_instant) {
+ DCHECK(ntp() && ntp()->contents() == contents);
+
+ if (!supports_instant) {
+ bool is_local = ntp()->IsLocal();
+ DeleteNTPSoon(ntp_.Pass());
+ if (!is_local)
+ ResetNTP(GetLocalInstantURL());
+ }
+
+ content::NotificationService::current()->Notify(
+ chrome::NOTIFICATION_INSTANT_NTP_SUPPORT_DETERMINED,
+ content::Source<InstantNTPPrerenderer>(this),
+ content::NotificationService::NoDetails());
+}
+
+void InstantNTPPrerenderer::InstantPageAboutToNavigateMainFrame(
+ const content::WebContents* contents,
+ const GURL& url) {
+ NOTREACHED();
+}
+
+void InstantNTPPrerenderer::FocusOmnibox(const content::WebContents* contents,
+ OmniboxFocusState state) {
+ NOTREACHED();
+}
+
+void InstantNTPPrerenderer::NavigateToURL(const content::WebContents* contents,
+ const GURL& url,
+ content::PageTransition transition,
+ WindowOpenDisposition disposition,
+ bool is_search_type) {
+ NOTREACHED();
+}
+
+void InstantNTPPrerenderer::DeleteMostVisitedItem(const GURL& url) {
+ NOTREACHED();
+}
+
+void InstantNTPPrerenderer::UndoMostVisitedDeletion(const GURL& url) {
+ NOTREACHED();
+}
+
+void InstantNTPPrerenderer::UndoAllMostVisitedDeletions() {
+ NOTREACHED();
+}
+
+void InstantNTPPrerenderer::InstantPageLoadFailed(
+ content::WebContents* contents) {
+ DCHECK(ntp() && ntp()->contents() == contents);
+
+ bool is_local = ntp()->IsLocal();
+ DeleteNTPSoon(ntp_.Pass());
+ if (!is_local)
+ ResetNTP(GetLocalInstantURL());
+}
+
+void InstantNTPPrerenderer::OnDefaultSearchProviderChanged(
+ const std::string& pref_name) {
+ DCHECK_EQ(pref_name, std::string(prefs::kDefaultSearchProviderID));
+ if (!extended_enabled() || !ntp())
+ return;
+
+ ResetNTP(GetInstantURL());
+}
+
+void InstantNTPPrerenderer::ResetNTP(const std::string& instant_url) {
+ // Instant NTP is only used in extended mode so we should always have a
+ // non-empty URL to use.
+ DCHECK(!instant_url.empty());
+ ntp_.reset(new InstantNTP(this, instant_url, profile_));
+ ntp_->InitContents(base::Bind(&InstantNTPPrerenderer::ReloadStaleNTP,
+ base::Unretained(this)));
+}
+
+void InstantNTPPrerenderer::ReloadStaleNTP() {
+ if (!extended_enabled())
+ return;
+
+ ResetNTP(GetInstantURL());
+}
+
+bool InstantNTPPrerenderer::PageIsCurrent() const {
+ const std::string& instant_url = GetInstantURL();
+ if (instant_url.empty() ||
+ !chrome::MatchesOriginAndPath(GURL(ntp()->instant_url()),
+ GURL(instant_url)))
+ return false;
+
+ return ntp()->supports_instant();
+}
+
+bool InstantNTPPrerenderer::ShouldSwitchToLocalNTP() const {
+ if (!ntp())
+ return true;
+
+ // Assume users with Javascript disabled do not want the online experience.
+ if (!IsJavascriptEnabled())
+ return true;
+
+ // Already a local page. Not calling IsLocal() because we want to distinguish
+ // between the Google-specific and generic local NTP.
+ if (extended_enabled() && ntp()->instant_url() == GetLocalInstantURL())
+ return false;
+
+ if (PageIsCurrent())
+ return false;
+
+ // The preloaded NTP does not support instant yet. If we're not in startup,
+ // always fall back to the local NTP. If we are in startup, use the local NTP
+ // (unless the finch flag to use the remote NTP is set).
+ return !(InStartup() && chrome::ShouldPreferRemoteNTPOnStartup());
+}
diff --git a/chrome/browser/ui/search/instant_ntp_prerenderer.h b/chrome/browser/ui/search/instant_ntp_prerenderer.h
new file mode 100644
index 0000000..cf0c0d3
--- /dev/null
+++ b/chrome/browser/ui/search/instant_ntp_prerenderer.h
@@ -0,0 +1,165 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_UI_SEARCH_INSTANT_NTP_PRERENDERER_H_
+#define CHROME_BROWSER_UI_SEARCH_INSTANT_NTP_PRERENDERER_H_
+
+#include <string>
+
+#include "base/compiler_specific.h"
+#include "base/gtest_prod_util.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/prefs/pref_change_registrar.h"
+#include "chrome/browser/ui/search/instant_page.h"
+#include "content/public/browser/web_contents.h"
+#include "net/base/network_change_notifier.h"
+
+class InstantExtendedTest;
+class InstantNTP;
+class InstantService;
+class InstantTestBase;
+class Profile;
+
+// InstantNTPPrerenderer maintains a prerendered instance of InstantNTP.
+//
+// An InstantNTP instance is a preloaded search page that will be swapped-in the
+// next time when the user navigates to the New Tab Page. It is never shown to
+// the user in an uncommitted state. It is backed by a WebContents and that is
+// owned by InstantNTP.
+//
+// InstantNTPPrerenderer is owned by InstantService.
+class InstantNTPPrerenderer
+ : public InstantPage::Delegate,
+ public net::NetworkChangeNotifier::NetworkChangeObserver {
+ public:
+ InstantNTPPrerenderer(Profile* profile, PrefService* prefs);
+ virtual ~InstantNTPPrerenderer();
+
+ // Preloads |ntp_| with a new InstantNTP.
+ void PreloadInstantNTP();
+
+ // Releases and returns the InstantNTP WebContents. May be NULL. Loads a new
+ // WebContents for the InstantNTP.
+ scoped_ptr<content::WebContents> ReleaseNTPContents() WARN_UNUSED_RESULT;
+
+ // The NTP WebContents. May be NULL. InstantNTPPrerenderer retains ownership.
+ content::WebContents* GetNTPContents() const;
+
+ // Invoked to null out |ntp_|.
+ void DeleteNTPContents();
+
+ // Invoked when the InstantNTP renderer process crashes.
+ void RenderProcessGone();
+
+ protected:
+ // Returns the local Instant URL. (Just a convenience wrapper to get the local
+ // Instant URL from InstantService.)
+ virtual std::string GetLocalInstantURL() const;
+
+ // Returns the correct Instant URL to use from the following possibilities:
+ // o The default search engine's Instant URL.
+ // o The local page (see GetLocalInstantURL())
+ // Returns an empty string if no valid Instant URL is available (this is only
+ // possible in non-extended mode where we don't have a local page fall-back).
+ virtual std::string GetInstantURL() const;
+
+ // Returns true if Javascript is enabled and false otherwise.
+ virtual bool IsJavascriptEnabled() const;
+
+ // Returns true if the browser is in startup.
+ virtual bool InStartup() const;
+
+ // Accessors are made protected for testing purposes.
+ virtual InstantNTP* ntp() const;
+ virtual bool extended_enabled() const;
+
+ Profile* profile() const {
+ return profile_;
+ }
+
+ private:
+ friend class InstantExtendedTest;
+ friend class InstantNTPPrerendererTest;
+ friend class InstantTestBase;
+
+ FRIEND_TEST_ALL_PREFIXES(InstantExtendedNetworkTest,
+ NTPReactsToNetworkChanges);
+ FRIEND_TEST_ALL_PREFIXES(InstantNTPPrerendererTest,
+ PrefersRemoteNTPOnStartup);
+ FRIEND_TEST_ALL_PREFIXES(InstantNTPPrerendererTest,
+ SwitchesToLocalNTPIfNoInstantSupport);
+ FRIEND_TEST_ALL_PREFIXES(InstantNTPPrerendererTest,
+ SwitchesToLocalNTPIfPathBad);
+ FRIEND_TEST_ALL_PREFIXES(InstantNTPPrerendererTest,
+ DoesNotSwitchToLocalNTPIfOnCurrentNTP);
+ FRIEND_TEST_ALL_PREFIXES(InstantNTPPrerendererTest,
+ DoesNotSwitchToLocalNTPIfOnLocalNTP);
+ FRIEND_TEST_ALL_PREFIXES(InstantNTPPrerendererTest,
+ SwitchesToLocalNTPIfJSDisabled);
+ FRIEND_TEST_ALL_PREFIXES(InstantNTPPrerendererTest,
+ SwitchesToLocalNTPIfNoNTPReady);
+ FRIEND_TEST_ALL_PREFIXES(InstantNTPPrerendererTest,
+ IsJavascriptEnabled);
+ FRIEND_TEST_ALL_PREFIXES(InstantNTPPrerendererTest,
+ IsJavascriptEnabledChecksContentSettings);
+ FRIEND_TEST_ALL_PREFIXES(InstantNTPPrerendererTest,
+ IsJavascriptEnabledChecksPrefs);
+ FRIEND_TEST_ALL_PREFIXES(InstantExtendedManualTest, MANUAL_ShowsGoogleNTP);
+ FRIEND_TEST_ALL_PREFIXES(InstantExtendedManualTest,
+ MANUAL_SearchesFromFakebox);
+
+ // Overridden from net::NetworkChangeNotifier::NetworkChangeObserver:
+ // If the network status changes, resets InstantNTP.
+ virtual void OnNetworkChanged(net::NetworkChangeNotifier::ConnectionType type)
+ OVERRIDE;
+
+ // Overridden from InstantPage::Delegate:
+ virtual void InstantSupportDetermined(const content::WebContents* contents,
+ bool supports_instant) OVERRIDE;
+ virtual void InstantPageAboutToNavigateMainFrame(
+ const content::WebContents* contents,
+ const GURL& url) OVERRIDE;
+ virtual void FocusOmnibox(const content::WebContents* contents,
+ OmniboxFocusState state) OVERRIDE;
+ virtual void NavigateToURL(const content::WebContents* contents,
+ const GURL& url,
+ content::PageTransition transition,
+ WindowOpenDisposition disposition,
+ bool is_search_type) OVERRIDE;
+ virtual void DeleteMostVisitedItem(const GURL& url) OVERRIDE;
+ virtual void UndoMostVisitedDeletion(const GURL& url) OVERRIDE;
+ virtual void UndoAllMostVisitedDeletions() OVERRIDE;
+ virtual void InstantPageLoadFailed(content::WebContents* contents) OVERRIDE;
+
+ // Called when the default search provider changes. Resets InstantNTP.
+ void OnDefaultSearchProviderChanged(const std::string& pref_name);
+
+ // Recreates |ntp_| using |instant_url|.
+ void ResetNTP(const std::string& instant_url);
+
+ // Resets |ntp_| with a new InstantNTP. Called when |ntp_| is stale or when a
+ // pref is changed.
+ void ReloadStaleNTP();
+
+ // Returns true if |ntp_| has an up-to-date Instant URL and supports Instant.
+ // Note that local URLs will not pass this check.
+ bool PageIsCurrent() const;
+
+ // Returns true if we should switch to using the local NTP.
+ bool ShouldSwitchToLocalNTP() const;
+
+ Profile* profile_;
+
+ // Whether the extended API is enabled.
+ const bool extended_enabled_;
+
+ // Preloaded InstantNTP.
+ scoped_ptr<InstantNTP> ntp_;
+
+ PrefChangeRegistrar profile_pref_registrar_;
+
+ DISALLOW_COPY_AND_ASSIGN(InstantNTPPrerenderer);
+};
+
+#endif // CHROME_BROWSER_UI_SEARCH_INSTANT_NTP_PRERENDERER_H_
diff --git a/chrome/browser/ui/search/instant_ntp_prerenderer_unittest.cc b/chrome/browser/ui/search/instant_ntp_prerenderer_unittest.cc
new file mode 100644
index 0000000..374c8fd
--- /dev/null
+++ b/chrome/browser/ui/search/instant_ntp_prerenderer_unittest.cc
@@ -0,0 +1,295 @@
+// Copyright 2013 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 "base/memory/scoped_ptr.h"
+#include "base/metrics/histogram.h"
+#include "base/metrics/histogram_samples.h"
+#include "base/metrics/statistics_recorder.h"
+#include "base/prefs/pref_service.h"
+#include "chrome/browser/content_settings/host_content_settings_map.h"
+#include "chrome/browser/search/search.h"
+#include "chrome/browser/ui/search/instant_ntp.h"
+#include "chrome/browser/ui/search/instant_ntp_prerenderer.h"
+#include "chrome/common/content_settings.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/test/test_browser_thread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using base::HistogramBase;
+using base::HistogramSamples;
+using base::StatisticsRecorder;
+
+class TestableInstantNTP : public InstantNTP {
+ public:
+ TestableInstantNTP(InstantNTPPrerenderer* ntp_prerenderer,
+ const std::string& instant_url,
+ Profile* profile)
+ : InstantNTP(ntp_prerenderer, instant_url, profile) {
+ }
+
+ // Overrides from InstantPage
+ virtual bool supports_instant() const OVERRIDE {
+ return test_supports_instant_;
+ }
+
+ virtual bool IsLocal() const OVERRIDE {
+ return test_is_local_;
+ };
+
+ virtual const std::string& instant_url() const OVERRIDE {
+ return test_instant_url_;
+ }
+
+ void set_instant_url(const std::string& instant_url) {
+ test_instant_url_ = instant_url;
+ }
+
+ void set_supports_instant(bool supports_instant) {
+ test_supports_instant_ = supports_instant;
+ }
+
+ void set_is_local(bool is_local) {
+ test_is_local_ = is_local;
+ }
+
+ private:
+ std::string test_instant_url_;
+ bool test_supports_instant_;
+ bool test_is_local_;
+};
+
+class TestableInstantNTPPrerenderer : public InstantNTPPrerenderer {
+ public:
+ explicit TestableInstantNTPPrerenderer(TestingProfile* profile)
+ : InstantNTPPrerenderer(profile, NULL),
+ test_instant_url_("http://test_url"),
+ test_extended_enabled_(true),
+ override_javascript_enabled_(true),
+ test_javascript_enabled_(true),
+ test_in_startup_(false),
+ test_ntp_(NULL) {}
+
+ // Overrides from InstantNTPPrerenderer
+ virtual std::string GetInstantURL() const OVERRIDE {
+ return test_instant_url_;
+ }
+
+ virtual std::string GetLocalInstantURL() const OVERRIDE {
+ return "http://local_instant_url";
+ }
+
+ virtual bool extended_enabled() const OVERRIDE {
+ return test_extended_enabled_;
+ }
+
+ virtual InstantNTP* ntp() const OVERRIDE {
+ return test_ntp_;
+ }
+
+ virtual bool IsJavascriptEnabled() const OVERRIDE {
+ if (override_javascript_enabled_)
+ return test_javascript_enabled_;
+ else
+ return InstantNTPPrerenderer::IsJavascriptEnabled();
+ }
+
+ virtual bool InStartup() const OVERRIDE {
+ return test_in_startup_;
+ }
+
+ void set_instant_url(const std::string& instant_url) {
+ test_instant_url_ = instant_url;
+ }
+
+ void set_extended_enabled(bool extended_enabled) {
+ test_extended_enabled_ = extended_enabled;
+ }
+
+ void set_ntp(InstantNTP* ntp) {
+ test_ntp_ = ntp;
+ }
+
+ void set_javascript_enabled(bool javascript_enabled) {
+ override_javascript_enabled_ = true;
+ test_javascript_enabled_ = javascript_enabled;
+ }
+
+ void set_override_javascript_enabled(bool override_javascript_enabled) {
+ override_javascript_enabled_ = override_javascript_enabled;
+ }
+
+ void set_in_startup(bool in_startup) {
+ test_in_startup_ = in_startup;
+ }
+
+private:
+ std::string test_instant_url_;
+ bool test_extended_enabled_;
+ bool override_javascript_enabled_;
+ bool test_javascript_enabled_;
+ bool test_in_startup_;
+ InstantNTP* test_ntp_;
+};
+
+class InstantNTPPrerendererTest : public testing::Test {
+ public:
+ InstantNTPPrerendererTest()
+ : ui_thread_(content::BrowserThread::UI),
+ instant_ntp_prerenderer_(new TestableInstantNTPPrerenderer(&profile_)) {
+ }
+
+ virtual void SetUp() OVERRIDE {
+ base::StatisticsRecorder::Initialize();
+ }
+
+ TestableInstantNTPPrerenderer* instant_ntp_prerenderer() {
+ return instant_ntp_prerenderer_.get();
+ }
+
+ Profile* profile() {
+ return instant_ntp_prerenderer()->profile();
+ }
+
+ private:
+ content::TestBrowserThread ui_thread_;
+ scoped_ptr<TestableInstantNTPPrerenderer> instant_ntp_prerenderer_;
+ mutable TestingProfile profile_;
+};
+
+TEST_F(InstantNTPPrerendererTest, PrefersRemoteNTPOnStartup) {
+ std::string instant_url("http://instant_url");
+ scoped_ptr<TestableInstantNTP> ntp(new TestableInstantNTP(
+ instant_ntp_prerenderer(), instant_url, profile()));
+ ntp->set_is_local(false);
+ instant_ntp_prerenderer()->set_ntp(ntp.get());
+ instant_ntp_prerenderer()->set_javascript_enabled(true);
+ instant_ntp_prerenderer()->set_extended_enabled(true);
+ instant_ntp_prerenderer()->set_instant_url(instant_url);
+ ntp->set_instant_url(instant_url);
+ ntp->set_supports_instant(false);
+ instant_ntp_prerenderer()->set_in_startup(true);
+ EXPECT_EQ(!chrome::ShouldPreferRemoteNTPOnStartup(),
+ instant_ntp_prerenderer()->ShouldSwitchToLocalNTP());
+}
+
+TEST_F(InstantNTPPrerendererTest, SwitchesToLocalNTPIfNoInstantSupport) {
+ std::string instant_url("http://instant_url");
+ scoped_ptr<TestableInstantNTP> ntp(new TestableInstantNTP(
+ instant_ntp_prerenderer(), instant_url, profile()));
+ ntp.reset(new TestableInstantNTP(instant_ntp_prerenderer(), instant_url,
+ profile()));
+ ntp->set_is_local(false);
+ instant_ntp_prerenderer()->set_ntp(ntp.get());
+ instant_ntp_prerenderer()->set_javascript_enabled(true);
+ instant_ntp_prerenderer()->set_extended_enabled(true);
+ instant_ntp_prerenderer()->set_instant_url(instant_url);
+ ntp->set_instant_url(instant_url);
+ ntp->set_supports_instant(false);
+ instant_ntp_prerenderer()->set_in_startup(false);
+ EXPECT_TRUE(instant_ntp_prerenderer()->ShouldSwitchToLocalNTP());
+}
+
+TEST_F(InstantNTPPrerendererTest, SwitchesToLocalNTPIfPathBad) {
+ std::string instant_url("http://instant_url");
+ scoped_ptr<TestableInstantNTP> ntp(new TestableInstantNTP(
+ instant_ntp_prerenderer(), instant_url, profile()));
+ ntp.reset(new TestableInstantNTP(instant_ntp_prerenderer(), instant_url,
+ profile()));
+ ntp->set_is_local(false);
+ instant_ntp_prerenderer()->set_ntp(ntp.get());
+ instant_ntp_prerenderer()->set_javascript_enabled(true);
+ instant_ntp_prerenderer()->set_extended_enabled(true);
+ instant_ntp_prerenderer()->set_instant_url("http://bogus_url");
+ ntp->set_instant_url(instant_url);
+ ntp->set_supports_instant(true);
+ instant_ntp_prerenderer()->set_in_startup(false);
+ EXPECT_TRUE(instant_ntp_prerenderer()->ShouldSwitchToLocalNTP());
+}
+
+TEST_F(InstantNTPPrerendererTest, DoesNotSwitchToLocalNTPIfOnCurrentNTP) {
+ std::string instant_url("http://instant_url");
+ scoped_ptr<TestableInstantNTP> ntp(new TestableInstantNTP(
+ instant_ntp_prerenderer(), instant_url, profile()));
+ ntp.reset(new TestableInstantNTP(instant_ntp_prerenderer(), instant_url,
+ profile()));
+ ntp->set_is_local(false);
+ instant_ntp_prerenderer()->set_ntp(ntp.get());
+ instant_ntp_prerenderer()->set_javascript_enabled(true);
+ instant_ntp_prerenderer()->set_extended_enabled(true);
+ instant_ntp_prerenderer()->set_instant_url(instant_url);
+ ntp->set_instant_url(instant_url);
+ ntp->set_supports_instant(true);
+ instant_ntp_prerenderer()->set_in_startup(false);
+ EXPECT_FALSE(instant_ntp_prerenderer()->ShouldSwitchToLocalNTP());
+}
+
+TEST_F(InstantNTPPrerendererTest, DoesNotSwitchToLocalNTPIfOnLocalNTP) {
+ std::string instant_url("http://instant_url");
+ scoped_ptr<TestableInstantNTP> ntp(new TestableInstantNTP(
+ instant_ntp_prerenderer(), instant_url, profile()));
+ ntp.reset(new TestableInstantNTP(instant_ntp_prerenderer(), instant_url,
+ profile()));
+ ntp->set_is_local(false);
+ instant_ntp_prerenderer()->set_ntp(ntp.get());
+ instant_ntp_prerenderer()->set_javascript_enabled(true);
+ instant_ntp_prerenderer()->set_extended_enabled(true);
+ instant_ntp_prerenderer()->set_instant_url(instant_url);
+ ntp->set_instant_url("http://local_instant_url");
+ ntp->set_supports_instant(true);
+ instant_ntp_prerenderer()->set_in_startup(false);
+ EXPECT_FALSE(instant_ntp_prerenderer()->ShouldSwitchToLocalNTP());
+}
+
+TEST_F(InstantNTPPrerendererTest, SwitchesToLocalNTPIfJSDisabled) {
+ std::string instant_url("http://instant_url");
+ scoped_ptr<TestableInstantNTP> ntp(new TestableInstantNTP(
+ instant_ntp_prerenderer(), instant_url, profile()));
+ ntp.reset(new TestableInstantNTP(instant_ntp_prerenderer(), instant_url,
+ profile()));
+ ntp->set_is_local(false);
+ instant_ntp_prerenderer()->set_ntp(ntp.get());
+ instant_ntp_prerenderer()->set_javascript_enabled(false);
+ instant_ntp_prerenderer()->set_extended_enabled(true);
+ instant_ntp_prerenderer()->set_instant_url(instant_url);
+ ntp->set_instant_url("http://local_instant_url");
+ ntp->set_supports_instant(true);
+ instant_ntp_prerenderer()->set_in_startup(false);
+ EXPECT_TRUE(instant_ntp_prerenderer()->ShouldSwitchToLocalNTP());
+}
+
+TEST_F(InstantNTPPrerendererTest, SwitchesToLocalNTPIfNoNTPReady) {
+ EXPECT_TRUE(instant_ntp_prerenderer()->ShouldSwitchToLocalNTP());
+}
+
+TEST_F(InstantNTPPrerendererTest, IsJavascriptEnabled) {
+ instant_ntp_prerenderer()->set_override_javascript_enabled(false);
+ EXPECT_TRUE(instant_ntp_prerenderer()->IsJavascriptEnabled());
+}
+
+TEST_F(InstantNTPPrerendererTest, IsJavascriptEnabledChecksContentSettings) {
+ instant_ntp_prerenderer()->set_override_javascript_enabled(false);
+ instant_ntp_prerenderer()->profile()->GetHostContentSettingsMap()
+ ->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT,
+ CONTENT_SETTING_DEFAULT);
+ EXPECT_TRUE(instant_ntp_prerenderer()->IsJavascriptEnabled());
+ instant_ntp_prerenderer()->profile()->GetHostContentSettingsMap()
+ ->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT,
+ CONTENT_SETTING_ALLOW);
+ EXPECT_TRUE(instant_ntp_prerenderer()->IsJavascriptEnabled());
+ instant_ntp_prerenderer()->profile()->GetHostContentSettingsMap()
+ ->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_JAVASCRIPT,
+ CONTENT_SETTING_BLOCK);
+ EXPECT_FALSE(instant_ntp_prerenderer()->IsJavascriptEnabled());
+}
+
+TEST_F(InstantNTPPrerendererTest, IsJavascriptEnabledChecksPrefs) {
+ instant_ntp_prerenderer()->set_override_javascript_enabled(false);
+ instant_ntp_prerenderer()->profile()->GetPrefs()->SetBoolean(
+ prefs::kWebKitJavascriptEnabled, true);
+ EXPECT_TRUE(instant_ntp_prerenderer()->IsJavascriptEnabled());
+ instant_ntp_prerenderer()->profile()->GetPrefs()->SetBoolean(
+ prefs::kWebKitJavascriptEnabled, false);
+ EXPECT_FALSE(instant_ntp_prerenderer()->IsJavascriptEnabled());
+}
diff --git a/chrome/browser/ui/search/instant_page.cc b/chrome/browser/ui/search/instant_page.cc
index 39fc72c..9177352 100644
--- a/chrome/browser/ui/search/instant_page.cc
+++ b/chrome/browser/ui/search/instant_page.cc
@@ -6,6 +6,10 @@
#include "apps/app_launcher.h"
#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/search/instant_service.h"
+#include "chrome/browser/search/instant_service_factory.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/ui/search/instant_tab.h"
#include "chrome/browser/ui/search/search_model.h"
@@ -15,6 +19,8 @@
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_source.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/frame_navigate_params.h"
#include "ui/base/resource/resource_bundle.h"
@@ -26,6 +32,13 @@
InstantPage::~InstantPage() {
if (contents())
SearchTabHelper::FromWebContents(contents())->model()->RemoveObserver(this);
+
+ // |profile_| may be NULL during unit tests.
+ if (profile_) {
+ InstantService* instant_service =
+ InstantServiceFactory::GetForProfile(profile_);
+ instant_service->RemoveObserver(this);
+ }
}
bool InstantPage::supports_instant() const {
@@ -62,11 +75,18 @@
}
InstantPage::InstantPage(Delegate* delegate, const std::string& instant_url,
- bool is_incognito)
- : delegate_(delegate),
+ Profile* profile, bool is_incognito)
+ : profile_(profile),
+ delegate_(delegate),
ipc_sender_(InstantIPCSender::Create(is_incognito)),
instant_url_(instant_url),
is_incognito_(is_incognito) {
+ // |profile_| may be NULL during unit tests.
+ if (profile_) {
+ InstantService* instant_service =
+ InstantServiceFactory::GetForProfile(profile_);
+ instant_service->AddObserver(this);
+ }
}
void InstantPage::SetContents(content::WebContents* web_contents) {
@@ -161,6 +181,20 @@
delegate_->InstantPageLoadFailed(contents());
}
+void InstantPage::ThemeInfoChanged(const ThemeBackgroundInfo& theme_info) {
+ sender()->SendThemeBackgroundInfo(theme_info);
+}
+
+void InstantPage::MostVisitedItemsChanged(
+ const std::vector<InstantMostVisitedItem>& items) {
+ sender()->SendMostVisitedItems(items);
+
+ content::NotificationService::current()->Notify(
+ chrome::NOTIFICATION_INSTANT_SENT_MOST_VISITED_ITEMS,
+ content::Source<InstantPage>(this),
+ content::NotificationService::NoDetails());
+}
+
void InstantPage::ModelChanged(const SearchModel::State& old_state,
const SearchModel::State& new_state) {
if (old_state.instant_support != new_state.instant_support)
diff --git a/chrome/browser/ui/search/instant_page.h b/chrome/browser/ui/search/instant_page.h
index f26e940..efd42b3 100644
--- a/chrome/browser/ui/search/instant_page.h
+++ b/chrome/browser/ui/search/instant_page.h
@@ -12,6 +12,7 @@
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
+#include "chrome/browser/search/instant_service_observer.h"
#include "chrome/browser/ui/search/instant_ipc_sender.h"
#include "chrome/browser/ui/search/search_model_observer.h"
#include "chrome/common/instant_types.h"
@@ -20,6 +21,8 @@
#include "content/public/common/page_transition_types.h"
class GURL;
+class InstantService;
+class Profile;
namespace content {
struct FrameNavigateParams;
@@ -36,6 +39,7 @@
// InstantPage is not used directly but via one of its derived classes,
// InstantNTP and InstantTab.
class InstantPage : public content::WebContentsObserver,
+ public InstantServiceObserver,
public SearchModelObserver {
public:
// InstantPage calls its delegate in response to messages received from the
@@ -43,19 +47,11 @@
// we are observing.
class Delegate {
public:
- // Called when a RenderView is created, so that state can be initialized.
- virtual void InstantPageRenderViewCreated(
- const content::WebContents* contents) = 0;
-
// Called upon determination of Instant API support. Either in response to
// the page loading or because we received some other message.
virtual void InstantSupportDetermined(const content::WebContents* contents,
bool supports_instant) = 0;
- // Called when the underlying RenderView's process crashed.
- virtual void InstantPageRenderProcessGone(
- const content::WebContents* contents) = 0;
-
// Called when the page is about to navigate to |url|.
virtual void InstantPageAboutToNavigateMainFrame(
const content::WebContents* contents,
@@ -120,7 +116,7 @@
protected:
InstantPage(Delegate* delegate, const std::string& instant_url,
- bool is_incognito);
+ Profile* profile, bool is_incognito);
// Sets |web_contents| as the page to communicate with. |web_contents| may be
// NULL, which effectively stops all communication.
@@ -128,6 +124,8 @@
Delegate* delegate() const { return delegate_; }
+ Profile* profile() const { return profile_; }
+
// These functions are called before processing messages received from the
// page. By default, all messages are handled, but any derived classes may
// choose to ignore some or all of the received messages by overriding these
@@ -172,6 +170,11 @@
const string16& error_description,
content::RenderViewHost* render_view_host) OVERRIDE;
+ // Overridden from InstantServiceObserver:
+ virtual void ThemeInfoChanged(const ThemeBackgroundInfo& theme_info) OVERRIDE;
+ virtual void MostVisitedItemsChanged(
+ const std::vector<InstantMostVisitedItem>& items) OVERRIDE;
+
// Overridden from SearchModelObserver:
virtual void ModelChanged(const SearchModel::State& old_state,
const SearchModel::State& new_state) OVERRIDE;
@@ -192,6 +195,10 @@
void ClearContents();
+ // Returns the InstantService for the |profile_|.
+ InstantService* GetInstantService();
+
+ Profile* profile_;
Delegate* const delegate_;
scoped_ptr<InstantIPCSender> ipc_sender_;
const std::string instant_url_;
diff --git a/chrome/browser/ui/search/instant_page_unittest.cc b/chrome/browser/ui/search/instant_page_unittest.cc
index e16c96d..2b1ec86 100644
--- a/chrome/browser/ui/search/instant_page_unittest.cc
+++ b/chrome/browser/ui/search/instant_page_unittest.cc
@@ -20,6 +20,8 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
+class Profile;
+
namespace {
class FakePageDelegate : public InstantPage::Delegate {
@@ -27,8 +29,6 @@
virtual ~FakePageDelegate() {
}
- MOCK_METHOD1(InstantPageRenderViewCreated,
- void(const content::WebContents* contents));
MOCK_METHOD2(InstantSupportDetermined,
void(const content::WebContents* contents,
bool supports_instant));
@@ -55,7 +55,7 @@
class FakePage : public InstantPage {
public:
FakePage(Delegate* delegate, const std::string& instant_url,
- bool is_incognito);
+ Profile* profile, bool is_incognito);
virtual ~FakePage();
// InstantPage overrride.
@@ -75,18 +75,14 @@
};
FakePage::FakePage(Delegate* delegate, const std::string& instant_url,
- bool is_incognito)
- : InstantPage(delegate, instant_url, is_incognito),
+ Profile* profile, bool is_incognito)
+ : InstantPage(delegate, instant_url, profile, is_incognito),
should_handle_messages_(true) {
}
FakePage::~FakePage() {
}
-void FakePage::set_should_handle_messages(bool should_handle_messages) {
- should_handle_messages_ = should_handle_messages;
-}
-
bool FakePage::ShouldProcessDeleteMostVisitedItem() {
return should_handle_messages_;
}
@@ -99,6 +95,10 @@
return should_handle_messages_;
}
+void FakePage::set_should_handle_messages(bool should_handle_messages) {
+ should_handle_messages_ = should_handle_messages;
+}
+
} // namespace
class InstantPageTest : public ChromeRenderViewHostTestHarness {
@@ -121,7 +121,7 @@
}
TEST_F(InstantPageTest, IsLocal) {
- page.reset(new FakePage(&delegate, "", false));
+ page.reset(new FakePage(&delegate, "", NULL, false));
EXPECT_FALSE(page->supports_instant());
EXPECT_FALSE(page->IsLocal());
page->SetContents(web_contents());
@@ -132,7 +132,7 @@
}
TEST_F(InstantPageTest, DetermineIfPageSupportsInstant_Local) {
- page.reset(new FakePage(&delegate, "", false));
+ page.reset(new FakePage(&delegate, "", NULL, false));
EXPECT_FALSE(page->supports_instant());
page->SetContents(web_contents());
NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
@@ -145,7 +145,7 @@
}
TEST_F(InstantPageTest, DetermineIfPageSupportsInstant_NonLocal) {
- page.reset(new FakePage(&delegate, "", false));
+ page.reset(new FakePage(&delegate, "", NULL, false));
EXPECT_FALSE(page->supports_instant());
page->SetContents(web_contents());
NavigateAndCommit(GURL("chrome-search://foo/bar"));
@@ -160,7 +160,7 @@
}
TEST_F(InstantPageTest, DispatchRequestToDeleteMostVisitedItem) {
- page.reset(new FakePage(&delegate, "", false));
+ page.reset(new FakePage(&delegate, "", NULL, false));
page->SetContents(web_contents());
NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
GURL item_url("www.foo.com");
@@ -172,7 +172,7 @@
}
TEST_F(InstantPageTest, DispatchRequestToUndoMostVisitedDeletion) {
- page.reset(new FakePage(&delegate, "", false));
+ page.reset(new FakePage(&delegate, "", NULL, false));
page->SetContents(web_contents());
NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
GURL item_url("www.foo.com");
@@ -184,7 +184,7 @@
}
TEST_F(InstantPageTest, DispatchRequestToUndoAllMostVisitedDeletions) {
- page.reset(new FakePage(&delegate, "", false));
+ page.reset(new FakePage(&delegate, "", NULL, false));
page->SetContents(web_contents());
NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
int page_id = web_contents()->GetController().GetActiveEntry()->GetPageID();
@@ -195,7 +195,7 @@
}
TEST_F(InstantPageTest, IgnoreMessageReceivedFromIncognitoPage) {
- page.reset(new FakePage(&delegate, "", true));
+ page.reset(new FakePage(&delegate, "", NULL, true));
page->SetContents(web_contents());
NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
GURL item_url("www.foo.com");
@@ -220,7 +220,7 @@
}
TEST_F(InstantPageTest, IgnoreMessageIfThePageIsNotActive) {
- page.reset(new FakePage(&delegate, "", false));
+ page.reset(new FakePage(&delegate, "", NULL, false));
page->SetContents(web_contents());
NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
GURL item_url("www.foo.com");
@@ -245,7 +245,7 @@
}
TEST_F(InstantPageTest, IgnoreMessageReceivedFromThePage) {
- page.reset(new FakePage(&delegate, "", false));
+ page.reset(new FakePage(&delegate, "", NULL, false));
page->SetContents(web_contents());
// Ignore the messages received from the page.
@@ -271,7 +271,7 @@
}
TEST_F(InstantPageTest, PageURLDoesntBelongToInstantRenderer) {
- page.reset(new FakePage(&delegate, "", false));
+ page.reset(new FakePage(&delegate, "", NULL, false));
EXPECT_FALSE(page->supports_instant());
NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
page->SetContents(web_contents());
@@ -296,7 +296,7 @@
// Test to verify that ChromeViewMsg_DetermineIfPageSupportsInstant message
// reply handler updates the instant support state in InstantPage.
TEST_F(InstantPageTest, PageSupportsInstant) {
- page.reset(new FakePage(&delegate, "", false));
+ page.reset(new FakePage(&delegate, "", NULL, false));
EXPECT_FALSE(page->supports_instant());
page->SetContents(web_contents());
NavigateAndCommit(GURL("chrome-search://foo/bar"));
@@ -322,7 +322,7 @@
}
TEST_F(InstantPageTest, AppropriateMessagesSentToIncognitoPages) {
- page.reset(new FakePage(&delegate, "", true));
+ page.reset(new FakePage(&delegate, "", NULL, true));
page->SetContents(web_contents());
NavigateAndCommit(GURL(chrome::kChromeSearchLocalNtpUrl));
process()->sink().ClearMessages();
diff --git a/chrome/browser/ui/search/instant_tab.cc b/chrome/browser/ui/search/instant_tab.cc
index ff54979..ef2500d 100644
--- a/chrome/browser/ui/search/instant_tab.cc
+++ b/chrome/browser/ui/search/instant_tab.cc
@@ -3,12 +3,14 @@
// found in the LICENSE file.
#include "chrome/browser/ui/search/instant_tab.h"
+
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/ntp/ntp_user_data_logger.h"
#include "content/public/browser/web_contents.h"
InstantTab::InstantTab(InstantPage::Delegate* delegate,
- bool is_incognito)
- : InstantPage(delegate, "", is_incognito) {
+ Profile* profile)
+ : InstantPage(delegate, "", profile, profile->IsOffTheRecord()) {
}
InstantTab::~InstantTab() {
diff --git a/chrome/browser/ui/search/instant_tab.h b/chrome/browser/ui/search/instant_tab.h
index 14e065e..2aac53d 100644
--- a/chrome/browser/ui/search/instant_tab.h
+++ b/chrome/browser/ui/search/instant_tab.h
@@ -9,11 +9,13 @@
#include "base/compiler_specific.h"
#include "chrome/browser/ui/search/instant_page.h"
+class Profile;
+
// InstantTab represents a committed page (i.e. an actual tab on the tab strip)
// that supports the Instant API.
class InstantTab : public InstantPage {
public:
- InstantTab(InstantPage::Delegate* delegate, bool is_incognito);
+ InstantTab(InstantPage::Delegate* delegate, Profile* profile);
virtual ~InstantTab();
// Start observing |contents| for messages. Sends a message to determine if
diff --git a/chrome/browser/ui/search/instant_test_utils.cc b/chrome/browser/ui/search/instant_test_utils.cc
index 5c94421..50eb25c 100644
--- a/chrome/browser/ui/search/instant_test_utils.cc
+++ b/chrome/browser/ui/search/instant_test_utils.cc
@@ -9,10 +9,13 @@
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/search/instant_service.h"
+#include "chrome/browser/search/instant_service_factory.h"
#include "chrome/browser/search_engines/template_url_service.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/ui/omnibox/omnibox_view.h"
#include "chrome/browser/ui/search/instant_ntp.h"
+#include "chrome/browser/ui/search/instant_ntp_prerenderer.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/interactive_test_utils.h"
@@ -52,7 +55,10 @@
service->Add(template_url); // Takes ownership of |template_url|.
service->SetDefaultSearchProvider(template_url);
- instant()->ReloadStaleNTP();
+ InstantService* instant_service =
+ InstantServiceFactory::GetForProfile(browser_->profile());
+ ASSERT_NE(static_cast<InstantService*>(NULL), instant_service);
+ instant_service->ntp_prerenderer()->ReloadStaleNTP();
}
void InstantTestBase::SetInstantURL(const std::string& url) {
@@ -88,7 +94,12 @@
chrome::NOTIFICATION_INSTANT_NTP_SUPPORT_DETERMINED,
content::NotificationService::AllSources());
FocusOmnibox();
- if (!instant()->ntp() || !instant()->ntp()->supports_instant())
+
+ InstantService* instant_service =
+ InstantServiceFactory::GetForProfile(browser_->profile());
+ ASSERT_NE(static_cast<InstantService*>(NULL), instant_service);
+ if (!instant_service->ntp_prerenderer()->ntp() ||
+ !instant_service->ntp_prerenderer()->ntp()->supports_instant())
ntp_observer.Wait();
}
@@ -127,7 +138,11 @@
}
bool InstantTestBase::ExecuteScript(const std::string& script) {
- return content::ExecuteScript(instant()->GetNTPContents(), script);
+ InstantService* instant_service =
+ InstantServiceFactory::GetForProfile(browser_instant()->profile());
+ if (!instant_service)
+ return false;
+ return content::ExecuteScript(instant_service->GetNTPContents(), script);
}
bool InstantTestBase::CheckVisibilityIs(content::WebContents* contents,
diff --git a/chrome/browser/ui/search/search_model.cc b/chrome/browser/ui/search/search_model.cc
index 694f456..fac64e6 100644
--- a/chrome/browser/ui/search/search_model.cc
+++ b/chrome/browser/ui/search/search_model.cc
@@ -8,24 +8,20 @@
#include "chrome/browser/ui/search/search_model_observer.h"
SearchModel::State::State()
- : top_bars_visible(true),
- instant_support(INSTANT_SUPPORT_UNKNOWN),
+ : instant_support(INSTANT_SUPPORT_UNKNOWN),
voice_search_supported(false) {
}
SearchModel::State::State(const SearchMode& mode,
- bool top_bars_visible,
InstantSupportState instant_support,
bool voice_search_supported)
: mode(mode),
- top_bars_visible(top_bars_visible),
instant_support(instant_support),
voice_search_supported(voice_search_supported) {
}
bool SearchModel::State::operator==(const State& rhs) const {
- return mode == rhs.mode && top_bars_visible == rhs.top_bars_visible &&
- instant_support == rhs.instant_support &&
+ return mode == rhs.mode && instant_support == rhs.instant_support &&
voice_search_supported == rhs.voice_search_supported;
}
@@ -61,27 +57,6 @@
const State old_state = state_;
state_.mode = new_mode;
- // For |SEARCH_SUGGESTIONS| and |SEARCH_RESULTS| modes, SearchBox API will
- // determine visibility of top bars via SetTopBarsVisible(); for other modes,
- // top bars are always visible, if available.
- if (!state_.mode.is_search())
- state_.top_bars_visible = true;
-
- FOR_EACH_OBSERVER(SearchModelObserver, observers_,
- ModelChanged(old_state, state_));
-}
-
-void SearchModel::SetTopBarsVisible(bool visible) {
- DCHECK(chrome::IsInstantExtendedAPIEnabled())
- << "Please do not try to set the SearchModel state without first "
- << "checking if Search is enabled.";
-
- if (state_.top_bars_visible == visible)
- return;
-
- const State old_state = state_;
- state_.top_bars_visible = visible;
-
FOR_EACH_OBSERVER(SearchModelObserver, observers_,
ModelChanged(old_state, state_));
}
diff --git a/chrome/browser/ui/search/search_model.h b/chrome/browser/ui/search/search_model.h
index 3ddb58e..dfbdf4f 100644
--- a/chrome/browser/ui/search/search_model.h
+++ b/chrome/browser/ui/search/search_model.h
@@ -25,7 +25,6 @@
struct State {
State();
State(const SearchMode& mode,
- bool top_bars_visible,
InstantSupportState instant_support,
bool voice_search_supported);
@@ -34,9 +33,6 @@
// The display mode of UI elements such as the toolbar, the tab strip, etc.
SearchMode mode;
- // The visibility of top bars such as bookmark and info bars.
- bool top_bars_visible;
-
// Does the current page support Instant?
InstantSupportState instant_support;
@@ -59,12 +55,6 @@
// Get the active mode.
const SearchMode& mode() const { return state_.mode; }
- // Set visibility of top bars. Change notifications are sent to observers.
- void SetTopBarsVisible(bool visible);
-
- // Get the visibility of top bars.
- bool top_bars_visible() const { return state_.top_bars_visible; }
-
// Sets the page instant support state. Change notifications are sent to
// observers.
void SetInstantSupportState(InstantSupportState instant_support);
diff --git a/chrome/browser/ui/search/search_model_unittest.cc b/chrome/browser/ui/search/search_model_unittest.cc
index 762256b..a1d0365 100644
--- a/chrome/browser/ui/search/search_model_unittest.cc
+++ b/chrome/browser/ui/search/search_model_unittest.cc
@@ -135,23 +135,8 @@
EXPECT_TRUE(model->state() == expected_new_state);
}
-TEST_F(SearchModelTest, UpdateTopBarVisibility) {
- mock_observer.VerifyNotificationCount(0);
- EXPECT_TRUE(model->top_bars_visible());
-
- SearchModel::State expected_old_state = model->state();
- SearchModel::State expected_new_state(model->state());
- expected_new_state.top_bars_visible = false;
-
- model->SetTopBarsVisible(false);
- mock_observer.VerifySearchModelStates(expected_old_state, expected_new_state);
- mock_observer.VerifyNotificationCount(1);
- EXPECT_FALSE(model->top_bars_visible());
-}
-
TEST_F(SearchModelTest, UpdateSearchModelState) {
SearchModel::State expected_new_state(model->state());
- expected_new_state.top_bars_visible = false;
expected_new_state.instant_support = INSTANT_SUPPORT_NO;
EXPECT_FALSE(model->state() == expected_new_state);
model->SetState(expected_new_state);
diff --git a/chrome/browser/ui/search/search_tab_helper.cc b/chrome/browser/ui/search/search_tab_helper.cc
index 281667f..8b6dee9 100644
--- a/chrome/browser/ui/search/search_tab_helper.cc
+++ b/chrome/browser/ui/search/search_tab_helper.cc
@@ -205,7 +205,6 @@
// OmniboxEditModel::SetInputInProgress() which is called from
// OmniboxEditModel::Revert().
model_.SetState(SearchModel::State(SearchMode(type, origin),
- model_.state().top_bars_visible,
model_.instant_support(),
model_.state().voice_search_supported));
} else {
diff --git a/chrome/browser/ui/startup/autolaunch_prompt_win.cc b/chrome/browser/ui/startup/autolaunch_prompt_win.cc
index 0671954..4471fca 100644
--- a/chrome/browser/ui/startup/autolaunch_prompt_win.cc
+++ b/chrome/browser/ui/startup/autolaunch_prompt_win.cc
@@ -36,7 +36,7 @@
// The delegate for the infobar shown when Chrome is auto-launched.
class AutolaunchInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
- // Creates an autolaunch delegate and adds it to |infobar_service|.
+ // Creates an autolaunch infobar delegate and adds it to |infobar_service|.
static void Create(InfoBarService* infobar_service, Profile* profile);
private:
diff --git a/chrome/browser/ui/startup/bad_flags_prompt.cc b/chrome/browser/ui/startup/bad_flags_prompt.cc
index 71c977a..f8bbea9 100644
--- a/chrome/browser/ui/startup/bad_flags_prompt.cc
+++ b/chrome/browser/ui/startup/bad_flags_prompt.cc
@@ -11,6 +11,7 @@
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_switches.h"
+#include "extensions/common/switches.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
@@ -32,7 +33,7 @@
// Browser plugin is dangerous on regular pages because it breaks the Same
// Origin Policy.
switches::kEnableBrowserPluginForAllViewTypes,
- switches::kExtensionsOnChromeURLs,
+ extensions::switches::kExtensionsOnChromeURLs,
// This parameter should be used only for server side developments.
switches::kTranslateScriptURL,
NULL
@@ -44,9 +45,8 @@
InfoBarService::FromWebContents(web_contents),
InfoBarDelegate::kNoIconID,
l10n_util::GetStringFUTF16(IDS_BAD_FLAGS_WARNING_MESSAGE,
- UTF8ToUTF16(std::string("--") + *flag)),
+ UTF8ToUTF16(std::string("--") + *flag)),
false);
-
return;
}
}
diff --git a/chrome/browser/ui/startup/default_browser_prompt.cc b/chrome/browser/ui/startup/default_browser_prompt.cc
index 4550195..786dcad 100644
--- a/chrome/browser/ui/startup/default_browser_prompt.cc
+++ b/chrome/browser/ui/startup/default_browser_prompt.cc
@@ -58,7 +58,8 @@
// The delegate for the infobar shown when Chrome is not the default browser.
class DefaultBrowserInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
- // Creates a default browser delegate and adds it to |infobar_service|.
+ // Creates a default browser infobar delegate and adds it to
+ // |infobar_service|.
static void Create(InfoBarService* infobar_service,
PrefService* prefs,
bool interactive_flow_required);
diff --git a/chrome/browser/ui/startup/obsolete_os_infobar_delegate.h b/chrome/browser/ui/startup/obsolete_os_infobar_delegate.h
index eedaac9..058ec48 100644
--- a/chrome/browser/ui/startup/obsolete_os_infobar_delegate.h
+++ b/chrome/browser/ui/startup/obsolete_os_infobar_delegate.h
@@ -16,7 +16,7 @@
// a "Learn More" link.
class ObsoleteOSInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
- // Creates an obsolete OS delegate and adds it to |infobar_service|.
+ // Creates an obsolete OS infobar delegate and adds it to |infobar_service|.
static void Create(InfoBarService* infobar_service);
private:
diff --git a/chrome/browser/ui/startup/session_crashed_prompt.cc b/chrome/browser/ui/startup/session_crashed_infobar_delegate.cc
similarity index 80%
rename from chrome/browser/ui/startup/session_crashed_prompt.cc
rename to chrome/browser/ui/startup/session_crashed_infobar_delegate.cc
index d504839..b5a68b6 100644
--- a/chrome/browser/ui/startup/session_crashed_prompt.cc
+++ b/chrome/browser/ui/startup/session_crashed_infobar_delegate.cc
@@ -2,10 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/ui/startup/session_crashed_prompt.h"
+#include "chrome/browser/ui/startup/session_crashed_infobar_delegate.h"
#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/sessions/session_restore.h"
@@ -16,7 +15,6 @@
#include "content/public/browser/dom_storage_context.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/storage_partition.h"
-#include "content/public/browser/web_contents.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
@@ -25,30 +23,29 @@
// static
void SessionCrashedInfoBarDelegate::Create(Browser* browser) {
- // Assume that if the user is launching incognito they were previously
- // running incognito so that we have nothing to restore from.
- if (browser->profile()->IsOffTheRecord())
- return;
-
- // In ChromeBot tests, there might be a race. This line appears to get
- // called during shutdown and |web_contents| can be NULL.
- content::WebContents* tab =
+ // Assume that if the user is launching incognito they were previously running
+ // incognito so that we have nothing to restore from.
+ // Also, in ChromeBot tests, there might be a race. This code appears to be
+ // called during shutdown when there is no active WebContents.
+ Profile* profile = browser->profile();
+ content::WebContents* web_contents =
browser->tab_strip_model()->GetActiveWebContents();
- if (!tab)
+ if (profile->IsOffTheRecord() || !web_contents)
return;
- InfoBarService* infobar_service = InfoBarService::FromWebContents(tab);
+ InfoBarService* infobar_service =
+ InfoBarService::FromWebContents(web_contents);
infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
- new SessionCrashedInfoBarDelegate(infobar_service, browser)));
+ new SessionCrashedInfoBarDelegate(infobar_service, profile)));
}
SessionCrashedInfoBarDelegate::SessionCrashedInfoBarDelegate(
InfoBarService* infobar_service,
- Browser* browser)
+ Profile* profile)
: ConfirmInfoBarDelegate(infobar_service),
accepted_(false),
removed_notification_received_(false),
- profile_(browser->profile()) {
+ profile_(profile) {
// TODO(pkasting,marja): Once InfoBars own they delegates, this is not needed
// any more. Then we can rely on delegates getting destroyed, and we can
// initiate the session storage scavenging only in the destructor. (Currently,
@@ -61,8 +58,8 @@
// If the info bar wasn't accepted, it was either dismissed or expired. In
// that case, session restore won't happen.
if (!accepted_ && !removed_notification_received_) {
- content::BrowserContext::GetDefaultStoragePartition(profile_)
- ->GetDOMStorageContext()->StartScavengingUnusedSessionStorage();
+ content::BrowserContext::GetDefaultStoragePartition(profile_)->
+ GetDOMStorageContext()->StartScavengingUnusedSessionStorage();
}
}
@@ -98,9 +95,9 @@
behavior = SessionRestore::CLOBBER_CURRENT_TAB;
}
}
- SessionRestore::RestoreSession(
- browser->profile(), browser, browser->host_desktop_type(), behavior,
- std::vector<GURL>());
+ SessionRestore::RestoreSession(browser->profile(), browser,
+ browser->host_desktop_type(), behavior,
+ std::vector<GURL>());
accepted_ = true;
return true;
}
diff --git a/chrome/browser/ui/startup/session_crashed_prompt.h b/chrome/browser/ui/startup/session_crashed_infobar_delegate.h
similarity index 81%
rename from chrome/browser/ui/startup/session_crashed_prompt.h
rename to chrome/browser/ui/startup/session_crashed_infobar_delegate.h
index a10f4d3..e842d5d 100644
--- a/chrome/browser/ui/startup/session_crashed_prompt.h
+++ b/chrome/browser/ui/startup/session_crashed_infobar_delegate.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_UI_STARTUP_SESSION_CRASHED_PROMPT_H_
-#define CHROME_BROWSER_UI_STARTUP_SESSION_CRASHED_PROMPT_H_
+#ifndef CHROME_BROWSER_UI_STARTUP_SESSION_CRASHED_INFOBAR_DELEGATE_H_
+#define CHROME_BROWSER_UI_STARTUP_SESSION_CRASHED_INFOBAR_DELEGATE_H_
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
@@ -18,8 +18,8 @@
class SessionCrashedInfoBarDelegate : public ConfirmInfoBarDelegate,
public content::NotificationObserver {
public:
- // If |browser| is not incognito, creates a session crashed delegate and adds
- // it to the InfoBarService for |browser|.
+ // If |browser| is not incognito, creates a session crashed infobar delegate
+ // and adds it to the InfoBarService for |browser|.
static void Create(Browser* browser);
private:
@@ -30,7 +30,7 @@
#endif
SessionCrashedInfoBarDelegate(InfoBarService* infobar_service,
- Browser* browser);
+ Profile* profile);
virtual ~SessionCrashedInfoBarDelegate();
// ConfirmInfoBarDelegate:
@@ -53,4 +53,4 @@
DISALLOW_COPY_AND_ASSIGN(SessionCrashedInfoBarDelegate);
};
-#endif // CHROME_BROWSER_UI_STARTUP_SESSION_CRASHED_PROMPT_H_
+#endif // CHROME_BROWSER_UI_STARTUP_SESSION_CRASHED_INFOBAR_DELEGATE_H_
diff --git a/chrome/browser/ui/startup/session_crashed_infobar_delegate_unittest.cc b/chrome/browser/ui/startup/session_crashed_infobar_delegate_unittest.cc
index f9bcfe4..473928d 100644
--- a/chrome/browser/ui/startup/session_crashed_infobar_delegate_unittest.cc
+++ b/chrome/browser/ui/startup/session_crashed_infobar_delegate_unittest.cc
@@ -2,12 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "chrome/browser/ui/startup/session_crashed_infobar_delegate.h"
+
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/testing_pref_service.h"
#include "base/run_loop.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/sessions/session_service_factory.h"
-#include "chrome/browser/ui/startup/session_crashed_prompt.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
@@ -60,9 +61,9 @@
InfoBarService* infobar_service =
InfoBarService::FromWebContents(web_contents);
EXPECT_EQ(1U, infobar_service->infobar_count());
- scoped_ptr<SessionCrashedInfoBarDelegate> info_bar(
- reinterpret_cast<SessionCrashedInfoBarDelegate*>(
- InfoBarService::FromWebContents(web_contents)->infobar_at(0)));
+ scoped_ptr<ConfirmInfoBarDelegate> infobar(InfoBarService::FromWebContents(
+ web_contents)->infobar_at(0)->AsConfirmInfoBarDelegate());
+ ASSERT_TRUE(infobar);
// Open another browser.
scoped_ptr<Browser> opened_browser(
@@ -83,7 +84,7 @@
EXPECT_EQ(1U, infobar_service->infobar_count());
// This used to crash.
- info_bar->Accept();
+ infobar->Accept();
// Ramp down the test.
tab_strip->CloseWebContentsAt(0, TabStripModel::CLOSE_NONE);
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
index 0b09eba..c26ac9d 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
@@ -64,7 +64,7 @@
#include "chrome/browser/ui/startup/default_browser_prompt.h"
#include "chrome/browser/ui/startup/google_api_keys_infobar_delegate.h"
#include "chrome/browser/ui/startup/obsolete_os_infobar_delegate.h"
-#include "chrome/browser/ui/startup/session_crashed_prompt.h"
+#include "chrome/browser/ui/startup/session_crashed_infobar_delegate.h"
#include "chrome/browser/ui/startup/startup_browser_creator.h"
#include "chrome/browser/ui/sync/sync_promo_ui.h"
#include "chrome/browser/ui/tabs/pinned_tab_codec.h"
@@ -357,7 +357,7 @@
AppListService::InitAll(profile);
if (command_line_.HasSwitch(switches::kShowAppList)) {
AppListService::RecordShowTimings(command_line_);
- AppListService::Get()->ShowAppList(profile);
+ AppListService::Get()->ShowForProfile(profile);
return true;
}
diff --git a/chrome/browser/ui/sync/one_click_signin_helper.cc b/chrome/browser/ui/sync/one_click_signin_helper.cc
index 992b88a..0fd124a 100644
--- a/chrome/browser/ui/sync/one_click_signin_helper.cc
+++ b/chrome/browser/ui/sync/one_click_signin_helper.cc
@@ -25,7 +25,6 @@
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/defaults.h"
#include "chrome/browser/google/google_util.h"
-#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/prefs/scoped_user_pref_update.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_info_cache.h"
@@ -33,6 +32,7 @@
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/signin/chrome_signin_manager_delegate.h"
+#include "chrome/browser/signin/signin_global_error.h"
#include "chrome/browser/signin/signin_manager.h"
#include "chrome/browser/signin/signin_manager_delegate.h"
#include "chrome/browser/signin/signin_manager_factory.h"
@@ -49,6 +49,7 @@
#include "chrome/browser/ui/sync/signin_histogram.h"
#include "chrome/browser/ui/tab_modal_confirm_dialog.h"
#include "chrome/browser/ui/tab_modal_confirm_dialog_delegate.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/net/url_util.h"
@@ -180,8 +181,15 @@
UMA_HISTOGRAM_ENUMERATION("Signin.AppsPageLinkActions", action,
one_click_signin::HISTOGRAM_MAX);
break;
+ case SyncPromoUI::SOURCE_BOOKMARK_BUBBLE:
+ UMA_HISTOGRAM_ENUMERATION("Signin.BookmarkBubbleActions", action,
+ one_click_signin::HISTOGRAM_MAX);
+ break;
default:
- NOTREACHED() << "Invalid Source";
+ // This switch statement needs to be updated when the enum Source changes.
+ COMPILE_ASSERT(SyncPromoUI::SOURCE_UNKNOWN == 9,
+ kSourceEnumHasChangedButNotThisSwitchStatement);
+ NOTREACHED();
return;
}
UMA_HISTOGRAM_ENUMERATION("Signin.AllAccessPointActions", action,
@@ -415,8 +423,7 @@
const std::string& last_email,
const std::string& email,
Callback callback)
- : TabModalConfirmDialogDelegate(contents),
- last_email_(last_email),
+ : last_email_(last_email),
email_(email),
callback_(callback) {
}
@@ -503,6 +510,20 @@
delete this; // Failure.
}
+void CloseTab(content::WebContents* tab) {
+ Browser* browser = chrome::FindBrowserWithWebContents(tab);
+ if (browser) {
+ TabStripModel* tab_strip_model = browser->tab_strip_model();
+ if (tab_strip_model) {
+ int index = tab_strip_model->GetIndexOfWebContents(tab);
+ if (index != TabStripModel::kNoTab) {
+ tab_strip_model->ExecuteContextMenuCommand(
+ index, TabStripModel::CommandCloseTab);
+ }
+ }
+ }
+}
+
} // namespace
@@ -1120,6 +1141,11 @@
return;
}
+ // Initialize |original_source_| if this is the first time the page has
+ // finished loading.
+ if (original_source_ == SyncPromoUI::SOURCE_UNKNOWN)
+ original_source_ = source_;
+
// In explicit sign ins, the user may have changed the box
// "Let me choose what to sync". This is reflected as a change in the
// source of the continue URL. Make one last check of the current URL
@@ -1184,9 +1210,18 @@
LogHistogramValue(source_, one_click_signin::HISTOGRAM_ACCEPTED);
LogHistogramValue(source_, one_click_signin::HISTOGRAM_WITH_DEFAULTS);
}
+
+ // - If sign in was initiated from the NTP or the hotdog menu, sync with
+ // default settings.
+ // - If sign in was initiated from the settings page for first time sync
+ // set up, show the advanced sync settings dialog.
+ // - If sign in was initiated from the settings page due to a re-auth,
+ // simply navigate back to the settings page.
OneClickSigninSyncStarter::StartSyncMode start_mode =
source_ == SyncPromoUI::SOURCE_SETTINGS ?
- OneClickSigninSyncStarter::CONFIGURE_SYNC_FIRST :
+ SigninGlobalError::GetForProfile(profile)->HasMenuItem() ?
+ OneClickSigninSyncStarter::SHOW_SETTINGS_WITHOUT_CONFIGURE :
+ OneClickSigninSyncStarter::CONFIGURE_SYNC_FIRST :
OneClickSigninSyncStarter::SYNC_WITH_DEFAULT_SETTINGS;
std::string last_email =
@@ -1219,17 +1254,21 @@
// If this explicit sign in is not from settings page/webstore, show
// the NTP/Apps page after sign in completes. In the case of the
- // settings page, it will get closed by SyncSetupHandler. In the case
+ // settings page, it will get auto-closed after sync setup. In the case
// of webstore, it will redirect back to webstore.
RedirectToNtpOrAppsPageIfNecessary(web_contents(), source_);
}
- if (source_ == SyncPromoUI::SOURCE_SETTINGS &&
- SyncPromoUI::GetSourceForSyncPromoURL(continue_url_) ==
- SyncPromoUI::SOURCE_WEBSTORE_INSTALL) {
+ // Observe the sync service if the Webstore tab or the settings tab
+ // requested a gaia sign in, so that when sign in and sync setup are
+ // successful, we can redirect to the correct URL, or auto-close the gaia
+ // sign in tab.
+ if (original_source_ == SyncPromoUI::SOURCE_SETTINGS ||
+ (original_source_ == SyncPromoUI::SOURCE_WEBSTORE_INSTALL &&
+ source_ == SyncPromoUI::SOURCE_SETTINGS)) {
redirect_url_ = continue_url_;
ProfileSyncService* sync_service =
- ProfileSyncServiceFactory::GetForProfile(profile);
+ ProfileSyncServiceFactory::GetForProfile(profile);
if (sync_service)
sync_service->AddObserver(this);
}
@@ -1259,15 +1298,27 @@
ProfileSyncService* sync_service =
ProfileSyncServiceFactory::GetForProfile(profile);
- // Sync setup not completed yet.
- if (sync_service->FirstSetupInProgress())
- return;
+ // At this point, the sign in process is complete, and control has been handed
+ // back to the sync engine. Close the gaia sign in tab if |redirect_url_|
+ // contains the |auto_close| parameter. Otherwise, wait for sync setup to
+ // complete and then navigate to |redirect_url_|.
+ if (SyncPromoUI::IsAutoCloseEnabledInURL(redirect_url_)) {
+ // Close the gaia sign in tab via a task to make sure we aren't in the
+ // middle of any webui handler code.
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&CloseTab, base::Unretained(contents)));
+ } else {
+ // Sync setup not completed yet.
+ if (sync_service->FirstSetupInProgress())
+ return;
- if (sync_service->sync_initialized()) {
- contents->GetController().LoadURL(redirect_url_,
- content::Referrer(),
- content::PAGE_TRANSITION_AUTO_TOPLEVEL,
- std::string());
+ if (sync_service->sync_initialized()) {
+ contents->GetController().LoadURL(redirect_url_,
+ content::Referrer(),
+ content::PAGE_TRANSITION_AUTO_TOPLEVEL,
+ std::string());
+ }
}
// Clear the redirect URL.
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_starter.cc b/chrome/browser/ui/sync/one_click_signin_sync_starter.cc
index e26356b..d5c232a 100644
--- a/chrome/browser/ui/sync/one_click_signin_sync_starter.cc
+++ b/chrome/browser/ui/sync/one_click_signin_sync_starter.cc
@@ -357,9 +357,23 @@
}
void OneClickSigninSyncStarter::SigninSuccess() {
+ // Before handing control back to sync setup, update the auth error state of
+ // ProfileSyncService if needed. This is necessary because ProfileSyncService
+ // will normally update its auth error state only after attempting a sync
+ // cycle, and we do not want old auth errors to remain visible on the menu or
+ // the settings page.
+ // TODO(rsimha): We shouldn't have to do this here. PSS must update its auth
+ // state after the backend is inititialized if it waiting_for_auth() is true.
+ ProfileSyncService* profile_sync_service = GetProfileSyncService();
+ if (profile_sync_service &&
+ profile_sync_service->GetAuthError().state() !=
+ GoogleServiceAuthError::NONE) {
+ profile_sync_service->UpdateAuthErrorState(
+ GoogleServiceAuthError::AuthErrorNone());
+ }
+
switch (start_mode_) {
case SYNC_WITH_DEFAULT_SETTINGS: {
- ProfileSyncService* profile_sync_service = GetProfileSyncService();
// Just kick off the sync machine, no need to configure it first.
if (profile_sync_service)
profile_sync_service->SetSyncSetupCompleted();
@@ -376,7 +390,10 @@
break;
}
case CONFIGURE_SYNC_FIRST:
- ConfigureSync();
+ ShowSettingsPageInNewTab(true); // Show sync config UI.
+ break;
+ case SHOW_SETTINGS_WITHOUT_CONFIGURE:
+ ShowSettingsPageInNewTab(false); // Don't show sync config UI.
break;
default:
NOTREACHED();
@@ -410,7 +427,7 @@
}
}
-void OneClickSigninSyncStarter::ConfigureSync() {
+void OneClickSigninSyncStarter::ShowSettingsPageInNewTab(bool configure_sync) {
// Give the user a chance to configure things. We don't clear the
// ProfileSyncService::setup_in_progress flag because we don't want sync
// to start up until after the configure UI is displayed (the configure UI
@@ -426,7 +443,15 @@
if (force_same_tab_navigation_) {
ShowSyncSettingsPageOnSameTab();
} else {
- chrome::ShowSettingsSubPage(browser_, chrome::kSyncSetupSubPage);
+ // If the user is setting up sync for the first time, let them configure
+ // advanced sync settings. However, in the case of re-authentication,
+ // return the user to the settings page without showing any config UI.
+ if (configure_sync) {
+ chrome::ShowSettingsSubPage(browser_, chrome::kSyncSetupSubPage);
+ } else {
+ FinishProfileSyncServiceSetup();
+ chrome::ShowSettings(browser_);
+ }
}
} else {
// Sync is disabled - just display the settings page.
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_starter.h b/chrome/browser/ui/sync/one_click_signin_sync_starter.h
index ce4ccda..0bbe183 100644
--- a/chrome/browser/ui/sync/one_click_signin_sync_starter.h
+++ b/chrome/browser/ui/sync/one_click_signin_sync_starter.h
@@ -38,6 +38,11 @@
// to configure which data types to sync before sync is enabled.
CONFIGURE_SYNC_FIRST,
+ // Starts the process of re-authenticating the user via SigninManager,
+ // and once completed, redirects the user to the settings page, but doesn't
+ // display the configure sync UI.
+ SHOW_SETTINGS_WITHOUT_CONFIGURE,
+
// The process should be aborted because the undo button has been pressed.
UNDO_SYNC
};
@@ -147,8 +152,11 @@
void FinishProfileSyncServiceSetup();
- // Displays the sync configuration UI.
- void ConfigureSync();
+ // Displays the settings UI in a new tab. Brings up the advanced sync settings
+ // dialog if |configure_sync| is true.
+ void ShowSettingsPageInNewTab(bool configure_sync);
+
+ // Displays the sync configuration UI in the same tab.
void ShowSyncSettingsPageOnSameTab();
// Shows the post-signin confirmation bubble. If |custom_message| is empty,
diff --git a/chrome/browser/ui/sync/sync_promo_ui.cc b/chrome/browser/ui/sync/sync_promo_ui.cc
index 8698f14..15a597c 100644
--- a/chrome/browser/ui/sync/sync_promo_ui.cc
+++ b/chrome/browser/ui/sync/sync_promo_ui.cc
@@ -97,10 +97,6 @@
if (net::NetworkChangeNotifier::IsOffline())
return false;
- // Don't show if the profile is an incognito.
- if (profile->IsOffTheRecord())
- return false;
-
// Don't show for managed profiles.
if (profile->GetPrefs()->GetBoolean(prefs::kProfileIsManaged))
return false;
@@ -143,6 +139,10 @@
bool is_new_profile) {
DCHECK(profile);
+ // Don't show if the profile is an incognito.
+ if (profile->IsOffTheRecord())
+ return false;
+
if (!ShouldShowSyncPromo(profile))
return false;
@@ -224,12 +224,16 @@
// The continue URL includes a source parameter that can be extracted using
// the function GetSourceForSyncPromoURL() below. This is used to know
// which of the chrome sign in access points was used to sign the user in.
+ // It is also parsed for the |auto_close| flag, which indicates that the tab
+ // must be closed after sync setup is successful.
// See OneClickSigninHelper for details.
url_string = GaiaUrls::GetInstance()->service_login_url();
url_string.append("?service=chromiumsync&sarp=1");
std::string continue_url = GetSyncLandingURL(
kSyncPromoQueryKeySource, static_cast<int>(source));
+ if (auto_close)
+ base::StringAppendF(&continue_url, "&%s=1", kSyncPromoQueryKeyAutoClose);
base::StringAppendF(&url_string, "&%s=%s", kSyncPromoQueryKeyContinue,
net::EscapeQueryParamValue(
@@ -261,6 +265,17 @@
}
// static
+bool SyncPromoUI::IsAutoCloseEnabledInURL(const GURL& url) {
+ std::string value;
+ if (net::GetValueForKeyInQuery(url, kSyncPromoQueryKeyAutoClose, &value)) {
+ int enabled = 0;
+ if (base::StringToInt(value, &enabled) && enabled == 1)
+ return true;
+ }
+ return false;
+}
+
+// static
bool SyncPromoUI::IsContinueUrlForWebBasedSigninFlow(const GURL& url) {
GURL::Replacements replacements;
replacements.ClearQuery();
diff --git a/chrome/browser/ui/sync/sync_promo_ui.h b/chrome/browser/ui/sync/sync_promo_ui.h
index 12b04b5..46fa449 100644
--- a/chrome/browser/ui/sync/sync_promo_ui.h
+++ b/chrome/browser/ui/sync/sync_promo_ui.h
@@ -29,6 +29,7 @@
SOURCE_WEBSTORE_INSTALL,
SOURCE_APP_LAUNCHER,
SOURCE_APPS_PAGE_LINK,
+ SOURCE_BOOKMARK_BUBBLE,
SOURCE_UNKNOWN, // This must be last.
};
@@ -72,6 +73,9 @@
// The source identifies from where the sync promo was opened.
static Source GetSourceForSyncPromoURL(const GURL& url);
+ // Returns true if the auto_close parameter in the given URL is set to true.
+ static bool IsAutoCloseEnabledInURL(const GURL& url);
+
// Returns true if the given URL is the standard continue URL used with the
// sync promo when the web-based flow is enabled. The query parameters
// of the URL are ignored for this comparison.
diff --git a/chrome/browser/ui/tab_contents/core_tab_helper.cc b/chrome/browser/ui/tab_contents/core_tab_helper.cc
index 52106b8..169e23a 100644
--- a/chrome/browser/ui/tab_contents/core_tab_helper.cc
+++ b/chrome/browser/ui/tab_contents/core_tab_helper.cc
@@ -7,6 +7,9 @@
#include "base/command_line.h"
#include "base/metrics/histogram.h"
#include "chrome/browser/renderer_host/web_cache_manager.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_command_controller.h"
+#include "chrome/browser/ui/browser_finder.h"
#include "chrome/common/chrome_switches.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
@@ -21,7 +24,8 @@
CoreTabHelper::CoreTabHelper(WebContents* web_contents)
: content::WebContentsObserver(web_contents),
- delegate_(NULL) {
+ delegate_(NULL),
+ content_restrictions_(0) {
}
CoreTabHelper::~CoreTabHelper() {
@@ -38,6 +42,9 @@
}
switch (web_contents()->GetLoadState().state) {
+ case net::LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL:
+ case net::LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET:
+ return l10n_util::GetStringUTF16(IDS_LOAD_STATE_WAITING_FOR_SOCKET_SLOT);
case net::LOAD_STATE_WAITING_FOR_DELEGATE:
if (!web_contents()->GetLoadState().param.empty()) {
return l10n_util::GetStringFUTF16(IDS_LOAD_STATE_WAITING_FOR_DELEGATE,
@@ -107,9 +114,24 @@
unload_detached_start_time_ = base::TimeTicks::Now();
}
+void CoreTabHelper::UpdateContentRestrictions(int content_restrictions) {
+ content_restrictions_ = content_restrictions;
+#if !defined(OS_ANDROID)
+ Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
+ if (!browser)
+ return;
+
+ browser->command_controller()->ContentRestrictionsChanged();
+#endif
+}
+
////////////////////////////////////////////////////////////////////////////////
// WebContentsObserver overrides
+void CoreTabHelper::DidStartLoading(content::RenderViewHost* render_view_host) {
+ UpdateContentRestrictions(0);
+}
+
void CoreTabHelper::WasShown() {
WebCacheManager::GetInstance()->ObserveActivity(
web_contents()->GetRenderProcessHost()->GetID());
diff --git a/chrome/browser/ui/tab_contents/core_tab_helper.h b/chrome/browser/ui/tab_contents/core_tab_helper.h
index c8e6782..7f0ffe3 100644
--- a/chrome/browser/ui/tab_contents/core_tab_helper.h
+++ b/chrome/browser/ui/tab_contents/core_tab_helper.h
@@ -39,6 +39,8 @@
// Set the time during close when the tab is no longer visible.
void OnUnloadDetachedStarted();
+ void UpdateContentRestrictions(int content_restrictions);
+
CoreTabHelperDelegate* delegate() const { return delegate_; }
void set_delegate(CoreTabHelperDelegate* d) { delegate_ = d; }
@@ -47,12 +49,15 @@
}
base::TimeTicks new_tab_start_time() const { return new_tab_start_time_; }
+ int content_restrictions() const { return content_restrictions_; }
private:
explicit CoreTabHelper(content::WebContents* web_contents);
friend class content::WebContentsUserData<CoreTabHelper>;
// content::WebContentsObserver overrides:
+ virtual void DidStartLoading(
+ content::RenderViewHost* render_view_host) OVERRIDE;
virtual void WasShown() OVERRIDE;
virtual void WebContentsDestroyed(
content::WebContents* web_contents) OVERRIDE;
@@ -75,6 +80,10 @@
// The time when the tab was removed from view during close.
base::TimeTicks unload_detached_start_time_;
+ // Content restrictions, used to disable print/copy etc based on content's
+ // (full-page plugins for now only) permissions.
+ int content_restrictions_;
+
DISALLOW_COPY_AND_ASSIGN(CoreTabHelper);
};
diff --git a/chrome/browser/ui/tab_modal_confirm_dialog.h b/chrome/browser/ui/tab_modal_confirm_dialog.h
index 6bd54ac..838e705 100644
--- a/chrome/browser/ui/tab_modal_confirm_dialog.h
+++ b/chrome/browser/ui/tab_modal_confirm_dialog.h
@@ -12,7 +12,7 @@
}
// Base class for the tab modal confirm dialog.
-class TabModalConfirmDialog : public TabModalConfirmDialogCloseDelegate {
+class TabModalConfirmDialog : public TabModalConfirmDialogOperationsDelegate {
public:
// Platform specific factory function. This function will automatically show
// the dialog.
@@ -24,9 +24,11 @@
// Cancels the dialog.
virtual void CancelTabModalDialog() = 0;
- // TabModalConfirmDialogCloseDelegate:
+ // TabModalConfirmDialogOperationsDelegate:
// Closes the dialog.
virtual void CloseDialog() = 0;
+ // Prevents the dialog from closing on WebContents load start.
+ virtual void SetPreventCloseOnLoadStart(bool prevent) = 0;
protected:
virtual ~TabModalConfirmDialog() {}
diff --git a/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.cc b/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.cc
index 1ced79b..b4355ba 100644
--- a/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.cc
+++ b/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.cc
@@ -14,10 +14,8 @@
#include "testing/gtest/include/gtest/gtest.h"
MockTabModalConfirmDialogDelegate::MockTabModalConfirmDialogDelegate(
- content::WebContents* web_contents,
Delegate* delegate)
- : TabModalConfirmDialogDelegate(web_contents),
- delegate_(delegate) {
+ : delegate_(delegate) {
}
MockTabModalConfirmDialogDelegate::~MockTabModalConfirmDialogDelegate() {
@@ -49,8 +47,7 @@
}
void TabModalConfirmDialogTest::SetUpOnMainThread() {
- delegate_ = new MockTabModalConfirmDialogDelegate(
- browser()->tab_strip_model()->GetActiveWebContents(), this);
+ delegate_ = new MockTabModalConfirmDialogDelegate(this);
dialog_ = TabModalConfirmDialog::Create(
delegate_, browser()->tab_strip_model()->GetActiveWebContents());
content::RunAllPendingInMessageLoop();
diff --git a/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.h b/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.h
index 0f22b37..0c0fd15 100644
--- a/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.h
+++ b/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.h
@@ -21,8 +21,7 @@
virtual ~Delegate() {}
};
- MockTabModalConfirmDialogDelegate(content::WebContents* web_contents,
- Delegate* delegate);
+ MockTabModalConfirmDialogDelegate(Delegate* delegate);
virtual ~MockTabModalConfirmDialogDelegate();
virtual string16 GetTitle() OVERRIDE;
diff --git a/chrome/browser/ui/tab_modal_confirm_dialog_delegate.cc b/chrome/browser/ui/tab_modal_confirm_dialog_delegate.cc
index c8d87ea..d2711dc 100644
--- a/chrome/browser/ui/tab_modal_confirm_dialog_delegate.cc
+++ b/chrome/browser/ui/tab_modal_confirm_dialog_delegate.cc
@@ -4,31 +4,20 @@
#include "chrome/browser/ui/tab_modal_confirm_dialog_delegate.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "content/public/browser/navigation_controller.h"
-#include "content/public/browser/notification_source.h"
-#include "content/public/browser/web_contents.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
-using content::NavigationController;
using content::WebContents;
-TabModalConfirmDialogDelegate::TabModalConfirmDialogDelegate(
- WebContents* web_contents)
- : close_delegate_(NULL),
+TabModalConfirmDialogDelegate::TabModalConfirmDialogDelegate()
+ : operations_delegate_(NULL),
closing_(false) {
- NavigationController* controller = &web_contents->GetController();
- registrar_.Add(this, content::NOTIFICATION_LOAD_START,
- content::Source<NavigationController>(controller));
- registrar_.Add(this, chrome::NOTIFICATION_TAB_CLOSING,
- content::Source<NavigationController>(controller));
}
TabModalConfirmDialogDelegate::~TabModalConfirmDialogDelegate() {
// If we end up here, the window has been closed, so make sure we don't close
// it again.
- close_delegate_ = NULL;
+ operations_delegate_ = NULL;
// Make sure everything is cleaned up.
Cancel();
}
@@ -63,20 +52,6 @@
CloseDialog();
}
-void TabModalConfirmDialogDelegate::Observe(
- int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- // Close the dialog if we load a page (because the action might not apply to
- // the same page anymore) or if the tab is closed.
- if (type == content::NOTIFICATION_LOAD_START ||
- type == chrome::NOTIFICATION_TAB_CLOSING) {
- Cancel();
- } else {
- NOTREACHED();
- }
-}
-
gfx::Image* TabModalConfirmDialogDelegate::GetIcon() {
return NULL;
}
@@ -112,6 +87,6 @@
}
void TabModalConfirmDialogDelegate::CloseDialog() {
- if (close_delegate_)
- close_delegate_->CloseDialog();
+ if (operations_delegate_)
+ operations_delegate_->CloseDialog();
}
diff --git a/chrome/browser/ui/tab_modal_confirm_dialog_delegate.h b/chrome/browser/ui/tab_modal_confirm_dialog_delegate.h
index e58e00d..29413a1 100644
--- a/chrome/browser/ui/tab_modal_confirm_dialog_delegate.h
+++ b/chrome/browser/ui/tab_modal_confirm_dialog_delegate.h
@@ -8,8 +8,6 @@
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/strings/string16.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
#include "ui/base/window_open_disposition.h"
namespace content {
@@ -20,26 +18,30 @@
class Image;
}
-class TabModalConfirmDialogCloseDelegate {
+// Operations to be performed on the dialog by the
+// TabModalConfirmDialogDelegate.
+class TabModalConfirmDialogOperationsDelegate {
public:
- TabModalConfirmDialogCloseDelegate() {}
- virtual ~TabModalConfirmDialogCloseDelegate() {}
+ TabModalConfirmDialogOperationsDelegate() {}
+ virtual ~TabModalConfirmDialogOperationsDelegate() {}
virtual void CloseDialog() = 0;
+ virtual void SetPreventCloseOnLoadStart(bool prevent) = 0;
private:
- DISALLOW_COPY_AND_ASSIGN(TabModalConfirmDialogCloseDelegate);
+ DISALLOW_COPY_AND_ASSIGN(TabModalConfirmDialogOperationsDelegate);
};
// This class acts as the delegate for a simple tab-modal dialog confirming
// whether the user wants to execute a certain action.
-class TabModalConfirmDialogDelegate : public content::NotificationObserver {
+class TabModalConfirmDialogDelegate {
public:
- explicit TabModalConfirmDialogDelegate(content::WebContents* web_contents);
+ TabModalConfirmDialogDelegate();
virtual ~TabModalConfirmDialogDelegate();
- void set_close_delegate(TabModalConfirmDialogCloseDelegate* close_delegate) {
- close_delegate_ = close_delegate;
+ void set_operations_delegate(
+ TabModalConfirmDialogOperationsDelegate* operations_delegate) {
+ operations_delegate_ = operations_delegate;
}
// Accepts the confirmation prompt and calls |OnAccepted|.
@@ -81,18 +83,10 @@
virtual const char* GetCancelButtonIcon();
protected:
- TabModalConfirmDialogCloseDelegate* close_delegate() {
- return close_delegate_;
+ TabModalConfirmDialogOperationsDelegate* operations_delegate() {
+ return operations_delegate_;
}
- // content::NotificationObserver implementation.
- // Watch for a new load or a closed tab and dismiss the dialog if they occur.
- virtual void Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) OVERRIDE;
-
- content::NotificationRegistrar registrar_;
-
private:
// It is guaranteed that exactly one of |OnAccepted|, |OnCanceled| or
// |OnLinkClicked| is eventually called. These method are private to
@@ -109,7 +103,7 @@
// Close the dialog.
void CloseDialog();
- TabModalConfirmDialogCloseDelegate* close_delegate_;
+ TabModalConfirmDialogOperationsDelegate* operations_delegate_;
// True iff we are in the process of closing, to avoid running callbacks
// multiple times.
bool closing_;
diff --git a/chrome/browser/ui/toolbar/action_box_button_controller.cc b/chrome/browser/ui/toolbar/action_box_button_controller.cc
deleted file mode 100644
index 253756c..0000000
--- a/chrome/browser/ui/toolbar/action_box_button_controller.cc
+++ /dev/null
@@ -1,184 +0,0 @@
-// 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/ui/toolbar/action_box_button_controller.h"
-
-#include "base/logging.h"
-#include "base/metrics/histogram.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/app/chrome_command_ids.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/extensions/api/page_launcher/page_launcher_api.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_system.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_commands.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/browser/ui/toolbar/action_box_menu_model.h"
-#include "chrome/common/extensions/api/extension_action/action_info.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/extension_set.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_source.h"
-#include "content/public/browser/render_widget_host_view.h"
-#include "content/public/browser/user_metrics.h"
-#include "content/public/browser/web_contents.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#include "ui/base/resource/resource_bundle.h"
-
-
-using content::UserMetricsAction;
-using content::WebContents;
-using extensions::ActionInfo;
-
-void ActionBoxButtonController::Delegate::ShowMenu(
- scoped_ptr<ActionBoxMenuModel> menu_model) {
-}
-
-ActionBoxButtonController::ActionBoxButtonController(Browser* browser,
- Delegate* delegate)
- : browser_(browser),
- delegate_(delegate),
- next_command_id_(0) {
- DCHECK(browser_);
- DCHECK(delegate_);
- registrar_.Add(this,
- chrome::NOTIFICATION_EXTENSION_UNLOADED,
- content::Source<Profile>(browser->profile()));
-}
-
-ActionBoxButtonController::~ActionBoxButtonController() {}
-
-scoped_ptr<ActionBoxMenuModel> ActionBoxButtonController::CreateMenuModel() {
- // Build a menu model and display the menu.
- scoped_ptr<ActionBoxMenuModel> menu_model(
- new ActionBoxMenuModel(browser_->profile(), this));
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-
- // In some unit tests, GetActiveWebContents can return NULL.
- bool starred = browser_->tab_strip_model()->GetActiveWebContents() &&
- BookmarkTabHelper::FromWebContents(browser_->tab_strip_model()->
- GetActiveWebContents())->is_starred();
- menu_model->AddItemWithStringId(
- IDC_BOOKMARK_PAGE_FROM_STAR,
- starred ? IDS_TOOLTIP_STARRED : IDS_TOOLTIP_STAR);
- menu_model->SetIcon(
- menu_model->GetIndexOfCommandId(IDC_BOOKMARK_PAGE_FROM_STAR),
- rb.GetNativeImageNamed(starred ? IDR_STAR_LIT : IDR_STAR));
-
- ExtensionService* extension_service =
- extensions::ExtensionSystem::Get(browser_->profile())->
- extension_service();
- if (extension_service) {
- const ExtensionSet* extensions = extension_service->extensions();
- for (ExtensionSet::const_iterator it = extensions->begin();
- it != extensions->end(); ++it) {
- const extensions::Extension* extension = it->get();
- if (ActionInfo::GetPageLauncherInfo(extension)) {
- int command_id = GetCommandIdForExtension(*extension);
- menu_model->AddExtension(*extension, command_id);
- }
- }
- }
- return menu_model.Pass();
-}
-
-void ActionBoxButtonController::OnButtonClicked() {
- content::RecordAction(UserMetricsAction("ActionBox.ClickButton"));
- delegate_->ShowMenu(CreateMenuModel());
-}
-
-bool ActionBoxButtonController::IsCommandIdChecked(int command_id) const {
- return false;
-}
-
-bool ActionBoxButtonController::IsCommandIdEnabled(int command_id) const {
- return true;
-}
-
-bool ActionBoxButtonController::GetAcceleratorForCommandId(
- int command_id,
- ui::Accelerator* accelerator) {
- return false;
-}
-
-void ActionBoxButtonController::ExecuteCommand(int command_id,
- int event_flags) {
- // If the command id belongs to an extension, dispatch an onClicked event
- // to its pageLauncher.
- ExtensionIdCommandMap::const_iterator it =
- extension_command_ids_.find(command_id);
- if (it != extension_command_ids_.end()) {
- WebContents* web_contents =
- browser_->tab_strip_model()->GetActiveWebContents();
-
- std::string page_title = UTF16ToUTF8(web_contents->GetTitle());
- std::string selected_text =
- UTF16ToUTF8(web_contents->GetRenderWidgetHostView()->GetSelectedText());
- extensions::PageLauncherAPI::DispatchOnClickedEvent(
- browser_->profile(),
- it->second,
- web_contents->GetURL(),
- web_contents->GetContentsMimeType(),
- page_title.empty() ? NULL : &page_title,
- selected_text.empty() ? NULL : &selected_text);
- return;
- }
-
- // Otherwise, let the browser handle the command.
- chrome::ExecuteCommand(browser_, command_id);
-}
-
-int ActionBoxButtonController::GetCommandIdForExtension(
- const extensions::Extension& extension) {
- for (ExtensionIdCommandMap::const_iterator it =
- extension_command_ids_.begin();
- it != extension_command_ids_.end(); ++it) {
- if (it->second == extension.id())
- return it->first;
- }
-
- int command_id = GetNextCommandId();
- extension_command_ids_[command_id] = extension.id();
-
- return command_id;
-}
-
-int ActionBoxButtonController::GetNextCommandId() {
- int command_id = next_command_id_;
- // Find an available command id to return next time the function is called.
- do {
- next_command_id_++;
- // Larger command ids are reserved for non-dynamic entries, so we start
- // reusing old ids at this point.
- if (next_command_id_ >= IDC_MinimumLabelValue)
- next_command_id_ = 0;
- } while (extension_command_ids_.find(next_command_id_) !=
- extension_command_ids_.end());
-
- return command_id;
-}
-
-void ActionBoxButtonController::Observe(
- int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- DCHECK_EQ(type, chrome::NOTIFICATION_EXTENSION_UNLOADED);
- const extensions::Extension* extension =
- content::Details<extensions::UnloadedExtensionInfo>(details)->extension;
-
- // Remove any entry point command ids associated with the extension.
- for (ExtensionIdCommandMap::iterator it = extension_command_ids_.begin();
- it != extension_command_ids_.end();) {
- if (it->second== extension->id())
- extension_command_ids_.erase(it++);
- else
- ++it;
- }
- // TODO(kalman): if there's a menu open, remove it from that too.
- // We may also want to listen to EXTENSION_LOADED to do the opposite.
-}
diff --git a/chrome/browser/ui/toolbar/action_box_button_controller.h b/chrome/browser/ui/toolbar/action_box_button_controller.h
deleted file mode 100644
index f61af21..0000000
--- a/chrome/browser/ui/toolbar/action_box_button_controller.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_UI_TOOLBAR_ACTION_BOX_BUTTON_CONTROLLER_H_
-#define CHROME_BROWSER_UI_TOOLBAR_ACTION_BOX_BUTTON_CONTROLLER_H_
-
-#include <map>
-#include <string>
-
-#include "base/memory/scoped_ptr.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
-#include "ui/base/models/simple_menu_model.h"
-
-class ActionBoxMenuModel;
-class Browser;
-
-namespace extensions {
-class Extension;
-}
-
-namespace ui {
-class MenuModel;
-}
-
-// Controller for the action box.
-//
-// This should have the same lifetime as the action box itself -- that is, more
-// or less the lifetime of the tab -- unlike ActionBoxMenuModel which is scoped
-// to the menu being open.
-class ActionBoxButtonController : public ui::SimpleMenuModel::Delegate,
- public content::NotificationObserver {
- public:
- class Delegate {
- public:
- // Shows the menu with the given |menu_model|.
- virtual void ShowMenu(scoped_ptr<ActionBoxMenuModel> menu_model);
-
- protected:
- virtual ~Delegate() {}
- };
-
- ActionBoxButtonController(Browser* browser, Delegate* delegate);
- virtual ~ActionBoxButtonController();
-
- // Creates and populates an ActionBoxMenuModel according to the current
- // state of the browser.
- scoped_ptr<ActionBoxMenuModel> CreateMenuModel();
-
- // Notifies this that the action box button has been clicked.
- // Methods on the Delegate may be called re-entrantly.
- void OnButtonClicked();
-
- // Overridden from ui::SimpleMenuModel::Delegate:
- virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
- virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
- virtual bool GetAcceleratorForCommandId(
- int command_id,
- ui::Accelerator* accelerator) OVERRIDE;
- virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;
-
- private:
- // Gets the command ID for an extension, creating a new one if necessary.
- int GetCommandIdForExtension(const extensions::Extension& extension);
-
- // Returns the next command ID to be used.
- int GetNextCommandId();
-
- // content::NotificationObserver implementation.
- virtual void Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) OVERRIDE;
-
- Browser* browser_;
-
- Delegate* delegate_;
-
- typedef std::map<int, std::string> ExtensionIdCommandMap;
- ExtensionIdCommandMap extension_command_ids_;
-
- // The command ID to assign to the next dynamic entry that needs one.
- int next_command_id_;
-
- content::NotificationRegistrar registrar_;
-
- DISALLOW_COPY_AND_ASSIGN(ActionBoxButtonController);
-};
-
-#endif // CHROME_BROWSER_UI_TOOLBAR_ACTION_BOX_BUTTON_CONTROLLER_H_
diff --git a/chrome/browser/ui/toolbar/action_box_context_menu_controller.cc b/chrome/browser/ui/toolbar/action_box_context_menu_controller.cc
deleted file mode 100644
index 4978c3a..0000000
--- a/chrome/browser/ui/toolbar/action_box_context_menu_controller.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright 2013 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/ui/toolbar/action_box_context_menu_controller.h"
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/app/chrome_command_ids.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_system.h"
-#include "chrome/browser/extensions/extension_uninstall_dialog.h"
-#include "chrome/browser/extensions/management_policy.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/chrome_pages.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/manifest_url_handler.h"
-#include "content/public/browser/page_navigator.h"
-#include "content/public/common/page_transition_types.h"
-#include "content/public/common/referrer.h"
-#include "grit/chromium_strings.h"
-#include "grit/generated_resources.h"
-#include "ui/base/models/menu_separator_types.h"
-#include "ui/base/window_open_disposition.h"
-#include "url/gurl.h"
-
-using extensions::Extension;
-
-namespace {
-
-// Takes care of running the uninstall extension dialog. This class deletes
-// itself after the user has responded to the dialog.
-class ExtensionUninstaller : public ExtensionUninstallDialog::Delegate {
- public:
- ExtensionUninstaller(Browser* browser, Profile* profile);
-
- void ShowDialog(const Extension* extension);
-
- // ExtensionUninstallDialog::Delegate:
- virtual void ExtensionUninstallAccepted() OVERRIDE;
- virtual void ExtensionUninstallCanceled() OVERRIDE;
-
- private:
- virtual ~ExtensionUninstaller();
-
- scoped_ptr<ExtensionUninstallDialog> dialog_;
- std::string extension_id_;
- Profile* profile_;
-
- DISALLOW_COPY_AND_ASSIGN(ExtensionUninstaller);
-};
-
-ExtensionUninstaller::ExtensionUninstaller(Browser* browser, Profile* profile)
- : dialog_(ExtensionUninstallDialog::Create(profile,
- browser,
- this)),
- profile_(profile) {
-}
-
-ExtensionUninstaller::~ExtensionUninstaller() {
-}
-
-void ExtensionUninstaller::ShowDialog(const Extension* extension) {
- extension_id_ = extension->id();
- dialog_->ConfirmUninstall(extension);
-}
-
-void ExtensionUninstaller::ExtensionUninstallAccepted() {
- ExtensionService* extension_service =
- extensions::ExtensionSystem::Get(profile_)->extension_service();
- if (extension_service->GetInstalledExtension(extension_id_))
- extension_service->UninstallExtension(extension_id_, false, NULL);
- delete this;
-}
-
-void ExtensionUninstaller::ExtensionUninstallCanceled() {
- delete this;
-}
-
-} // namespace
-
-ActionBoxContextMenuController::ActionBoxContextMenuController(
- Browser* browser,
- const Extension* extension)
- : browser_(browser),
- extension_id_(extension->id()),
- menu_model_(this) {
- std::string extension_name = extension->name();
- // Ampersands need to be escaped to avoid being treated like
- // mnemonics in the menu.
- ReplaceChars(extension_name, "&", "&&", &extension_name);
- menu_model_.AddItem(IDC_ACTION_BOX_EXTENSION_HOMEPAGE,
- UTF8ToUTF16(extension_name));
- menu_model_.AddSeparator(ui::NORMAL_SEPARATOR);
- menu_model_.AddItemWithStringId(IDC_ACTION_BOX_EXTENSION_MANAGE,
- IDS_MANAGE_EXTENSION);
- menu_model_.AddItemWithStringId(IDC_ACTION_BOX_EXTENSION_UNINSTALL,
- IDS_EXTENSIONS_UNINSTALL);
-}
-
-ActionBoxContextMenuController::~ActionBoxContextMenuController() {
-}
-
-bool ActionBoxContextMenuController::IsCommandIdChecked(int command_id) const {
- return false;
-}
-
-bool ActionBoxContextMenuController::IsCommandIdEnabled(int command_id) const {
- const Extension* extension = GetExtension();
- if (!extension)
- return false;
-
- switch (command_id) {
- case IDC_ACTION_BOX_EXTENSION_HOMEPAGE:
- return extensions::ManifestURL::GetHomepageURL(extension).is_valid();
- case IDC_ACTION_BOX_EXTENSION_MANAGE:
- return true;
- case IDC_ACTION_BOX_EXTENSION_UNINSTALL: {
- return extensions::ExtensionSystem::Get(browser_->profile())->
- management_policy()->UserMayModifySettings(extension, NULL);
- }
- default: {
- NOTREACHED();
- return false;
- }
- }
-}
-
-bool ActionBoxContextMenuController::GetAcceleratorForCommandId(
- int command_id,
- ui::Accelerator* accelerator) {
- return false;
-}
-
-void ActionBoxContextMenuController::ExecuteCommand(int command_id,
- int event_flags) {
- const Extension* extension = GetExtension();
- if (!extension)
- return;
-
- switch (command_id) {
- case IDC_ACTION_BOX_EXTENSION_HOMEPAGE: {
- content::OpenURLParams params(
- extensions::ManifestURL::GetHomepageURL(extension),
- content::Referrer(), NEW_FOREGROUND_TAB,
- content::PAGE_TRANSITION_LINK, false);
- browser_->OpenURL(params);
- break;
- }
- case IDC_ACTION_BOX_EXTENSION_MANAGE: {
- chrome::ShowExtensions(browser_, extension->id());
- break;
- }
- case IDC_ACTION_BOX_EXTENSION_UNINSTALL: {
- ExtensionUninstaller* uninstaller =
- new ExtensionUninstaller(browser_, browser_->profile());
- uninstaller->ShowDialog(extension);
- break;
- }
- default:
- NOTREACHED();
- }
-}
-
-const Extension* ActionBoxContextMenuController::GetExtension() const {
- ExtensionService* extension_service =
- extensions::ExtensionSystem::Get(browser_->profile())->
- extension_service();
- return extension_service->GetInstalledExtension(extension_id_);
-}
diff --git a/chrome/browser/ui/toolbar/action_box_context_menu_controller.h b/chrome/browser/ui/toolbar/action_box_context_menu_controller.h
deleted file mode 100644
index 92cf0e7..0000000
--- a/chrome/browser/ui/toolbar/action_box_context_menu_controller.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CHROME_BROWSER_UI_TOOLBAR_ACTION_BOX_CONTEXT_MENU_CONTROLLER_H__
-#define CHROME_BROWSER_UI_TOOLBAR_ACTION_BOX_CONTEXT_MENU_CONTROLLER_H__
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "ui/base/models/simple_menu_model.h"
-
-class Browser;
-
-namespace extensions {
-class Extension;
-} // namespace extensions
-
-namespace ui {
-class Accelerator;
-class MenuModel;
-} // namespace ui
-
-// This class handles building a context menu for extensions in the action
-// box. It also contains the logic necessary for executing the actions
-// associated with each menu entry.
-class ActionBoxContextMenuController : public ui::SimpleMenuModel::Delegate {
- public:
- // |browser| and |extension| must not be NULL.
- ActionBoxContextMenuController(Browser* browser,
- const extensions::Extension* extension);
- virtual ~ActionBoxContextMenuController();
-
- ui::MenuModel* menu_model() { return &menu_model_; }
-
- // ui::SimpleMenuModel::Delegate:
- virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
- virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
- virtual bool GetAcceleratorForCommandId(
- int command_id,
- ui::Accelerator* accelerator) OVERRIDE;
- virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;
-
- private:
- const extensions::Extension* GetExtension() const;
-
- Browser* browser_;
- std::string extension_id_;
- ui::SimpleMenuModel menu_model_;
-
- DISALLOW_COPY_AND_ASSIGN(ActionBoxContextMenuController);
-};
-
-#endif // CHROME_BROWSER_UI_TOOLBAR_ACTION_BOX_CONTEXT_MENU_CONTROLLER_H__
diff --git a/chrome/browser/ui/toolbar/action_box_menu_model.cc b/chrome/browser/ui/toolbar/action_box_menu_model.cc
deleted file mode 100644
index 9a5197a..0000000
--- a/chrome/browser/ui/toolbar/action_box_menu_model.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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/ui/toolbar/action_box_menu_model.h"
-
-#include "base/logging.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_system.h"
-#include "chrome/browser/extensions/extension_toolbar_model.h"
-#include "chrome/common/extensions/api/extension_action/action_info.h"
-
-
-using extensions::ActionInfo;
-
-////////////////////////////////////////////////////////////////////////////////
-// ActionBoxMenuModel
-
-ActionBoxMenuModel::ActionBoxMenuModel(Profile* profile,
- ui::SimpleMenuModel::Delegate* delegate)
- : ui::SimpleMenuModel(delegate),
- profile_(profile) {
-
-}
-
-ActionBoxMenuModel::~ActionBoxMenuModel() {
-}
-
-void ActionBoxMenuModel::AddExtension(const extensions::Extension& extension,
- int command_id) {
- if (extension_ids_.empty())
- AddSeparator(ui::NORMAL_SEPARATOR);
- extension_ids_.push_back(extension.id());
- const ActionInfo* page_launcher_info =
- ActionInfo::GetPageLauncherInfo(&extension);
- DCHECK(page_launcher_info);
- AddItem(command_id, UTF8ToUTF16(page_launcher_info->default_title));
-}
-
-bool ActionBoxMenuModel::IsItemExtension(int index) {
- // The extensions are always at the end of the model.
- CHECK(index < GetItemCount());
- return index >= GetFirstExtensionIndex();
-}
-
-const extensions::Extension* ActionBoxMenuModel::GetExtensionAt(int index) {
- if (!IsItemExtension(index))
- return NULL;
-
- int index_in_extension_ids = index - GetFirstExtensionIndex();
- CHECK_GE(index_in_extension_ids, 0);
- CHECK_LT(index_in_extension_ids, static_cast<int>(extension_ids_.size()));
-
- ExtensionService* extension_service =
- extensions::ExtensionSystem::Get(profile_)->extension_service();
- return extension_service->extensions()->GetByID(
- extension_ids_[index_in_extension_ids]);
-}
-
-void ActionBoxMenuModel::ExecuteCommand(int command_id) {
- delegate()->ExecuteCommand(command_id, 0);
-}
-
-int ActionBoxMenuModel::GetFirstExtensionIndex() {
- return GetItemCount() - extension_ids_.size();
-}
diff --git a/chrome/browser/ui/toolbar/action_box_menu_model.h b/chrome/browser/ui/toolbar/action_box_menu_model.h
deleted file mode 100644
index 02c21a8..0000000
--- a/chrome/browser/ui/toolbar/action_box_menu_model.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_UI_TOOLBAR_ACTION_BOX_MENU_MODEL_H_
-#define CHROME_BROWSER_UI_TOOLBAR_ACTION_BOX_MENU_MODEL_H_
-
-#include <map>
-
-#include "chrome/common/extensions/extension.h"
-#include "content/public/browser/notification_observer.h"
-#include "ui/base/models/simple_menu_model.h"
-
-class Profile;
-
-// A menu model that builds the contents of the action box menu. Effectively,
-// a ui::SimpleMenuModel with methods specifically for dealing with extension
-// content.
-//
-// This model should be built on demand since its content reflects the state of
-// the browser at creation time.
-class ActionBoxMenuModel : public ui::SimpleMenuModel {
- public:
- ActionBoxMenuModel(Profile* profile, ui::SimpleMenuModel::Delegate* delegate);
- virtual ~ActionBoxMenuModel();
-
- // Adds an extension to the model with a given command ID.
- void AddExtension(const extensions::Extension& extension, int command_id);
-
- // Returns true if item associated with an extension.
- bool IsItemExtension(int index);
-
- // Returns an extension associated with model item at |index|
- // or NULL if it is not an extension item.
- const extensions::Extension* GetExtensionAt(int index);
-
- // Calls ExecuteCommand on the delegate.
- void ExecuteCommand(int command_id);
-
- private:
- friend class ActionBoxMenuModelTest;
- // Gets the index of the first extension. This may be equal to the number of
- // total items in the model if there are no extensions installed.
- int GetFirstExtensionIndex();
-
- Profile* profile_;
-
- // The list of extensions added to the menu, in order, if any.
- extensions::ExtensionIdList extension_ids_;
-
- DISALLOW_COPY_AND_ASSIGN(ActionBoxMenuModel);
-};
-
-#endif // CHROME_BROWSER_UI_TOOLBAR_ACTION_BOX_MENU_MODEL_H_
diff --git a/chrome/browser/ui/toolbar/action_box_menu_model_unittest.cc b/chrome/browser/ui/toolbar/action_box_menu_model_unittest.cc
deleted file mode 100644
index 8b5b419..0000000
--- a/chrome/browser/ui/toolbar/action_box_menu_model_unittest.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// 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/ui/toolbar/action_box_menu_model.h"
-
-#include "base/memory/scoped_ptr.h"
-#include "base/prefs/testing_pref_service.h"
-#include "base/values.h"
-#include "chrome/app/chrome_command_ids.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_command_controller.h"
-#include "chrome/browser/ui/browser_commands.h"
-#include "chrome/browser/ui/toolbar/action_box_button_controller.h"
-#include "chrome/common/extensions/feature_switch.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/test/base/browser_with_test_window_test.h"
-#include "chrome/test/base/testing_profile.h"
-#include "chrome/test/base/ui_test_utils.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#include "sync/notifier/invalidation_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/base/resource/resource_bundle.h"
-
-using extensions::FeatureSwitch;
-
-class ActionBoxMenuModelTest : public BrowserWithTestWindowTest,
- public ActionBoxButtonController::Delegate {
- public:
- ActionBoxMenuModelTest() {}
-
- virtual void SetUp() OVERRIDE {
- BrowserWithTestWindowTest::SetUp();
- controller_.reset(new ActionBoxButtonController(browser(), this));
- }
-
- virtual void TearDown() OVERRIDE {
- controller_.reset();
- BrowserWithTestWindowTest::TearDown();
- }
-
- scoped_ptr<ActionBoxMenuModel> CreateModel() {
- return controller_->CreateMenuModel();
- }
-
- void InitProfile(){
- profile()->set_incognito(true);
- profile()->GetPrefs()->ClearPref(prefs::kGoogleServicesUsername);
- }
-
- void SetProfileSignedIn() {
- profile()->set_incognito(false);
- // Set username pref (i.e. sign in),
- profile()->GetPrefs()->SetString(prefs::kGoogleServicesUsername, "foo");
- }
-
- void NavigateToBookmarkablePage() {
- AddTab(browser(), GURL("http://www.google.com"));
- }
-
- void NavigateToLocalPage() {
- AddTab(browser(), GURL("chrome://blank"));
- }
-
- private:
- scoped_ptr<ActionBoxButtonController> controller_;
-
- DISALLOW_COPY_AND_ASSIGN(ActionBoxMenuModelTest);
-};
-
-// Tests that Bookmark Star is lit up only on bookmarked pages.
-TEST_F(ActionBoxMenuModelTest, BookmarkedPage) {
- FeatureSwitch::ScopedOverride enable_action_box(FeatureSwitch::action_box(),
- true);
- // Set up bookmark model
- profile()->CreateBookmarkModel(true);
- ui_test_utils::WaitForBookmarkModelToLoad(profile());
-
- // Navigate to a url.
- GURL url1("http://www.google.com");
- AddTab(browser(), url1);
-
- scoped_ptr<ActionBoxMenuModel> model = CreateModel();
-
- // Bokomark item should be in menu.
- int bookmark_item_index = model->GetIndexOfCommandId(
- IDC_BOOKMARK_PAGE_FROM_STAR);
- ASSERT_NE(-1, bookmark_item_index);
-
- gfx::Image bookmark_icon;
- gfx::Image unlit_icon;
- gfx::Image lit_icon;
-
- model->GetIconAt(bookmark_item_index, &bookmark_icon);
- unlit_icon =
- ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(IDR_STAR);
-
- SkBitmap bookmark_icon_bitmap = *bookmark_icon.ToSkBitmap();
- SkBitmap unlit_icon_bitmap = *unlit_icon.ToSkBitmap();
- SkAutoLockPixels a(bookmark_icon_bitmap);
- SkAutoLockPixels b(unlit_icon_bitmap);
-
- // Verify that the icon in the menu is the unlit icon.
- EXPECT_EQ(0, memcmp(bookmark_icon_bitmap.getPixels(),
- unlit_icon_bitmap.getPixels(),
- unlit_icon_bitmap.getSize()));
-
- // Now bookmark it.
- chrome::BookmarkCurrentPage(browser());
-
- scoped_ptr<ActionBoxMenuModel> model2 = CreateModel();
-
- model2->GetIconAt(bookmark_item_index, &bookmark_icon);
- lit_icon =
- ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed(IDR_STAR_LIT);
-
- SkBitmap bookmark_icon_bitmap2 = *bookmark_icon.ToSkBitmap();
- SkBitmap lit_icon_bitmap = *lit_icon.ToSkBitmap();
- SkAutoLockPixels c(bookmark_icon_bitmap2);
- SkAutoLockPixels d(lit_icon_bitmap);
-
-
- // Verify that the icon in the menu is the lit icon.
- EXPECT_EQ(0, memcmp(bookmark_icon_bitmap2.getPixels(),
- lit_icon_bitmap.getPixels(),
- lit_icon_bitmap.getSize()));
-}
diff --git a/chrome/browser/ui/toolbar/test_toolbar_model.cc b/chrome/browser/ui/toolbar/test_toolbar_model.cc
index 3b452a7..95411b3 100644
--- a/chrome/browser/ui/toolbar/test_toolbar_model.cc
+++ b/chrome/browser/ui/toolbar/test_toolbar_model.cc
@@ -29,11 +29,13 @@
return url_;
}
-bool TestToolbarModel::WouldReplaceSearchURLWithSearchTerms() const {
+bool TestToolbarModel::WouldReplaceSearchURLWithSearchTerms(
+ bool ignore_editing) const {
return should_replace_url_;
}
-ToolbarModel::SecurityLevel TestToolbarModel::GetSecurityLevel() const {
+ToolbarModel::SecurityLevel TestToolbarModel::GetSecurityLevel(
+ bool ignore_editing) const {
return security_level_;
}
diff --git a/chrome/browser/ui/toolbar/test_toolbar_model.h b/chrome/browser/ui/toolbar/test_toolbar_model.h
index 256cb2c..80b9f19 100644
--- a/chrome/browser/ui/toolbar/test_toolbar_model.h
+++ b/chrome/browser/ui/toolbar/test_toolbar_model.h
@@ -20,8 +20,9 @@
bool display_search_urls_as_search_terms) const OVERRIDE;
virtual string16 GetCorpusNameForMobile() const OVERRIDE;
virtual GURL GetURL() const OVERRIDE;
- virtual bool WouldReplaceSearchURLWithSearchTerms() const OVERRIDE;
- virtual SecurityLevel GetSecurityLevel() const OVERRIDE;
+ virtual bool WouldReplaceSearchURLWithSearchTerms(
+ bool ignore_editing) const OVERRIDE;
+ virtual SecurityLevel GetSecurityLevel(bool ignore_editing) const OVERRIDE;
virtual int GetIcon() const OVERRIDE;
virtual string16 GetEVCertName() const OVERRIDE;
virtual bool ShouldDisplayURL() const OVERRIDE;
diff --git a/chrome/browser/ui/toolbar/toolbar_model.h b/chrome/browser/ui/toolbar/toolbar_model.h
index 9ef715d..8238cb6 100644
--- a/chrome/browser/ui/toolbar/toolbar_model.h
+++ b/chrome/browser/ui/toolbar/toolbar_model.h
@@ -51,11 +51,17 @@
virtual GURL GetURL() const = 0;
// Returns true if a call to GetText(true) would successfully replace the URL
- // with search terms.
- virtual bool WouldReplaceSearchURLWithSearchTerms() const = 0;
+ // with search terms. If |ignore_editing| is true, the result reflects the
+ // underlying state of the page without regard to any user edits that may be
+ // in progress in the omnibox.
+ virtual bool WouldReplaceSearchURLWithSearchTerms(bool ignore_editing)
+ const = 0;
- // Returns the security level that the toolbar should display.
- virtual SecurityLevel GetSecurityLevel() const = 0;
+ // Returns the security level that the toolbar should display. If
+ // |ignore_editing| is true, the result reflects the underlying state of the
+ // page without regard to any user edits that may be in progress in the
+ // omnibox.
+ virtual SecurityLevel GetSecurityLevel(bool ignore_editing) const = 0;
// Returns the resource_id of the icon to show to the left of the address,
// based on the current URL. This doesn't cover specialized icons while the
diff --git a/chrome/browser/ui/toolbar/toolbar_model_impl.cc b/chrome/browser/ui/toolbar/toolbar_model_impl.cc
index 8ecf05c..4e6f66b 100644
--- a/chrome/browser/ui/toolbar/toolbar_model_impl.cc
+++ b/chrome/browser/ui/toolbar/toolbar_model_impl.cc
@@ -93,7 +93,7 @@
string16 ToolbarModelImpl::GetText(
bool display_search_urls_as_search_terms) const {
if (display_search_urls_as_search_terms) {
- string16 search_terms(GetSearchTerms());
+ string16 search_terms(GetSearchTerms(false));
if (!search_terms.empty())
return search_terms;
}
@@ -114,7 +114,7 @@
}
string16 ToolbarModelImpl::GetCorpusNameForMobile() const {
- if (!WouldReplaceSearchURLWithSearchTerms())
+ if (!WouldReplaceSearchURLWithSearchTerms(false))
return string16();
GURL url(GetURL());
// If there is a query in the url fragment look for the corpus name there,
@@ -145,8 +145,9 @@
return GURL(content::kAboutBlankURL);
}
-bool ToolbarModelImpl::WouldReplaceSearchURLWithSearchTerms() const {
- return !GetSearchTerms().empty();
+bool ToolbarModelImpl::WouldReplaceSearchURLWithSearchTerms(
+ bool ignore_editing) const {
+ return !GetSearchTerms(ignore_editing).empty();
}
bool ToolbarModelImpl::ShouldDisplayURL() const {
@@ -181,15 +182,17 @@
return true;
}
-ToolbarModel::SecurityLevel ToolbarModelImpl::GetSecurityLevel() const {
- if (input_in_progress_) // When editing, assume no security style.
+ToolbarModel::SecurityLevel
+ ToolbarModelImpl::GetSecurityLevel(bool ignore_editing) const {
+ if (!ignore_editing && input_in_progress_) {
+ // When editing, assume no security style.
return NONE;
-
+ }
return GetSecurityLevelForWebContents(delegate_->GetActiveWebContents());
}
int ToolbarModelImpl::GetIcon() const {
- if (WouldReplaceSearchURLWithSearchTerms())
+ if (WouldReplaceSearchURLWithSearchTerms(false))
return IDR_OMNIBOX_SEARCH_SECURED;
static int icon_ids[NUM_SECURITY_LEVELS] = {
@@ -201,11 +204,11 @@
IDR_OMNIBOX_HTTPS_INVALID,
};
DCHECK(arraysize(icon_ids) == NUM_SECURITY_LEVELS);
- return icon_ids[GetSecurityLevel()];
+ return icon_ids[GetSecurityLevel(false)];
}
string16 ToolbarModelImpl::GetEVCertName() const {
- DCHECK_EQ(GetSecurityLevel(), EV_SECURE);
+ DCHECK_EQ(GetSecurityLevel(false), EV_SECURE);
scoped_refptr<net::X509Certificate> cert;
// Note: Navigation controller and active entry are guaranteed non-NULL or
// the security level would be NONE.
@@ -252,7 +255,7 @@
NULL;
}
-string16 ToolbarModelImpl::GetSearchTerms() const {
+string16 ToolbarModelImpl::GetSearchTerms(bool ignore_editing) const {
const WebContents* web_contents = delegate_->GetActiveWebContents();
string16 search_terms(chrome::GetSearchTerms(web_contents));
if (search_terms.empty())
@@ -270,15 +273,16 @@
(entry->GetSSL().security_style == content::SECURITY_STYLE_UNKNOWN))
return search_terms;
- // If the URL is using a Google base URL specified via the command line, skip
+ // If the URL is using a Google base URL specified via the command line, we
+ // allow search term replacement any time the user isn't editing, bypassing
// the security check below.
- if (entry &&
+ if ((ignore_editing || !input_in_progress_) && entry &&
google_util::StartsWithCommandLineGoogleBaseURL(entry->GetVirtualURL()))
return search_terms;
// Otherwise, extract search terms for HTTPS pages that do not have a security
// error.
- ToolbarModel::SecurityLevel security_level = GetSecurityLevel();
+ ToolbarModel::SecurityLevel security_level = GetSecurityLevel(ignore_editing);
return ((security_level == NONE) || (security_level == SECURITY_ERROR)) ?
string16() : search_terms;
}
diff --git a/chrome/browser/ui/toolbar/toolbar_model_impl.h b/chrome/browser/ui/toolbar/toolbar_model_impl.h
index 39b5707..651e809 100644
--- a/chrome/browser/ui/toolbar/toolbar_model_impl.h
+++ b/chrome/browser/ui/toolbar/toolbar_model_impl.h
@@ -41,8 +41,9 @@
bool display_search_urls_as_search_terms) const OVERRIDE;
virtual string16 GetCorpusNameForMobile() const OVERRIDE;
virtual GURL GetURL() const OVERRIDE;
- virtual bool WouldReplaceSearchURLWithSearchTerms() const OVERRIDE;
- virtual SecurityLevel GetSecurityLevel() const OVERRIDE;
+ virtual bool WouldReplaceSearchURLWithSearchTerms(
+ bool ignore_editing) const OVERRIDE;
+ virtual SecurityLevel GetSecurityLevel(bool ignore_editing) const OVERRIDE;
virtual int GetIcon() const OVERRIDE;
virtual string16 GetEVCertName() const OVERRIDE;
virtual bool ShouldDisplayURL() const OVERRIDE;
@@ -62,8 +63,10 @@
Profile* GetProfile() const;
// Returns search terms as in chrome::GetSearchTerms() unless the page is
- // insufficiently secure.
- string16 GetSearchTerms() const;
+ // insufficiently secure. If |ignore_editing| is true, the result reflects
+ // the underlying state of the page without regard to any user edits that
+ // may be in progress in the omnibox.
+ string16 GetSearchTerms(bool ignore_editing) const;
ToolbarModelDelegate* delegate_;
diff --git a/chrome/browser/ui/toolbar/toolbar_model_unittest.cc b/chrome/browser/ui/toolbar/toolbar_model_unittest.cc
index c3da77c..20595cb 100644
--- a/chrome/browser/ui/toolbar/toolbar_model_unittest.cc
+++ b/chrome/browser/ui/toolbar/toolbar_model_unittest.cc
@@ -235,7 +235,7 @@
EXPECT_EQ(should_display, toolbar_model->ShouldDisplayURL());
EXPECT_EQ(expected_text, toolbar_model->GetText(can_replace));
EXPECT_EQ(would_replace,
- toolbar_model->WouldReplaceSearchURLWithSearchTerms());
+ toolbar_model->WouldReplaceSearchURLWithSearchTerms(false));
// Check after commit.
CommitPendingLoad(controller);
@@ -248,7 +248,17 @@
EXPECT_EQ(should_display, toolbar_model->ShouldDisplayURL());
EXPECT_EQ(expected_text, toolbar_model->GetText(can_replace));
EXPECT_EQ(would_replace,
- toolbar_model->WouldReplaceSearchURLWithSearchTerms());
+ toolbar_model->WouldReplaceSearchURLWithSearchTerms(false));
+
+ // Now pretend the user started modifying the omnibox.
+ toolbar_model->SetInputInProgress(true);
+ EXPECT_FALSE(toolbar_model->WouldReplaceSearchURLWithSearchTerms(false));
+ EXPECT_EQ(would_replace,
+ toolbar_model->WouldReplaceSearchURLWithSearchTerms(true));
+
+ // Tell the ToolbarModel that the user has stopped editing. This prevents
+ // this function from having side effects.
+ toolbar_model->SetInputInProgress(false);
}
@@ -275,7 +285,8 @@
const TestItem& test_item = test_items[i];
NavigateAndCheckText(test_item.url, test_item.expected_text,
test_item.expected_replace_text_active,
- test_item.would_replace, test_item.should_display);
+ test_item.would_replace,
+ test_item.should_display);
}
}
@@ -294,14 +305,14 @@
ToolbarModel* toolbar_model = browser()->toolbar_model();
controller->GetVisibleEntry()->GetSSL().security_style =
content::SECURITY_STYLE_UNKNOWN;
- EXPECT_TRUE(toolbar_model->WouldReplaceSearchURLWithSearchTerms());
+ EXPECT_TRUE(toolbar_model->WouldReplaceSearchURLWithSearchTerms(false));
// When done loading, we shouldn't extract search terms if we didn't get an
// authenticated connection.
CommitPendingLoad(controller);
controller->GetVisibleEntry()->GetSSL().security_style =
content::SECURITY_STYLE_UNKNOWN;
- EXPECT_FALSE(toolbar_model->WouldReplaceSearchURLWithSearchTerms());
+ EXPECT_FALSE(toolbar_model->WouldReplaceSearchURLWithSearchTerms(false));
}
// When the Google base URL is overridden on the command line, we should extract
diff --git a/chrome/browser/ui/views/action_box_context_menu.cc b/chrome/browser/ui/views/action_box_context_menu.cc
deleted file mode 100644
index 2beac0b..0000000
--- a/chrome/browser/ui/views/action_box_context_menu.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2013 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/ui/views/action_box_context_menu.h"
-
-#include "chrome/browser/ui/toolbar/action_box_context_menu_controller.h"
-#include "ui/gfx/point.h"
-#include "ui/gfx/size.h"
-#include "ui/views/controls/menu/menu_model_adapter.h"
-#include "ui/views/controls/menu/menu_runner.h"
-
-using views::MenuRunner;
-
-ActionBoxContextMenu::ActionBoxContextMenu(
- Browser* browser,
- const extensions::Extension* extension)
- : controller_(browser, extension) {
-}
-
-ActionBoxContextMenu::~ActionBoxContextMenu() {
-}
-
-views::MenuRunner::RunResult ActionBoxContextMenu::RunMenuAt(
- const gfx::Point& p,
- views::Widget* parent_widget,
- ui::MenuSourceType source_type) {
- adapter_.reset(new views::MenuModelAdapter(controller_.menu_model()));
- menu_runner_.reset(new MenuRunner(adapter_->CreateMenu()));
- return menu_runner_->RunMenuAt(
- parent_widget,
- NULL, // No menu button.
- gfx::Rect(p, gfx::Size()),
- views::MenuItemView::TOPLEFT,
- source_type,
- (MenuRunner::CONTEXT_MENU | MenuRunner::IS_NESTED |
- MenuRunner::HAS_MNEMONICS));
-}
diff --git a/chrome/browser/ui/views/action_box_context_menu.h b/chrome/browser/ui/views/action_box_context_menu.h
deleted file mode 100644
index 605f40b..0000000
--- a/chrome/browser/ui/views/action_box_context_menu.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_ACTION_BOX_CONTEXT_MENU_H__
-#define CHROME_BROWSER_UI_VIEWS_ACTION_BOX_CONTEXT_MENU_H__
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/memory/scoped_ptr.h"
-#include "chrome/browser/ui/toolbar/action_box_context_menu_controller.h"
-#include "ui/views/controls/menu/menu_runner.h"
-
-class Browser;
-
-namespace extensions {
-class Extension;
-} // namespace extensions
-
-namespace gfx {
-class Point;
-} // namespace gfx
-
-namespace views {
-class MenuModelAdapter;
-class Widget;
-} // namespace views
-
-// This is the Views class responsible for showing the context menu for
-// extensions in the action box. Actually building and executing commands is
-// handled by ActionBoxContextMenuController.
-class ActionBoxContextMenu {
- public:
- ActionBoxContextMenu(Browser* browser,
- const extensions::Extension* extension);
- ~ActionBoxContextMenu();
-
- // See comments in menu_runner.h on how the return value should be used.
- views::MenuRunner::RunResult RunMenuAt(
- const gfx::Point& p,
- views::Widget* parent_widget,
- ui::MenuSourceType source_type) WARN_UNUSED_RESULT;
-
- private:
- ActionBoxContextMenuController controller_;
- scoped_ptr<views::MenuModelAdapter> adapter_;
- scoped_ptr<views::MenuRunner> menu_runner_;
-
- DISALLOW_COPY_AND_ASSIGN(ActionBoxContextMenu);
-};
-
-#endif // CHROME_BROWSER_UI_VIEWS_ACTION_BOX_CONTEXT_MENU_H__
diff --git a/chrome/browser/ui/views/action_box_menu.cc b/chrome/browser/ui/views/action_box_menu.cc
deleted file mode 100644
index d6a7ecd..0000000
--- a/chrome/browser/ui/views/action_box_menu.cc
+++ /dev/null
@@ -1,128 +0,0 @@
-// 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/ui/views/action_box_menu.h"
-
-#include "chrome/browser/extensions/extension_icon_image.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/toolbar/action_box_menu_model.h"
-#include "chrome/browser/ui/views/action_box_context_menu.h"
-#include "chrome/common/extensions/api/extension_action/action_info.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/extension_constants.h"
-#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
-#include "ui/views/controls/button/menu_button.h"
-#include "ui/views/controls/image_view.h"
-#include "ui/views/controls/menu/menu_runner.h"
-#include "ui/views/view.h"
-
-using extensions::ActionInfo;
-using extensions::Extension;
-using extensions::IconImage;
-
-namespace {
-class ExtensionImageView : public views::ImageView, public IconImage::Observer {
- public:
- ExtensionImageView(Profile* profile, const Extension* extension) {
- const ActionInfo* page_launcher_info =
- ActionInfo::GetPageLauncherInfo(extension);
- icon_.reset(new IconImage(profile,
- extension,
- page_launcher_info->default_icon,
- extension_misc::EXTENSION_ICON_ACTION,
- extensions::IconsInfo::GetDefaultAppIcon(),
- this));
- SetImage(icon_->image_skia());
- }
-
- private:
- virtual void OnExtensionIconImageChanged(
- extensions::IconImage* image) OVERRIDE {
- SetImage(icon_->image_skia());
- }
-
- scoped_ptr<extensions::IconImage> icon_;
-
- DISALLOW_COPY_AND_ASSIGN(ExtensionImageView);
-};
-} // namespace
-
-// static
-scoped_ptr<ActionBoxMenu> ActionBoxMenu::Create(
- Browser* browser,
- scoped_ptr<ActionBoxMenuModel> model) {
- scoped_ptr<ActionBoxMenu> menu(new ActionBoxMenu(browser, model.Pass()));
- menu->PopulateMenu();
- return menu.Pass();
-}
-
-ActionBoxMenu::~ActionBoxMenu() {
-}
-
-void ActionBoxMenu::RunMenu(views::MenuButton* menu_button,
- gfx::Point menu_offset) {
- views::View::ConvertPointToScreen(menu_button, &menu_offset);
- menu_parent_ = menu_button->GetWidget();
-
- // Ignore the result since we don't need to handle a deleted menu specially.
- ignore_result(
- menu_runner_->RunMenuAt(menu_parent_,
- menu_button,
- gfx::Rect(menu_offset, menu_button->size()),
- views::MenuItemView::TOPRIGHT,
- ui::MENU_SOURCE_NONE,
- views::MenuRunner::HAS_MNEMONICS));
-}
-
-ActionBoxMenu::ActionBoxMenu(Browser* browser,
- scoped_ptr<ActionBoxMenuModel> model)
- : browser_(browser),
- menu_parent_(NULL),
- model_(model.Pass()) {
- views::MenuItemView* menu = new views::MenuItemView(this);
- menu->set_has_icons(true);
-
- menu_runner_.reset(new views::MenuRunner(menu));
-}
-
-void ActionBoxMenu::ExecuteCommand(int id) {
- model_->ExecuteCommand(id);
-}
-
-bool ActionBoxMenu::ShowContextMenu(views::MenuItemView* source,
- int id,
- const gfx::Point& p,
- ui::MenuSourceType source_type) {
- DCHECK(menu_parent_);
-
- int index = model_->GetIndexOfCommandId(id);
- if (!model_->IsItemExtension(index))
- return false;
-
- context_menu_.reset(
- new ActionBoxContextMenu(browser_, model_->GetExtensionAt(index)));
- if (context_menu_->RunMenuAt(p, menu_parent_, source_type) ==
- views::MenuRunner::MENU_DELETED)
- return true;
- context_menu_.reset();
- return true;
-}
-
-void ActionBoxMenu::PopulateMenu() {
- for (int model_index = 0; model_index < model_->GetItemCount();
- ++model_index) {
- views::MenuItemView* menu_item =
- menu_runner_->GetMenu()->AppendMenuItemFromModel(
- model_.get(), model_index, model_->GetCommandIdAt(model_index));
- if (model_->GetTypeAt(model_index) == ui::MenuModel::TYPE_COMMAND) {
- if (model_->IsItemExtension(model_index)) {
- const Extension* extension = model_->GetExtensionAt(model_index);
- ExtensionImageView* view = new ExtensionImageView(browser_->profile(),
- extension);
- // |menu_item| will own the |view| from now on.
- menu_item->SetIconView(view);
- }
- }
- }
-}
diff --git a/chrome/browser/ui/views/action_box_menu.h b/chrome/browser/ui/views/action_box_menu.h
deleted file mode 100644
index 3248013..0000000
--- a/chrome/browser/ui/views/action_box_menu.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_ACTION_BOX_MENU_H_
-#define CHROME_BROWSER_UI_VIEWS_ACTION_BOX_MENU_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "ui/views/controls/menu/menu_delegate.h"
-
-class ActionBoxContextMenu;
-class ActionBoxMenuModel;
-class Browser;
-
-namespace views {
-class MenuButton;
-class MenuItemView;
-class MenuRunner;
-}
-
-// ActionBoxMenu adapts the ActionBoxMenuModel to view's menu related classes.
-class ActionBoxMenu : public views::MenuDelegate {
- public:
- // Constructs and initializes an ActionBoxMenu.
- static scoped_ptr<ActionBoxMenu> Create(Browser* browser,
- scoped_ptr<ActionBoxMenuModel> model);
-
- virtual ~ActionBoxMenu();
-
- // Shows the menu relative to the specified button.
- void RunMenu(views::MenuButton* menu_button, gfx::Point menu_offset);
-
- private:
- ActionBoxMenu(Browser* browser, scoped_ptr<ActionBoxMenuModel> model);
-
- // Overridden from views::MenuDelegate:
- virtual void ExecuteCommand(int id) OVERRIDE;
- virtual bool ShowContextMenu(views::MenuItemView* source,
- int id,
- const gfx::Point& p,
- ui::MenuSourceType source_type) OVERRIDE;
-
- // Populates |root_| with all the child menu items from the |model_|.
- void PopulateMenu();
-
- Browser* browser_;
-
- scoped_ptr<ActionBoxContextMenu> context_menu_;
- scoped_ptr<views::MenuRunner> menu_runner_;
- views::Widget* menu_parent_;
-
- // The model that tracks the order of the toolbar icons.
- scoped_ptr<ActionBoxMenuModel> model_;
-
- DISALLOW_COPY_AND_ASSIGN(ActionBoxMenu);
-};
-
-#endif // CHROME_BROWSER_UI_VIEWS_ACTION_BOX_MENU_H_
diff --git a/chrome/browser/ui/views/app_list/app_list_controller_win.cc b/chrome/browser/ui/views/app_list/app_list_controller_win.cc
index 20cc64f..6bbb595 100644
--- a/chrome/browser/ui/views/app_list/app_list_controller_win.cc
+++ b/chrome/browser/ui/views/app_list/app_list_controller_win.cc
@@ -301,20 +301,20 @@
void AppListClosing();
void AppListActivationChanged(bool active);
void ShowAppListDuringModeSwitch(Profile* requested_profile);
- void DisableAppList();
app_list::AppListView* GetView() { return current_view_; }
// AppListService overrides:
+ virtual void HandleFirstRun() OVERRIDE;
virtual void Init(Profile* initial_profile) OVERRIDE;
- virtual void ShowAppList(Profile* requested_profile) OVERRIDE;
+ virtual void ShowForProfile(Profile* requested_profile) OVERRIDE;
virtual void DismissAppList() OVERRIDE;
virtual bool IsAppListVisible() const OVERRIDE;
- virtual void EnableAppList(Profile* initial_profile) OVERRIDE;
virtual gfx::NativeWindow GetAppListWindow() OVERRIDE;
virtual AppListControllerDelegate* CreateControllerDelegate() OVERRIDE;
// AppListServiceImpl overrides:
+ virtual void CreateShortcut() OVERRIDE;
virtual void OnSigninStatusChanged() OVERRIDE;
private:
@@ -388,6 +388,8 @@
// the right mouse button down, but not if this happens twice in a row.
bool preserving_focus_for_taskbar_menu_;
+ bool enable_app_list_on_next_init_;
+
base::WeakPtrFactory<AppListController> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(AppListController);
@@ -480,6 +482,7 @@
can_close_app_list_(true),
regain_first_lost_focus_(false),
preserving_focus_for_taskbar_menu_(false),
+ enable_app_list_on_next_init_(false),
weak_factory_(this) {}
AppListController::~AppListController() {
@@ -500,7 +503,7 @@
current_view_->OnSigninStatusChanged();
}
-void AppListController::ShowAppList(Profile* requested_profile) {
+void AppListController::ShowForProfile(Profile* requested_profile) {
DCHECK(requested_profile);
ScopedKeepAlive show_app_list_keepalive;
@@ -527,7 +530,7 @@
return;
}
- SaveProfilePathToLocalState(requested_profile->GetPath());
+ SetProfilePath(requested_profile->GetPath());
DismissAppList();
PopulateViewFromProfile(requested_profile);
@@ -545,7 +548,7 @@
void AppListController::ShowAppListDuringModeSwitch(
Profile* requested_profile) {
regain_first_lost_focus_ = true;
- ShowAppList(requested_profile);
+ ShowForProfile(requested_profile);
}
void AppListController::PopulateViewFromProfile(Profile* requested_profile) {
@@ -851,12 +854,28 @@
current_view_->Prerender();
}
+void AppListController::HandleFirstRun() {
+ PrefService* local_state = g_browser_process->local_state();
+ // If the app list is already enabled during first run, then the user had
+ // opted in to the app launcher before uninstalling, so we re-enable to
+ // restore shortcuts to the app list.
+ // Note we can't directly create the shortcuts here because the IO thread
+ // hasn't been created yet.
+ enable_app_list_on_next_init_ = local_state->GetBoolean(
+ apps::prefs::kAppLauncherHasBeenEnabled);
+}
+
void AppListController::Init(Profile* initial_profile) {
// In non-Ash metro mode, we can not show the app list for this process, so do
// not bother performing Init tasks.
if (win8::IsSingleWindowMetroMode())
return;
+ if (enable_app_list_on_next_init_) {
+ enable_app_list_on_next_init_ = false;
+ EnableAppList(initial_profile);
+ }
+
PrefService* prefs = g_browser_process->local_state();
if (prefs->HasPrefPath(prefs::kRestartWithAppList) &&
prefs->GetBoolean(prefs::kRestartWithAppList)) {
@@ -893,26 +912,18 @@
ScheduleWarmup();
MigrateAppLauncherEnabledPref();
-
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableAppList))
- EnableAppList(initial_profile);
-
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableAppList))
- DisableAppList();
+ HandleCommandLineFlags(initial_profile);
}
bool AppListController::IsAppListVisible() const {
return current_view_ && current_view_->GetWidget()->IsVisible();
}
-void AppListController::EnableAppList(Profile* initial_profile) {
- SaveProfilePathToLocalState(initial_profile->GetPath());
+void AppListController::CreateShortcut() {
// Check if the app launcher shortcuts have ever been created before.
// Shortcuts should only be created once. If the user unpins the taskbar
// shortcut, they can restore it by pinning the start menu or desktop
// shortcut.
- PrefService* local_state = g_browser_process->local_state();
- local_state->SetBoolean(apps::prefs::kAppLauncherHasBeenEnabled, true);
ShellIntegration::ShortcutLocations shortcut_locations;
shortcut_locations.on_desktop = true;
shortcut_locations.in_quick_launch_bar = true;
@@ -929,11 +940,6 @@
user_data_dir, GetAppModelId(), shortcut_locations));
}
-void AppListController::DisableAppList() {
- PrefService* local_state = g_browser_process->local_state();
- local_state->SetBoolean(apps::prefs::kAppLauncherHasBeenEnabled, false);
-}
-
void AppListController::ScheduleWarmup() {
// Post a task to create the app list. This is posted to not impact startup
// time.
diff --git a/chrome/browser/ui/views/autofill/autofill_credit_card_bubble_views.cc b/chrome/browser/ui/views/autofill/autofill_credit_card_bubble_views.cc
index 13f5ae5..4853230 100644
--- a/chrome/browser/ui/views/autofill/autofill_credit_card_bubble_views.cc
+++ b/chrome/browser/ui/views/autofill/autofill_credit_card_bubble_views.cc
@@ -25,18 +25,13 @@
AutofillCreditCardBubbleViews::~AutofillCreditCardBubbleViews() {}
void AutofillCreditCardBubbleViews::Show() {
- views::BubbleDelegateView::CreateBubble(this);
// TODO(dbeam): investigate why this steals focus from the web contents.
+ views::BubbleDelegateView::CreateBubble(this);
- views::BubbleFrameView* frame_view = GetBubbleFrameView();
- frame_view->SetTitle(controller_->BubbleTitle());
+ GetBubbleFrameView()->SetTitle(controller_->BubbleTitle());
- views::Widget* widget = GetWidget();
- widget->SetSize(frame_view->GetPreferredSize());
- // Calls |frame_view_->Layout()| if necessary.
- frame_view->SetBoundsRect(frame_view->bounds());
-
- widget->Show();
+ GetWidget()->Show();
+ SizeToContents();
}
void AutofillCreditCardBubbleViews::Hide() {
diff --git a/chrome/browser/ui/views/autofill/autofill_dialog_views.cc b/chrome/browser/ui/views/autofill/autofill_dialog_views.cc
index a3523a6..29dda7c 100644
--- a/chrome/browser/ui/views/autofill/autofill_dialog_views.cc
+++ b/chrome/browser/ui/views/autofill/autofill_dialog_views.cc
@@ -33,6 +33,7 @@
#include "ui/gfx/skia_util.h"
#include "ui/views/background.h"
#include "ui/views/border.h"
+#include "ui/views/controls/button/blue_button.h"
#include "ui/views/controls/button/checkbox.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/button/label_button.h"
@@ -109,6 +110,11 @@
// Spacing between lines of text in the overlay view.
const int kOverlayTextInterlineSpacing = 10;
+// A dimmer text color used in various parts of the dialog. TODO(estade): should
+// this be part of NativeTheme? Currently the value is duplicated in several
+// places.
+const SkColor kGreyTextColor = SkColorSetRGB(102, 102, 102);
+
const char kDecoratedTextfieldClassName[] = "autofill/DecoratedTextfield";
const char kNotificationAreaClassName[] = "autofill/NotificationArea";
const char kOverlayViewClassName[] = "autofill/OverlayView";
@@ -541,7 +547,7 @@
AutofillDialogViews::OverlayView::OverlayView(views::ButtonListener* listener)
: image_view_(new views::ImageView()),
message_stack_(new views::View()),
- button_(new views::LabelButton(listener, string16())) {
+ button_(new views::BlueButton(listener, string16())) {
set_border(views::Border::CreateEmptyBorder(12, 12, 12, 12));
set_background(views::Background::CreateSolidBackground(GetNativeTheme()->
GetSystemColor(ui::NativeTheme::kColorId_DialogBackground)));
@@ -556,7 +562,6 @@
kOverlayTextPadding, kOverlayTextPadding, 0, kOverlayTextPadding));
AddChildView(button_);
- button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON);
button_->set_focusable(true);
}
@@ -640,9 +645,7 @@
button_->SizeToPreferredSize();
y -= button_->height();
button_->SetPosition(gfx::Point(
- bounds.width() - button_->width() -
- views::kButtonHEdgeMarginNew,
- y));
+ bounds.CenterPoint().x() - button_->width() / 2, y));
y -= views::kButtonVEdgeMarginNew;
}
@@ -1107,6 +1110,8 @@
web_contents_modal_dialog_manager->delegate()->
GetWebContentsModalDialogHost());
web_contents_modal_dialog_manager->ShowDialog(window_->GetNativeView());
+ web_contents_modal_dialog_manager->SetPreventCloseOnLoadStart(
+ window_->GetNativeView(), true);
focus_manager_ = window_->GetFocusManager();
focus_manager_->AddFocusChangeListener(this);
@@ -1465,6 +1470,10 @@
controller_->ConfirmButtonText() : controller_->CancelButtonText();
}
+bool AutofillDialogViews::ShouldDefaultButtonBeBlue() const {
+ return true;
+}
+
bool AutofillDialogViews::IsDialogButtonEnabled(ui::DialogButton button) const {
return controller_->IsDialogButtonEnabled(button);
}
@@ -1490,7 +1499,9 @@
views::Background::CreateSolidBackground(kShadingColor));
legal_document_view_ = new views::StyledLabel(string16(), this);
- legal_document_view_->SetDisplayedOnBackgroundColor(kShadingColor);
+ views::StyledLabel::RangeStyleInfo default_style;
+ default_style.color = kGreyTextColor;
+ legal_document_view_->SetDefaultStyle(default_style);
footnote_view_->AddChildView(legal_document_view_);
footnote_view_->SetVisible(false);
@@ -1503,17 +1514,15 @@
}
bool AutofillDialogViews::Cancel() {
- controller_->OnCancel();
- return true;
+ return controller_->OnCancel();
}
bool AutofillDialogViews::Accept() {
if (ValidateForm())
- controller_->OnAccept();
- else if (!validity_map_.empty())
- validity_map_.begin()->first->RequestFocus();
+ return controller_->OnAccept();
- // |controller_| decides when to hide the dialog.
+ if (!validity_map_.empty())
+ validity_map_.begin()->first->RequestFocus();
return false;
}
@@ -1961,8 +1970,10 @@
std::map<views::View*, string16>::iterator error_message =
validity_map_.find(view);
- if (error_message != validity_map_.end())
+ if (error_message != validity_map_.end()) {
+ view->ScrollRectToVisible(view->GetLocalBounds());
error_bubble_.reset(new ErrorBubble(view, error_message->second));
+ }
}
void AutofillDialogViews::MarkInputsInvalid(DialogSection section,
diff --git a/chrome/browser/ui/views/autofill/autofill_dialog_views.h b/chrome/browser/ui/views/autofill/autofill_dialog_views.h
index 626d21a..cae7ce1 100644
--- a/chrome/browser/ui/views/autofill/autofill_dialog_views.h
+++ b/chrome/browser/ui/views/autofill/autofill_dialog_views.h
@@ -123,6 +123,7 @@
virtual views::View* CreateOverlayView() OVERRIDE;
virtual int GetDialogButtons() const OVERRIDE;
virtual string16 GetDialogButtonLabel(ui::DialogButton button) const OVERRIDE;
+ virtual bool ShouldDefaultButtonBeBlue() const OVERRIDE;
virtual bool IsDialogButtonEnabled(ui::DialogButton button) const OVERRIDE;
virtual views::View* CreateExtraView() OVERRIDE;
virtual views::View* CreateTitlebarExtraView() OVERRIDE;
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
index ca52a45..86b9060 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h"
+#include "base/command_line.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -13,9 +14,10 @@
#include "chrome/browser/bookmarks/bookmark_utils.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/bookmarks/bookmark_editor.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/sync/sync_promo_ui.h"
#include "chrome/browser/ui/views/bookmarks/bookmark_bubble_view_observer.h"
+#include "chrome/browser/ui/views/bookmarks/bookmark_sync_promo_view.h"
+#include "chrome/common/chrome_switches.h"
#include "content/public/browser/user_metrics.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
@@ -41,6 +43,9 @@
// Minimum width of the the bubble.
const int kMinBubbleWidth = 350;
+// Width of the border of a button.
+const int kControlBorderWidth = 2;
+
} // namespace
// Declared in browser_dialogs.h so callers don't have to depend on our header.
@@ -49,10 +54,15 @@
void ShowBookmarkBubbleView(views::View* anchor_view,
BookmarkBubbleViewObserver* observer,
+ scoped_ptr<BookmarkBubbleDelegate> delegate,
Profile* profile,
const GURL& url,
bool newly_bookmarked) {
- BookmarkBubbleView::ShowBubble(anchor_view, observer, profile, url,
+ BookmarkBubbleView::ShowBubble(anchor_view,
+ observer,
+ delegate.Pass(),
+ profile,
+ url,
newly_bookmarked);
}
@@ -71,15 +81,21 @@
BookmarkBubbleView* BookmarkBubbleView::bookmark_bubble_ = NULL;
// static
-void BookmarkBubbleView::ShowBubble(views::View* anchor_view,
- BookmarkBubbleViewObserver* observer,
- Profile* profile,
- const GURL& url,
- bool newly_bookmarked) {
+void BookmarkBubbleView::ShowBubble(
+ views::View* anchor_view,
+ BookmarkBubbleViewObserver* observer,
+ scoped_ptr<BookmarkBubbleDelegate> delegate,
+ Profile* profile,
+ const GURL& url,
+ bool newly_bookmarked) {
if (IsShowing())
return;
- bookmark_bubble_ = new BookmarkBubbleView(anchor_view, observer, profile, url,
+ bookmark_bubble_ = new BookmarkBubbleView(anchor_view,
+ observer,
+ delegate.Pass(),
+ profile,
+ url,
newly_bookmarked);
views::BubbleDelegateView::CreateBubble(bookmark_bubble_)->Show();
// Select the entire title textfield contents when the bubble is first shown.
@@ -123,7 +139,7 @@
if (observer_)
observer_->OnBookmarkBubbleHidden();
- }
+}
bool BookmarkBubbleView::AcceleratorPressed(
const ui::Accelerator& accelerator) {
@@ -172,14 +188,22 @@
GridLayout* layout = new GridLayout(this);
SetLayoutManager(layout);
- const int kTitleColumnSetID = 0;
- ColumnSet* cs = layout->AddColumnSet(kTitleColumnSetID);
+ // Column sets used in the layout of the bubble.
+ enum ColumnSetID {
+ TITLE_COLUMN_SET_ID,
+ CONTENT_COLUMN_SET_ID,
+ SYNC_PROMO_COLUMN_SET_ID
+ };
+
+ ColumnSet* cs = layout->AddColumnSet(TITLE_COLUMN_SET_ID);
+ cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew);
cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, GridLayout::USE_PREF,
0, 0);
+ cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew);
// The column layout used for middle and bottom rows.
- const int kFirstColumnSetID = 1;
- cs = layout->AddColumnSet(kFirstColumnSetID);
+ cs = layout->AddColumnSet(CONTENT_COLUMN_SET_ID);
+ cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew);
cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
GridLayout::USE_PREF, 0, 0);
cs->AddPaddingColumn(0, views::kUnrelatedControlHorizontalSpacing);
@@ -193,12 +217,13 @@
cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
cs->AddColumn(GridLayout::LEADING, GridLayout::TRAILING, 0,
GridLayout::USE_PREF, 0, 0);
+ cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew);
- layout->StartRow(0, kTitleColumnSetID);
+ layout->StartRow(0, TITLE_COLUMN_SET_ID);
layout->AddView(title_label);
layout->AddPaddingRow(0, views::kUnrelatedControlHorizontalSpacing);
- layout->StartRow(0, kFirstColumnSetID);
+ layout->StartRow(0, CONTENT_COLUMN_SET_ID);
views::Label* label = new views::Label(
l10n_util::GetStringUTF16(IDS_BOOKMARK_BUBBLE_TITLE_TEXT));
layout->AddView(label);
@@ -208,28 +233,52 @@
layout->AddPaddingRow(0, views::kUnrelatedControlHorizontalSpacing);
- layout->StartRow(0, kFirstColumnSetID);
+ layout->StartRow(0, CONTENT_COLUMN_SET_ID);
layout->AddView(combobox_label);
layout->AddView(parent_combobox_, 5, 1);
layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
- layout->StartRow(0, kFirstColumnSetID);
+ layout->StartRow(0, CONTENT_COLUMN_SET_ID);
layout->SkipColumns(2);
layout->AddView(remove_button_);
layout->AddView(edit_button_);
layout->AddView(close_button_);
+ layout->AddPaddingRow(
+ 0,
+ views::kUnrelatedControlVerticalSpacing - kControlBorderWidth);
+
+ const CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kEnableBookmarkSyncPromo) &&
+ SyncPromoUI::ShouldShowSyncPromo(profile_)) {
+ // The column layout used for the sync promo.
+ cs = layout->AddColumnSet(SYNC_PROMO_COLUMN_SET_ID);
+ cs->AddColumn(GridLayout::FILL,
+ GridLayout::FILL,
+ 1,
+ GridLayout::USE_PREF,
+ 0,
+ 0);
+ layout->StartRow(0, SYNC_PROMO_COLUMN_SET_ID);
+
+ sync_promo_view_ = new BookmarkSyncPromoView(delegate_.get());
+ layout->AddView(sync_promo_view_);
+ }
+
AddAccelerator(ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE));
}
-BookmarkBubbleView::BookmarkBubbleView(views::View* anchor_view,
- BookmarkBubbleViewObserver* observer,
- Profile* profile,
- const GURL& url,
- bool newly_bookmarked)
+BookmarkBubbleView::BookmarkBubbleView(
+ views::View* anchor_view,
+ BookmarkBubbleViewObserver* observer,
+ scoped_ptr<BookmarkBubbleDelegate> delegate,
+ Profile* profile,
+ const GURL& url,
+ bool newly_bookmarked)
: BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT),
observer_(observer),
+ delegate_(delegate.Pass()),
profile_(profile),
url_(url),
newly_bookmarked_(newly_bookmarked),
@@ -242,13 +291,14 @@
close_button_(NULL),
title_tf_(NULL),
parent_combobox_(NULL),
+ sync_promo_view_(NULL),
remove_bookmark_(false),
apply_edits_(true) {
const SkColor background_color = GetNativeTheme()->GetSystemColor(
ui::NativeTheme::kColorId_DialogBackground);
set_color(background_color);
set_background(views::Background::CreateSolidBackground(background_color));
- set_margins(gfx::Insets(12, 19, 18, 18));
+ set_margins(gfx::Insets(views::kPanelVertMargin, 0, 0, 0));
// Compensate for built-in vertical padding in the anchor view's image.
set_anchor_view_insets(gfx::Insets(7, 0, 7, 0));
}
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h
index da03710..82cdfa9 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h
@@ -7,7 +7,10 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/gtest_prod_util.h"
+#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
+#include "chrome/browser/ui/bookmarks/bookmark_bubble_delegate.h"
#include "chrome/browser/ui/bookmarks/recently_used_folders_combo_model.h"
#include "ui/views/bubble/bubble_delegate.h"
#include "ui/views/controls/button/button.h"
@@ -32,6 +35,7 @@
public:
static void ShowBubble(views::View* anchor_view,
BookmarkBubbleViewObserver* observer,
+ scoped_ptr<BookmarkBubbleDelegate> delegate,
Profile* profile,
const GURL& url,
bool newly_bookmarked);
@@ -56,9 +60,14 @@
virtual void Init() OVERRIDE;
private:
+ friend class BookmarkBubbleViewTest;
+ FRIEND_TEST_ALL_PREFIXES(BookmarkBubbleViewTest, SyncPromoSignedIn);
+ FRIEND_TEST_ALL_PREFIXES(BookmarkBubbleViewTest, SyncPromoNotSignedIn);
+
// Creates a BookmarkBubbleView.
BookmarkBubbleView(views::View* anchor_view,
BookmarkBubbleViewObserver* observer,
+ scoped_ptr<BookmarkBubbleDelegate> delegate,
Profile* profile,
const GURL& url,
bool newly_bookmarked);
@@ -92,6 +101,9 @@
// Our observer, to notify when the bubble shows or hides.
BookmarkBubbleViewObserver* observer_;
+ // Delegate, to handle clicks on the sign in link.
+ scoped_ptr<BookmarkBubbleDelegate> delegate_;
+
// The profile.
Profile* profile_;
@@ -119,6 +131,9 @@
// the current parent.
views::Combobox* parent_combobox_;
+ // Bookmark sync promo view, if displayed.
+ views::View* sync_promo_view_;
+
// When the destructor is invoked should the bookmark be removed?
bool remove_bookmark_;
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc
new file mode 100644
index 0000000..1809017
--- /dev/null
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view_unittest.cc
@@ -0,0 +1,110 @@
+// Copyright 2013 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/ui/views/bookmarks/bookmark_bubble_view.h"
+
+#include <string>
+
+#include "base/command_line.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/bookmarks/bookmark_model_factory.h"
+#include "chrome/browser/bookmarks/bookmark_utils.h"
+#include "chrome/browser/signin/fake_signin_manager.h"
+#include "chrome/browser/signin/signin_manager.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/ui/bookmarks/bookmark_bubble_delegate.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/test/base/browser_with_test_window_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+
+namespace {
+const char kTestBookmarkURL[] = "http://www.google.com";
+} // namespace
+
+class BookmarkBubbleViewTest : public BrowserWithTestWindowTest {
+ public:
+ BookmarkBubbleViewTest() {}
+
+ // testing::Test:
+ virtual void SetUp() OVERRIDE {
+ BrowserWithTestWindowTest::SetUp();
+
+ CommandLine* command_line = CommandLine::ForCurrentProcess();
+ command_line->AppendSwitch(switches::kEnableBookmarkSyncPromo);
+
+ profile()->CreateBookmarkModel(true);
+ ui_test_utils::WaitForBookmarkModelToLoad(profile());
+
+ bookmark_utils::AddIfNotBookmarked(
+ BookmarkModelFactory::GetForProfile(profile()),
+ GURL(kTestBookmarkURL),
+ string16());
+ }
+
+ virtual void TearDown() OVERRIDE {
+ // Make sure the bubble is destroyed before the profile to avoid a crash.
+ bubble_.reset();
+
+ BrowserWithTestWindowTest::TearDown();
+ }
+
+ protected:
+ // Creates a bookmark bubble view.
+ void CreateBubbleView() {
+ scoped_ptr<BookmarkBubbleDelegate> delegate;
+ bubble_.reset(new BookmarkBubbleView(NULL,
+ NULL,
+ delegate.Pass(),
+ profile(),
+ GURL(kTestBookmarkURL),
+ true));
+ }
+
+ void CreateSigninManager(const std::string& username) {
+ SigninManagerBase* signin_manager =
+ static_cast<SigninManagerBase*>(
+ SigninManagerFactory::GetInstance()->SetTestingFactoryAndUse(
+ profile(),
+ &BookmarkBubbleViewTest::BuildFakeSignInManager));
+ signin_manager->Initialize(profile(), NULL);
+
+ if (!username.empty()) {
+ ASSERT_TRUE(signin_manager);
+ signin_manager->SetAuthenticatedUsername(username);
+ }
+ }
+
+ scoped_ptr<BookmarkBubbleView> bubble_;
+
+ private:
+ static BrowserContextKeyedService* BuildFakeSignInManager(
+ content::BrowserContext* profile) {
+#if defined(OS_CHROMEOS)
+ return new FakeSigninManagerBase();
+#else // !defined(OS_CHROMEOS)
+ return new FakeSigninManager(static_cast<Profile*>(profile));
+#endif
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(BookmarkBubbleViewTest);
+};
+
+// Verifies that the sync promo is not displayed for a signed in user.
+TEST_F(BookmarkBubbleViewTest, SyncPromoSignedIn) {
+ CreateSigninManager("fake_username");
+ CreateBubbleView();
+ bubble_->Init();
+ EXPECT_FALSE(bubble_->sync_promo_view_);
+}
+
+// Verifies that the sync promo is displayed for a user that is not signed in.
+TEST_F(BookmarkBubbleViewTest, SyncPromoNotSignedIn) {
+ CreateBubbleView();
+ bubble_->Init();
+#if defined(OS_CHROMEOS)
+ EXPECT_FALSE(bubble_->sync_promo_view_);
+#else // !defined(OS_CHROMEOS)
+ EXPECT_TRUE(bubble_->sync_promo_view_);
+#endif
+}
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_sync_promo_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_sync_promo_view.cc
new file mode 100644
index 0000000..ef722e8
--- /dev/null
+++ b/chrome/browser/ui/views/bookmarks/bookmark_sync_promo_view.cc
@@ -0,0 +1,78 @@
+// Copyright 2013 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/ui/views/bookmarks/bookmark_sync_promo_view.h"
+
+#include "base/strings/string16.h"
+#include "chrome/browser/ui/bookmarks/bookmark_bubble_delegate.h"
+#include "grit/generated_resources.h"
+#include "third_party/skia/include/core/SkColor.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/gfx/font.h"
+#include "ui/views/background.h"
+#include "ui/views/border.h"
+#include "ui/views/controls/styled_label.h"
+#include "ui/views/layout/box_layout.h"
+#include "ui/views/layout/layout_constants.h"
+
+namespace {
+// Background color of the promo.
+const SkColor kBackgroundColor = SkColorSetRGB(245, 245, 245);
+
+// Color of the top border of the promo.
+const SkColor kBorderColor = SkColorSetRGB(229, 229, 229);
+
+// Width of the top border of the promo.
+const int kBorderWidth = 1;
+
+// Color of the text of the promo.
+const SkColor kTextColor = SkColorSetRGB(102, 102, 102);
+
+} // namespace
+
+BookmarkSyncPromoView::BookmarkSyncPromoView(BookmarkBubbleDelegate* delegate)
+ : delegate_(delegate) {
+ set_background(views::Background::CreateSolidBackground(kBackgroundColor));
+ set_border(views::Border::CreateSolidSidedBorder(kBorderWidth,
+ 0,
+ 0,
+ 0,
+ kBorderColor));
+ size_t offset;
+ string16 link_text = l10n_util::GetStringUTF16(IDS_BOOKMARK_SYNC_PROMO_LINK);
+ string16 promo_text = l10n_util::GetStringFUTF16(
+ IDS_BOOKMARK_SYNC_PROMO_MESSAGE,
+ link_text,
+ &offset);
+
+ views::StyledLabel* promo_label = new views::StyledLabel(promo_text, this);
+ promo_label->SetDisplayedOnBackgroundColor(kBackgroundColor);
+
+ views::StyledLabel::RangeStyleInfo link_style =
+ views::StyledLabel::RangeStyleInfo::CreateForLink();
+ link_style.font_style = gfx::Font::NORMAL;
+ promo_label->AddStyleRange(ui::Range(offset, offset + link_text.length()),
+ link_style);
+
+ views::StyledLabel::RangeStyleInfo promo_style;
+ promo_style.color = kTextColor;
+ ui::Range before_link_range(0, offset);
+ if (!before_link_range.is_empty())
+ promo_label->AddStyleRange(before_link_range, promo_style);
+ ui::Range after_link_range(offset + link_text.length(), promo_text.length());
+ if (!after_link_range.is_empty())
+ promo_label->AddStyleRange(after_link_range, promo_style);
+
+ views::BoxLayout* layout = new views::BoxLayout(views::BoxLayout::kVertical,
+ views::kButtonHEdgeMarginNew,
+ views::kPanelVertMargin,
+ 0);
+ SetLayoutManager(layout);
+ AddChildView(promo_label);
+}
+
+void BookmarkSyncPromoView::StyledLabelLinkClicked(const ui::Range& range,
+ int event_flags) {
+ delegate_->OnSignInLinkClicked();
+}
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_sync_promo_view.h b/chrome/browser/ui/views/bookmarks/bookmark_sync_promo_view.h
new file mode 100644
index 0000000..deb37a1
--- /dev/null
+++ b/chrome/browser/ui/views/bookmarks/bookmark_sync_promo_view.h
@@ -0,0 +1,33 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_SYNC_PROMO_VIEW_H_
+#define CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_SYNC_PROMO_VIEW_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "ui/views/controls/styled_label_listener.h"
+#include "ui/views/view.h"
+
+class BookmarkBubbleDelegate;
+
+// Bookmark sync promo displayed at the bottom of the bookmark bubble.
+class BookmarkSyncPromoView : public views::StyledLabelListener,
+ public views::View {
+ public:
+ // |delegate| is not owned by BookmarkSyncPromoView.
+ explicit BookmarkSyncPromoView(BookmarkBubbleDelegate* delegate);
+
+ private:
+ // views::StyledLabelListener:
+ virtual void StyledLabelLinkClicked(const ui::Range& range,
+ int event_flags) OVERRIDE;
+
+ // Delegate, to handle clicks on the sign in link.
+ BookmarkBubbleDelegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(BookmarkSyncPromoView);
+};
+
+#endif // CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_SYNC_PROMO_VIEW_H_
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_sync_promo_view_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_sync_promo_view_unittest.cc
new file mode 100644
index 0000000..34ee686
--- /dev/null
+++ b/chrome/browser/ui/views/bookmarks/bookmark_sync_promo_view_unittest.cc
@@ -0,0 +1,42 @@
+// Copyright 2013 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/ui/views/bookmarks/bookmark_sync_promo_view.h"
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/ui/bookmarks/bookmark_bubble_delegate.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/events/event_constants.h"
+#include "ui/base/range/range.h"
+
+class BookmarkSyncPromoViewTest : public BookmarkBubbleDelegate,
+ public testing::Test {
+ public:
+ BookmarkSyncPromoViewTest() : sign_in_clicked_count_(0) {}
+
+ protected:
+ // BookmarkBubbleDelegate:
+ virtual void OnSignInLinkClicked() OVERRIDE {
+ ++sign_in_clicked_count_;
+ }
+
+ // Number of times that OnSignInLinkClicked has been called.
+ int sign_in_clicked_count_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BookmarkSyncPromoViewTest);
+};
+
+TEST_F(BookmarkSyncPromoViewTest, SignInLink) {
+ scoped_ptr<BookmarkSyncPromoView> sync_promo;
+ sync_promo.reset(new BookmarkSyncPromoView(this));
+
+ // Simulate clicking the "Sign in" link.
+ views::StyledLabelListener* listener = sync_promo.get();
+ listener->StyledLabelLinkClicked(ui::Range(), ui::EF_NONE);
+
+ EXPECT_EQ(1, sign_in_clicked_count_);
+}
diff --git a/chrome/browser/ui/views/browser_dialogs.h b/chrome/browser/ui/views/browser_dialogs.h
index 2dd992e..30d12a5 100644
--- a/chrome/browser/ui/views/browser_dialogs.h
+++ b/chrome/browser/ui/views/browser_dialogs.h
@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_UI_VIEWS_BROWSER_DIALOGS_H_
#define CHROME_BROWSER_UI_VIEWS_BROWSER_DIALOGS_H_
+#include "base/memory/scoped_ptr.h"
#include "ui/gfx/native_widget_types.h"
// This file contains functions for running a variety of browser dialogs and
@@ -14,6 +15,7 @@
// TODO: Make as many of these methods as possible cross platform, and move them
// into chrome/browser/ui/browser_dialogs.h.
+class BookmarkBubbleDelegate;
class BookmarkBubbleViewObserver;
class Browser;
class BrowserView;
@@ -36,6 +38,7 @@
// Shows or hides the bookmark bubble anchored to the supplied view.
void ShowBookmarkBubbleView(views::View* anchor_view,
BookmarkBubbleViewObserver* observer,
+ scoped_ptr<BookmarkBubbleDelegate> delegate,
Profile* profile,
const GURL& url,
bool newly_bookmarked);
diff --git a/chrome/browser/ui/views/collected_cookies_views.cc b/chrome/browser/ui/views/collected_cookies_views.cc
index 4024245..3e602b4 100644
--- a/chrome/browser/ui/views/collected_cookies_views.cc
+++ b/chrome/browser/ui/views/collected_cookies_views.cc
@@ -332,7 +332,7 @@
layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
layout->StartRow(0, single_column_layout_id);
- cookie_info_view_ = new CookieInfoView(false);
+ cookie_info_view_ = new CookieInfoView();
layout->AddView(cookie_info_view_);
layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
diff --git a/chrome/browser/ui/views/cookie_info_view.cc b/chrome/browser/ui/views/cookie_info_view.cc
index ad0bea2..7cef982 100644
--- a/chrome/browser/ui/views/cookie_info_view.cc
+++ b/chrome/browser/ui/views/cookie_info_view.cc
@@ -20,7 +20,6 @@
#include "ui/gfx/canvas.h"
#include "ui/gfx/color_utils.h"
#include "ui/views/border.h"
-#include "ui/views/controls/combobox/combobox.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/layout/grid_layout.h"
@@ -37,7 +36,7 @@
///////////////////////////////////////////////////////////////////////////////
// CookieInfoView, public:
-CookieInfoView::CookieInfoView(bool editable_expiration_date)
+CookieInfoView::CookieInfoView()
: name_label_(NULL),
name_value_field_(NULL),
content_label_(NULL),
@@ -51,11 +50,7 @@
created_label_(NULL),
created_value_field_(NULL),
expires_label_(NULL),
- expires_value_field_(NULL),
- expires_value_combobox_(NULL),
- expire_view_(NULL),
- editable_expiration_date_(editable_expiration_date),
- delegate_(NULL) {
+ expires_value_field_(NULL) {
}
CookieInfoView::~CookieInfoView() {
@@ -74,20 +69,7 @@
base::TimeFormatFriendlyDateAndTime(cookie.ExpiryDate()) :
l10n_util::GetStringUTF16(IDS_COOKIES_COOKIE_EXPIRES_SESSION);
- if (editable_expiration_date_) {
- expire_combo_values_.clear();
- if (cookie.IsPersistent())
- expire_combo_values_.push_back(expire_text);
- expire_combo_values_.push_back(
- l10n_util::GetStringUTF16(IDS_COOKIES_COOKIE_EXPIRES_SESSION));
- expires_value_combobox_->ModelChanged();
- expires_value_combobox_->SetSelectedIndex(0);
- expires_value_combobox_->SetEnabled(true);
- expires_value_combobox_->set_listener(this);
- } else {
- expires_value_field_->SetText(expire_text);
- }
-
+ expires_value_field_->SetText(expire_text);
send_for_value_field_->SetText(cookie.IsSecure() ?
l10n_util::GetStringUTF16(IDS_COOKIES_COOKIE_SENDFOR_SECURE) :
l10n_util::GetStringUTF16(IDS_COOKIES_COOKIE_SENDFOR_ANY));
@@ -112,8 +94,7 @@
path_value_field_->SetText(no_cookie_string);
send_for_value_field_->SetText(no_cookie_string);
created_value_field_->SetText(no_cookie_string);
- if (expires_value_field_)
- expires_value_field_->SetText(no_cookie_string);
+ expires_value_field_->SetText(no_cookie_string);
EnableCookieDisplay(false);
}
@@ -124,8 +105,7 @@
path_value_field_->SetEnabled(enabled);
send_for_value_field_->SetEnabled(enabled);
created_value_field_->SetEnabled(enabled);
- if (expires_value_field_)
- expires_value_field_->SetEnabled(enabled);
+ expires_value_field_->SetEnabled(enabled);
}
///////////////////////////////////////////////////////////////////////////////
@@ -137,25 +117,6 @@
Init();
}
-///////////////////////////////////////////////////////////////////////////////
-// CookieInfoView, views::ComboboxListener overrides.
-
-void CookieInfoView::OnSelectedIndexChanged(views::Combobox* combobox) {
- DCHECK_EQ(combobox, expires_value_combobox_);
- if (delegate_)
- delegate_->ModifyExpireDate(combobox->selected_index() != 0);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// CookieInfoView, ui::ComboboxModel overrides.
-int CookieInfoView::GetItemCount() const {
- return static_cast<int>(expire_combo_values_.size());
-}
-
-string16 CookieInfoView::GetItemAt(int index) {
- return expire_combo_values_[index];
-}
-
void CookieInfoView::AddLabelRow(int layout_id, views::GridLayout* layout,
views::View* label, views::View* value) {
layout->StartRow(0, layout_id);
@@ -206,10 +167,7 @@
created_value_field_ = new views::Textfield;
expires_label_ = new views::Label(
l10n_util::GetStringUTF16(IDS_COOKIES_COOKIE_EXPIRES_LABEL));
- if (editable_expiration_date_)
- expires_value_combobox_ = new views::Combobox(this);
- else
- expires_value_field_ = new views::Textfield;
+ expires_value_field_ = new views::Textfield;
using views::GridLayout;
using views::ColumnSet;
@@ -248,14 +206,8 @@
send_for_value_field_);
AddLabelRow(three_column_layout_id, layout, created_label_,
created_value_field_);
-
- if (editable_expiration_date_) {
- AddControlRow(three_column_layout_id, layout, expires_label_,
- expires_value_combobox_);
- } else {
- AddLabelRow(three_column_layout_id, layout, expires_label_,
- expires_value_field_);
- }
+ AddLabelRow(three_column_layout_id, layout, expires_label_,
+ expires_value_field_);
// Color these borderless text areas the same as the containing dialog.
#if defined(USE_AURA) || !defined(OS_WIN)
@@ -282,9 +234,7 @@
created_value_field_->SetReadOnly(true);
created_value_field_->RemoveBorder();
created_value_field_->SetBackgroundColor(text_area_background);
- if (expires_value_field_) {
- expires_value_field_->SetReadOnly(true);
- expires_value_field_->RemoveBorder();
- expires_value_field_->SetBackgroundColor(text_area_background);
- }
+ expires_value_field_->SetReadOnly(true);
+ expires_value_field_->RemoveBorder();
+ expires_value_field_->SetBackgroundColor(text_area_background);
}
diff --git a/chrome/browser/ui/views/cookie_info_view.h b/chrome/browser/ui/views/cookie_info_view.h
index 82a3de2..bcf9219 100644
--- a/chrome/browser/ui/views/cookie_info_view.h
+++ b/chrome/browser/ui/views/cookie_info_view.h
@@ -11,8 +11,6 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/strings/string16.h"
-#include "ui/base/models/combobox_model.h"
-#include "ui/views/controls/combobox/combobox_listener.h"
#include "ui/views/view.h"
namespace views {
@@ -26,25 +24,12 @@
}
///////////////////////////////////////////////////////////////////////////////
-// CookieInfoViewDelegate
-//
-class CookieInfoViewDelegate {
- public:
- virtual void ModifyExpireDate(bool session_expire) = 0;
-
- protected:
- virtual ~CookieInfoViewDelegate() {}
-};
-
-///////////////////////////////////////////////////////////////////////////////
// CookieInfoView
//
// Responsible for displaying a tabular grid of Cookie information.
-class CookieInfoView : public views::View,
- public views::ComboboxListener,
- public ui::ComboboxModel {
+class CookieInfoView : public views::View {
public:
- explicit CookieInfoView(bool editable_expiration_date);
+ CookieInfoView();
virtual ~CookieInfoView();
// Update the display from the specified CookieNode.
@@ -61,20 +46,11 @@
// Enables or disables the cookie property text fields.
void EnableCookieDisplay(bool enabled);
- void set_delegate(CookieInfoViewDelegate* delegate) { delegate_ = delegate; }
-
protected:
// views::View:
virtual void ViewHierarchyChanged(
const ViewHierarchyChangedDetails& details) OVERRIDE;
- // views::ComboboxListener:
- virtual void OnSelectedIndexChanged(views::Combobox* combobox) OVERRIDE;
-
- // ui::ComboboxModel:
- virtual int GetItemCount() const OVERRIDE;
- virtual string16 GetItemAt(int index) OVERRIDE;
-
private:
// Layout helper routines.
void AddLabelRow(int layout_id, views::GridLayout* layout,
@@ -100,20 +76,6 @@
views::Textfield* created_value_field_;
views::Label* expires_label_;
views::Textfield* expires_value_field_;
- views::Combobox* expires_value_combobox_;
- views::View* expire_view_;
-
- // Option values for expires_value_combobox_.
- std::vector<string16> expire_combo_values_;
-
- // True if expiration date can be edited. In this case we will show
- // expires_value_combobox_ instead of expires_value_field_. The cookie's
- // expiration date is editable only this class is used in
- // CookiesPromptView (alert before cookie is set), in all other cases we
- // don't let user directly change cookie setting.
- bool editable_expiration_date_;
-
- CookieInfoViewDelegate* delegate_;
DISALLOW_COPY_AND_ASSIGN(CookieInfoView);
};
diff --git a/chrome/browser/ui/views/download/download_item_view.cc b/chrome/browser/ui/views/download/download_item_view.cc
index 4977edf..11561a0 100644
--- a/chrome/browser/ui/views/download/download_item_view.cc
+++ b/chrome/browser/ui/views/download/download_item_view.cc
@@ -30,7 +30,7 @@
#include "content/public/browser/download_danger_type.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
-#include "third_party/icu/public/common/unicode/uchar.h"
+#include "third_party/icu/source/common/unicode/uchar.h"
#include "ui/base/accessibility/accessible_view_state.h"
#include "ui/base/animation/slide_animation.h"
#include "ui/base/events/event.h"
@@ -907,7 +907,8 @@
// If |is_mouse_gesture| is false, |p| is ignored. The menu is shown aligned
// to drop down arrow button.
- if (!source_type == ui::MENU_SOURCE_MOUSE) {
+ if (source_type != ui::MENU_SOURCE_MOUSE &&
+ source_type != ui::MENU_SOURCE_TOUCH) {
drop_down_pressed_ = true;
SetState(NORMAL, PUSHED);
point.SetPoint(drop_down_x_left_, box_y_);
diff --git a/chrome/browser/ui/views/extensions/shell_window_frame_view.cc b/chrome/browser/ui/views/extensions/shell_window_frame_view.cc
index c2e0e94..f346e65 100644
--- a/chrome/browser/ui/views/extensions/shell_window_frame_view.cc
+++ b/chrome/browser/ui/views/extensions/shell_window_frame_view.cc
@@ -194,21 +194,19 @@
bool can_ever_resize = frame_->widget_delegate() ?
frame_->widget_delegate()->CanResize() :
false;
- if (can_ever_resize) {
- // Don't allow overlapping resize handles when the window is maximized or
- // fullscreen, as it can't be resized in those states.
- int resize_border =
- frame_->IsMaximized() || frame_->IsFullscreen() ? 0 :
- resize_inside_bounds_size;
- int frame_component = GetHTComponentForFrame(point,
- resize_border,
- resize_border,
- resize_area_corner_size,
- resize_area_corner_size,
- can_ever_resize);
- if (frame_component != HTNOWHERE)
- return frame_component;
- }
+ // Don't allow overlapping resize handles when the window is maximized or
+ // fullscreen, as it can't be resized in those states.
+ int resize_border =
+ (frame_->IsMaximized() || frame_->IsFullscreen()) ? 0 :
+ resize_inside_bounds_size;
+ int frame_component = GetHTComponentForFrame(point,
+ resize_border,
+ resize_border,
+ resize_area_corner_size,
+ resize_area_corner_size,
+ can_ever_resize);
+ if (frame_component != HTNOWHERE)
+ return frame_component;
// Check for possible draggable region in the client area for the frameless
// window.
diff --git a/chrome/browser/ui/views/external_tab_container_win.cc b/chrome/browser/ui/views/external_tab_container_win.cc
index 63e2688..b921b66 100644
--- a/chrome/browser/ui/views/external_tab_container_win.cc
+++ b/chrome/browser/ui/views/external_tab_container_win.cc
@@ -66,9 +66,7 @@
#include "content/public/common/ssl_status.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
-#include "third_party/WebKit/public/platform/WebCString.h"
#include "third_party/WebKit/public/platform/WebReferrerPolicy.h"
-#include "third_party/WebKit/public/platform/WebString.h"
#include "ui/base/events/event_utils.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/menu_model.h"
@@ -93,9 +91,7 @@
using content::RenderViewHost;
using content::SSLStatus;
using content::WebContents;
-using WebKit::WebCString;
using WebKit::WebReferrerPolicy;
-using WebKit::WebString;
namespace {
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 913a417..7e7add1 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -35,6 +35,8 @@
#include "chrome/browser/themes/theme_service_factory.h"
#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h"
+#include "chrome/browser/ui/bookmarks/bookmark_bubble_delegate.h"
+#include "chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.h"
#include "chrome/browser/ui/bookmarks/bookmark_utils.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_command_controller.h"
@@ -66,8 +68,6 @@
#include "chrome/browser/ui/views/frame/browser_view_layout_delegate.h"
#include "chrome/browser/ui/views/frame/contents_container.h"
#include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
-#include "chrome/browser/ui/views/frame/instant_overlay_controller_views.h"
-#include "chrome/browser/ui/views/frame/overlay_container.h"
#include "chrome/browser/ui/views/frame/top_container_view.h"
#include "chrome/browser/ui/views/fullscreen_exit_bubble_views.h"
#include "chrome/browser/ui/views/infobars/infobar_container_view.h"
@@ -399,7 +399,6 @@
contents_web_view_(NULL),
devtools_container_(NULL),
contents_container_(NULL),
- overlay_container_(NULL),
contents_split_(NULL),
devtools_dock_side_(DEVTOOLS_DOCK_SIDE_BOTTOM),
devtools_window_(NULL),
@@ -425,8 +424,6 @@
// Immersive mode may need to reparent views before they are removed/deleted.
immersive_mode_controller_.reset();
- overlay_controller_.reset();
-
browser_->tab_strip_model()->RemoveObserver(this);
#if defined(OS_WIN) && !defined(USE_AURA)
@@ -930,29 +927,6 @@
}
}
-void BrowserView::OnOverlayStateChanged(bool repaint_infobars) {
- Layout();
-
- // |top_container_| paints to a layer when in immersive fullscreen. Paint
- // |overlay_container_| to a layer in this case so that the overlay stays
- // stacked on top of |top_container_| in z-order.
- if (overlay_container_->visible() &&
- immersive_mode_controller_->IsRevealed()) {
- overlay_container_->SetPaintToLayer(true);
- overlay_container_->SetFillsBoundsOpaquely(false);
- }
-
- // When immersive mode is not reveal and infobar container is visible, set top
- // infobar arrow as per overlay state. Layout() needs to happen before
- // GetMaxTopInfoBarArrowHeight() because the latter checks for visibility of
- // overlay_container_| which is determined in Layout().
- if (repaint_infobars &&
- infobar_container_->visible() &&
- !immersive_mode_controller_->IsRevealed()) {
- infobar_container_->SetMaxTopArrowHeight(GetMaxTopInfoBarArrowHeight());
- }
-}
-
LocationBar* BrowserView::GetLocationBar() const {
return GetLocationBarView();
}
@@ -1115,9 +1089,15 @@
}
void BrowserView::ShowBookmarkBubble(const GURL& url, bool already_bookmarked) {
+ scoped_ptr<BookmarkBubbleDelegate> delegate;
+ delegate.reset(new BookmarkBubbleSignInDelegate(browser_.get()));
+
chrome::ShowBookmarkBubbleView(GetToolbarView()->GetBookmarkBubbleAnchor(),
- bookmark_bar_view_.get(), browser_->profile(),
- url, !already_bookmarked);
+ bookmark_bar_view_.get(),
+ delegate.Pass(),
+ browser_->profile(),
+ url,
+ !already_bookmarked);
}
void BrowserView::ShowBookmarkPrompt() {
@@ -1190,8 +1170,6 @@
void BrowserView::WebContentsFocused(WebContents* contents) {
if (contents_web_view_->GetWebContents() == contents)
contents_web_view_->OnWebContentsFocused(contents);
- else if (overlay_container_->overlay_web_contents() == contents)
- overlay_controller_->overlay()->OnWebContentsFocused(contents);
else
devtools_container_->OnWebContentsFocused(contents);
}
@@ -1405,15 +1383,6 @@
int reason) {
DCHECK(new_contents);
- // See if the Instant overlay is being activated (committed).
- if (overlay_container_->overlay_web_contents() == new_contents) {
- MakeOverlayContentsActiveContents();
- views::WebView* old_container = contents_web_view_;
- contents_web_view_ = overlay_controller_->release_overlay();
- old_container->SetWebContents(NULL);
- delete old_container;
- }
-
// If |contents_container_| already has the correct WebContents, we can save
// some work. This also prevents extra events from being reported by the
// Visibility API under Windows, as ChangeWebContents will briefly hide
@@ -1906,6 +1875,10 @@
tabstrip_->SetImmersiveStyle(immersive);
}
+WebContents* BrowserView::GetWebContents() {
+ return GetActiveWebContents();
+}
+
///////////////////////////////////////////////////////////////////////////////
// BrowserView, InfoBarContainer::Delegate overrides:
@@ -2018,17 +1991,9 @@
find_bar_host_view_ = new View();
AddChildView(find_bar_host_view_);
- overlay_container_ =
- new OverlayContainer(this, immersive_mode_controller_.get());
- overlay_container_->SetVisible(false);
- AddChildView(overlay_container_);
-
if (window_switcher_button_)
AddChildView(window_switcher_button_);
- overlay_controller_.reset(
- new InstantOverlayControllerViews(browser(), overlay_container_));
-
immersive_mode_controller_->Init(this, GetWidget(), top_container_);
BrowserViewLayout* browser_view_layout = new BrowserViewLayout;
@@ -2041,7 +2006,6 @@
infobar_container_,
contents_split_,
contents_container_,
- overlay_container_,
immersive_mode_controller_.get());
SetLayoutManager(browser_view_layout);
@@ -2694,39 +2658,11 @@
AppModalDialogQueue::GetInstance()->ActivateModalDialog();
}
-void BrowserView::MakeOverlayContentsActiveContents() {
- views::WebView* overlay = overlay_controller_->overlay();
- DCHECK_EQ(overlay_container_, overlay->parent());
- overlay_container_->ResetOverlayAndContents();
-
- // |overlay|'s current parent is |OverlayContainer|, and will be reparented
- // to |ContentsContainer|. |overlay|'s height is either same as
- // |contents_web_view_| or taller when it appears over the attached bookmark
- // and/or info bars. The latter means it's also taller than the parent's
- // height since |contents_web_view_|'s max height is the parent's height.
- // Reparenting this taller overlay will force a clip to be installed on it;
- // on ChromeOS, this results in a call into not-implemented
- // views::NativeViewHostAura::InstallClip(). So set the bounds of |overlay|
- // to same as |contents_web_view_| before reparenting.
- // Note:
- // - |overlay|'s origin is not (0,0), so just resizing it without changing the
- // origin may still result in the undesired clipping
- // - there won't be extra repositioning or resizing of |overlay| since its new
- // bounds will be unchanged in ContentsContainer::Layout().
- if (overlay->bounds().bottom() > contents_container_->height())
- overlay->SetBoundsRect(contents_web_view_->bounds());
- contents_container_->AddChildView(overlay);
- contents_container_->SetActive(overlay);
-
- // Overlay is gone, force re-layout of |BrowserView| and infobars.
- OnOverlayStateChanged(true);
-}
-
int BrowserView::GetMaxTopInfoBarArrowHeight() {
int top_arrow_height = 0;
- // Only show the arrows when not in fullscreen and when there's no overlay
- // and no omnibox popup.
- if (!IsFullscreen() && !overlay_container_->visible() &&
+ // Only show the arrows when not in fullscreen and when there's no omnibox
+ // popup.
+ if (!IsFullscreen() &&
!GetLocationBar()->GetLocationEntry()->model()->popup_model()->IsOpen()) {
const LocationIconView* location_icon_view =
toolbar_->location_bar()->location_icon_view();
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index 2da4edc..6d0c871 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -48,9 +48,7 @@
class DownloadShelfView;
class FullscreenExitBubbleViews;
class InfoBarContainerView;
-class InstantOverlayControllerViews;
class LocationBarView;
-class OverlayContainer;
class StatusBubbleViews;
class SearchViewController;
class TabStrip;
@@ -257,10 +255,6 @@
// animations.
void ToolbarSizeChanged(bool is_animating);
- // Called from OverlayContainer::SetOverlay() when overlay is to be shown,
- // expanded or hidden. Set |repaint_infobars| to true to repaint infobars.
- void OnOverlayStateChanged(bool repaint_infobars);
-
#if defined(USE_ASH)
// Test support.
// Note: This is only needed to be BrowserLauncherItemController instead of
@@ -441,6 +435,7 @@
virtual FullscreenController* GetFullscreenController() OVERRIDE;
virtual void FullscreenStateChanged() OVERRIDE;
virtual void SetImmersiveStyle(bool immersive) OVERRIDE;
+ virtual content::WebContents* GetWebContents() OVERRIDE;
// InfoBarContainer::Delegate overrides
virtual SkColor GetInfoBarSeparatorColor() const OVERRIDE;
@@ -473,9 +468,6 @@
ContentsContainer* GetContentsContainerForTest() {
return contents_container_;
}
- OverlayContainer* GetOverlayContainerForTest() {
- return overlay_container_;
- }
views::WebView* GetContentsWebViewForTest() { return contents_web_view_; }
private:
@@ -609,11 +601,6 @@
// an existing showing one to the front.
void ActivateAppModalDialog() const;
- // Called when overlay is committed, i.e. made the active contents, where
- // the overlay is reparented from |overlay_container_| to
- // |contents_container_|.
- void MakeOverlayContentsActiveContents();
-
// Returns the max top arrow height for infobar.
int GetMaxTopInfoBarArrowHeight();
@@ -636,16 +623,9 @@
// | | Navigation buttons, address bar, menu (toolbar_) | |
// | -------------------------------------------------------------- |
// |------------------------------------------------------------------|
- // | OverlayContainer (overlay_container_) [1] |
- // | -------------------------------------------------------------- |
- // | | overlay_controller_->overlay_ | |
- // | |------------------------------------------------------------| |
- // | | overlay drop shadow if overlay is partial-height | |
- // | -------------------------------------------------------------- |
+ // | All infobars (infobar_container_) [1] |
// |------------------------------------------------------------------|
- // | All infobars (infobar_container_) [2] |
- // |------------------------------------------------------------------|
- // | Bookmarks (bookmark_bar_view_) [2] |
+ // | Bookmarks (bookmark_bar_view_) [1] |
// |------------------------------------------------------------------|
// | Debugger splitter (contents_split_) |
// | -------------------------------------------------------------- |
@@ -662,17 +642,14 @@
// | Active downloads (download_shelf_) |
// --------------------------------------------------------------------
//
- // [1] Overlay container is only visible when there's an overlay; it is
- // directly below the toolbar in the y-axis, and appears on top the
- // attached bookmark and/or info bars.
- // [2] The bookmark bar and info bar are swapped when on the new tab page.
- // Additionally contents_container_ is positioned on top of the bookmark
- // bar when the bookmark bar is detached. This is done to allow the
- // overlay_controller_->overlay_ to appear over the bookmark bar.
+ // [1] The bookmark bar and info bar are swapped when on the new tab page.
+ // Additionally when the bookmark bar is detached, contents_container_ is
+ // positioned on top of the bar while the tab's contents are placed below
+ // the bar. This allows the find bar to always align with the top of
+ // contents_container_ regardless if there's bookmark or info bars.
// The view that manages the tab strip, toolbar, and sometimes the bookmark
- // bar. Stacked second in the view hiearachy behind |overlay_container_|
- // (refer to comments for |overlay_container_|) so it can be used to slide out
+ // bar. Stacked top in the view hiearachy so it can be used to slide out
// the top views in immersive fullscreen.
TopContainerView* top_container_;
@@ -711,11 +688,6 @@
// The view managing the |contents_web_view_|.
ContentsContainer* contents_container_;
- // The view managing the |overlay_controller_->overlay_| and, if necessary,
- // a drop shadow below the overlay in the y-axis. Stacked at the top of the
- // view hiearachy so it can appear over attached bookmark and/or info bars.
- OverlayContainer* overlay_container_;
-
// Split view containing the contents container and devtools container.
views::SingleSplitView* contents_split_;
@@ -790,8 +762,6 @@
gfx::ScopedSysColorChangeListener color_change_listener_;
- scoped_ptr<InstantOverlayControllerViews> overlay_controller_;
-
mutable base::WeakPtrFactory<BrowserView> activate_modal_dialog_factory_;
DISALLOW_COPY_AND_ASSIGN(BrowserView);
diff --git a/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc b/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc
index 4440fcf..e225c63 100644
--- a/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc
@@ -15,7 +15,6 @@
#include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
#include "chrome/browser/ui/views/frame/contents_container.h"
#include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
-#include "chrome/browser/ui/views/frame/overlay_container.h"
#include "chrome/browser/ui/views/frame/top_container_view.h"
#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
#include "chrome/browser/ui/views/tabs/tab.h"
@@ -69,221 +68,3 @@
// Focus is released from the location bar.
EXPECT_FALSE(location_bar_view->Contains(focus_manager->GetFocusedView()));
}
-
-//////////////////////////////////////////////////////////////////////////////
-
-#if defined(HTML_INSTANT_EXTENDED_POPUP)
-class BrowserViewInstantExtendedTest : public InProcessBrowserTest,
- public InstantTestBase {
- public:
- BrowserViewInstantExtendedTest() {}
- virtual ~BrowserViewInstantExtendedTest() {}
-
- virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
- chrome::EnableInstantExtendedAPIForTesting();
- ASSERT_TRUE(https_test_server().Start());
- GURL instant_url = https_test_server().GetURL(
- "files/instant_extended.html?strk=1&");
- InstantTestBase::Init(instant_url);
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(BrowserViewInstantExtendedTest);
-};
-
-IN_PROC_BROWSER_TEST_F(BrowserViewInstantExtendedTest,
- InstantExtendedForOverlay) {
- BookmarkBarView::DisableAnimationsForTesting(true);
-
- BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
- ContentsContainer* contents_container =
- browser_view->GetContentsContainerForTest();
- OverlayContainer* overlay_container =
- browser_view->GetOverlayContainerForTest();
-
- // Start up instant.
- ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
-
- // Enable attached bookmark bar.
- BookmarkBarView* bookmark_bar = browser_view->GetBookmarkBarView();
- chrome::ExecuteCommand(browser(), IDC_SHOW_BOOKMARK_BAR);
- EXPECT_TRUE(bookmark_bar->visible());
- EXPECT_FALSE(bookmark_bar->IsDetached());
-
- // Overlay container is invisible but at front of view hierarchy.
- EXPECT_FALSE(overlay_container->visible());
- EXPECT_EQ(browser_view->child_count() - 1,
- browser_view->GetIndexOf(overlay_container));
-
- ////////////////////////////////////////////////////////////////////////////
- // Test suggestions on a normal web page, which are in an overlay.
-
- // Focus omnibox, which constructs an overlay web contents.
- FocusOmniboxAndWaitForInstantOverlayAndNTPSupport();
- // Typing in the omnibox should show suggestions in an overlay view.
- SetOmniboxTextAndWaitForOverlayToShow("santa");
- EXPECT_TRUE(instant()->model()->mode().is_search_suggestions());
-
- views::WebView* overlay = overlay_container->GetOverlayWebViewForTest();
- content::WebContents* overlay_contents = overlay->web_contents();
-
- // Overlay container is still at front, but is now visible and has an overlay.
- EXPECT_EQ(browser_view->child_count() - 1,
- browser_view->GetIndexOf(overlay_container));
- EXPECT_TRUE(overlay_container->visible());
- EXPECT_EQ(overlay_container, overlay->parent());
-
- // Content area is still immediately below the visible attached bookmark bar.
- EXPECT_TRUE(bookmark_bar->visible());
- EXPECT_EQ(GetRectInWidget(bookmark_bar).bottom(),
- GetRectInWidget(browser_view->GetContentsWebViewForTest()).y());
-
- // Overlay web view (with suggestions) aligns with the bottom of the toolbar.
- gfx::Rect overlay_rect_in_widget = GetRectInWidget(
- overlay_container->GetOverlayWebViewForTest());
- EXPECT_EQ(GetRectInWidget(browser_view->toolbar()).bottom(),
- overlay_rect_in_widget.y());
-
- // Commit the search by pressing Enter.
- browser_view->GetLocationBar()->AcceptInput();
-
- // Overlay is reparented to and becomes active in ContentsContainer with the
- // same web contents, which is the active contents in browser, while overlay
- // container is childless and invisible.
- EXPECT_EQ(contents_container, overlay->parent());
- EXPECT_EQ(overlay, contents_container->GetActiveWebViewForTest());
- EXPECT_EQ(overlay_contents, overlay->web_contents());
- EXPECT_EQ(overlay_contents,
- browser()->tab_strip_model()->GetActiveWebContents());
- EXPECT_EQ(1, contents_container->child_count());
- EXPECT_EQ(0, overlay_container->child_count());
- EXPECT_FALSE(overlay_container->visible());
-
- BookmarkBarView::DisableAnimationsForTesting(false);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-// Immersive fullscreen is currently enabled only on Chrome OS.
-#if defined(OS_CHROMEOS)
-
-class BrowserViewImmersiveInstantExtendedTest : public InProcessBrowserTest,
- public InstantTestBase {
- public:
- BrowserViewImmersiveInstantExtendedTest() {}
- virtual ~BrowserViewImmersiveInstantExtendedTest() {}
-
- virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
- ImmersiveFullscreenConfiguration::EnableImmersiveFullscreenForTest();
- chrome::EnableInstantExtendedAPIForTesting();
- ASSERT_TRUE(https_test_server().Start());
- GURL instant_url = https_test_server().GetURL(
- "files/instant_extended.html?strk=1&");
- InstantTestBase::Init(instant_url);
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(BrowserViewImmersiveInstantExtendedTest);
-};
-
-IN_PROC_BROWSER_TEST_F(BrowserViewImmersiveInstantExtendedTest,
- ImmersiveInstantExtended) {
- ui::ScopedAnimationDurationScaleMode zero_duration_mode(
- ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
- BookmarkBarView::DisableAnimationsForTesting(true);
-
- // Cache some pointers we'll need below.
- BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
- ToolbarView* toolbar = browser_view->toolbar();
-
- // Start up both instant and immersive fullscreen.
- ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
- ASSERT_TRUE(ImmersiveFullscreenConfiguration::UseImmersiveFullscreen());
- chrome::ToggleFullscreenMode(browser());
- ASSERT_TRUE(browser_view->IsFullscreen());
- ASSERT_TRUE(browser_view->immersive_mode_controller()->IsEnabled());
-
- ////////////////////////////////////////////////////////////////////////////
- // Test suggestions on a normal web page, which are in an overlay.
-
- // Focus omnibox, which constructs an overlay web contents.
- FocusOmniboxAndWaitForInstantOverlayAndNTPSupport();
- EXPECT_TRUE(instant()->model()->mode().is_default());
- // The above testing code doesn't trigger the views location bar focus path,
- // so force it to happen explicitly.
- browser_view->SetFocusToLocationBar(false);
- EXPECT_TRUE(browser_view->immersive_mode_controller()->IsRevealed());
- // Content area is immediately below the tab indicators.
- views::WebView* contents_web_view =
- browser_view->GetContentsWebViewForTest();
- EXPECT_EQ(GetRectInWidget(browser_view).y() + Tab::GetImmersiveHeight(),
- GetRectInWidget(contents_web_view).y());
-
- // Typing in the omnibox should show suggestions in an overlay view.
- SetOmniboxTextAndWaitForOverlayToShow("santa");
- EXPECT_TRUE(instant()->model()->mode().is_search_suggestions());
- // Content area is still immediately below the tab indicators.
- EXPECT_EQ(GetRectInWidget(browser_view).y() + Tab::GetImmersiveHeight(),
- GetRectInWidget(contents_web_view).y());
- // Overlay web view (with suggestions) aligns with the bottom of the omnibox.
- OverlayContainer* overlay_container =
- browser_view->GetOverlayContainerForTest();
- gfx::Rect overlay_rect_in_widget = GetRectInWidget(
- overlay_container->GetOverlayWebViewForTest());
- EXPECT_EQ(GetRectInWidget(toolbar).bottom(), overlay_rect_in_widget.y());
-
- // Overlay container layer is on top of top container layer, so that it
- // paints over the bookmark bar and bottom of toolbar.
- ui::Layer* top_container_layer = browser_view->top_container()->layer();
- if (top_container_layer != NULL) {
- ui::Layer* overlay_container_layer = overlay_container->layer();
- EXPECT_TRUE(overlay_container_layer != NULL);
- if (overlay_container_layer && overlay_container_layer->parent()) {
- const std::vector<ui::Layer*>& children =
- overlay_container_layer->parent()->children();
- size_t top_index =
- std::find(children.begin(), children.end(), top_container_layer) -
- children.begin();
- size_t overlay_index =
- std::find(children.begin(), children.end(), overlay_container_layer) -
- children.begin();
- EXPECT_TRUE(overlay_index > top_index);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////
- // Test suggestions on the NTP, which are not in an overlay.
-
- // Navigate to the Instant NTP, and wait for it to be recognized.
- content::WindowedNotificationObserver instant_tab_observer(
- chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
- content::NotificationService::AllSources());
- ui_test_utils::NavigateToURLWithDisposition(browser(),
- GURL(chrome::kChromeUINewTabURL),
- CURRENT_TAB,
- ui_test_utils::BROWSER_TEST_NONE);
- instant_tab_observer.Wait();
-
- // Type in the omnibox, which should generate suggestions in the main page
- // contents.
- SetOmniboxText("claus");
- while (!omnibox()->model()->autocomplete_controller()->done()) {
- content::WindowedNotificationObserver autocomplete_observer(
- chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY,
- content::NotificationService::AllSources());
- autocomplete_observer.Wait();
- }
- // Ensure JavaScript has finished running by executing a blank script.
- EXPECT_TRUE(ExecuteScript(std::string()));
- // We're still revealed, since focus is in the omnibox.
- EXPECT_TRUE(browser_view->immersive_mode_controller()->IsRevealed());
- // The active web contents are aligned with the toolbar.
- gfx::Rect web_view_rect_in_widget = GetRectInWidget(
- browser_view->GetContentsContainerForTest()->GetActiveWebViewForTest());
- EXPECT_EQ(GetRectInWidget(toolbar).bottom(), web_view_rect_in_widget.y());
-
- BookmarkBarView::DisableAnimationsForTesting(false);
-}
-
-#endif // defined(OS_CHROMEOS)
-#endif // defined(HTML_INSTANT_EXTENDED_POPUP)
diff --git a/chrome/browser/ui/views/frame/browser_view_layout.cc b/chrome/browser/ui/views/frame/browser_view_layout.cc
index a015739..0a936d2 100644
--- a/chrome/browser/ui/views/frame/browser_view_layout.cc
+++ b/chrome/browser/ui/views/frame/browser_view_layout.cc
@@ -19,7 +19,6 @@
#include "chrome/browser/ui/views/frame/browser_view_layout_delegate.h"
#include "chrome/browser/ui/views/frame/contents_container.h"
#include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
-#include "chrome/browser/ui/views/frame/overlay_container.h"
#include "chrome/browser/ui/views/frame/top_container_view.h"
#include "chrome/browser/ui/views/fullscreen_exit_bubble_views.h"
#include "chrome/browser/ui/views/infobars/infobar_container_view.h"
@@ -127,7 +126,6 @@
infobar_container_(NULL),
contents_split_(NULL),
contents_container_(NULL),
- overlay_container_(NULL),
download_shelf_(NULL),
immersive_mode_controller_(NULL),
dialog_host_(new WebContentsModalDialogHostViews(this)),
@@ -146,7 +144,6 @@
InfoBarContainerView* infobar_container,
views::View* contents_split,
ContentsContainer* contents_container,
- OverlayContainer* overlay_container,
ImmersiveModeController* immersive_mode_controller) {
delegate_.reset(delegate);
browser_ = browser;
@@ -157,7 +154,6 @@
infobar_container_ = infobar_container;
contents_split_ = contents_split;
contents_container_ = contents_container;
- overlay_container_ = overlay_container;
immersive_mode_controller_ = immersive_mode_controller;
}
@@ -339,15 +335,6 @@
}
top = LayoutToolbar(top);
- // Overlay container requires updated toolbar bounds to determine its
- // position, and needs to be laid out before:
- // - GetTopMarginForActiveContent(), which calls GetInstantUIState() to check
- // if overlay container is visible
- // - LayoutInfoBar(): children of infobar container will layout and call
- // BrowserView::DrawInfoBarArrows(), which checks if overlay container is
- // visible.
- LayoutOverlayContainer();
-
top = LayoutBookmarkAndInfoBars(top, browser_view->y());
// Top container requires updated toolbar and bookmark bar to compute bounds.
@@ -356,16 +343,11 @@
int bottom = LayoutDownloadShelf(browser_view->height());
// Treat a detached bookmark bar as if the web contents container is shifted
// upwards and overlaps it.
- top -= GetContentsOffsetForBookmarkBar();
+ int active_top_margin = GetContentsOffsetForBookmarkBar();
+ contents_container_->SetActiveTopMargin(active_top_margin);
+ top -= active_top_margin;
LayoutContentsSplitView(top, bottom);
- // Instant extended can put suggestions in a web view, which can require an
- // offset to align with the omnibox. This offset must be recomputed after
- // split view layout to account for infobar heights.
- int active_top_margin = GetTopMarginForActiveContent();
- if (contents_container_->SetActiveTopMargin(active_top_margin))
- contents_container_->Layout();
-
// This must be done _after_ we lay out the WebContents since this
// code calls back into us to find the bounding box the find bar
// must be laid out within, and that code depends on the
@@ -532,29 +514,6 @@
contents_split_->SetBoundsRect(contents_split_bounds);
}
-void BrowserViewLayout::LayoutOverlayContainer() {
- bool full_height = overlay_container_->IsOverlayFullHeight();
- int preferred_height = 0;
- if (!full_height)
- preferred_height = overlay_container_->GetPreferredSize().height();
- overlay_container_->SetVisible(full_height || preferred_height > 0);
- if (!overlay_container_->visible())
- return;
- gfx::Point bottom_edge(0, toolbar_->bounds().bottom());
- views::View::ConvertPointToTarget(
- toolbar_->parent(), browser_view_, &bottom_edge);
- // Overlaps with the toolbar like the attached bookmark bar would, so as to
- // completely obscure the attached bookmark bar if it were visible.
- bottom_edge.Offset(0,
- -(views::NonClientFrameView::kClientEdgeThickness +
- BookmarkBarView::kToolbarAttachedBookmarkBarOverlap));
- gfx::Rect rect(vertical_layout_rect_);
- rect.Inset(0, bottom_edge.y(), 0, 0);
- if (!full_height && preferred_height < rect.height())
- rect.set_height(preferred_height);
- overlay_container_->SetBoundsRect(rect);
-}
-
void BrowserViewLayout::UpdateTopContainerBounds() {
gfx::Rect top_container_bounds(top_container_->GetPreferredSize());
@@ -584,48 +543,6 @@
bookmark_bar_->GetFullyDetachedToolbarOverlap();
}
-int BrowserViewLayout::GetTopMarginForActiveContent() {
- // During an immersive reveal, if instant extended is showing suggestions
- // in the main active web view, ensure that active web view appears aligned
- // with the bottom of the omnibox.
- InstantUIState instant_ui_state = GetInstantUIState();
- if (instant_ui_state == kInstantUIFullPageResults &&
- immersive_mode_controller_->IsRevealed())
- return GetTopMarginForImmersiveInstant();
-
- // Usually we only use a margin if there's a detached bookmarks bar.
- return GetContentsOffsetForBookmarkBar();
-}
-
-int BrowserViewLayout::GetTopMarginForImmersiveInstant() {
- // Compute the position of the bottom edge of the top container views,
- // expressed as an offset in the coordinates of |contents_container_|,
- // because the offset will be applied in |contents_container_| layout.
- // NOTE: This requires contents_split_ layout to be complete, as the
- // coordinate system conversion depends on the contents_split_ origin.
- gfx::Point bottom_edge(0, top_container_->height());
- views::View::ConvertPointToTarget(top_container_,
- contents_container_,
- &bottom_edge);
- return bottom_edge.y();
-}
-
-BrowserViewLayout::InstantUIState BrowserViewLayout::GetInstantUIState() {
- if (!browser()->search_model()->mode().is_search())
- return kInstantUINone;
-
- // If the search suggestions are already being displayed in the overlay
- // contents then return kInstantUIOverlay.
- if (overlay_container_->visible())
- return kInstantUIOverlay;
-
- // Top bars stay visible until the results page notifies Chrome it is ready.
- if (browser()->search_model()->top_bars_visible())
- return kInstantUINone;
-
- return kInstantUIFullPageResults;
-}
-
int BrowserViewLayout::LayoutDownloadShelf(int bottom) {
if (delegate_->DownloadShelfNeedsLayout()) {
bool visible = browser()->SupportsWindowFeature(
diff --git a/chrome/browser/ui/views/frame/browser_view_layout.h b/chrome/browser/ui/views/frame/browser_view_layout.h
index c0e8287..dd64a40 100644
--- a/chrome/browser/ui/views/frame/browser_view_layout.h
+++ b/chrome/browser/ui/views/frame/browser_view_layout.h
@@ -19,7 +19,6 @@
class ContentsContainer;
class ImmersiveModeController;
class InfoBarContainerView;
-class OverlayContainer;
class TabContentsContainer;
class TabStrip;
@@ -56,7 +55,6 @@
InfoBarContainerView* infobar_container,
views::View* contents_split,
ContentsContainer* contents_container,
- OverlayContainer* overlay_container,
ImmersiveModeController* immersive_mode_controller);
// Sets or updates views that are not available when |this| is initialized.
@@ -98,16 +96,6 @@
FRIEND_TEST_ALL_PREFIXES(BrowserViewLayoutTest, LayoutDownloadShelf);
class WebContentsModalDialogHostViews;
- enum InstantUIState {
- // No instant suggestions are being shown.
- kInstantUINone,
- // Instant suggestions are displayed in a overlay overlapping the tab
- // contents.
- kInstantUIOverlay,
- // Instant suggestions are displayed in the main tab contents.
- kInstantUIFullPageResults,
- };
-
Browser* browser() { return browser_; }
// Layout the tab strip region, returns the coordinate of the bottom of the
@@ -126,9 +114,6 @@
// |contents_split_| and other views.
void LayoutContentsSplitView(int top, int bottom);
- // Layout the |overlay_container_| view below the toolbar.
- void LayoutOverlayContainer();
-
// Updates |top_container_|'s bounds. The new bounds depend on the size of
// the bookmark bar and the toolbar.
void UpdateTopContainerBounds();
@@ -142,14 +127,6 @@
// preview contents hides the bookmark bar.
int GetTopMarginForActiveContent();
- // Returns the top margin for the active or overlay web view in
- // |contents_container_| for an immersive fullscreen reveal while instant
- // extended is providing suggestions.
- int GetTopMarginForImmersiveInstant();
-
- // Returns the state of instant extended suggestions.
- InstantUIState GetInstantUIState();
-
// Layout the Download Shelf, returns the coordinate of the top of the
// control, for laying out the previous control.
int LayoutDownloadShelf(int bottom);
@@ -177,7 +154,6 @@
InfoBarContainerView* infobar_container_;
views::View* contents_split_;
ContentsContainer* contents_container_;
- OverlayContainer* overlay_container_;
views::View* download_shelf_;
ImmersiveModeController* immersive_mode_controller_;
diff --git a/chrome/browser/ui/views/frame/browser_view_layout_unittest.cc b/chrome/browser/ui/views/frame/browser_view_layout_unittest.cc
index 104c403..09226ba 100644
--- a/chrome/browser/ui/views/frame/browser_view_layout_unittest.cc
+++ b/chrome/browser/ui/views/frame/browser_view_layout_unittest.cc
@@ -8,7 +8,6 @@
#include "chrome/browser/ui/views/frame/browser_view_layout_delegate.h"
#include "chrome/browser/ui/views/frame/contents_container.h"
#include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
-#include "chrome/browser/ui/views/frame/overlay_container.h"
#include "chrome/browser/ui/views/infobars/infobar_container_view.h"
#include "chrome/browser/ui/views/tabs/tab_strip.h"
#include "chrome/test/base/browser_with_test_window_test.h"
@@ -134,7 +133,6 @@
infobar_container_(NULL),
contents_split_(NULL),
contents_container_(NULL),
- overlay_container_(NULL),
active_web_view_(NULL) {}
virtual ~BrowserViewLayoutTest() {}
@@ -163,10 +161,6 @@
top_container_->AddChildView(toolbar_);
root_view_->AddChildView(top_container_);
- overlay_container_ =
- new OverlayContainer(NULL, immersive_mode_controller_.get());
- root_view_->AddChildView(overlay_container_);
-
infobar_container_ = new InfoBarContainerView(NULL);
root_view_->AddChildView(infobar_container_);
@@ -188,7 +182,6 @@
infobar_container_,
contents_split_,
contents_container_,
- overlay_container_,
immersive_mode_controller_.get());
}
@@ -204,7 +197,6 @@
InfoBarContainerView* infobar_container_;
MockView* contents_split_;
ContentsContainer* contents_container_;
- OverlayContainer* overlay_container_;
MockView* active_web_view_;
scoped_ptr<MockImmersiveModeController> immersive_mode_controller_;
@@ -216,7 +208,6 @@
TEST_F(BrowserViewLayoutTest, BrowserViewLayout) {
EXPECT_TRUE(layout()->browser());
EXPECT_TRUE(layout()->GetWebContentsModalDialogHost());
- EXPECT_EQ(BrowserViewLayout::kInstantUINone, layout()->GetInstantUIState());
EXPECT_FALSE(layout()->InfobarVisible());
}
diff --git a/chrome/browser/ui/views/frame/browser_view_unittest.cc b/chrome/browser/ui/views/frame/browser_view_unittest.cc
index c140e6b..8bb3377 100644
--- a/chrome/browser/ui/views/frame/browser_view_unittest.cc
+++ b/chrome/browser/ui/views/frame/browser_view_unittest.cc
@@ -15,7 +15,6 @@
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
#include "chrome/browser/ui/views/frame/browser_view_layout.h"
-#include "chrome/browser/ui/views/frame/overlay_container.h"
#include "chrome/browser/ui/views/frame/top_container_view.h"
#include "chrome/browser/ui/views/infobars/infobar_container_view.h"
#include "chrome/browser/ui/views/tabs/tab_strip.h"
@@ -172,8 +171,6 @@
browser_view()->GetContentsSplitForTest();
views::WebView* contents_web_view =
browser_view()->GetContentsWebViewForTest();
- OverlayContainer* overlay_container =
- browser_view()->GetOverlayContainerForTest();
// Start with a single tab open to a normal page.
AddTab(browser, GURL("about:blank"));
@@ -183,15 +180,12 @@
EXPECT_EQ(top_container, browser_view()->toolbar()->parent());
EXPECT_EQ(top_container, browser_view()->GetBookmarkBarView()->parent());
EXPECT_EQ(browser_view(), browser_view()->infobar_container()->parent());
- EXPECT_EQ(browser_view(), overlay_container->parent());
- // Overlay container is at the front of the view hierarchy, followed by the
- // find bar host and the top container.
+ // Find bar host is at the front of the view hierarchy, followed by the top
+ // container.
EXPECT_EQ(browser_view()->child_count() - 1,
- browser_view()->GetIndexOf(overlay_container));
- EXPECT_EQ(browser_view()->child_count() - 2,
browser_view()->GetIndexOf(browser_view()->find_bar_host_view()));
- EXPECT_EQ(browser_view()->child_count() - 3,
+ EXPECT_EQ(browser_view()->child_count() - 2,
browser_view()->GetIndexOf(top_container));
// Verify basic layout.
@@ -230,13 +224,11 @@
EXPECT_TRUE(bookmark_bar->visible());
EXPECT_TRUE(bookmark_bar->IsDetached());
EXPECT_EQ(browser_view(), bookmark_bar->parent());
- // Overlay container is still at the front of the view hierarchy, followed by
- // the find bar host and the top container.
+ // Find bar host is still at the front of the view hierarchy, followed by
+ // the top container.
EXPECT_EQ(browser_view()->child_count() - 1,
- browser_view()->GetIndexOf(overlay_container));
- EXPECT_EQ(browser_view()->child_count() - 2,
browser_view()->GetIndexOf(browser_view()->find_bar_host_view()));
- EXPECT_EQ(browser_view()->child_count() - 3,
+ EXPECT_EQ(browser_view()->child_count() - 2,
browser_view()->GetIndexOf(top_container));
// Bookmark bar layout on NTP.
@@ -260,8 +252,8 @@
EXPECT_FALSE(bookmark_bar->visible());
EXPECT_FALSE(bookmark_bar->IsDetached());
EXPECT_EQ(top_container, bookmark_bar->parent());
- // Top container is still third from front.
- EXPECT_EQ(browser_view()->child_count() - 3,
+ // Top container is still second from front.
+ EXPECT_EQ(browser_view()->child_count() - 2,
browser_view()->GetIndexOf(top_container));
BookmarkBarView::DisableAnimationsForTesting(false);
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller.h b/chrome/browser/ui/views/frame/immersive_mode_controller.h
index f8f23de..f4a504b 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller.h
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller.h
@@ -11,6 +11,10 @@
class BookmarkBarView;
class FullscreenController;
+namespace content {
+class WebContents;
+}
+
namespace gfx {
class Rect;
class Size;
@@ -61,6 +65,10 @@
// Returns the browser's FullscreenController.
virtual FullscreenController* GetFullscreenController() = 0;
+ // Returns the browser's active web contents for the active tab, or NULL if
+ // such does not exist.
+ virtual content::WebContents* GetWebContents() = 0;
+
// Notifies the delegate that fullscreen has been entered or exited.
virtual void FullscreenStateChanged() = 0;
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
index 8b1b5f7..9fd4fac 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h"
#include <set>
+#include <vector>
#include "ash/ash_switches.h"
#include "ash/shell.h"
@@ -16,6 +17,8 @@
#include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
#include "chrome/browser/ui/views/frame/top_container_view.h"
#include "content/public/browser/notification_service.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_view.h"
#include "ui/aura/client/activation_client.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/capture_client.h"
@@ -48,7 +51,7 @@
// How many pixels a gesture can start away from |top_container_| when in
// closed state and still be considered near it. This is needed to overcome
// issues with poor location values near the edge of the display.
-const int kNearTopContainerDistance = 5;
+const int kNearTopContainerDistance = 8;
// Used to multiply x value of an update in check to determine if gesture is
// vertical. This is used to make sure that gesture is close to vertical instead
@@ -347,6 +350,7 @@
reveal_state_ = CLOSED;
EnablePaintToLayer(false);
delegate_->SetImmersiveStyle(false);
+ SetRenderWindowTopInsetsForTouch(0);
// Relayout the root view because disabling immersive fullscreen may have
// changed the result of NonClientFrameView::GetBoundsForClientView().
@@ -940,6 +944,7 @@
// top-of-window views to their initial offscreen position for the
// animation.
delegate_->SetImmersiveStyle(false);
+ SetRenderWindowTopInsetsForTouch(0);
LayoutBrowserRootView();
// Do not do any more processing if LayoutBrowserView() changed
@@ -959,7 +964,7 @@
animation_->Show();
}
- if (previous_reveal_state == CLOSED)
+ if (previous_reveal_state == CLOSED)
FOR_EACH_OBSERVER(Observer, observers_, OnImmersiveRevealStarted());
}
@@ -1037,6 +1042,7 @@
EnablePaintToLayer(false);
// Update tabstrip for closed state.
delegate_->SetImmersiveStyle(true);
+ SetRenderWindowTopInsetsForTouch(kNearTopContainerDistance);
LayoutBrowserRootView();
}
@@ -1083,6 +1089,18 @@
(location.x() < near_bounds.right()));
}
+void ImmersiveModeControllerAsh::SetRenderWindowTopInsetsForTouch(
+ int top_inset) {
+ content::WebContents* contents = delegate_->GetWebContents();
+ if (contents) {
+ aura::Window* window = contents->GetView()->GetContentNativeView();
+ gfx::Insets inset(top_inset, 0, 0, 0);
+ window->SetHitTestBoundsOverrideOuter(
+ window->hit_test_bounds_override_outer_mouse(),
+ inset);
+ }
+}
+
void ImmersiveModeControllerAsh::RecreateBubbleManager() {
bubble_manager_.reset(new BubbleManager(this));
const std::vector<aura::Window*> transient_children =
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.h b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.h
index a1e909e..8ba1f2a 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.h
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.h
@@ -223,6 +223,13 @@
// child of |top_container_|.
void RecreateBubbleManager();
+ // Shrinks or expands the touch hit test by updating insets for the render
+ // window depending on if top_inset is positive or negative respectively.
+ // Used to ensure that touch events at the top of the screen go to the top
+ // container so a slide gesture can be generated when the content window is
+ // consuming all touch events sent to it.
+ void SetRenderWindowTopInsetsForTouch(int top_inset);
+
// Injected dependencies. Not owned.
Delegate* delegate_;
views::Widget* widget_;
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc
index 644798b..450115c 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc
@@ -23,6 +23,8 @@
#include "chrome/browser/ui/views/tabs/tab_strip.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_view.h"
#include "content/public/test/test_utils.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/env.h"
@@ -422,4 +424,36 @@
EXPECT_TRUE(controller()->ShouldHideTabIndicators());
}
+// Validate top container touch insets are being updated at the correct time in
+// immersive mode.
+IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerAshTest,
+ ImmersiveTopContainerInsets) {
+ content::WebContents* contents = browser_view()->GetActiveWebContents();
+ aura::Window* window = contents->GetView()->GetContentNativeView();
+
+ // Turning immersive mode on sets positive top touch insets on the render view
+ // window.
+ chrome::ToggleFullscreenMode(browser());
+ ASSERT_TRUE(browser_view()->IsFullscreen());
+ ASSERT_TRUE(controller()->IsEnabled());
+ EXPECT_TRUE(window->hit_test_bounds_override_outer_touch().top() > 0);
+
+ // Trigger a reveal resets insets as now the touch target for the top
+ // container is large enough.
+ controller()->StartRevealForTest(true);
+ EXPECT_TRUE(window->hit_test_bounds_override_outer_touch().top() == 0);
+
+ // End reveal by moving the mouse off the top-of-window views. We
+ // should see the top insets being positive again to allow a bigger touch
+ // target.
+ controller()->SetMouseHoveredForTest(false);
+ EXPECT_TRUE(window->hit_test_bounds_override_outer_touch().top() > 0);
+
+ // Disabling immersive mode resets the top touch insets to 0.
+ chrome::ToggleFullscreenMode(browser());
+ ASSERT_FALSE(browser_view()->IsFullscreen());
+ ASSERT_FALSE(controller()->IsEnabled());
+ EXPECT_TRUE(window->hit_test_bounds_override_outer_touch().top() == 0);
+}
+
#endif // defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc
index b02982b..3a206ab 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc
@@ -34,6 +34,9 @@
virtual void SetImmersiveStyle(bool immersive) OVERRIDE {
immersive_style_ = immersive;
}
+ virtual content::WebContents* GetWebContents() OVERRIDE {
+ return NULL;
+ }
private:
bool immersive_style_;
diff --git a/chrome/browser/ui/views/frame/instant_overlay_controller_views.cc b/chrome/browser/ui/views/frame/instant_overlay_controller_views.cc
deleted file mode 100644
index abee4db..0000000
--- a/chrome/browser/ui/views/frame/instant_overlay_controller_views.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 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/ui/views/frame/instant_overlay_controller_views.h"
-
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/search/search.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/search/instant_overlay_model.h"
-#include "chrome/browser/ui/search/search_model.h"
-#include "chrome/browser/ui/search/search_tab_helper.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/browser/ui/view_ids.h"
-#include "chrome/browser/ui/views/frame/overlay_container.h"
-#include "chrome/browser/ui/views/infobars/infobar_container_view.h"
-#include "ui/views/controls/webview/webview.h"
-
-InstantOverlayControllerViews::InstantOverlayControllerViews(
- Browser* browser,
- OverlayContainer* overlay_container)
- : InstantOverlayController(browser),
- overlay_container_(overlay_container) {
-}
-
-InstantOverlayControllerViews::~InstantOverlayControllerViews() {
-}
-
-void InstantOverlayControllerViews::OverlayStateChanged(
- const InstantOverlayModel& model) {
- if (model.mode().is_ntp() || model.mode().is_search_suggestions()) {
- // Show the overlay.
- if (!overlay_) {
- overlay_.reset(new views::WebView(browser_->profile()));
- overlay_->set_id(VIEW_ID_TAB_CONTAINER);
- }
- // Drop shadow is only needed if search mode is not |NTP| and overlay does
- // not fill up the entire contents page.
- bool draw_drop_shadow = !model.mode().is_ntp() &&
- !(overlay_container_->WillOverlayBeFullHeight(model.height(),
- model.height_units()));
- content::WebContents* web_contents = model.GetOverlayContents();
- overlay_container_->SetOverlay(overlay_.get(),
- web_contents,
- model.height(),
- model.height_units(),
- draw_drop_shadow);
- overlay_->SetWebContents(web_contents);
- } else if (overlay_) {
- // Hide the overlay. SetWebContents() must happen before SetOverlay().
- overlay_->SetWebContents(NULL);
- overlay_container_->SetOverlay(
- NULL, NULL, 100, INSTANT_SIZE_PERCENT, false);
- overlay_.reset();
- }
-}
diff --git a/chrome/browser/ui/views/frame/instant_overlay_controller_views.h b/chrome/browser/ui/views/frame/instant_overlay_controller_views.h
deleted file mode 100644
index 59fa5a3..0000000
--- a/chrome/browser/ui/views/frame/instant_overlay_controller_views.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 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.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_FRAME_INSTANT_OVERLAY_CONTROLLER_VIEWS_H_
-#define CHROME_BROWSER_UI_VIEWS_FRAME_INSTANT_OVERLAY_CONTROLLER_VIEWS_H_
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/memory/scoped_ptr.h"
-#include "chrome/browser/ui/search/instant_overlay_controller.h"
-
-class Browser;
-class OverlayContainer;
-
-namespace views {
-class WebView;
-}
-
-// A controller that manages the Views-specific Instant overlay. Its primary
-// role is to respond to display-state changes from the Instant model and
-// reflect this in the visibility and layout of the overlay.
-class InstantOverlayControllerViews : public InstantOverlayController {
- public:
- InstantOverlayControllerViews(Browser* browser,
- OverlayContainer* overlay_container);
- virtual ~InstantOverlayControllerViews();
-
- views::WebView* overlay() { return overlay_.get(); }
-
- views::WebView* release_overlay() WARN_UNUSED_RESULT {
- return overlay_.release();
- }
-
- private:
- // Overridden from InstantOverlayController:
- virtual void OverlayStateChanged(const InstantOverlayModel& model) OVERRIDE;
-
- OverlayContainer* const overlay_container_;
-
- // The view that contains the Instant overlay web contents.
- scoped_ptr<views::WebView> overlay_;
-
- DISALLOW_COPY_AND_ASSIGN(InstantOverlayControllerViews);
-};
-
-#endif // CHROME_BROWSER_UI_VIEWS_FRAME_INSTANT_OVERLAY_CONTROLLER_VIEWS_H_
diff --git a/chrome/browser/ui/views/frame/overlay_container.cc b/chrome/browser/ui/views/frame/overlay_container.cc
deleted file mode 100644
index 317e568..0000000
--- a/chrome/browser/ui/views/frame/overlay_container.cc
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright 2013 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/ui/views/frame/overlay_container.h"
-
-#include "chrome/browser/themes/theme_properties.h"
-#include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
-#include "chrome/browser/ui/views/detachable_toolbar_view.h"
-#include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_types.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
-#include "grit/theme_resources.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/image/image_skia.h"
-#include "ui/views/controls/webview/webview.h"
-
-#if defined(USE_AURA)
-#include "ui/aura/window.h"
-#endif // USE_AURA
-
-namespace {
-
-const int kToolbarOverlap = views::NonClientFrameView::kClientEdgeThickness +
- BookmarkBarView::kToolbarAttachedBookmarkBarOverlap;
-
-bool IsFullHeight(int height, InstantSizeUnits units) {
- return height == 100 && units == INSTANT_SIZE_PERCENT;
-}
-
-int OverlayHeightInPixels(int parent_height, int overlay_height,
- InstantSizeUnits overlay_height_units) {
- parent_height = std::max(0, parent_height);
- overlay_height = std::max(0, overlay_height);
- switch (overlay_height_units) {
- case INSTANT_SIZE_PERCENT:
- return std::min(parent_height, (parent_height * overlay_height) / 100);
-
- case INSTANT_SIZE_PIXELS:
- return std::min(parent_height, overlay_height);
- }
- NOTREACHED() << "unknown units: " << overlay_height_units;
- return 0;
-}
-
-// This class draws the drop shadow below the overlay when the non-NTP overlay
-// doesn't fill up the entire content page.
-// This class is owned by OverlayContainer, which:
-// - adds it as child when shadow is needed
-// - removes it as child when shadow is not needed or when overlay is nuked or
-// when overlay is removed as child
-class ShadowView : public views::View {
- public:
- ShadowView() {
- drop_shadow_ = *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
- IDR_OVERLAY_DROP_SHADOW);
-
- SetPaintToLayer(true);
- SetFillsBoundsOpaquely(false);
- set_owned_by_client();
- }
-
- virtual ~ShadowView() {}
-
- virtual gfx::Size GetPreferredSize() OVERRIDE {
- // Only height really matters, since images will be stretched horizontally
- // across.
- return drop_shadow_.size();
- }
-
- virtual const char* GetClassName() const OVERRIDE {
- return "OverlayDropShadow";
- }
-
- protected:
- virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
- // Stretch drop shadow horizontally across.
- canvas->DrawImageInt(
- drop_shadow_,
- 0, 0, drop_shadow_.width(), drop_shadow_.height(),
- 0, 0, width(), drop_shadow_.height(),
- true);
- }
-
- private:
- gfx::ImageSkia drop_shadow_;
-
- DISALLOW_COPY_AND_ASSIGN(ShadowView);
-};
-
-} // namespace
-
-OverlayContainer::OverlayContainer(
- BrowserView* browser_view,
- ImmersiveModeController* immersive_mode_controller)
- : browser_view_(browser_view),
- immersive_mode_controller_(immersive_mode_controller),
- overlay_(NULL),
- overlay_web_contents_(NULL),
- draw_drop_shadow_(false),
- overlay_height_(0),
- overlay_height_units_(INSTANT_SIZE_PIXELS) {
-}
-
-OverlayContainer::~OverlayContainer() {
-}
-
-void OverlayContainer::ResetOverlayAndContents() {
- // Since |overlay_| will be nuked, shadow view is not needed anymore.
- shadow_view_.reset();
- overlay_ = NULL;
- overlay_web_contents_ = NULL;
- // Allow top views to close in immersive fullscreen.
- immersive_revealed_lock_.reset();
- // Unregister from observing previous |overlay_web_contents_|.
- registrar_.RemoveAll();
-}
-
-void OverlayContainer::SetOverlay(views::WebView* overlay,
- content::WebContents* overlay_web_contents,
- int height,
- InstantSizeUnits units,
- bool draw_drop_shadow) {
- // If drawing drop shadow, clip the bottom 1-px-thick separator out of
- // overlay.
- // TODO(kuan): remove this when GWS gives chrome the height without the
- // separator.
-#if !defined(OS_WIN)
- if (draw_drop_shadow)
- --height;
-#endif // !defined(OS_WIN)
-
- if (overlay_ == overlay && overlay_web_contents_ == overlay_web_contents &&
- overlay_height_ == height && overlay_height_units_ == units &&
- draw_drop_shadow_ == draw_drop_shadow) {
- return;
- }
-
- bool repaint_infobars = false;
-
- if (overlay_ != overlay) {
- if (overlay_) {
- RemoveChildView(overlay_);
- } else {
- // There's no previous overlay, repaint infobars when showing the new one.
- repaint_infobars = true;
- }
-
- overlay_ = overlay;
- if (overlay_) {
- AddChildView(overlay_);
- // Hold the top views open in immersive fullscreen.
- immersive_revealed_lock_.reset(
- immersive_mode_controller_->GetRevealedLock(
- ImmersiveModeController::ANIMATE_REVEAL_NO));
- } else {
- // There's no more overlay, repaint infobars that were obscured by the
- // previous overlay.
- repaint_infobars = true;
- // Allow top views to close in immersive fullscreen.
- immersive_revealed_lock_.reset();
- }
- }
-
- if (overlay_web_contents_ != overlay_web_contents) {
- // Unregister from observing previous |overlay_web_contents_|.
- registrar_.RemoveAll();
-
- overlay_web_contents_ = overlay_web_contents;
-
-#if !defined(OS_WIN)
- // Register to new overlay web contents' render view host.
- if (overlay_web_contents_) {
- content::RenderViewHost* rvh = overlay_web_contents_->GetRenderViewHost();
- DCHECK(rvh);
- if (rvh) {
- content::NotificationSource source =
- content::Source<content::RenderWidgetHost>(rvh);
- registrar_.Add(this,
- content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE,
- source);
- }
- }
-#endif // !defined(OS_WIN)
- }
-
- overlay_height_ = height;
- overlay_height_units_ = units;
- draw_drop_shadow_ = draw_drop_shadow;
-
- // Add shadow view if there's overlay and drop shadow is needed.
- // Remove shadow view if there's no overlay.
- // If there's overlay and drop shadow is not needed, that means the partial-
- // height overlay is going to be full-height. Don't remove the shadow view
- // yet because its view will disappear noticeably faster than the webview-ed
- // overlay is repainted at the full height - when resizing web contents page,
- // RenderWidgetHostViewAura locks the compositor until texture is updated or
- // timeout occurs. This out-of-sync refresh results in a split second where
- // there's no separator between the overlay and active contents, making the
- // overlay contents erroneously appear to be part of active contents.
- // When the overlay is repainted at the full height, we'll be notified via
- // NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKGING_STORE, at which time
- // the shadow view will be removed.
- if (overlay_ && draw_drop_shadow_) {
-#if !defined(OS_WIN)
- if (!shadow_view_.get()) {
- // Shadow view has not been created.
- shadow_view_.reset(new ShadowView());
- AddChildView(shadow_view_.get());
- }
-#endif // !defined(OS_WIN)
- } else if (!overlay_) {
- shadow_view_.reset();
- }
-
- // Force re-layout of parent and/or re-layout of infobars.
- browser_view_->OnOverlayStateChanged(repaint_infobars);
-}
-
-gfx::Rect OverlayContainer::GetOverlayBounds() const {
- gfx::Point screen_loc;
- ConvertPointToScreen(this, &screen_loc);
- return gfx::Rect(screen_loc, size());
-}
-
-bool OverlayContainer::WillOverlayBeFullHeight(
- int overlay_height,
- InstantSizeUnits overlay_height_units) const {
- return IsFullHeight(overlay_height, overlay_height_units);
-}
-
-bool OverlayContainer::IsOverlayFullHeight() const {
- return overlay_ && IsFullHeight(overlay_height_, overlay_height_units_);
-}
-
-gfx::Size OverlayContainer::GetPreferredSize() {
- if (!overlay_)
- return gfx::Size();
- // Make sure IsOverlayFullHeight() is called before this function, because
- // when overlay is full height, its height is determined by its parent
- // (i.e. whatever is available from below toolbar), which is not yet known
- // now.
- DCHECK(!IsOverlayFullHeight());
- // Width doesn't matter.
- // Height includes overlap with toolbar, |overlay_|'s height and, if
- // necessary, |shadow_view_|'s height.
- gfx::Size preferred_size(0, kToolbarOverlap + overlay_height_);
- if (shadow_view_)
- preferred_size.Enlarge(0, shadow_view_->GetPreferredSize().height());
- return preferred_size;
-}
-
-void OverlayContainer::Layout() {
- if (!overlay_)
- return;
- int target_overlay_height = OverlayHeightInPixels(
- height() - kToolbarOverlap, overlay_height_, overlay_height_units_);
- overlay_->SetBounds(0, kToolbarOverlap, width(), target_overlay_height);
- if (draw_drop_shadow_) {
-#if !defined(OS_WIN)
- DCHECK(shadow_view_.get() && shadow_view_->parent());
- shadow_view_->SetBounds(0, overlay_->bounds().bottom(), width(),
- shadow_view_->GetPreferredSize().height());
-#endif // !defined(OS_WIN)
- }
-
- // Need to invoke views::View in case any views whose bounds didn't change
- // still need a layout.
- views::View::Layout();
-}
-
-void OverlayContainer::OnPaint(gfx::Canvas* canvas) {
- // Paint the region which overlaps with the toolbar as a continuation of the
- // toolbar, like attached bookmark bar does.
- gfx::Rect toolbar_background_bounds(width(),
- BookmarkBarView::kToolbarAttachedBookmarkBarOverlap);
- gfx::Point background_image_offset =
- browser_view_->OffsetPointForToolbarBackgroundImage(
- gfx::Point(GetMirroredX(), y()));
- DetachableToolbarView::PaintBackgroundAttachedMode(canvas, GetThemeProvider(),
- toolbar_background_bounds, background_image_offset,
- browser_view_->browser()->host_desktop_type());
- // Paint a separator below toolbar.
- canvas->FillRect(
- gfx::Rect(0,
- BookmarkBarView::kToolbarAttachedBookmarkBarOverlap,
- width(),
- views::NonClientFrameView::kClientEdgeThickness),
- ThemeProperties::GetDefaultColor(
- ThemeProperties::COLOR_TOOLBAR_SEPARATOR));
-}
-
-const char* OverlayContainer::GetClassName() const {
- return "OverlayContainer";
-}
-
-void OverlayContainer::Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- DCHECK_EQ(content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE,
- type);
- // Remove shadow view if it's not needed.
- if (overlay_ && !draw_drop_shadow_) {
- DCHECK(overlay_web_contents_);
- DCHECK_EQ(overlay_web_contents_->GetRenderViewHost(),
- (content::Source<content::RenderWidgetHost>(source)).ptr());
- shadow_view_.reset();
- }
-}
diff --git a/chrome/browser/ui/views/frame/overlay_container.h b/chrome/browser/ui/views/frame/overlay_container.h
deleted file mode 100644
index 9646e6a..0000000
--- a/chrome/browser/ui/views/frame/overlay_container.h
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_FRAME_OVERLAY_CONTAINER_H_
-#define CHROME_BROWSER_UI_VIEWS_FRAME_OVERLAY_CONTAINER_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/memory/scoped_ptr.h"
-#include "chrome/common/instant_types.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
-#include "ui/views/view.h"
-
-class BrowserView;
-class ImmersiveModeController;
-class ImmersiveRevealedLock;
-
-namespace content {
-class WebContents;
-}
-
-namespace gfx {
-class Canvas;
-class Rect;
-}
-
-namespace views {
-class WebView;
-};
-
-// OverlayContainer is responsible for managing the overlay WebContents view.
-// OverlayContainer has up to two children: one for Instant's WebContents and,
-// if necessary, one for the drop shadow below it in the y-axis.
-class OverlayContainer : public views::View,
- public content::NotificationObserver {
- public:
- OverlayContainer(BrowserView* browser_view,
- ImmersiveModeController* immersive_mode_controller);
- virtual ~OverlayContainer();
-
- // Sets the overlay view. This does not delete the old.
- void SetOverlay(views::WebView* overlay,
- content::WebContents* overlay_web_contents,
- int height,
- InstantSizeUnits units,
- bool draw_drop_shadow);
-
- // Called after overlay view has been reparented to |ContentsContainer| and
- // has been made the active view.
- void ResetOverlayAndContents();
-
- // Returns the bounds the overlay would be shown at.
- gfx::Rect GetOverlayBounds() const;
-
- // Returns true if overlay will occupy full height of available space based on
- // |overlay_height| and |overlay_height_units|.
- bool WillOverlayBeFullHeight(int overlay_height,
- InstantSizeUnits overlay_height_units) const;
-
- // Returns true if |overlay_| is not NULL and it is occupying full height of
- // available space. Must be called before GetPreferredSize(), and only call
- // the latter if this returns false.
- bool IsOverlayFullHeight() const;
-
- content::WebContents* overlay_web_contents() const {
- return overlay_web_contents_;
- }
-
- // Overridden from views::View:
- // GetPreferredSize() must only be called if IsOverlayFullHeight() returns
- // false; if overlay is full height, height of OverlayContainer can only be
- // determined by the parent's height, not here.
- virtual gfx::Size GetPreferredSize() OVERRIDE;
- virtual void Layout() OVERRIDE;
- virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
- virtual const char* GetClassName() const OVERRIDE;
-
- // Testing interface:
- views::WebView* GetOverlayWebViewForTest() { return overlay_; }
-
- private:
- // content::NotificationObserver implementation.
- virtual void Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) OVERRIDE;
-
- BrowserView* const browser_view_;
- ImmersiveModeController* immersive_mode_controller_;
-
- // Used to force the top views open while in immersive fullscreen.
- scoped_ptr<ImmersiveRevealedLock> immersive_revealed_lock_;
-
- // Owned by |InstantOverlayControllerViews|.
- views::WebView* overlay_;
-
- // Owned by |IntantController| if not NULL, else |InstantModel|.
- content::WebContents* overlay_web_contents_;
-
- // Drop shadow below partial-height |overlay_|.
- scoped_ptr<views::View> shadow_view_;
- bool draw_drop_shadow_;
-
- // The desired height of the overlay and units.
- int overlay_height_;
- InstantSizeUnits overlay_height_units_;
-
- content::NotificationRegistrar registrar_;
-
- DISALLOW_COPY_AND_ASSIGN(OverlayContainer);
-};
-
-#endif // CHROME_BROWSER_UI_VIEWS_FRAME_OVERLAY_CONTAINER_H_
diff --git a/chrome/browser/ui/views/infobars/OWNERS b/chrome/browser/ui/views/infobars/OWNERS
new file mode 100644
index 0000000..bf426d6
--- /dev/null
+++ b/chrome/browser/ui/views/infobars/OWNERS
@@ -0,0 +1 @@
+pkasting@chromium.org
diff --git a/chrome/browser/ui/views/infobars/alternate_nav_infobar_view.cc b/chrome/browser/ui/views/infobars/alternate_nav_infobar_view.cc
index c76b933..87ad887 100644
--- a/chrome/browser/ui/views/infobars/alternate_nav_infobar_view.cc
+++ b/chrome/browser/ui/views/infobars/alternate_nav_infobar_view.cc
@@ -10,12 +10,14 @@
#include "ui/views/controls/label.h"
#include "ui/views/controls/link.h"
+
// AlternateNavInfoBarDelegate -------------------------------------------------
InfoBar* AlternateNavInfoBarDelegate::CreateInfoBar(InfoBarService* owner) {
return new AlternateNavInfoBarView(owner, this);
}
+
// AlternateNavInfoBarView -----------------------------------------------------
AlternateNavInfoBarView::AlternateNavInfoBarView(
diff --git a/chrome/browser/ui/views/infobars/confirm_infobar.cc b/chrome/browser/ui/views/infobars/confirm_infobar.cc
index 68e775f..82da528 100644
--- a/chrome/browser/ui/views/infobars/confirm_infobar.cc
+++ b/chrome/browser/ui/views/infobars/confirm_infobar.cc
@@ -11,12 +11,14 @@
#include "ui/views/controls/label.h"
#include "ui/views/controls/link.h"
+
// ConfirmInfoBarDelegate -----------------------------------------------------
InfoBar* ConfirmInfoBarDelegate::CreateInfoBar(InfoBarService* owner) {
return new ConfirmInfoBar(owner, this);
}
+
// ConfirmInfoBar -------------------------------------------------------------
ConfirmInfoBar::ConfirmInfoBar(InfoBarService* owner,
diff --git a/chrome/browser/ui/views/infobars/extension_infobar.cc b/chrome/browser/ui/views/infobars/extension_infobar.cc
index 6c2e220..a555909 100644
--- a/chrome/browser/ui/views/infobars/extension_infobar.cc
+++ b/chrome/browser/ui/views/infobars/extension_infobar.cc
@@ -30,7 +30,7 @@
// ExtensionInfoBarDelegate ----------------------------------------------------
InfoBar* ExtensionInfoBarDelegate::CreateInfoBar(InfoBarService* owner) {
- return new ExtensionInfoBar(browser_, owner, this);
+ return new ExtensionInfoBar(owner, this, browser_);
}
@@ -78,9 +78,9 @@
} // namespace
-ExtensionInfoBar::ExtensionInfoBar(Browser* browser,
- InfoBarService* owner,
- ExtensionInfoBarDelegate* delegate)
+ExtensionInfoBar::ExtensionInfoBar(InfoBarService* owner,
+ ExtensionInfoBarDelegate* delegate,
+ Browser* browser)
: InfoBarView(owner, delegate),
delegate_(delegate),
browser_(browser),
@@ -88,9 +88,9 @@
icon_as_menu_(NULL),
icon_as_image_(NULL),
weak_ptr_factory_(this) {
- delegate->set_observer(this);
+ GetDelegate()->set_observer(this);
- int height = delegate->height();
+ int height = GetDelegate()->height();
SetBarTargetHeight((height > 0) ? (height + kSeparatorLineHeight) : 0);
}
@@ -173,8 +173,8 @@
const gfx::Point& point) {
if (!owner())
return; // We're closing; don't call anything, it might access the owner.
- const extensions::Extension* extension = GetDelegate()->extension_host()->
- extension();
+ const extensions::Extension* extension =
+ GetDelegate()->extension_host()->extension();
DCHECK(icon_as_menu_);
scoped_refptr<ExtensionContextMenuModel> options_menu_contents =
diff --git a/chrome/browser/ui/views/infobars/extension_infobar.h b/chrome/browser/ui/views/infobars/extension_infobar.h
index ce5e550..930c714 100644
--- a/chrome/browser/ui/views/infobars/extension_infobar.h
+++ b/chrome/browser/ui/views/infobars/extension_infobar.h
@@ -20,9 +20,9 @@
public ExtensionInfoBarDelegate::DelegateObserver,
public views::MenuButtonListener {
public:
- ExtensionInfoBar(Browser* browser,
- InfoBarService* owner,
- ExtensionInfoBarDelegate* delegate);
+ ExtensionInfoBar(InfoBarService* owner,
+ ExtensionInfoBarDelegate* delegate,
+ Browser* browser);
private:
virtual ~ExtensionInfoBar();
diff --git a/chrome/browser/ui/views/infobars/infobar_view.cc b/chrome/browser/ui/views/infobars/infobar_view.cc
index 1208c6a..0936c95 100644
--- a/chrome/browser/ui/views/infobars/infobar_view.cc
+++ b/chrome/browser/ui/views/infobars/infobar_view.cc
@@ -61,7 +61,7 @@
icon_(NULL),
close_button_(NULL) {
set_owned_by_client(); // InfoBar deletes itself at the appropriate time.
- set_background(new InfoBarBackground(delegate->GetInfoBarType()));
+ set_background(new InfoBarBackground(InfoBar::delegate()->GetInfoBarType()));
}
InfoBarView::~InfoBarView() {
@@ -355,7 +355,7 @@
if (delegate()) {
state->name = l10n_util::GetStringUTF16(
(delegate()->GetInfoBarType() == InfoBarDelegate::WARNING_TYPE) ?
- IDS_ACCNAME_INFOBAR_WARNING : IDS_ACCNAME_INFOBAR_PAGE_ACTION);
+ IDS_ACCNAME_INFOBAR_WARNING : IDS_ACCNAME_INFOBAR_PAGE_ACTION);
}
state->role = ui::AccessibilityTypes::ROLE_ALERT;
}
diff --git a/chrome/browser/ui/views/infobars/translate_infobar_base.cc b/chrome/browser/ui/views/infobars/translate_infobar_base.cc
index 7683c2c..03a8738 100644
--- a/chrome/browser/ui/views/infobars/translate_infobar_base.cc
+++ b/chrome/browser/ui/views/infobars/translate_infobar_base.cc
@@ -16,6 +16,7 @@
#include "ui/views/controls/button/menu_button.h"
#include "ui/views/controls/label.h"
+
// TranslateInfoBarDelegate ---------------------------------------------------
InfoBar* TranslateInfoBarDelegate::CreateInfoBar(InfoBarService* owner) {
@@ -26,6 +27,7 @@
return new TranslateMessageInfoBar(owner, this);
}
+
// TranslateInfoBarBase -------------------------------------------------------
// static
@@ -103,7 +105,7 @@
}
const views::Background& TranslateInfoBarBase::GetBackground() {
- return GetDelegate()->IsError() ? error_background_ : *background();
+ return GetDelegate()->is_error() ? error_background_ : *background();
}
void TranslateInfoBarBase::FadeBackground(gfx::Canvas* canvas,
diff --git a/chrome/browser/ui/views/infobars/translate_infobar_base.h b/chrome/browser/ui/views/infobars/translate_infobar_base.h
index d8ff765..617173f 100644
--- a/chrome/browser/ui/views/infobars/translate_infobar_base.h
+++ b/chrome/browser/ui/views/infobars/translate_infobar_base.h
@@ -24,8 +24,6 @@
const string16& text);
protected:
- static const int kButtonInLabelSpacing;
-
TranslateInfoBarBase(InfoBarService* owner,
TranslateInfoBarDelegate* delegate);
virtual ~TranslateInfoBarBase();
@@ -37,6 +35,8 @@
// Convenience to retrieve the TranslateInfoBarDelegate for this infobar.
TranslateInfoBarDelegate* GetDelegate();
+ static const int kButtonInLabelSpacing;
+
private:
// InfoBarView:
virtual void OnPaintBackground(gfx::Canvas* canvas) OVERRIDE;
diff --git a/chrome/browser/ui/views/location_bar/OWNERS b/chrome/browser/ui/views/location_bar/OWNERS
new file mode 100644
index 0000000..bf426d6
--- /dev/null
+++ b/chrome/browser/ui/views/location_bar/OWNERS
@@ -0,0 +1 @@
+pkasting@chromium.org
diff --git a/chrome/browser/ui/views/location_bar/action_box_button_view.cc b/chrome/browser/ui/views/location_bar/action_box_button_view.cc
deleted file mode 100644
index 89dd94e..0000000
--- a/chrome/browser/ui/views/location_bar/action_box_button_view.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// 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/ui/views/location_bar/action_box_button_view.h"
-
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/toolbar/action_box_menu_model.h"
-#include "chrome/browser/ui/view_ids.h"
-#include "chrome/browser/ui/views/action_box_menu.h"
-#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#include "ui/base/accessibility/accessible_view_state.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/path.h"
-
-ActionBoxButtonView::ActionBoxButtonView(Browser* browser,
- const gfx::Point& menu_offset)
- : views::MenuButton(NULL, string16(), this, false),
- browser_(browser),
- menu_offset_(menu_offset),
- controller_(browser, this) {
- set_id(VIEW_ID_ACTION_BOX_BUTTON);
- SetTooltipText(l10n_util::GetStringUTF16(IDS_TOOLTIP_ACTION_BOX_BUTTON));
- SetIcon(*ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
- IDR_ACTION_BOX_BUTTON_NORMAL));
- SetHoverIcon(*ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
- IDR_ACTION_BOX_BUTTON_HOVER));
- SetPushedIcon(*ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
- IDR_ACTION_BOX_BUTTON_PRESSED));
- set_accessibility_focusable(true);
- set_border(NULL);
- SizeToPreferredSize();
-}
-
-ActionBoxButtonView::~ActionBoxButtonView() {
-}
-
-int ActionBoxButtonView::GetBuiltInHorizontalPadding() const {
- return GetBuiltInHorizontalPaddingImpl();
-}
-
-void ActionBoxButtonView::GetAccessibleState(ui::AccessibleViewState* state) {
- MenuButton::GetAccessibleState(state);
- state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_ACTION_BOX_BUTTON);
-}
-
-void ActionBoxButtonView::OnMenuButtonClicked(View* source,
- const gfx::Point& point) {
- controller_.OnButtonClicked();
-}
-
-void ActionBoxButtonView::ShowMenu(scoped_ptr<ActionBoxMenuModel> menu_model) {
- menu_ = ActionBoxMenu::Create(browser_, menu_model.Pass());
- menu_->RunMenu(this, menu_offset_);
-}
diff --git a/chrome/browser/ui/views/location_bar/action_box_button_view.h b/chrome/browser/ui/views/location_bar/action_box_button_view.h
deleted file mode 100644
index f3d02de..0000000
--- a/chrome/browser/ui/views/location_bar/action_box_button_view.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_ACTION_BOX_BUTTON_VIEW_H_
-#define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_ACTION_BOX_BUTTON_VIEW_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "chrome/browser/ui/toolbar/action_box_button_controller.h"
-#include "chrome/browser/ui/views/location_bar/touchable_location_bar_view.h"
-#include "ui/views/controls/button/menu_button.h"
-#include "ui/views/controls/button/menu_button_listener.h"
-
-class ActionBoxMenu;
-class Browser;
-
-// ActionBoxButtonView displays a plus button with associated menu.
-class ActionBoxButtonView : public views::MenuButton,
- public views::MenuButtonListener,
- public ActionBoxButtonController::Delegate,
- public TouchableLocationBarView {
- public:
- ActionBoxButtonView(Browser* browser, const gfx::Point& menu_offset);
- virtual ~ActionBoxButtonView();
-
- ActionBoxButtonController* action_box_button_controller() {
- return &controller_;
- }
-
- // TouchableLocationBarView:
- virtual int GetBuiltInHorizontalPadding() const OVERRIDE;
-
- private:
- // Overridden from views::CustomButton:
- virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
-
- // Overridden from views::MenuButtonListener:
- virtual void OnMenuButtonClicked(View* source,
- const gfx::Point& point) OVERRIDE;
-
- // Overridden from ActionBoxButtonController::Delegate:
- virtual void ShowMenu(scoped_ptr<ActionBoxMenuModel> menu_model) OVERRIDE;
-
- Browser* browser_;
-
- gfx::Point menu_offset_;
-
- ActionBoxButtonController controller_;
-
- scoped_ptr<ActionBoxMenu> menu_;
-
- DISALLOW_COPY_AND_ASSIGN(ActionBoxButtonView);
-};
-
-#endif // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_ACTION_BOX_BUTTON_VIEW_H_
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc
index 4016fd8..352f878 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -38,7 +38,6 @@
#include "chrome/browser/ui/views/bookmarks/bookmark_prompt_view.h"
#include "chrome/browser/ui/views/browser_dialogs.h"
#include "chrome/browser/ui/views/extensions/extension_popup.h"
-#include "chrome/browser/ui/views/location_bar/action_box_button_view.h"
#include "chrome/browser/ui/views/location_bar/autofill_credit_card_view.h"
#include "chrome/browser/ui/views/location_bar/content_setting_image_view.h"
#include "chrome/browser/ui/views/location_bar/ev_bubble_view.h"
@@ -76,6 +75,7 @@
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/gfx/skia_util.h"
+#include "ui/native_theme/native_theme.h"
#include "ui/views/background.h"
#include "ui/views/border.h"
#include "ui/views/button_drag_utils.h"
@@ -96,7 +96,6 @@
#if !defined(OS_CHROMEOS)
#include "chrome/browser/ui/views/first_run_bubble.h"
-#include "ui/native_theme/native_theme.h"
#endif
#if defined(USE_AURA)
@@ -187,7 +186,6 @@
open_pdf_in_reader_view_(NULL),
script_bubble_icon_view_(NULL),
star_view_(NULL),
- action_box_button_view_(NULL),
is_popup_mode_(is_popup_mode),
show_focus_rect_(false),
template_url_service_(NULL),
@@ -343,14 +341,6 @@
star_view_->SetVisible(false);
AddChildView(star_view_);
- if (extensions::FeatureSwitch::action_box()->IsEnabled() && !is_popup_mode_ &&
- browser_) {
- action_box_button_view_ = new ActionBoxButtonView(
- browser_,
- gfx::Point(GetHorizontalEdgeThickness(), vertical_edge_thickness()));
- AddChildView(action_box_button_view_);
- }
-
registrar_.Add(this,
chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED,
content::Source<Profile>(profile_));
@@ -487,12 +477,9 @@
command_updater_->UpdateCommandEnabled(IDC_BOOKMARK_PAGE, star_enabled);
command_updater_->UpdateCommandEnabled(IDC_BOOKMARK_PAGE_FROM_STAR,
star_enabled);
- if (star_view_ && !extensions::FeatureSwitch::action_box()->IsEnabled())
+ if (star_view_)
star_view_->SetVisible(star_enabled);
- if (action_box_button_view_)
- action_box_button_view_->SetVisible(!model_->GetInputInProgress());
-
location_entry_->Update(tab_for_state_restoring);
OnChanged();
@@ -588,22 +575,13 @@
}
void LocationBarView::SetStarToggled(bool on) {
- if (!star_view_)
- return;
- star_view_->SetToggled(on);
- if (action_box_button_view_ && (star_view_->visible() != on)) {
- star_view_->SetVisible(on);
- Layout();
- }
+ if (star_view_)
+ star_view_->SetToggled(on);
}
void LocationBarView::ShowBookmarkPrompt() {
- if (action_box_button_view_) {
- BookmarkPromptView::ShowPrompt(action_box_button_view_,
- profile_->GetPrefs());
- } else if (star_view_ && star_view_->visible()) {
+ if (star_view_ && star_view_->visible())
BookmarkPromptView::ShowPrompt(star_view_, profile_->GetPrefs());
- }
}
void LocationBarView::ZoomChangedForActiveTab(bool can_show_bubble) {
@@ -723,7 +701,7 @@
selected_keyword_view_->set_is_extension_icon(false);
}
}
- } else if (model_->GetSecurityLevel() == ToolbarModel::EV_SECURE) {
+ } else if (model_->GetSecurityLevel(false) == ToolbarModel::EV_SECURE) {
ev_bubble_view_->SetLabel(model_->GetEVCertName());
// The largest fraction of the omnibox that can be taken by the EV bubble.
const double kMaxBubbleFraction = 0.5;
@@ -737,12 +715,6 @@
location_icon_view_);
}
- if (action_box_button_view_ && action_box_button_view_->visible()) {
- trailing_decorations.AddDecoration(
- vertical_edge_thickness(), location_height,
- action_box_button_view_->GetBuiltInHorizontalPadding(),
- action_box_button_view_);
- }
if (star_view_ && star_view_->visible()) {
trailing_decorations.AddDecoration(
vertical_edge_thickness(), location_height,
@@ -1160,8 +1132,6 @@
right_anchor = star_view_;
if (!right_anchor)
right_anchor = script_bubble_icon_view_;
- if (!right_anchor)
- right_anchor = action_box_button_view_;
DCHECK(right_anchor);
// Add the page actions in reverse order, so that the child views are
@@ -1252,7 +1222,8 @@
return;
const int32 tab_id = SessionID::IdForTab(web_contents);
- const ToolbarModel::SecurityLevel security_level = model_->GetSecurityLevel();
+ const ToolbarModel::SecurityLevel security_level =
+ model_->GetSecurityLevel(false);
const SkColor text_color = GetColor(security_level, TEXT);
const SkColor background_color = GetColor(security_level, BACKGROUND);
@@ -1486,11 +1457,6 @@
NOTREACHED();
}
-void LocationBarView::TestActionBoxMenuItemSelected(int command_id) {
- action_box_button_view_->action_box_button_controller()->
- ExecuteCommand(command_id, 0);
-}
-
bool LocationBarView::GetBookmarkStarVisibility() {
DCHECK(star_view_);
return star_view_->visible();
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h
index 0fc5ddf..96151da 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.h
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.h
@@ -310,7 +310,6 @@
virtual ExtensionAction* GetPageAction(size_t index) OVERRIDE;
virtual ExtensionAction* GetVisiblePageAction(size_t index) OVERRIDE;
virtual void TestPageActionPressed(size_t index) OVERRIDE;
- virtual void TestActionBoxMenuItemSelected(int command_id) OVERRIDE;
virtual bool GetBookmarkStarVisibility() OVERRIDE;
// TemplateURLServiceObserver:
@@ -502,9 +501,6 @@
// The star.
StarView* star_view_;
- // The action box button (plus).
- ActionBoxButtonView* action_box_button_view_;
-
// Whether we're in popup mode.
const bool is_popup_mode_;
diff --git a/chrome/browser/ui/views/message_center/web_notification_tray.cc b/chrome/browser/ui/views/message_center/web_notification_tray.cc
index eb65227..655bb3a 100644
--- a/chrome/browser/ui/views/message_center/web_notification_tray.cc
+++ b/chrome/browser/ui/views/message_center/web_notification_tray.cc
@@ -281,7 +281,8 @@
if (!status_tray)
return NULL;
- StatusIcon* status_icon = status_tray->CreateStatusIcon();
+ StatusIcon* status_icon =
+ status_tray->CreateStatusIcon(StatusTray::NOTIFICATION_TRAY_ICON);
if (!status_icon)
return NULL;
diff --git a/chrome/browser/ui/views/omnibox/OWNERS b/chrome/browser/ui/views/omnibox/OWNERS
new file mode 100644
index 0000000..bf426d6
--- /dev/null
+++ b/chrome/browser/ui/views/omnibox/OWNERS
@@ -0,0 +1 @@
+pkasting@chromium.org
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
index 0c59dbc..0a5c54f 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -360,7 +360,7 @@
bool visibly_changed_permanent_text =
model()->UpdatePermanentText(toolbar_model()->GetText(true));
ToolbarModel::SecurityLevel security_level =
- toolbar_model()->GetSecurityLevel();
+ toolbar_model()->GetSecurityLevel(false);
bool changed_security_level = (security_level != security_level_);
security_level_ = security_level;
@@ -779,7 +779,7 @@
if (command_id == IDS_PASTE_AND_GO)
return model()->CanPasteAndGo(GetClipboardText());
if (command_id == IDC_COPY_URL) {
- return toolbar_model()->WouldReplaceSearchURLWithSearchTerms() &&
+ return toolbar_model()->WouldReplaceSearchURLWithSearchTerms(false) &&
!model()->user_input_in_progress();
}
return command_updater()->IsCommandEnabled(command_id);
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_win.cc b/chrome/browser/ui/views/omnibox/omnibox_view_win.cc
index bde208b..d4b80da 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_win.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_win.cc
@@ -602,7 +602,7 @@
model()->UpdatePermanentText(toolbar_model()->GetText(true));
const ToolbarModel::SecurityLevel security_level =
- toolbar_model()->GetSecurityLevel();
+ toolbar_model()->GetSecurityLevel(false);
const bool changed_security_level = (security_level != security_level_);
// Bail early when no visible state will actually change (prevents an
@@ -1177,7 +1177,7 @@
case IDC_COPY_URL:
return !!CanCopy() &&
!model()->user_input_in_progress() &&
- toolbar_model()->WouldReplaceSearchURLWithSearchTerms();
+ toolbar_model()->WouldReplaceSearchURLWithSearchTerms(false);
case IDC_PASTE:
return !!CanPaste();
case IDS_PASTE_AND_GO:
diff --git a/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.cc b/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.cc
new file mode 100644
index 0000000..f257a3f
--- /dev/null
+++ b/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.cc
@@ -0,0 +1,52 @@
+// Copyright 2013 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/ui/views/status_icons/status_icon_linux_wrapper.h"
+
+StatusIconLinuxWrapper::StatusIconLinuxWrapper(StatusIconLinux* status_icon) {
+ status_icon_.reset(status_icon);
+ status_icon_->set_delegate(this);
+}
+
+StatusIconLinuxWrapper::~StatusIconLinuxWrapper() {}
+
+void StatusIconLinuxWrapper::SetImage(const gfx::ImageSkia& image) {
+ status_icon_->SetImage(image);
+}
+
+void StatusIconLinuxWrapper::SetPressedImage(const gfx::ImageSkia& image) {
+ status_icon_->SetPressedImage(image);
+}
+
+void StatusIconLinuxWrapper::SetToolTip(const string16& tool_tip) {
+ status_icon_->SetToolTip(tool_tip);
+}
+
+void StatusIconLinuxWrapper::SetClickActionLabel(const string16& label) {
+ status_icon_->SetClickActionLabel(label);
+}
+
+void StatusIconLinuxWrapper::DisplayBalloon(const gfx::ImageSkia& icon,
+ const string16& title,
+ const string16& contents) {
+ notification_.DisplayBalloon(icon, title, contents);
+}
+
+void StatusIconLinuxWrapper::OnClick() {
+ DispatchClickEvent();
+}
+
+StatusIconLinuxWrapper* StatusIconLinuxWrapper::CreateWrappedStatusIcon() {
+ const ui::LinuxUI* linux_ui = ui::LinuxUI::instance();
+ if (linux_ui) {
+ scoped_ptr<StatusIconLinux> status_icon = linux_ui->CreateLinuxStatusIcon();
+ if (status_icon.get())
+ return new StatusIconLinuxWrapper(status_icon.release());
+ }
+ return NULL;
+}
+
+void StatusIconLinuxWrapper::UpdatePlatformContextMenu(ui::MenuModel* model) {
+ status_icon_->UpdatePlatformContextMenu(model);
+}
diff --git a/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.h b/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.h
new file mode 100644
index 0000000..5bb7dbf
--- /dev/null
+++ b/chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.h
@@ -0,0 +1,53 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_STATUS_ICONS_STATUS_ICON_LINUX_WRAPPER_H_
+#define CHROME_BROWSER_UI_VIEWS_STATUS_ICONS_STATUS_ICON_LINUX_WRAPPER_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/status_icons/desktop_notification_balloon.h"
+#include "chrome/browser/status_icons/status_icon.h"
+#include "ui/linux_ui/linux_ui.h"
+
+// Wrapper class for StatusIconLinux that implements the standard StatusIcon
+// interface. Also handles callbacks from StatusIconLinux.
+class StatusIconLinuxWrapper : public StatusIcon,
+ public StatusIconLinux::Delegate {
+ public:
+ virtual ~StatusIconLinuxWrapper();
+
+ // StatusIcon overrides:
+ virtual void SetImage(const gfx::ImageSkia& image) OVERRIDE;
+ virtual void SetPressedImage(const gfx::ImageSkia& image) OVERRIDE;
+ virtual void SetToolTip(const string16& tool_tip) OVERRIDE;
+ virtual void SetClickActionLabel(const string16& label) OVERRIDE;
+ virtual void DisplayBalloon(const gfx::ImageSkia& icon,
+ const string16& title,
+ const string16& contents) OVERRIDE;
+
+ // StatusIconLinux::Delegate overrides:
+ virtual void OnClick() OVERRIDE;
+
+ static StatusIconLinuxWrapper* CreateWrappedStatusIcon();
+
+ protected:
+ // StatusIcon overrides:
+ // Invoked after a call to SetContextMenu() to let the platform-specific
+ // subclass update the native context menu based on the new model. If NULL is
+ // passed, subclass should destroy the native context menu.
+ virtual void UpdatePlatformContextMenu(ui::MenuModel* model) OVERRIDE;
+
+ private:
+ // A status icon wrapper should only be created by calling
+ // CreateWrappedStatusIcon().
+ explicit StatusIconLinuxWrapper(StatusIconLinux* status_icon);
+
+ // Notification balloon.
+ DesktopNotificationBalloon notification_;
+ scoped_ptr<StatusIconLinux> status_icon_;
+
+ DISALLOW_COPY_AND_ASSIGN(StatusIconLinuxWrapper);
+};
+
+#endif // CHROME_BROWSER_UI_VIEWS_STATUS_ICONS_STATUS_ICON_LINUX_WRAPPER_H_
diff --git a/chrome/browser/ui/views/status_icons/status_tray_linux.cc b/chrome/browser/ui/views/status_icons/status_tray_linux.cc
index 9fc274a..2aa06c4 100644
--- a/chrome/browser/ui/views/status_icons/status_tray_linux.cc
+++ b/chrome/browser/ui/views/status_icons/status_tray_linux.cc
@@ -2,9 +2,32 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/status_icons/status_tray.h"
+#include "chrome/browser/ui/views/status_icons/status_tray_linux.h"
-// Status icons are not currently supported on linux/views or Aura.
+#ifndef OS_CHROMEOS
+#include "chrome/browser/ui/views/status_icons/status_icon_linux_wrapper.h"
+#include "ui/linux_ui/linux_ui.h"
+
+StatusTrayLinux::StatusTrayLinux() {
+}
+
+StatusTrayLinux::~StatusTrayLinux() {
+}
+
+StatusIcon* StatusTrayLinux::CreatePlatformStatusIcon(StatusIconType type) {
+ return StatusIconLinuxWrapper::CreateWrappedStatusIcon();
+}
+
+StatusTray* StatusTray::Create() {
+ const ui::LinuxUI* linux_ui = ui::LinuxUI::instance();
+
+ // Only create a status tray if we can actually create status icons.
+ if (linux_ui && linux_ui->IsStatusIconSupported())
+ return new StatusTrayLinux();
+ return NULL;
+}
+#else
StatusTray* StatusTray::Create() {
return NULL;
}
+#endif
diff --git a/chrome/browser/ui/views/status_icons/status_tray_linux.h b/chrome/browser/ui/views/status_icons/status_tray_linux.h
new file mode 100644
index 0000000..ea38ae5
--- /dev/null
+++ b/chrome/browser/ui/views/status_icons/status_tray_linux.h
@@ -0,0 +1,24 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_STATUS_ICONS_STATUS_TRAY_LINUX_H_
+#define CHROME_BROWSER_UI_VIEWS_STATUS_ICONS_STATUS_TRAY_LINUX_H_
+
+#include "base/compiler_specific.h"
+#include "chrome/browser/status_icons/status_tray.h"
+
+class StatusTrayLinux : public StatusTray {
+ public:
+ StatusTrayLinux();
+ virtual ~StatusTrayLinux();
+
+ protected:
+ // Overriden from StatusTray:
+ virtual StatusIcon* CreatePlatformStatusIcon(StatusIconType type) OVERRIDE;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(StatusTrayLinux);
+};
+
+#endif // CHROME_BROWSER_UI_VIEWS_STATUS_ICONS_STATUS_TRAY_LINUX_H_
diff --git a/chrome/browser/ui/views/status_icons/status_tray_win.cc b/chrome/browser/ui/views/status_icons/status_tray_win.cc
index 97792f7..8df1cf5 100644
--- a/chrome/browser/ui/views/status_icons/status_tray_win.cc
+++ b/chrome/browser/ui/views/status_icons/status_tray_win.cc
@@ -15,6 +15,15 @@
static const UINT kStatusIconMessage = WM_APP + 1;
+namespace {
+// |kBaseIconId| is 2 to avoid conflicts with plugins that hard-code id 1.
+const UINT kBaseIconId = 2;
+
+UINT ReservedIconId(StatusTray::StatusIconType type) {
+ return kBaseIconId + static_cast<UINT>(type);
+}
+} // namespace
+
StatusTrayWin::StatusTrayWin()
: next_icon_id_(1),
atom_(0),
@@ -110,12 +119,22 @@
UnregisterClass(MAKEINTATOM(atom_), instance_);
}
-StatusIcon* StatusTrayWin::CreatePlatformStatusIcon() {
- if (win8::IsSingleWindowMetroMode()) {
- return new StatusIconMetro(next_icon_id_++);
- } else {
- return new StatusIconWin(next_icon_id_++, window_, kStatusIconMessage);
- }
+StatusIcon* StatusTrayWin::CreatePlatformStatusIcon(
+ StatusTray::StatusIconType type) {
+ UINT next_icon_id;
+ if (type == StatusTray::OTHER_ICON)
+ next_icon_id = NextIconId();
+ else
+ next_icon_id = ReservedIconId(type);
+
+ if (win8::IsSingleWindowMetroMode())
+ return new StatusIconMetro(next_icon_id);
+ return new StatusIconWin(next_icon_id, window_, kStatusIconMessage);
+}
+
+UINT StatusTrayWin::NextIconId() {
+ UINT icon_id = next_icon_id_++;
+ return kBaseIconId + static_cast<UINT>(NAMED_STATUS_ICON_COUNT) + icon_id;
}
StatusTray* StatusTray::Create() {
diff --git a/chrome/browser/ui/views/status_icons/status_tray_win.h b/chrome/browser/ui/views/status_icons/status_tray_win.h
index ba03e8f..87974f0 100644
--- a/chrome/browser/ui/views/status_icons/status_tray_win.h
+++ b/chrome/browser/ui/views/status_icons/status_tray_win.h
@@ -20,9 +20,10 @@
UINT message,
WPARAM wparam,
LPARAM lparam);
+
protected:
// Overriden from StatusTray:
- virtual StatusIcon* CreatePlatformStatusIcon() OVERRIDE;
+ virtual StatusIcon* CreatePlatformStatusIcon(StatusIconType type) OVERRIDE;
private:
// Static callback invoked when a message comes in to our messaging window.
@@ -31,6 +32,8 @@
WPARAM wparam,
LPARAM lparam);
+ UINT NextIconId();
+
// The unique icon ID we will assign to the next icon.
UINT next_icon_id_;
diff --git a/chrome/browser/ui/views/status_icons/status_tray_win_unittest.cc b/chrome/browser/ui/views/status_icons/status_tray_win_unittest.cc
index 3968cdc..b42fd96 100644
--- a/chrome/browser/ui/views/status_icons/status_tray_win_unittest.cc
+++ b/chrome/browser/ui/views/status_icons/status_tray_win_unittest.cc
@@ -43,7 +43,7 @@
// Create an icon, set the images, tooltip, and context menu, then shut it
// down.
StatusTrayWin tray;
- StatusIcon* icon = tray.CreateStatusIcon();
+ StatusIcon* icon = tray.CreateStatusIcon(StatusTray::OTHER_ICON);
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
gfx::ImageSkia* image = rb.GetImageSkiaNamed(IDR_STATUS_TRAY_ICON);
icon->SetImage(*image);
@@ -58,7 +58,8 @@
TEST(StatusTrayWinTest, ClickOnIcon) {
// Create an icon, send a fake click event, make sure observer is called.
StatusTrayWin tray;
- StatusIconWin* icon = static_cast<StatusIconWin*>(tray.CreateStatusIcon());
+ StatusIconWin* icon = static_cast<StatusIconWin*>(
+ tray.CreateStatusIcon(StatusTray::OTHER_ICON));
FakeStatusIconObserver observer;
icon->AddObserver(&observer);
// Mimic a click.
@@ -72,7 +73,8 @@
TEST(StatusTrayWinTest, ClickOnBalloon) {
// Create an icon, send a fake click event, make sure observer is called.
StatusTrayWin tray;
- StatusIconWin* icon = static_cast<StatusIconWin*>(tray.CreateStatusIcon());
+ StatusIconWin* icon = static_cast<StatusIconWin*>(
+ tray.CreateStatusIcon(StatusTray::OTHER_ICON));
FakeStatusIconObserver observer;
icon->AddObserver(&observer);
// Mimic a click.
diff --git a/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc b/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc
index e9183af..3439214 100644
--- a/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc
+++ b/chrome/browser/ui/views/sync/profile_signin_confirmation_dialog_views.cc
@@ -194,12 +194,9 @@
IDS_ENTERPRISE_SIGNIN_EXPLANATION_WITHOUT_PROFILE_CREATION_NEW_STYLE,
username, learn_more_text, &offsets);
explanation_label_ = new views::StyledLabel(signin_explanation_text, this);
- views::StyledLabel::RangeStyleInfo link_style =
- views::StyledLabel::RangeStyleInfo::CreateForLink();
- link_style.font_style = gfx::Font::NORMAL;
explanation_label_->AddStyleRange(
ui::Range(offsets[1], offsets[1] + learn_more_text.size()),
- link_style);
+ views::StyledLabel::RangeStyleInfo::CreateForLink());
// Layout the components.
views::GridLayout* dialog_layout = new views::GridLayout(this);
diff --git a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc
index c5f1eaa..bd4df7a 100644
--- a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc
+++ b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc
@@ -178,11 +178,8 @@
}
views::Widget* ChromeWebContentsViewDelegateViews::GetTopLevelWidget() {
- gfx::NativeWindow top_level_window =
- web_contents_->GetView()->GetTopLevelNativeWindow();
- if (!top_level_window)
- return NULL;
- return views::Widget::GetWidgetForNativeWindow(top_level_window);
+ return views::Widget::GetTopLevelWidgetForNativeView(
+ web_contents_->GetView()->GetNativeView());
}
views::FocusManager*
diff --git a/chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc b/chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc
index 6823d1a..b6e35ab 100644
--- a/chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc
+++ b/chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc
@@ -39,7 +39,8 @@
TabModalConfirmDialogViews::TabModalConfirmDialogViews(
TabModalConfirmDialogDelegate* delegate,
content::WebContents* web_contents)
- : delegate_(delegate),
+ : web_contents_(web_contents),
+ delegate_(delegate),
dialog_(NULL),
browser_context_(web_contents->GetBrowserContext()) {
views::MessageBoxView::InitParams init_params(delegate->GetMessage());
@@ -59,7 +60,7 @@
web_contents_modal_dialog_manager->delegate()->
GetWebContentsModalDialogHost());
web_contents_modal_dialog_manager->ShowDialog(dialog_->GetNativeView());
- delegate_->set_close_delegate(this);
+ delegate_->set_operations_delegate(this);
}
TabModalConfirmDialogViews::~TabModalConfirmDialogViews() {
@@ -77,6 +78,13 @@
dialog_->Close();
}
+void TabModalConfirmDialogViews::SetPreventCloseOnLoadStart(bool prevent) {
+ WebContentsModalDialogManager* web_contents_modal_dialog_manager =
+ WebContentsModalDialogManager::FromWebContents(web_contents_);
+ web_contents_modal_dialog_manager->SetPreventCloseOnLoadStart(
+ dialog_->GetNativeView(), prevent);
+}
+
//////////////////////////////////////////////////////////////////////////////
// TabModalConfirmDialogViews, views::LinkListener implementation:
diff --git a/chrome/browser/ui/views/tab_modal_confirm_dialog_views.h b/chrome/browser/ui/views/tab_modal_confirm_dialog_views.h
index 28d2e5b..36e3de3 100644
--- a/chrome/browser/ui/views/tab_modal_confirm_dialog_views.h
+++ b/chrome/browser/ui/views/tab_modal_confirm_dialog_views.h
@@ -58,10 +58,13 @@
// TabModalConfirmDialogCloseDelegate:
virtual void CloseDialog() OVERRIDE;
+ virtual void SetPreventCloseOnLoadStart(bool prevent) OVERRIDE;
// views::LinkListener:
virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
+ content::WebContents* web_contents_;
+
scoped_ptr<TabModalConfirmDialogDelegate> delegate_;
// The message box view whose commands we handle.
diff --git a/chrome/browser/ui/website_settings/website_settings.cc b/chrome/browser/ui/website_settings/website_settings.cc
index c0c175c..e4d268a 100644
--- a/chrome/browser/ui/website_settings/website_settings.cc
+++ b/chrome/browser/ui/website_settings/website_settings.cc
@@ -24,7 +24,6 @@
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/content_settings/local_shared_objects_container.h"
#include "chrome/browser/history/history_service_factory.h"
-#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/policy/profile_policy_connector_factory.h"
#include "chrome/browser/profiles/profile.h"
@@ -136,6 +135,7 @@
case CONTENT_SETTINGS_TYPE_POPUPS:
case CONTENT_SETTINGS_TYPE_FULLSCREEN:
case CONTENT_SETTINGS_TYPE_MOUSELOCK:
+ case CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS:
primary_pattern = ContentSettingsPattern::FromURL(site_url_);
secondary_pattern = ContentSettingsPattern::Wildcard();
break;
diff --git a/chrome/browser/ui/website_settings/website_settings_infobar_delegate.cc b/chrome/browser/ui/website_settings/website_settings_infobar_delegate.cc
index 9c2ba16..f51f741 100644
--- a/chrome/browser/ui/website_settings/website_settings_infobar_delegate.cc
+++ b/chrome/browser/ui/website_settings/website_settings_infobar_delegate.cc
@@ -12,6 +12,7 @@
#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
+
// static
void WebsiteSettingsInfoBarDelegate::Create(InfoBarService* infobar_service) {
infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
diff --git a/chrome/browser/ui/website_settings/website_settings_infobar_delegate.h b/chrome/browser/ui/website_settings/website_settings_infobar_delegate.h
index 6f6b3d9..19fffa0 100644
--- a/chrome/browser/ui/website_settings/website_settings_infobar_delegate.h
+++ b/chrome/browser/ui/website_settings/website_settings_infobar_delegate.h
@@ -16,7 +16,8 @@
// the reload right from the infobar.
class WebsiteSettingsInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
- // Creates a website settings delegate and adds it to |infobar_service|.
+ // Creates a website settings infobar delegate and adds it to
+ // |infobar_service|.
static void Create(InfoBarService* infobar_service);
private:
diff --git a/chrome/browser/ui/webui/OWNERS b/chrome/browser/ui/webui/OWNERS
index 6df6124..dfafdfb 100644
--- a/chrome/browser/ui/webui/OWNERS
+++ b/chrome/browser/ui/webui/OWNERS
@@ -1,6 +1,7 @@
arv@chromium.org
bauerb@chromium.org
dbeam@chromium.org
+dubroy@chromium.org
estade@chromium.org
jhawkins@chromium.org
nkostylev@chromium.org
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
index 8a3959e..b73b847 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -46,6 +46,7 @@
#include "chrome/browser/ui/webui/profiler_ui.h"
#include "chrome/browser/ui/webui/quota_internals/quota_internals_ui.h"
#include "chrome/browser/ui/webui/signin/profile_signin_confirmation_ui.h"
+#include "chrome/browser/ui/webui/signin/user_chooser_ui.h"
#include "chrome/browser/ui/webui/signin_internals_ui.h"
#include "chrome/browser/ui/webui/sync_internals_ui.h"
#include "chrome/browser/ui/webui/translate_internals/translate_internals_ui.h"
@@ -391,6 +392,13 @@
return &NewWebUI<keyboard::KeyboardUIController>;
#endif
+#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) && !defined(OS_IOS)
+ if (url.host() == chrome::kChromeUIUserChooserHost &&
+ CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kNewProfileManagement))
+ return &NewWebUI<UserChooserUI>;
+#endif
+
if (url.host() == chrome::kChromeUIChromeURLsHost ||
url.host() == chrome::kChromeUICreditsHost ||
url.host() == chrome::kChromeUIDNSHost ||
diff --git a/chrome/browser/ui/webui/chromeos/login/network_state_informer.cc b/chrome/browser/ui/webui/chromeos/login/network_state_informer.cc
index bc6cf68..f090f56 100644
--- a/chrome/browser/ui/webui/chromeos/login/network_state_informer.cc
+++ b/chrome/browser/ui/webui/chromeos/login/network_state_informer.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
+#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/net/proxy_config_handler.h"
#include "chrome/browser/prefs/proxy_config_dictionary.h"
@@ -216,9 +217,10 @@
bool NetworkStateInformer::IsProxyConfigured(const NetworkState* network) {
DCHECK(network);
-
- scoped_ptr<ProxyConfigDictionary> proxy_dict(
- proxy_config::GetProxyConfigForNetwork(*network));
+ onc::ONCSource onc_source = onc::ONC_SOURCE_NONE;
+ scoped_ptr<ProxyConfigDictionary> proxy_dict =
+ proxy_config::GetProxyConfigForNetwork(
+ NULL, g_browser_process->local_state(), *network, &onc_source);
ProxyPrefs::ProxyMode mode;
return (proxy_dict &&
proxy_dict->GetMode(&mode) &&
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
index f679ad7..adfeb11 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -196,10 +196,14 @@
}
bool IsProxyError(NetworkStateInformer::State state,
- ErrorScreenActor::ErrorReason reason) {
+ ErrorScreenActor::ErrorReason reason,
+ net::Error frame_error) {
return state == NetworkStateInformer::PROXY_AUTH_REQUIRED ||
reason == ErrorScreenActor::ERROR_REASON_PROXY_AUTH_CANCELLED ||
- reason == ErrorScreenActor::ERROR_REASON_PROXY_CONNECTION_FAILED;
+ reason == ErrorScreenActor::ERROR_REASON_PROXY_CONNECTION_FAILED ||
+ (reason == ErrorScreenActor::ERROR_REASON_FRAME_ERROR &&
+ (frame_error == net::ERR_PROXY_CONNECTION_FAILED ||
+ frame_error == net::ERR_TUNNEL_CONNECTION_FAILED));
}
bool IsSigninScreen(const OobeUI::Screen screen) {
@@ -337,8 +341,7 @@
is_first_update_state_call_(true),
offline_login_active_(false),
last_network_state_(NetworkStateInformer::UNKNOWN),
- has_pending_auth_ui_(false),
- ignore_next_user_abort_frame_error_(false) {
+ has_pending_auth_ui_(false) {
DCHECK(network_state_informer_.get());
DCHECK(error_screen_actor_);
network_state_informer_->AddObserver(this);
@@ -446,7 +449,6 @@
}
void SigninScreenHandler::Show(bool oobe_ui) {
- TRACE_EVENT_ASYNC_BEGIN0("ui", "ShowLoginWebUI", this);
CHECK(delegate_);
oobe_ui_ = oobe_ui;
if (!page_is_ready()) {
@@ -628,7 +630,8 @@
ReloadGaiaScreen();
}
- if (reason == ErrorScreenActor::ERROR_REASON_FRAME_ERROR) {
+ if (reason == ErrorScreenActor::ERROR_REASON_FRAME_ERROR &&
+ !IsProxyError(state, reason, frame_error_)) {
LOG(WARNING) << "Retry page load due to reason: "
<< ErrorReasonString(reason);
ReloadGaiaScreen();
@@ -649,7 +652,7 @@
network_state_informer_->last_network_service_path();
const std::string network_id = GetNetworkUniqueId(service_path);
const bool is_under_captive_portal = IsUnderCaptivePortal(state, reason);
- const bool is_proxy_error = IsProxyError(state, reason);
+ const bool is_proxy_error = IsProxyError(state, reason, frame_error_);
const bool is_gaia_loading_timeout =
(reason == ErrorScreenActor::ERROR_REASON_LOADING_TIMEOUT);
@@ -728,7 +731,6 @@
}
LOG(WARNING) << "Reload auth extension frame.";
frame_state_ = FRAME_STATE_LOADING;
- ignore_next_user_abort_frame_error_ = true;
CallJS("login.GaiaSigninScreen.doReload");
}
@@ -1014,11 +1016,19 @@
// Allow locally managed user creation only if:
// 1. Enterprise managed device > is allowed by policy.
// 2. Consumer device > owner exists.
+ // 3. New users are allowed by owner.
+
+ CrosSettings* cros_settings = CrosSettings::Get();
+ bool allow_new_user = false;
+ cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user);
+
bool managed_users_allowed =
UserManager::Get()->AreLocallyManagedUsersAllowed();
bool managed_users_can_create = false;
- if (managed_users_allowed)
- managed_users_can_create = delegate_->GetUsers().size() > 0;
+ if (managed_users_allowed) {
+ managed_users_can_create =
+ (delegate_->GetUsers().size() > 0) && allow_new_user;
+ }
params->SetBoolean("managedUsersEnabled", managed_users_allowed);
params->SetBoolean("managedUsersCanCreate", managed_users_can_create);
}
@@ -1069,7 +1079,6 @@
params.SetString("gaiaUrl", gaia_url.spec());
frame_state_ = FRAME_STATE_LOADING;
- ignore_next_user_abort_frame_error_ = true;
CallJS("login.GaiaSigninScreen.loadAuthExtension", params);
}
@@ -1436,9 +1445,8 @@
}
void SigninScreenHandler::HandleLoginVisible(const std::string& source) {
- TRACE_EVENT_ASYNC_END0("ui", "ShowLoginWebUI", this);
- LOG(INFO) << "Login WebUI >> LoginVisible, source: " << source << ", "
- << "webui_visible_: " << webui_visible_;
+ LOG(WARNING) << "Login WebUI >> loginVisible, src: " << source << ", "
+ << "webui_visible_: " << webui_visible_;
if (!webui_visible_) {
// There might be multiple messages from OOBE UI so send notifications after
// the first one only.
@@ -1446,6 +1454,8 @@
chrome::NOTIFICATION_LOGIN_WEBUI_VISIBLE,
content::NotificationService::AllSources(),
content::NotificationService::NoDetails());
+ TRACE_EVENT_ASYNC_END0(
+ "ui", "ShowLoginWebUI", LoginDisplayHostImpl::kShowLoginWebUIid);
}
webui_visible_ = true;
if (preferences_changed_delayed_)
@@ -1503,26 +1513,20 @@
}
void SigninScreenHandler::HandleFrameLoadingCompleted(int status) {
- frame_error_ = static_cast<net::Error>(-status);
- if (frame_error_ == net::OK) {
+ const net::Error frame_error = static_cast<net::Error>(-status);
+ if (frame_error == net::ERR_ABORTED) {
+ LOG(WARNING) << "Ignore gaia frame error: " << frame_error;
+ return;
+ }
+ frame_error_ = frame_error;
+ if (frame_error == net::OK) {
LOG(INFO) << "Gaia frame is loaded";
frame_state_ = FRAME_STATE_LOADED;
} else {
- // Ignore net::ERR_ABORTED frame error once.
- if (ignore_next_user_abort_frame_error_ &&
- frame_error_ == net::ERR_ABORTED) {
- LOG(WARNING) << "Ignore gaia frame error: " << frame_error_;
- ignore_next_user_abort_frame_error_ = false;
- return;
- }
-
LOG(WARNING) << "Gaia frame error: " << frame_error_;
frame_state_ = FRAME_STATE_ERROR;
}
- // Frame load okay and other frame error clears the flag.
- ignore_next_user_abort_frame_error_ = false;
-
if (network_state_informer_->state() != NetworkStateInformer::ONLINE)
return;
if (frame_state_ == FRAME_STATE_LOADED) {
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
index 1c17b8c..aea2d03 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
@@ -459,12 +459,6 @@
// NOTIFICATION_AUTH_CANCELLED.
bool has_pending_auth_ui_;
- // Whether to ignore the next net::ERR_ABORTED frame error. ERR_ABORTED could
- // be triggered when reloading gaia frame's src with a pending load.
- // ReloadGaiaExtension() sets this flag to true to ignore potential
- // ERR_ABORTED triggered from its reload request. See http://crbug.com/242527.
- bool ignore_next_user_abort_frame_error_;
-
DISALLOW_COPY_AND_ASSIGN(SigninScreenHandler);
};
diff --git a/chrome/browser/ui/webui/crashes_ui.cc b/chrome/browser/ui/webui/crashes_ui.cc
index b885b01..293cae7 100644
--- a/chrome/browser/ui/webui/crashes_ui.cc
+++ b/chrome/browser/ui/webui/crashes_ui.cc
@@ -19,6 +19,7 @@
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
@@ -104,7 +105,8 @@
}
void CrashesDOMHandler::RegisterMessages() {
- upload_list_->LoadUploadListAsynchronously();
+ upload_list_->LoadUploadListAsynchronously(
+ content::BrowserThread::GetBlockingPool());
web_ui()->RegisterMessageCallback("requestCrashList",
base::Bind(&CrashesDOMHandler::HandleRequestCrashes,
diff --git a/chrome/browser/ui/webui/extensions/extension_icon_source.cc b/chrome/browser/ui/webui/extensions/extension_icon_source.cc
index 5cd6ed6..a25f0e3 100644
--- a/chrome/browser/ui/webui/extensions/extension_icon_source.cc
+++ b/chrome/browser/ui/webui/extensions/extension_icon_source.cc
@@ -65,7 +65,7 @@
struct ExtensionIconSource::ExtensionIconRequest {
content::URLDataSource::GotDataCallback callback;
- const extensions::Extension* extension;
+ scoped_refptr<const extensions::Extension> extension;
bool grayscale;
int size;
ExtensionIconSet::MatchType match;
diff --git a/chrome/browser/ui/webui/flash_ui.cc b/chrome/browser/ui/webui/flash_ui.cc
index 84a5eba..050b033 100644
--- a/chrome/browser/ui/webui/flash_ui.cc
+++ b/chrome/browser/ui/webui/flash_ui.cc
@@ -25,6 +25,7 @@
#include "chrome/browser/ui/webui/crashes_ui.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/url_constants.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/gpu_data_manager_observer.h"
#include "content/public/browser/plugin_service.h"
@@ -33,6 +34,7 @@
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "content/public/browser/web_ui_message_handler.h"
+#include "content/public/common/webplugininfo.h"
#include "gpu/config/gpu_info.h"
#include "grit/browser_resources.h"
#include "grit/chromium_strings.h"
@@ -41,7 +43,6 @@
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "webkit/plugins/plugin_constants.h"
-#include "webkit/plugins/webplugininfo.h"
#if defined(OS_WIN)
#include "base/win/windows_version.h"
@@ -99,7 +100,7 @@
void HandleRequestFlashInfo(const ListValue* args);
// Callback for the Flash plugin information.
- void OnGotPlugins(const std::vector<webkit::WebPluginInfo>& plugins);
+ void OnGotPlugins(const std::vector<content::WebPluginInfo>& plugins);
private:
// Called when we think we might have enough information to return data back
@@ -142,7 +143,8 @@
has_plugin_info_(false) {
// Request Crash data asynchronously.
upload_list_ = CrashUploadList::Create(this);
- upload_list_->LoadUploadListAsynchronously();
+ upload_list_->LoadUploadListAsynchronously(
+ content::BrowserThread::GetBlockingPool());
// Watch for changes in GPUInfo.
GpuDataManager::GetInstance()->AddObserver(this);
@@ -203,7 +205,7 @@
}
void FlashDOMHandler::OnGotPlugins(
- const std::vector<webkit::WebPluginInfo>& plugins) {
+ const std::vector<content::WebPluginInfo>& plugins) {
has_plugin_info_ = true;
MaybeRespondToPage();
}
@@ -266,7 +268,7 @@
AddPair(list, l10n_util::GetStringUTF16(IDS_ABOUT_VERSION_OS), os_label);
// Obtain the version of the Flash plugins.
- std::vector<webkit::WebPluginInfo> info_array;
+ std::vector<content::WebPluginInfo> info_array;
PluginService::GetInstance()->GetPluginInfoArray(
GURL(), kFlashPluginSwfMimeType, false, &info_array, NULL);
if (info_array.empty()) {
diff --git a/chrome/browser/ui/webui/gesture_config_ui.h b/chrome/browser/ui/webui/gesture_config_ui.h
index 3ef29cd..cfb8858 100644
--- a/chrome/browser/ui/webui/gesture_config_ui.h
+++ b/chrome/browser/ui/webui/gesture_config_ui.h
@@ -19,6 +19,9 @@
virtual ~GestureConfigUI();
private:
+ // TODO(mohsen): Add a whitelist of preferences that are allowed to be set or
+ // get here and check requested preferences against this whitelist.
+
/**
* Request a preference setting's value.
* This method is asynchronous; the result is provided by a call to
diff --git a/chrome/browser/ui/webui/media/webrtc_logs_ui.cc b/chrome/browser/ui/webui/media/webrtc_logs_ui.cc
index 54de606..6d4505a 100644
--- a/chrome/browser/ui/webui/media/webrtc_logs_ui.cc
+++ b/chrome/browser/ui/webui/media/webrtc_logs_ui.cc
@@ -19,6 +19,7 @@
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
@@ -112,7 +113,8 @@
}
void WebRtcLogsDOMHandler::RegisterMessages() {
- upload_list_->LoadUploadListAsynchronously();
+ upload_list_->LoadUploadListAsynchronously(
+ content::BrowserThread::GetBlockingPool());
web_ui()->RegisterMessageCallback("requestWebRtcLogsList",
base::Bind(&WebRtcLogsDOMHandler::HandleRequestWebRtcLogs,
diff --git a/chrome/browser/ui/webui/nacl_ui.cc b/chrome/browser/ui/webui/nacl_ui.cc
index 744d9cf..ed94181 100644
--- a/chrome/browser/ui/webui/nacl_ui.cc
+++ b/chrome/browser/ui/webui/nacl_ui.cc
@@ -28,13 +28,13 @@
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "content/public/browser/web_ui_message_handler.h"
+#include "content/public/common/webplugininfo.h"
#include "grit/browser_resources.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
-#include "webkit/plugins/webplugininfo.h"
#if defined(OS_WIN)
#include "base/win/windows_version.h"
@@ -109,7 +109,7 @@
void HandleRequestNaClInfo(const ListValue* args);
// Callback for the NaCl plugin information.
- void OnGotPlugins(const std::vector<webkit::WebPluginInfo>& plugins);
+ void OnGotPlugins(const std::vector<content::WebPluginInfo>& plugins);
// A helper callback that receives the result of checking if PNaCl path
// exists. |is_valid| is true if the PNaCl path that was returned by
@@ -236,7 +236,7 @@
}
void NaClDomHandler::OnGotPlugins(
- const std::vector<webkit::WebPluginInfo>& plugins) {
+ const std::vector<content::WebPluginInfo>& plugins) {
has_plugin_info_ = true;
MaybeRespondToPage();
}
@@ -282,7 +282,7 @@
AddLineBreak(list.get());
// Obtain the version of the NaCl plugin.
- std::vector<webkit::WebPluginInfo> info_array;
+ std::vector<content::WebPluginInfo> info_array;
PluginService::GetInstance()->GetPluginInfoArray(
GURL(), "application/x-nacl", false, &info_array, NULL);
string16 nacl_version;
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
index 1c5a136..e896dfa 100644
--- a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
+++ b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
@@ -1555,20 +1555,12 @@
LOG(ERROR) << error;
}
- chromeos::CertificateHandler::CertsByGUID imported_server_and_ca_certs;
chromeos::CertificateHandler certificate_handler;
- if (!certificate_handler.ImportCertificates(certificates, onc_source, NULL,
- &imported_server_and_ca_certs)) {
+ if (!certificate_handler.ImportCertificates(certificates, onc_source, NULL)) {
error += "Some certificates couldn't be imported. ";
LOG(ERROR) << error;
}
- if (!chromeos::onc::ResolveServerCertRefsInNetworks(
- imported_server_and_ca_certs, &network_configs)) {
- error += "Some certificate references could not be resolved. ";
- LOG(ERROR) << error;
- }
-
chromeos::NetworkLibrary* network_library =
chromeos::NetworkLibrary::Get();
network_library->LoadOncNetworks(network_configs, onc_source);
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
index aacd04b..cffe88f 100644
--- a/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
@@ -88,7 +88,7 @@
net::URLRequestContext* context = context_getter->GetURLRequestContext();
net::HttpNetworkSession* http_network_session =
context->http_transaction_factory()->GetSession();
- net::HttpServerProperties* http_server_properties =
+ base::WeakPtr<net::HttpServerProperties> http_server_properties =
http_network_session->http_server_properties();
net::HostPortPair origin(hostname, port);
http_server_properties->SetPipelineCapability(origin, capability);
diff --git a/chrome/browser/ui/webui/ntp/android/navigation_handler.cc b/chrome/browser/ui/webui/ntp/android/navigation_handler.cc
new file mode 100644
index 0000000..d5c9a2e
--- /dev/null
+++ b/chrome/browser/ui/webui/ntp/android/navigation_handler.cc
@@ -0,0 +1,89 @@
+// Copyright 2013 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/ui/webui/ntp/android/navigation_handler.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/metrics/histogram.h"
+#include "base/values.h"
+#include "chrome/browser/google/google_util.h"
+#include "chrome/common/url_constants.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_ui.h"
+#include "content/public/common/page_transition_types.h"
+
+NavigationHandler::NavigationHandler() {}
+
+NavigationHandler::~NavigationHandler() {
+ // Record an omnibox-based navigation, if there is one.
+ content::NavigationEntry* entry =
+ web_ui()->GetWebContents()->GetController().GetActiveEntry();
+ if (!entry)
+ return;
+
+ if (!(entry->GetTransitionType() &
+ content::PAGE_TRANSITION_FROM_ADDRESS_BAR) ||
+ entry->GetTransitionType() & content::PAGE_TRANSITION_FORWARD_BACK) {
+ return;
+ }
+
+ if (entry->GetURL().SchemeIs(chrome::kChromeUIScheme) &&
+ entry->GetURL().host() == chrome::kChromeUINewTabHost) {
+ return;
+ }
+
+ Action action;
+ if ((entry->GetTransitionType() & content::PAGE_TRANSITION_CORE_MASK) ==
+ content::PAGE_TRANSITION_GENERATED) {
+ action = ACTION_SEARCHED_USING_OMNIBOX;
+ } else if (google_util::IsGoogleHomePageUrl(entry->GetURL())) {
+ action = ACTION_NAVIGATED_TO_GOOGLE_HOMEPAGE;
+ } else {
+ action = ACTION_NAVIGATED_USING_OMNIBOX;
+ }
+ RecordAction(action);
+}
+
+void NavigationHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(
+ "openedMostVisited",
+ base::Bind(&NavigationHandler::HandleOpenedMostVisited,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "openedRecentlyClosed",
+ base::Bind(&NavigationHandler::HandleOpenedRecentlyClosed,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "openedBookmark",
+ base::Bind(&NavigationHandler::HandleOpenedBookmark,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "openedForeignSession",
+ base::Bind(&NavigationHandler::HandleOpenedForeignSession,
+ base::Unretained(this)));
+}
+
+void NavigationHandler::HandleOpenedMostVisited(const base::ListValue* args) {
+ RecordAction(ACTION_OPENED_MOST_VISITED_ENTRY);
+}
+
+void NavigationHandler::HandleOpenedRecentlyClosed(
+ const base::ListValue* args) {
+ RecordAction(ACTION_OPENED_RECENTLY_CLOSED_ENTRY);
+}
+
+void NavigationHandler::HandleOpenedBookmark(const base::ListValue* args) {
+ RecordAction(ACTION_OPENED_BOOKMARK);
+}
+
+void NavigationHandler::HandleOpenedForeignSession(
+ const base::ListValue* args) {
+ RecordAction(ACTION_OPENED_FOREIGN_SESSION);
+}
+
+void NavigationHandler::RecordAction(Action action) {
+ UMA_HISTOGRAM_ENUMERATION("NewTabPage.ActionAndroid", action, NUM_ACTIONS);
+}
diff --git a/chrome/browser/ui/webui/ntp/android/navigation_handler.h b/chrome/browser/ui/webui/ntp/android/navigation_handler.h
new file mode 100644
index 0000000..fc45d86
--- /dev/null
+++ b/chrome/browser/ui/webui/ntp/android/navigation_handler.h
@@ -0,0 +1,65 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_NTP_ANDROID_NAVIGATION_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_NTP_ANDROID_NAVIGATION_HANDLER_H_
+
+#include "base/compiler_specific.h"
+#include "content/public/browser/web_ui_message_handler.h"
+
+namespace base {
+class ListValue;
+}
+
+// Records a UMA stat ("NewTabPage.ActionAndroid") for the action the user takes
+// to navigate away from the NTP.
+class NavigationHandler : public content::WebUIMessageHandler {
+ public:
+ NavigationHandler();
+ virtual ~NavigationHandler();
+
+ // WebUIMessageHandler implementation.
+ virtual void RegisterMessages() OVERRIDE;
+
+ // Callback for "openedMostVisited".
+ void HandleOpenedMostVisited(const base::ListValue* args);
+
+ // Callback for "openedRecentlyClosed".
+ void HandleOpenedRecentlyClosed(const base::ListValue* args);
+
+ // Callback for "openedBookmark".
+ void HandleOpenedBookmark(const base::ListValue* args);
+
+ // Callback for "openedForeignSession".
+ void HandleOpenedForeignSession(const base::ListValue* args);
+
+ private:
+ // Possible actions taken by the user on the NTP. This enum is also defined in
+ // histograms.xml. WARNING: these values must stay in sync with histograms.xml
+ // and new actions can be added only at the end of the enum.
+ enum Action {
+ // User performed a search using the omnibox
+ ACTION_SEARCHED_USING_OMNIBOX = 0,
+ // User navigated to Google search homepage using the omnibox
+ ACTION_NAVIGATED_TO_GOOGLE_HOMEPAGE = 1,
+ // User navigated to any other page using the omnibox
+ ACTION_NAVIGATED_USING_OMNIBOX = 2,
+ // User opened a most visited page
+ ACTION_OPENED_MOST_VISITED_ENTRY = 3,
+ // User opened a recently closed tab
+ ACTION_OPENED_RECENTLY_CLOSED_ENTRY = 4,
+ // User opened a bookmark
+ ACTION_OPENED_BOOKMARK = 5,
+ // User opened a foreign session (from other devices section)
+ ACTION_OPENED_FOREIGN_SESSION = 6,
+ // The number of possible actions
+ NUM_ACTIONS = 7
+ };
+
+ void RecordAction(Action action);
+
+ DISALLOW_COPY_AND_ASSIGN(NavigationHandler);
+};
+
+#endif // CHROME_BROWSER_UI_WEBUI_NTP_ANDROID_NAVIGATION_HANDLER_H_
diff --git a/chrome/browser/ui/webui/ntp/new_tab_ui.cc b/chrome/browser/ui/webui/ntp/new_tab_ui.cc
index 35ac6b5..0d4836a 100644
--- a/chrome/browser/ui/webui/ntp/new_tab_ui.cc
+++ b/chrome/browser/ui/webui/ntp/new_tab_ui.cc
@@ -45,6 +45,7 @@
#else
#include "chrome/browser/ui/webui/ntp/android/bookmarks_handler.h"
#include "chrome/browser/ui/webui/ntp/android/context_menu_handler.h"
+#include "chrome/browser/ui/webui/ntp/android/navigation_handler.h"
#include "chrome/browser/ui/webui/ntp/android/new_tab_page_ready_handler.h"
#include "chrome/browser/ui/webui/ntp/android/promo_handler.h"
#endif
@@ -104,8 +105,8 @@
web_ui->AddMessageHandler(new browser_sync::ForeignSessionHandler());
web_ui->AddMessageHandler(new MostVisitedHandler());
web_ui->AddMessageHandler(new RecentlyClosedTabsHandler());
- web_ui->AddMessageHandler(new MetricsHandler());
#if !defined(OS_ANDROID)
+ web_ui->AddMessageHandler(new MetricsHandler());
web_ui->AddMessageHandler(new NewTabPageHandler());
if (NewTabUI::IsDiscoveryInNTPEnabled())
web_ui->AddMessageHandler(new SuggestionsHandler());
@@ -128,6 +129,7 @@
// These handlers are specific to the Android NTP page.
web_ui->AddMessageHandler(new BookmarksHandler());
web_ui->AddMessageHandler(new ContextMenuHandler());
+ web_ui->AddMessageHandler(new NavigationHandler());
web_ui->AddMessageHandler(new NewTabPageReadyHandler());
if (!GetProfile()->IsOffTheRecord())
web_ui->AddMessageHandler(new PromoHandler());
diff --git a/chrome/browser/ui/webui/omnibox/omnibox_ui_handler.cc b/chrome/browser/ui/webui/omnibox/omnibox_ui_handler.cc
index 3b62f03..c436f9d 100644
--- a/chrome/browser/ui/webui/omnibox/omnibox_ui_handler.cc
+++ b/chrome/browser/ui/webui/omnibox/omnibox_ui_handler.cc
@@ -123,8 +123,8 @@
output->SetInteger(item_prefix + ".relevance", it->relevance);
output->SetBoolean(item_prefix + ".deletable", it->deletable);
output->SetString(item_prefix + ".fill_into_edit", it->fill_into_edit);
- output->SetInteger(item_prefix + ".inline_autocomplete_offset",
- it->inline_autocomplete_offset);
+ output->SetString(item_prefix + ".inline_autocompletion",
+ it->inline_autocompletion);
output->SetString(item_prefix + ".destination_url",
it->destination_url.spec());
output->SetString(item_prefix + ".contents", it->contents);
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.h b/chrome/browser/ui/webui/options/browser_options_handler.h
index a9173f8..06199f0 100644
--- a/chrome/browser/ui/webui/options/browser_options_handler.h
+++ b/chrome/browser/ui/webui/options/browser_options_handler.h
@@ -10,6 +10,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "base/prefs/pref_change_registrar.h"
#include "base/prefs/pref_member.h"
#include "base/time/time.h"
#include "chrome/browser/profiles/profile.h"
@@ -24,8 +25,6 @@
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/system/pointer_device_observer.h"
-#else
-#include "base/prefs/pref_change_registrar.h"
#endif // defined(OS_CHROMEOS)
class AutocompleteController;
diff --git a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc
index e946409..7ef79d1 100644
--- a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc
@@ -104,20 +104,24 @@
}
void CoreChromeOSOptionsHandler::InitializeHandler() {
- // In case the options page is reloaded, forget the last selected network.
+ // This function is both called on the initial page load and on each reload.
+ // For the latter case, forget the last selected network.
proxy_config_service_.SetCurrentNetwork(std::string());
+ // And clear the cached configuration.
+ proxy_config_service_.UpdateFromPrefs();
CoreOptionsHandler::InitializeHandler();
+ PrefService* profile_prefs = NULL;
Profile* profile = Profile::FromWebUI(web_ui());
- PrefService* prefs = profile->GetPrefs();
- proxy_prefs_.Init(prefs);
- proxy_prefs_.Add(prefs::kProxy,
- base::Bind(&CoreChromeOSOptionsHandler::OnPreferenceChanged,
- base::Unretained(this),
- prefs));
- proxy_config_service_.SetPrefs(ProfileHelper::IsSigninProfile(profile),
- prefs);
+ if (!ProfileHelper::IsSigninProfile(profile)) {
+ profile_prefs = profile->GetPrefs();
+ ObservePref(prefs::kOpenNetworkConfiguration);
+ }
+ ObservePref(prefs::kProxy);
+ ObservePref(prefs::kDeviceOpenNetworkConfiguration);
+ proxy_config_service_.SetPrefs(profile_prefs,
+ g_browser_process->local_state());
}
base::Value* CoreChromeOSOptionsHandler::FetchPref(
@@ -215,12 +219,6 @@
::options::CoreOptionsHandler::Observe(type, source, details);
}
-void CoreChromeOSOptionsHandler::SelectNetwork(
- const std::string& service_path) {
- proxy_config_service_.SetCurrentNetwork(service_path);
- NotifyProxyPrefsChanged();
-}
-
void CoreChromeOSOptionsHandler::SelectNetworkCallback(
const base::ListValue* args) {
std::string service_path;
@@ -229,18 +227,24 @@
NOTREACHED();
return;
}
- SelectNetwork(service_path);
+ proxy_config_service_.SetCurrentNetwork(service_path);
+ NotifyProxyPrefsChanged();
}
void CoreChromeOSOptionsHandler::OnPreferenceChanged(
PrefService* service,
const std::string& pref_name) {
- // Special handling for preferences kUseSharedProxies and kProxy, the latter
- // controls the former and decides if it's managed by policy/extension.
- const PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs();
- if (service == pref_service &&
- (proxy_prefs_.IsObserved(pref_name) ||
- pref_name == prefs::kUseSharedProxies)) {
+ // Redetermine the current proxy settings and notify the UI if any of these
+ // preferences change.
+ if (pref_name == prefs::kOpenNetworkConfiguration ||
+ pref_name == prefs::kDeviceOpenNetworkConfiguration ||
+ pref_name == prefs::kProxy) {
+ NotifyProxyPrefsChanged();
+ return;
+ }
+ if (pref_name == prefs::kUseSharedProxies) {
+ // kProxy controls kUseSharedProxies and decides if it's managed by
+ // policy/extension.
NotifyPrefChanged(prefs::kUseSharedProxies, prefs::kProxy);
return;
}
@@ -257,6 +261,7 @@
}
void CoreChromeOSOptionsHandler::NotifyProxyPrefsChanged() {
+ proxy_config_service_.UpdateFromPrefs();
for (size_t i = 0; i < kProxySettingsCount; ++i) {
base::Value* value = NULL;
proxy_cros_settings_parser::GetProxyPrefValue(
diff --git a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h b/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h
index 52cb431..d73db1b 100644
--- a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h
+++ b/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h
@@ -6,7 +6,6 @@
#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_CORE_CHROMEOS_OPTIONS_HANDLER_H_
#include "base/compiler_specific.h"
-#include "base/prefs/pref_change_registrar.h"
#include "chrome/browser/chromeos/ui_proxy_config_service.h"
#include "chrome/browser/ui/webui/options/core_options_handler.h"
@@ -38,10 +37,6 @@
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
- // Select the network to show proxy settings for. Triggers pref notifications
- // about the updated proxy settings.
- void SelectNetwork(const std::string& service_path);
-
private:
virtual void OnPreferenceChanged(PrefService* service,
const std::string& pref_name) OVERRIDE;
@@ -55,7 +50,6 @@
void NotifyProxyPrefsChanged();
UIProxyConfigService proxy_config_service_;
- PrefChangeRegistrar proxy_prefs_;
};
} // namespace options
diff --git a/chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.cc
index 315738b..25fecc1 100644
--- a/chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.cc
@@ -36,17 +36,8 @@
// TODO(zork): Remove this blacklist when fonts are added to Chrome OS.
// see: crbug.com/240586
-const char* kLanguageBlacklist[] = {
- "km", // Khmer language
- "si", // Sinhala language
-};
-
bool IsBlacklisted(const std::string& language_code) {
- for (size_t i = 0; i < arraysize(kLanguageBlacklist); ++i) {
- if (language_code == kLanguageBlacklist[i])
- return true;
- }
- return false;
+ return language_code == "si"; // Sinhala
}
} // namespace
diff --git a/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc
index 9d1f9e1..9dad157 100644
--- a/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc
@@ -146,7 +146,7 @@
void DisplayOptionsHandler::SendAllDisplayInfo() {
DisplayManager* display_manager = GetDisplayManager();
- std::vector<const gfx::Display*> displays;
+ std::vector<gfx::Display> displays;
for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
displays.push_back(display_manager->GetDisplayAt(i));
}
@@ -154,7 +154,7 @@
}
void DisplayOptionsHandler::SendDisplayInfo(
- const std::vector<const gfx::Display*> displays) {
+ const std::vector<gfx::Display>& displays) {
DisplayManager* display_manager = GetDisplayManager();
ash::DisplayController* display_controller =
ash::Shell::GetInstance()->display_controller();
@@ -163,27 +163,27 @@
int64 primary_id = ash::Shell::GetScreen()->GetPrimaryDisplay().id();
base::ListValue js_displays;
for (size_t i = 0; i < displays.size(); ++i) {
- const gfx::Display* display = displays[i];
+ const gfx::Display& display = displays[i];
const ash::internal::DisplayInfo& display_info =
- display_manager->GetDisplayInfo(display->id());
- const gfx::Rect& bounds = display->bounds();
+ display_manager->GetDisplayInfo(display.id());
+ const gfx::Rect& bounds = display.bounds();
base::DictionaryValue* js_display = new base::DictionaryValue();
- js_display->SetString("id", base::Int64ToString(display->id()));
+ js_display->SetString("id", base::Int64ToString(display.id()));
js_display->SetInteger("x", bounds.x());
js_display->SetInteger("y", bounds.y());
js_display->SetInteger("width", bounds.width());
js_display->SetInteger("height", bounds.height());
js_display->SetString("name",
- display_manager->GetDisplayNameForId(display->id()));
- js_display->SetBoolean("isPrimary", display->id() == primary_id);
- js_display->SetBoolean("isInternal", display->IsInternal());
+ display_manager->GetDisplayNameForId(display.id()));
+ js_display->SetBoolean("isPrimary", display.id() == primary_id);
+ js_display->SetBoolean("isInternal", display.IsInternal());
js_display->SetInteger("orientation",
static_cast<int>(display_info.rotation()));
std::vector<float> ui_scales = DisplayManager::GetScalesForDisplay(
display_info);
base::ListValue* js_scales = new base::ListValue();
gfx::SizeF base_size = display_info.bounds_in_pixel().size();
- base_size.Scale(1.0f / display->device_scale_factor());
+ base_size.Scale(1.0f / display.device_scale_factor());
if (display_info.rotation() == gfx::Display::ROTATE_90 ||
display_info.rotation() == gfx::Display::ROTATE_270) {
float tmp = base_size.width();
diff --git a/chrome/browser/ui/webui/options/chromeos/display_options_handler.h b/chrome/browser/ui/webui/options/chromeos/display_options_handler.h
index 2459ac9..e34617b 100644
--- a/chrome/browser/ui/webui/options/chromeos/display_options_handler.h
+++ b/chrome/browser/ui/webui/options/chromeos/display_options_handler.h
@@ -42,7 +42,7 @@
void SendAllDisplayInfo();
// Sends the specified display information to the web_ui of options page.
- void SendDisplayInfo(const std::vector<const gfx::Display*> displays);
+ void SendDisplayInfo(const std::vector<gfx::Display>& displays);
// Called when the fade-out animation for mirroring status change is finished.
void OnFadeOutForMirroringFinished(bool is_mirroring);
diff --git a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc
index e9718a8..39b6d61 100644
--- a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc
@@ -279,6 +279,13 @@
base::Bind(&ShillError, "SetNetworkProperty"));
}
+const base::DictionaryValue* FindPolicyForActiveUser(
+ const NetworkState* network,
+ onc::ONCSource* onc_source) {
+ *onc_source = network->onc_source();
+ return NetworkLibrary::Get()->FindOncForNetwork(network->guid());
+}
+
std::string ActivationStateString(const std::string& activation_state) {
int id;
if (activation_state == flimflam::kActivationStateActivated)
@@ -636,12 +643,13 @@
shill_properties.GetString(flimflam::kL2tpIpsecUserProperty, &username);
dictionary->SetString(kTagUsername, username);
- // TODO(stevenjb): Move FindOncFornetwork()
- const base::DictionaryValue* onc = NetworkLibrary::Get()->
- FindOncForNetwork(vpn->guid());
+ onc::ONCSource onc_source = onc::ONC_SOURCE_NONE;
+ const base::DictionaryValue* onc = FindPolicyForActiveUser(vpn, &onc_source);
+
NetworkPropertyUIData hostname_ui_data;
hostname_ui_data.ParseOncProperty(
- vpn->onc_source(), onc,
+ onc_source,
+ onc,
base::StringPrintf("%s.%s", onc::network_config::kVPN, onc::vpn::kHost));
std::string provider_host;
shill_properties.GetString(flimflam::kProviderHostProperty, &provider_host);
@@ -1422,9 +1430,10 @@
return;
}
- const NetworkPropertyUIData property_ui_data(network->onc_source());
- const base::DictionaryValue* onc = NetworkLibrary::Get()->
- FindOncForNetwork(network->guid());
+ onc::ONCSource onc_source = onc::ONC_SOURCE_NONE;
+ const base::DictionaryValue* onc =
+ FindPolicyForActiveUser(network, &onc_source);
+ const NetworkPropertyUIData property_ui_data(onc_source);
base::DictionaryValue dictionary;
@@ -1496,7 +1505,7 @@
new base::FundamentalValue(preferred),
property_ui_data);
- NetworkPropertyUIData auto_connect_ui_data(network->onc_source());
+ NetworkPropertyUIData auto_connect_ui_data(onc_source);
std::string onc_path_to_auto_connect;
if (type == flimflam::kTypeWifi) {
onc_path_to_auto_connect = base::StringPrintf(
@@ -1511,9 +1520,7 @@
}
if (!onc_path_to_auto_connect.empty()) {
auto_connect_ui_data.ParseOncProperty(
- network->onc_source(),
- onc,
- onc_path_to_auto_connect);
+ onc_source, onc, onc_path_to_auto_connect);
}
SetValueDictionary(&dictionary, kTagAutoConnect,
new base::FundamentalValue(network->auto_connect()),
diff --git a/chrome/browser/ui/webui/options/chromeos/timezone_options_util.cc b/chrome/browser/ui/webui/options/chromeos/timezone_options_util.cc
index c6cd40b..4d09319 100644
--- a/chrome/browser/ui/webui/options/chromeos/timezone_options_util.cc
+++ b/chrome/browser/ui/webui/options/chromeos/timezone_options_util.cc
@@ -15,10 +15,10 @@
#include "base/values.h"
#include "chrome/browser/chromeos/system/timezone_settings.h"
#include "grit/generated_resources.h"
-#include "third_party/icu/public/common/unicode/ures.h"
-#include "third_party/icu/public/common/unicode/utypes.h"
-#include "third_party/icu/public/i18n/unicode/calendar.h"
-#include "third_party/icu/public/i18n/unicode/timezone.h"
+#include "third_party/icu/source/common/unicode/ures.h"
+#include "third_party/icu/source/common/unicode/utypes.h"
+#include "third_party/icu/source/i18n/unicode/calendar.h"
+#include "third_party/icu/source/i18n/unicode/timezone.h"
#include "ui/base/l10n/l10n_util.h"
namespace {
diff --git a/chrome/browser/ui/webui/options/core_options_handler.cc b/chrome/browser/ui/webui/options/core_options_handler.cc
index 5544b21..c933690 100644
--- a/chrome/browser/ui/webui/options/core_options_handler.cc
+++ b/chrome/browser/ui/webui/options/core_options_handler.cc
@@ -212,7 +212,11 @@
base::Bind(&CoreOptionsHandler::OnPreferenceChanged,
base::Unretained(this),
local_state_registrar_.prefs()));
- } else {
+ }
+ // TODO(pneubeck): change this to if/else once kProxy is only used as a user
+ // pref. Currently, it is both a user and a local state pref.
+ if (Profile::FromWebUI(web_ui())->GetPrefs()->FindPreference(
+ pref_name.c_str())) {
registrar_.Add(
pref_name.c_str(),
base::Bind(&CoreOptionsHandler::OnPreferenceChanged,
diff --git a/chrome/browser/ui/webui/options/manage_profile_handler.cc b/chrome/browser/ui/webui/options/manage_profile_handler.cc
index 3bda4a6..d684067 100644
--- a/chrome/browser/ui/webui/options/manage_profile_handler.cc
+++ b/chrome/browser/ui/webui/options/manage_profile_handler.cc
@@ -333,7 +333,10 @@
!base::GetValueAsFilePath(*file_path_value, &profile_file_path))
return;
- AppListService::Get()->SetAppListProfile(profile_file_path);
+ AppListService* app_list_service = AppListService::Get();
+ app_list_service->SetProfilePath(profile_file_path);
+ app_list_service->Show();
+
// Close the settings app, since it will now be for the wrong profile.
web_ui()->GetWebContents()->Close();
}
diff --git a/chrome/browser/ui/webui/options/preferences_browsertest.cc b/chrome/browser/ui/webui/options/preferences_browsertest.cc
index 6735944..365e211 100644
--- a/chrome/browser/ui/webui/options/preferences_browsertest.cc
+++ b/chrome/browser/ui/webui/options/preferences_browsertest.cc
@@ -18,13 +18,13 @@
#include "chrome/browser/policy/browser_policy_connector.h"
#include "chrome/browser/policy/external_data_fetcher.h"
#include "chrome/browser/policy/policy_map.h"
+#include "chrome/browser/policy/policy_types.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/ui_test_utils.h"
-#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/render_view_host.h"
@@ -36,13 +36,19 @@
#if defined(OS_CHROMEOS)
#include "base/strings/stringprintf.h"
+#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/net/proxy_config_handler.h"
#include "chrome/browser/chromeos/proxy_cros_settings_parser.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/cros_settings_names.h"
#include "chrome/browser/prefs/proxy_config_dictionary.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/shill_profile_client.h"
+#include "chromeos/dbus/shill_service_client.h"
#include "chromeos/network/network_state.h"
#include "chromeos/network/network_state_handler.h"
+#include "content/public/test/test_utils.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
#endif
using testing::AllOf;
@@ -93,8 +99,8 @@
ASSERT_TRUE(web_contents);
render_view_host_ = web_contents->GetRenderViewHost();
ASSERT_TRUE(render_view_host_);
- pref_change_registrar_.Init(user_prefs::UserPrefs::Get(browser()->profile()));
pref_service_ = browser()->profile()->GetPrefs();
+ pref_change_registrar_.Init(pref_service_);
ASSERT_TRUE(content::ExecuteScript(render_view_host_,
"function TestEnv() {"
" this.sentinelName_ = 'download.prompt_for_download';"
@@ -180,8 +186,8 @@
OnCommit(pref_service_->FindPreference(pref_name.c_str()));
}
-// Sets up a mock user policy provider.
void PreferencesBrowserTest::SetUpInProcessBrowserTestFixture() {
+ // Sets up a mock policy provider for user and device policies.
EXPECT_CALL(policy_provider_, IsInitializationComplete(_))
.WillRepeatedly(Return(true));
EXPECT_CALL(policy_provider_, RegisterPolicyDomain(_))
@@ -712,19 +718,26 @@
STLDeleteElements(&decorated_non_default_values);
}
+namespace {
+
+const char* kUserProfilePath = "user_profile";
+
+} // namespace
+
class ProxyPreferencesBrowserTest : public PreferencesBrowserTest {
public:
virtual void SetUpOnMainThread() OVERRIDE {
+ SetupNetworkEnvironment();
+ content::RunAllPendingInMessageLoop();
+
scoped_ptr<base::DictionaryValue> proxy_config_dict(
- ProxyConfigDictionary::CreateFixedServers(
- "127.0.0.1:8080",
- "*.google.com, 1.2.3.4:22"));
+ ProxyConfigDictionary::CreateFixedServers("127.0.0.1:8080",
+ "*.google.com, 1.2.3.4:22"));
ProxyConfigDictionary proxy_config(proxy_config_dict.get());
const chromeos::NetworkState* network = GetDefaultNetwork();
- chromeos::proxy_config::SetProxyConfigForNetwork(
- proxy_config, *network);
+ chromeos::proxy_config::SetProxyConfigForNetwork(proxy_config, *network);
std::string url = base::StringPrintf("%s?network=%s",
chrome::kChromeUIProxySettingsURL,
@@ -735,9 +748,62 @@
}
protected:
+ void SetupNetworkEnvironment() {
+ chromeos::ShillProfileClient::TestInterface* profile_test =
+ chromeos::DBusThreadManager::Get()->GetShillProfileClient()
+ ->GetTestInterface();
+ chromeos::ShillServiceClient::TestInterface* service_test =
+ chromeos::DBusThreadManager::Get()->GetShillServiceClient()
+ ->GetTestInterface();
+
+ profile_test->AddProfile(kUserProfilePath, "user");
+
+ service_test->ClearServices();
+ service_test->AddService("stub_ethernet",
+ "eth0",
+ flimflam::kTypeEthernet,
+ flimflam::kStateOnline,
+ true, // add to visible
+ true); // add to watchlist
+ service_test->SetServiceProperty("stub_ethernet",
+ flimflam::kGuidProperty,
+ base::StringValue("stub_ethernet"));
+ service_test->SetServiceProperty("stub_ethernet",
+ flimflam::kProfileProperty,
+ base::StringValue(kUserProfilePath));
+ profile_test->AddService(kUserProfilePath, "stub_wifi2");
+ }
+
+ void SetONCPolicy(const char* policy_name, policy::PolicyScope scope) {
+ std::string onc_policy =
+ "{ \"NetworkConfigurations\": ["
+ " { \"GUID\": \"stub_ethernet\","
+ " \"Type\": \"Ethernet\","
+ " \"Name\": \"My Ethernet\","
+ " \"Ethernet\": {"
+ " \"Authentication\": \"None\" },"
+ " \"ProxySettings\": {"
+ " \"PAC\": \"http://domain.com/x\","
+ " \"Type\": \"PAC\" }"
+ " }"
+ " ],"
+ " \"Type\": \"UnencryptedConfiguration\""
+ "}";
+
+ policy::PolicyMap map;
+ map.Set(policy_name,
+ policy::POLICY_LEVEL_MANDATORY,
+ scope,
+ new base::StringValue(onc_policy),
+ NULL);
+ policy_provider_.UpdateChromePolicy(map);
+
+ content::RunAllPendingInMessageLoop();
+ }
+
const chromeos::NetworkState* GetDefaultNetwork() {
- return chromeos::NetworkHandler::Get()->network_state_handler()->
- DefaultNetwork();
+ return chromeos::NetworkHandler::Get()->network_state_handler()
+ ->DefaultNetwork();
}
void SetProxyPref(const std::string& name, const base::Value& value) {
@@ -760,24 +826,30 @@
SetPref(name, type, &value, true, &observed_json);
}
- void VerifyCurrentProxyServer(const std::string& expected_server) {
- scoped_ptr<ProxyConfigDictionary> proxy_dict(
- chromeos::proxy_config::GetProxyConfigForNetwork(*GetDefaultNetwork()));
+ void VerifyCurrentProxyServer(const std::string& expected_server,
+ chromeos::onc::ONCSource expected_source) {
+ chromeos::onc::ONCSource actual_source;
+ scoped_ptr<ProxyConfigDictionary> proxy_dict =
+ chromeos::proxy_config::GetProxyConfigForNetwork(
+ pref_service_,
+ g_browser_process->local_state(),
+ *GetDefaultNetwork(),
+ &actual_source);
std::string actual_proxy_server;
EXPECT_TRUE(proxy_dict->GetProxyServer(&actual_proxy_server));
EXPECT_EQ(expected_server, actual_proxy_server);
+ EXPECT_EQ(expected_source, actual_source);
}
};
// Verifies that proxy settings are correctly pushed to JavaScript during
// initialization of the proxy settings page.
-IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest,
- ChromeOSInitializeProxy) {
+IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, ChromeOSInitializeProxy) {
// Boolean pref.
pref_names_.push_back(chromeos::kProxySingle);
non_default_values_.push_back(new base::FundamentalValue(true));
- // Integer pref.
+ // Integer prefs.
pref_names_.push_back(chromeos::kProxySingleHttpPort);
non_default_values_.push_back(new base::FundamentalValue(8080));
@@ -792,10 +864,91 @@
list->Append(new base::StringValue("1.2.3.4:22"));
non_default_values_.push_back(list);
+ // Verify that no policy is presented to the UI. This must be verified on the
+ // kProxyType and the kUseSharedProxies prefs.
+ pref_names_.push_back(chromeos::kProxyType);
+ non_default_values_.push_back(new base::FundamentalValue(2));
+
+ pref_names_.push_back(prefs::kUseSharedProxies);
+ non_default_values_.push_back(new base::FundamentalValue(false));
+
std::string observed_json;
SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
- VerifyObservedPrefs(observed_json, pref_names_, non_default_values_,
- "", false, false);
+ VerifyObservedPrefs(
+ observed_json, pref_names_, non_default_values_, "", false, false);
+}
+
+IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, ONCPolicy) {
+ SetONCPolicy(policy::key::kOpenNetworkConfiguration,
+ policy::POLICY_SCOPE_USER);
+
+ // Verify that per-network policy is presented to the UI. This must be
+ // verified on the kProxyType.
+ pref_names_.push_back(chromeos::kProxyType);
+ non_default_values_.push_back(new base::FundamentalValue(3));
+
+ std::string observed_json;
+ SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
+ VerifyObservedPrefs(
+ observed_json, pref_names_, non_default_values_, "policy", true, false);
+
+ // Verify that 'use-shared-proxies' is not affected by per-network policy.
+ pref_names_.clear();
+ STLDeleteElements(&non_default_values_);
+ pref_names_.push_back(prefs::kUseSharedProxies);
+ non_default_values_.push_back(new base::FundamentalValue(false));
+
+ SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
+ VerifyObservedPrefs(
+ observed_json, pref_names_, non_default_values_, "", false, false);
+}
+
+IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, DeviceONCPolicy) {
+ SetONCPolicy(policy::key::kDeviceOpenNetworkConfiguration,
+ policy::POLICY_SCOPE_MACHINE);
+
+ // Verify that the policy is presented to the UI. This verification must be
+ // done on the kProxyType pref.
+ pref_names_.push_back(chromeos::kProxyType);
+ non_default_values_.push_back(new base::FundamentalValue(3));
+
+ std::string observed_json;
+ SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
+ VerifyObservedPrefs(
+ observed_json, pref_names_, non_default_values_, "policy", true, false);
+
+ // Verify that 'use-shared-proxies' is not affected by per-network policy.
+ pref_names_.clear();
+ STLDeleteElements(&non_default_values_);
+ pref_names_.push_back(prefs::kUseSharedProxies);
+ non_default_values_.push_back(new base::FundamentalValue(false));
+
+ SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
+ VerifyObservedPrefs(
+ observed_json, pref_names_, non_default_values_, "", false, false);
+}
+
+IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, UserProxyPolicy) {
+ policy_names_.push_back(policy::key::kProxyMode);
+ default_values_.push_back(
+ new base::StringValue(ProxyPrefs::kAutoDetectProxyModeName));
+ SetUserPolicies(
+ policy_names_, default_values_, policy::POLICY_LEVEL_MANDATORY);
+ content::RunAllPendingInMessageLoop();
+
+ // Verify that the policy is presented to the UI. This verification must be
+ // done on the kProxyType pref.
+ pref_names_.push_back(chromeos::kProxyType);
+ non_default_values_.push_back(new base::FundamentalValue(3));
+
+ // Verify that 'use-shared-proxies' is controlled by the policy.
+ pref_names_.push_back(prefs::kUseSharedProxies);
+ non_default_values_.push_back(new base::FundamentalValue(false));
+
+ std::string observed_json;
+ SetupJavaScriptTestEnvironment(pref_names_, &observed_json);
+ VerifyObservedPrefs(
+ observed_json, pref_names_, non_default_values_, "policy", true, false);
}
// Verifies that modifications to the proxy settings are correctly pushed from
@@ -806,7 +959,8 @@
SetProxyPref(chromeos::kProxySingleHttpPort, base::FundamentalValue(123));
SetProxyPref(chromeos::kProxySingleHttp, base::StringValue("www.adomain.xy"));
- VerifyCurrentProxyServer("www.adomain.xy:123");
+ VerifyCurrentProxyServer("www.adomain.xy:123",
+ chromeos::onc::ONC_SOURCE_NONE);
}
// Verify that default proxy ports are used and that ports can be updated
@@ -825,7 +979,8 @@
// Verify default ports.
VerifyCurrentProxyServer(
- "http=a.com:80;https=4.3.2.1:80;ftp=c.com:80;socks=socks4://d.com:1080");
+ "http=a.com:80;https=4.3.2.1:80;ftp=c.com:80;socks=socks4://d.com:1080",
+ chromeos::onc::ONC_SOURCE_NONE);
// Set and verify the ports.
SetProxyPref(chromeos::kProxyHttpPort, base::FundamentalValue(1));
@@ -834,7 +989,8 @@
SetProxyPref(chromeos::kProxySocksPort, base::FundamentalValue(4));
VerifyCurrentProxyServer(
- "http=a.com:1;https=4.3.2.1:2;ftp=c.com:3;socks=socks4://d.com:4");
+ "http=a.com:1;https=4.3.2.1:2;ftp=c.com:3;socks=socks4://d.com:4",
+ chromeos::onc::ONC_SOURCE_NONE);
}
#endif
diff --git a/chrome/browser/ui/webui/options/preferences_browsertest.h b/chrome/browser/ui/webui/options/preferences_browsertest.h
index f8445d4..6cf4281 100644
--- a/chrome/browser/ui/webui/options/preferences_browsertest.h
+++ b/chrome/browser/ui/webui/options/preferences_browsertest.h
@@ -172,7 +172,7 @@
// the tab.
content::RenderViewHost* render_view_host_;
- // Mock user policy provider.
+ // Mock policy provider for both user and device policies.
policy::MockConfigurationPolicyProvider policy_provider_;
// Pref change registrar that detects changes to user-modified pref values
diff --git a/chrome/browser/ui/webui/plugins_ui.cc b/chrome/browser/ui/webui/plugins_ui.cc
index fa809f1..94b57dd 100644
--- a/chrome/browser/ui/webui/plugins_ui.cc
+++ b/chrome/browser/ui/webui/plugins_ui.cc
@@ -52,8 +52,8 @@
using content::PluginService;
using content::WebContents;
+using content::WebPluginInfo;
using content::WebUIMessageHandler;
-using webkit::WebPluginInfo;
namespace {
@@ -167,7 +167,7 @@
void LoadPlugins();
// Called on the UI thread when the plugin information is ready.
- void PluginsLoaded(const std::vector<webkit::WebPluginInfo>& plugins);
+ void PluginsLoaded(const std::vector<WebPluginInfo>& plugins);
content::NotificationRegistrar registrar_;
@@ -329,7 +329,7 @@
}
void PluginsDOMHandler::PluginsLoaded(
- const std::vector<webkit::WebPluginInfo>& plugins) {
+ const std::vector<WebPluginInfo>& plugins) {
Profile* profile = Profile::FromWebUI(web_ui());
PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(profile).get();
@@ -371,7 +371,7 @@
plugin_file->SetString("type", PluginTypeToString(group_plugin.type));
ListValue* mime_types = new ListValue();
- const std::vector<webkit::WebPluginMimeType>& plugin_mime_types =
+ const std::vector<content::WebPluginMimeType>& plugin_mime_types =
group_plugin.mime_types;
for (size_t k = 0; k < plugin_mime_types.size(); ++k) {
DictionaryValue* mime_type = new DictionaryValue();
diff --git a/chrome/browser/ui/webui/predictors/predictors_handler.cc b/chrome/browser/ui/webui/predictors/predictors_handler.cc
index 14c88cf..3536ac9 100644
--- a/chrome/browser/ui/webui/predictors/predictors_handler.cc
+++ b/chrome/browser/ui/webui/predictors/predictors_handler.cc
@@ -13,7 +13,7 @@
#include "chrome/browser/predictors/resource_prefetch_predictor_tables.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/web_ui.h"
-#include "webkit/glue/resource_type.h"
+#include "webkit/common/resource_type.h"
using predictors::AutocompleteActionPredictor;
using predictors::ResourcePrefetchPredictor;
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
index 98b2188..32e6012 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -62,7 +62,7 @@
#include "printing/page_range.h"
#include "printing/page_size_margins.h"
#include "printing/print_settings.h"
-#include "third_party/icu/public/i18n/unicode/ulocdata.h"
+#include "third_party/icu/source/i18n/unicode/ulocdata.h"
#if defined(OS_CHROMEOS)
// TODO(kinaba): provide more non-intrusive way for handling local/remote
@@ -92,8 +92,8 @@
FALLBACK_TO_ADVANCED_SETTINGS_DIALOG,
PREVIEW_FAILED,
PREVIEW_STARTED,
- INITIATOR_TAB_CRASHED, // UNUSED
- INITIATOR_TAB_CLOSED,
+ INITIATOR_CRASHED, // UNUSED
+ INITIATOR_CLOSED,
PRINT_WITH_CLOUD_PRINT,
USERACTION_BUCKET_BOUNDARY
};
@@ -157,8 +157,8 @@
// Name of a dictionary field holding cloud print related data;
const char kAppState[] = "appState";
-// Name of a dictionary field holding the initiator tab title.
-const char kInitiatorTabTitle[] = "initiatorTabTitle";
+// Name of a dictionary field holding the initiator title.
+const char kInitiatorTitle[] = "initiatorTitle";
// Name of a dictionary field holding the measurement system according to the
// locale.
const char kMeasurementSystem[] = "measurementSystem";
@@ -445,9 +445,9 @@
// Increment request count.
++regenerate_preview_request_count_;
- WebContents* initiator_tab = GetInitiatorTab();
- if (!initiator_tab) {
- ReportUserActionHistogram(INITIATOR_TAB_CLOSED);
+ WebContents* initiator = GetInitiator();
+ if (!initiator) {
+ ReportUserActionHistogram(INITIATOR_CLOSED);
print_preview_ui->OnClosePrintPreviewDialog();
return;
}
@@ -461,9 +461,9 @@
}
if (display_header_footer) {
settings->SetString(printing::kSettingHeaderFooterTitle,
- initiator_tab->GetTitle());
+ initiator->GetTitle());
std::string url;
- NavigationEntry* entry = initiator_tab->GetController().GetActiveEntry();
+ NavigationEntry* entry = initiator->GetController().GetActiveEntry();
if (entry)
url = entry->GetVirtualURL().spec();
settings->SetString(printing::kSettingHeaderFooterURL, url);
@@ -491,7 +491,7 @@
}
VLOG(1) << "Print preview request start";
- RenderViewHost* rvh = initiator_tab->GetRenderViewHost();
+ RenderViewHost* rvh = initiator->GetRenderViewHost();
rvh->Send(new PrintMsg_PrintPreview(rvh->GetRoutingID(), *settings));
}
@@ -503,9 +503,9 @@
UMA_HISTOGRAM_COUNTS("PrintPreview.RegeneratePreviewRequest.BeforePrint",
regenerate_preview_request_count_);
- WebContents* initiator_tab = GetInitiatorTab();
- if (initiator_tab) {
- RenderViewHost* rvh = initiator_tab->GetRenderViewHost();
+ WebContents* initiator = GetInitiator();
+ if (initiator) {
+ RenderViewHost* rvh = initiator->GetRenderViewHost();
rvh->Send(new PrintMsg_ResetScriptedPrintCount(rvh->GetRoutingID()));
}
@@ -556,15 +556,15 @@
ReportUserActionHistogram(PRINT_TO_PRINTER);
ReportPrintSettingsStats(*settings);
- // This tries to activate the initiator tab as well, so do not clear the
- // association with the initiator tab yet.
+ // This tries to activate the initiator as well, so do not clear the
+ // association with the initiator yet.
PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>(
web_ui()->GetController());
print_preview_ui->OnHidePreviewDialog();
- // Do this so the initiator tab can open a new print preview dialog, while
- // the current print preview dialog is still handling its print job.
- ClearInitiatorTabDetails();
+ // Do this so the initiator can open a new print preview dialog, while the
+ // current print preview dialog is still handling its print job.
+ ClearInitiatorDetails();
// The PDF being printed contains only the pages that the user selected,
// so ignore the page range and print all pages.
@@ -583,9 +583,9 @@
// printing has finished. Then the dialog closes and PrintPreviewDone() gets
// called. In the case below, since the preview dialog will be hidden and
// not closed, we need to make this call.
- if (initiator_tab) {
+ if (initiator) {
printing::PrintViewManager* print_view_manager =
- printing::PrintViewManager::FromWebContents(initiator_tab);
+ printing::PrintViewManager::FromWebContents(initiator);
print_view_manager->PrintPreviewDone();
}
}
@@ -601,7 +601,7 @@
PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>(
web_ui()->GetController());
// Pre-populating select file dialog with print job title.
- string16 print_job_title_utf16 = print_preview_ui->initiator_tab_title();
+ string16 print_job_title_utf16 = print_preview_ui->initiator_title();
#if defined(OS_WIN)
base::FilePath::StringType print_job_title(print_job_title_utf16);
@@ -627,11 +627,11 @@
void PrintPreviewHandler::HandleCancelPendingPrintRequest(
const ListValue* /*args*/) {
- WebContents* initiator_tab = GetInitiatorTab();
- if (initiator_tab)
- ClearInitiatorTabDetails();
- gfx::NativeWindow parent = initiator_tab ?
- initiator_tab->GetView()->GetTopLevelNativeWindow() :
+ WebContents* initiator = GetInitiator();
+ if (initiator)
+ ClearInitiatorDetails();
+ gfx::NativeWindow parent = initiator ?
+ initiator->GetView()->GetTopLevelNativeWindow() :
NULL;
chrome::ShowPrintErrorDialog(parent);
}
@@ -737,12 +737,12 @@
ReportStats();
ReportUserActionHistogram(FALLBACK_TO_ADVANCED_SETTINGS_DIALOG);
- WebContents* initiator_tab = GetInitiatorTab();
- if (!initiator_tab)
+ WebContents* initiator = GetInitiator();
+ if (!initiator)
return;
printing::PrintViewManager* print_view_manager =
- printing::PrintViewManager::FromWebContents(initiator_tab);
+ printing::PrintViewManager::FromWebContents(initiator);
print_view_manager->set_observer(this);
print_view_manager->PrintForSystemDialogNow();
@@ -848,7 +848,7 @@
std::string url;
if (!args->GetString(0, &url))
return;
- Browser* browser = chrome::FindBrowserWithWebContents(GetInitiatorTab());
+ Browser* browser = chrome::FindBrowserWithWebContents(GetInitiator());
if (!browser)
return;
chrome::AddSelectedTabWithURL(browser,
@@ -863,8 +863,8 @@
web_ui()->GetController());
base::DictionaryValue initial_settings;
- initial_settings.SetString(kInitiatorTabTitle,
- print_preview_ui->initiator_tab_title());
+ initial_settings.SetString(kInitiatorTitle,
+ print_preview_ui->initiator_title());
initial_settings.SetBoolean(printing::kSettingPreviewModifiable,
print_preview_ui->source_is_modifiable());
initial_settings.SetString(printing::kSettingPrinterName, default_printer);
@@ -944,12 +944,12 @@
web_ui()->CallJavascriptFunction("printToCloud", data_value);
}
-WebContents* PrintPreviewHandler::GetInitiatorTab() const {
+WebContents* PrintPreviewHandler::GetInitiator() const {
printing::PrintPreviewDialogController* dialog_controller =
printing::PrintPreviewDialogController::GetInstance();
if (!dialog_controller)
return NULL;
- return dialog_controller->GetInitiatorTab(preview_web_contents());
+ return dialog_controller->GetInitiator(preview_web_contents());
}
void PrintPreviewHandler::OnPrintDialogShown() {
@@ -991,12 +991,12 @@
}
void PrintPreviewHandler::OnPrintPreviewDialogDestroyed() {
- WebContents* initiator_tab = GetInitiatorTab();
- if (!initiator_tab)
+ WebContents* initiator = GetInitiator();
+ if (!initiator)
return;
printing::PrintViewManager* print_view_manager =
- printing::PrintViewManager::FromWebContents(initiator_tab);
+ printing::PrintViewManager::FromWebContents(initiator);
print_view_manager->set_observer(NULL);
}
@@ -1055,18 +1055,18 @@
print_preview_ui->OnFileSelectionCancelled();
}
-void PrintPreviewHandler::ClearInitiatorTabDetails() {
- WebContents* initiator_tab = GetInitiatorTab();
- if (!initiator_tab)
+void PrintPreviewHandler::ClearInitiatorDetails() {
+ WebContents* initiator = GetInitiator();
+ if (!initiator)
return;
- // We no longer require the initiator tab details. Remove those details
- // associated with the preview dialog to allow the initiator tab to create
- // another preview dialog.
+ // We no longer require the initiator details. Remove those details associated
+ // with the preview dialog to allow the initiator to create another preview
+ // dialog.
printing::PrintPreviewDialogController* dialog_controller =
printing::PrintPreviewDialogController::GetInstance();
if (dialog_controller)
- dialog_controller->EraseInitiatorTabInfo(preview_web_contents());
+ dialog_controller->EraseInitiatorInfo(preview_web_contents());
}
bool PrintPreviewHandler::GetPreviewDataAndTitle(
@@ -1085,7 +1085,7 @@
DCHECK(tmp_data->size() && tmp_data->front());
*data = tmp_data;
- *title = print_preview_ui->initiator_tab_title();
+ *title = print_preview_ui->initiator_title();
return true;
}
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.h b/chrome/browser/ui/webui/print_preview/print_preview_handler.h
index 6dde25d..36ec0a9 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.h
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.h
@@ -182,8 +182,8 @@
// Asks the browser to show the cloud print dialog.
void PrintWithCloudPrintDialog();
- // Gets the initiator tab for the print preview dialog.
- content::WebContents* GetInitiatorTab() const;
+ // Gets the initiator for the print preview dialog.
+ content::WebContents* GetInitiator() const;
// Closes the preview dialog.
void ClosePreviewDialog();
@@ -191,8 +191,8 @@
// Adds all the recorded stats taken so far to histogram counts.
void ReportStats();
- // Clears initiator tab details for the print preview dialog.
- void ClearInitiatorTabDetails();
+ // Clears initiator details for the print preview dialog.
+ void ClearInitiatorDetails();
// Posts a task to save |data| to pdf at |print_to_pdf_path_|.
void PostPrintToPdfTask();
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
index 142ac95..ca4c7e4 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
@@ -388,9 +388,9 @@
return print_preview_data_service()->GetAvailableDraftPageCount(id_);
}
-void PrintPreviewUI::SetInitiatorTabTitle(
+void PrintPreviewUI::SetInitiatorTitle(
const string16& job_title) {
- initiator_tab_title_ = job_title;
+ initiator_title_ = job_title;
}
// static
@@ -431,7 +431,7 @@
OnClosePrintPreviewDialog();
}
-void PrintPreviewUI::OnInitiatorTabClosed() {
+void PrintPreviewUI::OnInitiatorClosed() {
WebContents* preview_dialog = web_ui()->GetWebContents();
printing::BackgroundPrintingManager* background_printing_manager =
g_browser_process->background_printing_manager();
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.h b/chrome/browser/ui/webui/print_preview/print_preview_ui.h
index 51fdd02..1cd81e3 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_ui.h
+++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.h
@@ -53,9 +53,9 @@
int GetAvailableDraftPageCount();
// Setters
- void SetInitiatorTabTitle(const string16& initiator_tab_title);
+ void SetInitiatorTitle(const string16& initiator_title);
- string16 initiator_tab_title() { return initiator_tab_title_; }
+ string16 initiator_title() { return initiator_title_; }
bool source_is_modifiable() { return source_is_modifiable_; }
@@ -109,8 +109,8 @@
void OnReusePreviewData(int preview_request_id);
// Notifies the Web UI that preview dialog has been destroyed. This is the
- // last chance to communicate with the initiator tab before the association
- // is erased.
+ // last chance to communicate with the initiator before the association is
+ // erased.
void OnPrintPreviewDialogDestroyed();
// Notifies the Web UI that the print preview failed to render.
@@ -120,9 +120,9 @@
// closed, which may occur for several reasons, e.g. tab closure or crash.
void OnPrintPreviewDialogClosed();
- // Notifies the Web UI that initiator tab is closed, so we can disable all the
- // controls that need the initiator tab for generating the preview data.
- void OnInitiatorTabClosed();
+ // Notifies the Web UI that initiator is closed, so we can disable all the
+ // controls that need the initiator for generating the preview data.
+ void OnInitiatorClosed();
// Notifies the Web UI renderer that file selection has been cancelled.
void OnFileSelectionCancelled();
@@ -181,9 +181,9 @@
// Indicates whether only the selection should be printed.
bool print_selection_only_;
- // Store the initiator tab title, used for populating the print preview dialog
+ // Store the initiator title, used for populating the print preview dialog
// title.
- string16 initiator_tab_title_;
+ string16 initiator_title_;
// Keeps track of whether OnClosePrintPreviewDialog() has been called or not.
bool dialog_closed_;
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc
index 18cdd80..0f48f49 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc
@@ -20,7 +20,6 @@
#include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents.h"
#include "printing/print_job_constants.h"
-#include "webkit/plugins/npapi/mock_plugin_list.h"
using content::WebContents;
using web_modal::WebContentsModalDialogManager;
@@ -62,26 +61,24 @@
chrome::NewTab(browser());
}
-// Create/Get a preview tab for initiator tab.
+// Create/Get a preview tab for initiator.
TEST_F(PrintPreviewUIUnitTest, PrintPreviewData) {
- WebContents* initiator_tab =
- browser()->tab_strip_model()->GetActiveWebContents();
- ASSERT_TRUE(initiator_tab);
- EXPECT_FALSE(IsShowingWebContentsModalDialog(initiator_tab));
+ WebContents* initiator = browser()->tab_strip_model()->GetActiveWebContents();
+ ASSERT_TRUE(initiator);
+ EXPECT_FALSE(IsShowingWebContentsModalDialog(initiator));
printing::PrintPreviewDialogController* controller =
printing::PrintPreviewDialogController::GetInstance();
ASSERT_TRUE(controller);
printing::PrintViewManager* print_view_manager =
- printing::PrintViewManager::FromWebContents(initiator_tab);
+ printing::PrintViewManager::FromWebContents(initiator);
print_view_manager->PrintPreviewNow(false);
- WebContents* preview_dialog =
- controller->GetOrCreatePreviewDialog(initiator_tab);
+ WebContents* preview_dialog = controller->GetOrCreatePreviewDialog(initiator);
- EXPECT_NE(initiator_tab, preview_dialog);
+ EXPECT_NE(initiator, preview_dialog);
EXPECT_EQ(1, browser()->tab_strip_model()->count());
- EXPECT_TRUE(IsShowingWebContentsModalDialog(initiator_tab));
+ EXPECT_TRUE(IsShowingWebContentsModalDialog(initiator));
PrintPreviewUI* preview_ui = static_cast<PrintPreviewUI*>(
preview_dialog->GetWebUI()->GetController());
@@ -120,23 +117,21 @@
// Set and get the individual draft pages.
TEST_F(PrintPreviewUIUnitTest, PrintPreviewDraftPages) {
- WebContents* initiator_tab =
- browser()->tab_strip_model()->GetActiveWebContents();
- ASSERT_TRUE(initiator_tab);
+ WebContents* initiator = browser()->tab_strip_model()->GetActiveWebContents();
+ ASSERT_TRUE(initiator);
printing::PrintPreviewDialogController* controller =
printing::PrintPreviewDialogController::GetInstance();
ASSERT_TRUE(controller);
printing::PrintViewManager* print_view_manager =
- printing::PrintViewManager::FromWebContents(initiator_tab);
+ printing::PrintViewManager::FromWebContents(initiator);
print_view_manager->PrintPreviewNow(false);
- WebContents* preview_dialog =
- controller->GetOrCreatePreviewDialog(initiator_tab);
+ WebContents* preview_dialog = controller->GetOrCreatePreviewDialog(initiator);
- EXPECT_NE(initiator_tab, preview_dialog);
+ EXPECT_NE(initiator, preview_dialog);
EXPECT_EQ(1, browser()->tab_strip_model()->count());
- EXPECT_TRUE(IsShowingWebContentsModalDialog(initiator_tab));
+ EXPECT_TRUE(IsShowingWebContentsModalDialog(initiator));
PrintPreviewUI* preview_ui = static_cast<PrintPreviewUI*>(
preview_dialog->GetWebUI()->GetController());
@@ -182,23 +177,21 @@
// Test the browser-side print preview cancellation functionality.
TEST_F(PrintPreviewUIUnitTest, GetCurrentPrintPreviewStatus) {
- WebContents* initiator_tab =
- browser()->tab_strip_model()->GetActiveWebContents();
- ASSERT_TRUE(initiator_tab);
+ WebContents* initiator = browser()->tab_strip_model()->GetActiveWebContents();
+ ASSERT_TRUE(initiator);
printing::PrintPreviewDialogController* controller =
printing::PrintPreviewDialogController::GetInstance();
ASSERT_TRUE(controller);
printing::PrintViewManager* print_view_manager =
- printing::PrintViewManager::FromWebContents(initiator_tab);
+ printing::PrintViewManager::FromWebContents(initiator);
print_view_manager->PrintPreviewNow(false);
- WebContents* preview_dialog =
- controller->GetOrCreatePreviewDialog(initiator_tab);
+ WebContents* preview_dialog = controller->GetOrCreatePreviewDialog(initiator);
- EXPECT_NE(initiator_tab, preview_dialog);
+ EXPECT_NE(initiator, preview_dialog);
EXPECT_EQ(1, browser()->tab_strip_model()->count());
- EXPECT_TRUE(IsShowingWebContentsModalDialog(initiator_tab));
+ EXPECT_TRUE(IsShowingWebContentsModalDialog(initiator));
PrintPreviewUI* preview_ui = static_cast<PrintPreviewUI*>(
preview_dialog->GetWebUI()->GetController());
diff --git a/chrome/browser/ui/webui/signin/user_chooser_screen_handler.cc b/chrome/browser/ui/webui/signin/user_chooser_screen_handler.cc
new file mode 100644
index 0000000..c46a843
--- /dev/null
+++ b/chrome/browser/ui/webui/signin/user_chooser_screen_handler.cc
@@ -0,0 +1,229 @@
+// Copyright 2013 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/ui/webui/signin/user_chooser_screen_handler.h"
+
+#include "base/bind.h"
+#include "base/values.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_info_cache.h"
+#include "chrome/browser/profiles/profile_info_util.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/profiles/profile_window.h"
+#include "chrome/browser/ui/browser_commands.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/singleton_tabs.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_ui.h"
+#include "grit/browser_resources.h"
+#include "grit/chromium_strings.h"
+#include "grit/generated_resources.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/gfx/image/image_util.h"
+#include "ui/webui/web_ui_util.h"
+
+namespace {
+// User dictionary keys.
+const char kKeyUsername[] = "username";
+const char kKeyDisplayName[]= "displayName";
+const char kKeyEmailAddress[] = "emailAddress";
+const char kKeyPublicAccount[] = "publicAccount";
+const char kKeyLocallyManagedUser[] = "locallyManagedUser";
+const char kKeySignedIn[] = "signedIn";
+const char kKeyCanRemove[] = "canRemove";
+const char kKeyIsOwner[] = "isOwner";
+const char kKeyIsDesktop[] = "isDesktopUser";
+const char kKeyAvatarUrl[] = "userImage";
+const char kKeyNeedsSignin[] = "needsSignin";
+const char kGAIAPictureFileNameKey[] = "gaia_picture_file_name";
+
+// Max number of users to show.
+const size_t kMaxUsers = 18;
+
+// Type of the login screen UI that is currently presented to user.
+const char kSourceGaiaSignin[] = "gaia-signin";
+const char kSourceAccountPicker[] = "account-picker";
+
+// JS API callback names.
+const char kJsApiUserChooserInitialize[] = "userChooserInitialize";
+const char kJsApiUserChooserAddUser[] = "addUser";
+const char kJsApiUserChooserLaunchGuest[] = "launchGuest";
+const char kJsApiUserChooserLaunchUser[] = "launchUser";
+const char kJsApiUserChooserRemoveUser[] = "removeUser";
+
+void HandleAndDoNothing(const base::ListValue* args) {
+}
+
+} // namespace
+
+UserChooserScreenHandler::UserChooserScreenHandler() {
+}
+
+UserChooserScreenHandler::~UserChooserScreenHandler() {
+}
+
+void UserChooserScreenHandler::HandleInitialize(const base::ListValue* args) {
+ SendUserList();
+ web_ui()->CallJavascriptFunction("cr.ui.Oobe.showUserChooserScreen");
+}
+
+void UserChooserScreenHandler::HandleAddUser(const base::ListValue* args) {
+ // TODO(noms): Should redirect to a sign in page.
+ chrome::ShowSingletonTab(chrome::FindBrowserWithWebContents(
+ web_ui()->GetWebContents()),
+ GURL("chrome://settings/createProfile"));
+}
+
+void UserChooserScreenHandler::HandleRemoveUser(const base::ListValue* args) {
+ // TODO(noms): Should delete the user.
+ chrome::ShowSingletonTab(chrome::FindBrowserWithWebContents(
+ web_ui()->GetWebContents()),
+ GURL("chrome://settings/search#Users"));
+}
+
+void UserChooserScreenHandler::HandleLaunchGuest(const base::ListValue* args) {
+ // TODO(noms): Once guest mode is ready, should launch a guest browser.
+ chrome::NewIncognitoWindow(chrome::FindBrowserWithWebContents(
+ web_ui()->GetWebContents()));
+}
+
+void UserChooserScreenHandler::HandleLaunchUser(const base::ListValue* args) {
+ string16 emailAddress;
+ string16 displayName;
+
+ if (!args->GetString(0, &emailAddress) ||
+ !args->GetString(1, &displayName)) {
+ NOTREACHED();
+ return;
+ }
+
+ ProfileInfoCache& info_cache =
+ g_browser_process->profile_manager()->GetProfileInfoCache();
+ chrome::HostDesktopType desktop_type = chrome::GetActiveDesktop();
+
+ for (size_t i = 0; i < info_cache.GetNumberOfProfiles(); ++i) {
+ if (info_cache.GetUserNameOfProfileAtIndex(i) == emailAddress &&
+ info_cache.GetNameOfProfileAtIndex(i) == displayName) {
+ base::FilePath path = info_cache.GetPathOfProfileAtIndex(i);
+ profiles::SwitchToProfile(path, desktop_type, true);
+ break;
+ }
+ }
+}
+
+void UserChooserScreenHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(kJsApiUserChooserInitialize,
+ base::Bind(&UserChooserScreenHandler::HandleInitialize,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(kJsApiUserChooserAddUser,
+ base::Bind(&UserChooserScreenHandler::HandleAddUser,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(kJsApiUserChooserLaunchGuest,
+ base::Bind(&UserChooserScreenHandler::HandleLaunchGuest,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(kJsApiUserChooserLaunchUser,
+ base::Bind(&UserChooserScreenHandler::HandleLaunchUser,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(kJsApiUserChooserRemoveUser,
+ base::Bind(&UserChooserScreenHandler::HandleRemoveUser,
+ base::Unretained(this)));
+
+ const content::WebUI::MessageCallback& kDoNothingCallback =
+ base::Bind(&HandleAndDoNothing);
+
+ // Unused callbacks from screen_account_picker.js
+ web_ui()->RegisterMessageCallback("accountPickerReady", kDoNothingCallback);
+ web_ui()->RegisterMessageCallback("loginUIStateChanged", kDoNothingCallback);
+ web_ui()->RegisterMessageCallback("hideCaptivePortal", kDoNothingCallback);
+ // Unused callbacks from display_manager.js
+ web_ui()->RegisterMessageCallback("showAddUser", kDoNothingCallback);
+ web_ui()->RegisterMessageCallback("loadWallpaper", kDoNothingCallback);
+ web_ui()->RegisterMessageCallback("updateCurrentScreen", kDoNothingCallback);
+ web_ui()->RegisterMessageCallback("loginVisible", kDoNothingCallback);
+ // Unused callbacks from user_pod_row.js
+ web_ui()->RegisterMessageCallback("userImagesLoaded", kDoNothingCallback);
+}
+
+void UserChooserScreenHandler::GetLocalizedValues(
+ base::DictionaryValue* localized_strings) {
+ // For Control Bar.
+ localized_strings->SetString("signedIn",
+ l10n_util::GetStringUTF16(IDS_SCREEN_LOCK_ACTIVE_USER));
+ localized_strings->SetString("signinButton",
+ l10n_util::GetStringUTF16(IDS_LOGIN_BUTTON));
+ localized_strings->SetString("addUser",
+ l10n_util::GetStringUTF16(IDS_ADD_USER_BUTTON));
+ localized_strings->SetString("cancel", l10n_util::GetStringUTF16(IDS_CANCEL));
+ localized_strings->SetString("browseAsGuest",
+ l10n_util::GetStringUTF16(IDS_GO_INCOGNITO_BUTTON));
+ localized_strings->SetString("signOutUser",
+ l10n_util::GetStringUTF16(IDS_SCREEN_LOCK_SIGN_OUT));
+
+ // For AccountPickerScreen.
+ localized_strings->SetString("screenType", "login-add-user");
+ localized_strings->SetString("highlightStrength", "normal");
+ localized_strings->SetString("title", "User Chooser");
+ localized_strings->SetString("passwordHint",
+ l10n_util::GetStringUTF16(IDS_LOGIN_POD_EMPTY_PASSWORD_TEXT));
+ localized_strings->SetString("podMenuButtonAccessibleName",
+ l10n_util::GetStringUTF16(IDS_LOGIN_POD_MENU_BUTTON_ACCESSIBLE_NAME));
+ localized_strings->SetString("podMenuRemoveItemAccessibleName",
+ l10n_util::GetStringUTF16(
+ IDS_LOGIN_POD_MENU_REMOVE_ITEM_ACCESSIBLE_NAME));
+ localized_strings->SetString("removeUser",
+ l10n_util::GetStringUTF16(IDS_LOGIN_POD_REMOVE_USER));
+ localized_strings->SetString("passwordFieldAccessibleName",
+ l10n_util::GetStringUTF16(IDS_LOGIN_POD_PASSWORD_FIELD_ACCESSIBLE_NAME));
+ localized_strings->SetString("bootIntoWallpaper", "off");
+
+ }
+
+void UserChooserScreenHandler::SendUserList() {
+ ListValue users_list;
+ base::FilePath current_profile_path =
+ web_ui()->GetWebContents()->GetBrowserContext()->GetPath();
+ const ProfileInfoCache& info_cache =
+ g_browser_process->profile_manager()->GetProfileInfoCache();
+
+ for (size_t i = 0; i < info_cache.GetNumberOfProfiles(); ++i) {
+ DictionaryValue* profile_value = new DictionaryValue();
+
+ base::FilePath profile_path = info_cache.GetPathOfProfileAtIndex(i);
+ bool is_active_user = (profile_path == current_profile_path);
+ bool needs_signin = info_cache.ProfileIsSigninRequiredAtIndex(i);
+
+ profile_value->SetString(
+ kKeyUsername, info_cache.GetUserNameOfProfileAtIndex(i));
+ profile_value->SetString(
+ kKeyEmailAddress, info_cache.GetUserNameOfProfileAtIndex(i));
+ profile_value->SetString(
+ kKeyDisplayName, info_cache.GetNameOfProfileAtIndex(i));
+ profile_value->SetBoolean(kKeyPublicAccount, false);
+ profile_value->SetBoolean(kKeyLocallyManagedUser, false);
+ profile_value->SetBoolean(kKeySignedIn, is_active_user);
+ profile_value->SetBoolean(kKeyNeedsSignin, needs_signin);
+ profile_value->SetBoolean(kKeyIsOwner, false);
+ profile_value->SetBoolean(kKeyCanRemove, true);
+ profile_value->SetBoolean(kKeyIsDesktop, true);
+
+ bool is_gaia_picture =
+ info_cache.IsUsingGAIAPictureOfProfileAtIndex(i) &&
+ info_cache.GetGAIAPictureOfProfileAtIndex(i);
+
+ gfx::Image icon = profiles::GetSizedAvatarIconWithBorder(
+ info_cache.GetAvatarIconOfProfileAtIndex(i), is_gaia_picture, 160, 160);
+ profile_value->SetString(kKeyAvatarUrl,
+ webui::GetBitmapDataUrl(icon.AsBitmap()));
+
+ if (is_active_user)
+ users_list.Insert(0, profile_value);
+ else
+ users_list.Append(profile_value);
+ }
+
+ web_ui()->CallJavascriptFunction("login.AccountPickerScreen.loadUsers",
+ users_list, base::FundamentalValue(false), base::FundamentalValue(true));
+}
diff --git a/chrome/browser/ui/webui/signin/user_chooser_screen_handler.h b/chrome/browser/ui/webui/signin/user_chooser_screen_handler.h
new file mode 100644
index 0000000..3dbf1f4
--- /dev/null
+++ b/chrome/browser/ui/webui/signin/user_chooser_screen_handler.h
@@ -0,0 +1,39 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SIGNIN_USER_CHOOSER_SCREEN_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SIGNIN_USER_CHOOSER_SCREEN_HANDLER_H_
+
+#include "base/compiler_specific.h"
+#include "content/public/browser/web_ui_message_handler.h"
+
+namespace base {
+class DictionaryValue;
+class ListValue;
+}
+
+class UserChooserScreenHandler : public content::WebUIMessageHandler {
+ public:
+ UserChooserScreenHandler();
+ virtual ~UserChooserScreenHandler();
+
+ // WebUIMessageHandler implementation.
+ virtual void RegisterMessages() OVERRIDE;
+
+ void GetLocalizedValues(base::DictionaryValue* localized_strings);
+
+ private:
+ void HandleInitialize(const base::ListValue* args);
+ void HandleAddUser(const base::ListValue* args);
+ void HandleLaunchGuest(const base::ListValue* args);
+ void HandleLaunchUser(const base::ListValue* args);
+ void HandleRemoveUser(const base::ListValue* args);
+
+ // Sends user list to account chooser.
+ void SendUserList();
+
+ DISALLOW_COPY_AND_ASSIGN(UserChooserScreenHandler);
+};
+
+#endif // CHROME_BROWSER_UI_WEBUI_SIGNIN_USER_CHOOSER_SCREEN_HANDLER_H_
diff --git a/chrome/browser/ui/webui/signin/user_chooser_ui.cc b/chrome/browser/ui/webui/signin/user_chooser_ui.cc
new file mode 100644
index 0000000..0664716
--- /dev/null
+++ b/chrome/browser/ui/webui/signin/user_chooser_ui.cc
@@ -0,0 +1,75 @@
+// Copyright 2013 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/ui/webui/signin/user_chooser_ui.h"
+
+#include "base/values.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/webui/signin/user_chooser_screen_handler.h"
+#include "chrome/browser/ui/webui/theme_source.h"
+#include "chrome/common/url_constants.h"
+#include "content/public/browser/web_ui.h"
+#include "content/public/browser/web_ui_data_source.h"
+#include "grit/browser_resources.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/webui/web_ui_util.h"
+
+namespace {
+ // JS file names.
+ const char kStringsJSPath[] = "strings.js";
+ const char kUserChooserJSPath[] = "user_chooser.js";
+ const char kHeaderBarJSPath[] = "header_bar.js";
+ const char kAccountPickerJSPath[] = "screen_account_picker.js";
+}
+
+UserChooserUI::UserChooserUI(content::WebUI* web_ui)
+ : WebUIController(web_ui) {
+ // The web_ui object takes ownership of the handler, and will
+ // destroy it when it (the WebUI) is destroyed.
+ user_chooser_screen_handler_ = new UserChooserScreenHandler();
+ web_ui->AddMessageHandler(user_chooser_screen_handler_);
+
+ base::DictionaryValue localized_strings;
+ GetLocalizedStrings(&localized_strings);
+
+ Profile* profile = Profile::FromWebUI(web_ui);
+ // Set up the chrome://user-chooser/ source.
+ content::WebUIDataSource::Add(profile, CreateUIDataSource(localized_strings));
+
+#if defined(ENABLE_THEMES)
+ // Set up the chrome://theme/ source
+ ThemeSource* theme = new ThemeSource(profile);
+ content::URLDataSource::Add(profile, theme);
+#endif
+}
+
+UserChooserUI::~UserChooserUI() {
+}
+
+content::WebUIDataSource* UserChooserUI::CreateUIDataSource(
+ const base::DictionaryValue& localized_strings) {
+ content::WebUIDataSource* source =
+ content::WebUIDataSource::Create(chrome::kChromeUIUserChooserHost);
+ source->SetUseJsonJSFormatV2();
+ source->AddLocalizedStrings(localized_strings);
+ source->SetJsonPath(kStringsJSPath);
+
+ source->SetDefaultResource(IDR_USER_CHOOSER_HTML);
+ source->AddResourcePath(kUserChooserJSPath, IDR_USER_CHOOSER_JS);
+
+ return source;
+}
+
+void UserChooserUI::GetLocalizedStrings(
+ base::DictionaryValue* localized_strings) {
+ user_chooser_screen_handler_->GetLocalizedValues(localized_strings);
+ webui::SetFontAndTextDirection(localized_strings);
+
+#if defined(GOOGLE_CHROME_BUILD)
+ localized_strings->SetString("buildType", "chrome");
+#else
+ localized_strings->SetString("buildType", "chromium");
+#endif
+}
+
diff --git a/chrome/browser/ui/webui/signin/user_chooser_ui.h b/chrome/browser/ui/webui/signin/user_chooser_ui.h
new file mode 100644
index 0000000..4799bd7
--- /dev/null
+++ b/chrome/browser/ui/webui/signin/user_chooser_ui.h
@@ -0,0 +1,35 @@
+// Copyright 2013 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.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SIGNIN_USER_CHOOSER_UI_H_
+#define CHROME_BROWSER_UI_WEBUI_SIGNIN_USER_CHOOSER_UI_H_
+
+#include "content/public/browser/web_ui_controller.h"
+
+class UserChooserScreenHandler;
+
+namespace base {
+class DictionaryValue;
+}
+namespace content {
+class WebUIDataSource;
+}
+
+// A WebUI dialog to display available users.
+class UserChooserUI : public content::WebUIController {
+ public:
+ explicit UserChooserUI(content::WebUI* web_ui);
+ virtual ~UserChooserUI();
+
+ private:
+ content::WebUIDataSource* CreateUIDataSource(
+ const base::DictionaryValue& localized_strings);
+ void GetLocalizedStrings(base::DictionaryValue* localized_strings);
+
+ UserChooserScreenHandler* user_chooser_screen_handler_;
+
+ DISALLOW_COPY_AND_ASSIGN(UserChooserUI);
+};
+
+#endif // CHROME_BROWSER_UI_WEBUI_SIGNIN_USER_CHOOSER_UI_H_
diff --git a/chrome/browser/ui/webui/sync_promo/sync_promo_trial.cc b/chrome/browser/ui/webui/sync_promo/sync_promo_trial.cc
index a410d2b..5b51aaa 100644
--- a/chrome/browser/ui/webui/sync_promo/sync_promo_trial.cc
+++ b/chrome/browser/ui/webui/sync_promo/sync_promo_trial.cc
@@ -31,6 +31,8 @@
UMA_APP_LAUNCHER_SIGNED_IN,
UMA_APPS_PAGE_LINK_SHOWN,
UMA_APPS_PAGE_LINK_SIGNED_IN,
+ UMA_BOOKMARK_BUBBLE_SHOWN,
+ UMA_BOOKMARK_BUBBLE_SIGNED_IN,
UMA_MAX,
};
@@ -67,6 +69,9 @@
case SyncPromoUI::SOURCE_APPS_PAGE_LINK:
uma = UMA_APPS_PAGE_LINK_SHOWN;
break;
+ case SyncPromoUI::SOURCE_BOOKMARK_BUBBLE:
+ uma = UMA_BOOKMARK_BUBBLE_SHOWN;
+ break;
case SyncPromoUI::SOURCE_UNKNOWN:
uma = UMA_UNKNOWN_SHOWN;
break;
@@ -74,7 +79,7 @@
// If this assert hits, then the SyncPromoUI::Source enum has changed and
// the UMA enum above, this switch statement and histograms.xml all need
// to be updated to reflect that.
- COMPILE_ASSERT(SyncPromoUI::SOURCE_UNKNOWN == 8,
+ COMPILE_ASSERT(SyncPromoUI::SOURCE_UNKNOWN == 9,
kSourceEnumHasChangedButNotThisSwitchStatement);
NOTREACHED();
break;
@@ -111,12 +116,15 @@
case SyncPromoUI::SOURCE_APPS_PAGE_LINK:
uma = UMA_APPS_PAGE_LINK_SIGNED_IN;
break;
+ case SyncPromoUI::SOURCE_BOOKMARK_BUBBLE:
+ uma = UMA_BOOKMARK_BUBBLE_SIGNED_IN;
+ break;
case SyncPromoUI::SOURCE_UNKNOWN:
uma = UMA_UNKNOWN_SIGNED_IN;
break;
default:
// This switch statement needs to be updated when the enum Source changes.
- COMPILE_ASSERT(SyncPromoUI::SOURCE_UNKNOWN == 8,
+ COMPILE_ASSERT(SyncPromoUI::SOURCE_UNKNOWN == 9,
kSourceEnumHasChangedButNotThisSwitchStatement);
NOTREACHED();
break;
diff --git a/chrome/browser/ui/webui/sync_setup_browsertest.js b/chrome/browser/ui/webui/sync_setup_browsertest.js
index 91e3d84..d9f96bd 100644
--- a/chrome/browser/ui/webui/sync_setup_browsertest.js
+++ b/chrome/browser/ui/webui/sync_setup_browsertest.js
@@ -31,7 +31,6 @@
* Verifies starting point is not synced.
*/
verifyUnsynced: function() {
- assertFalse(BrowserOptions.getInstance().setupCompleted_);
assertFalse(BrowserOptions.getInstance().signedIn_);
},
diff --git a/chrome/browser/ui/webui/sync_setup_handler.cc b/chrome/browser/ui/webui/sync_setup_handler.cc
index eab551e..491b60a 100644
--- a/chrome/browser/ui/webui/sync_setup_handler.cc
+++ b/chrome/browser/ui/webui/sync_setup_handler.cc
@@ -23,6 +23,7 @@
#include "chrome/browser/profiles/profile_info_cache.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_metrics.h"
+#include "chrome/browser/signin/signin_global_error.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
@@ -30,7 +31,6 @@
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/sync/signin_histogram.h"
#include "chrome/browser/ui/sync/sync_promo_ui.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/webui/signin/login_ui_service.h"
#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
#include "chrome/common/chrome_switches.h"
@@ -111,37 +111,6 @@
return type_names;
}
-#if !defined(OS_CHROMEOS)
-// Signin logic not needed on ChromeOS
-void BringTabToFront(WebContents* web_contents) {
- DCHECK(web_contents);
- Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
- if (browser) {
- TabStripModel* tab_strip_model = browser->tab_strip_model();
- if (tab_strip_model) {
- int index = tab_strip_model->GetIndexOfWebContents(web_contents);
- if (index != TabStripModel::kNoTab)
- tab_strip_model->ActivateTabAt(index, false);
- }
- }
-}
-
-void CloseTab(content::WebContents* tab) {
- Browser* browser = chrome::FindBrowserWithWebContents(tab);
- if (browser) {
- TabStripModel* tab_strip_model = browser->tab_strip_model();
- if (tab_strip_model) {
- int index = tab_strip_model->GetIndexOfWebContents(tab);
- if (index != TabStripModel::kNoTab) {
- tab_strip_model->ExecuteContextMenuCommand(
- index, TabStripModel::CommandCloseTab);
- }
- }
- }
-}
-
-#endif
-
bool GetConfiguration(const std::string& json, SyncConfigInfo* config) {
scoped_ptr<Value> parsed_value(base::JSONReader::Read(json));
DictionaryValue* result;
@@ -208,11 +177,6 @@
SyncSetupHandler::SyncSetupHandler(ProfileManager* profile_manager)
: configuring_sync_(false),
-#if !defined(OS_CHROMEOS)
- last_signin_error_(GoogleServiceAuthError::NONE),
- retry_on_signin_failure_(true),
- active_gaia_signin_tab_(NULL),
-#endif
profile_manager_(profile_manager) {
}
@@ -332,14 +296,6 @@
ProfileSyncService* service = GetSyncService();
DCHECK(service);
if (!service->sync_initialized()) {
-
-#if !defined(OS_CHROMEOS)
- // When user tries to setup sync while the sync backend is not initialized,
- // kick the sync backend and wait for it to be ready and show spinner until
- // the backend gets ready.
- retry_on_signin_failure_ = false;
-#endif
-
service->UnsuppressAndStart();
// See if it's even possible to bring up the sync backend - if not
@@ -358,8 +314,7 @@
}
// Should only get here if user is signed in and sync is initialized, so no
- // longer need a SigninTracker or SyncStartupTracker.
- signin_tracker_.reset();
+ // longer need a SyncStartupTracker.
sync_startup_tracker_.reset();
configuring_sync_ = true;
DCHECK(service->sync_initialized()) <<
@@ -526,14 +481,12 @@
// visible. If the user exits the signin wizard after this without
// configuring sync, CloseSyncSetup() will ensure they are logged out.
configuring_sync_ = false;
-
DisplayGaiaLoginInNewTabOrWindow();
- signin_tracker_.reset(new SigninTracker(GetProfile(), this));
}
void SyncSetupHandler::DisplayGaiaLoginInNewTabOrWindow() {
- DCHECK(!active_gaia_signin_tab_);
- GURL url(SyncPromoUI::GetSyncPromoURL(SyncPromoUI::SOURCE_SETTINGS, false));
+ GURL url(SyncPromoUI::GetSyncPromoURL(SyncPromoUI::SOURCE_SETTINGS,
+ true)); // auto close after success.
Browser* browser = chrome::FindBrowserWithWebContents(
web_ui()->GetWebContents());
if (!browser) {
@@ -558,10 +511,9 @@
url = url.ReplaceComponents(replacements);
}
- active_gaia_signin_tab_ = browser->OpenURL(
+ browser->OpenURL(
content::OpenURLParams(url, content::Referrer(), SINGLETON_TAB,
content::PAGE_TRANSITION_AUTO_BOOKMARK, false));
- content::WebContentsObserver::Observe(active_gaia_signin_tab_);
}
#endif
@@ -603,7 +555,6 @@
// TODO(kochi): Handle error conditions other than timeout.
// http://crbug.com/128692
void SyncSetupHandler::DisplayTimeout() {
- DCHECK(!signin_tracker_);
// Stop a timer to handle timeout in waiting for checking network connection.
backend_start_timer_.reset();
@@ -616,10 +567,6 @@
"SyncSetupOverlay.showSyncSetupPage", page, args);
}
-void SyncSetupHandler::RecordSignin() {
- // By default, do nothing - subclasses can override.
-}
-
void SyncSetupHandler::OnDidClosePage(const ListValue* args) {
CloseOverlay();
}
@@ -643,22 +590,6 @@
DisplayConfigureSync(true, false);
}
-void SyncSetupHandler::SigninFailed(const GoogleServiceAuthError& error) {
- DCHECK(!backend_start_timer_);
-
-#if defined(OS_CHROMEOS)
- // TODO(peria): Show error dialog for prompting sign in and out on
- // Chrome OS. http://crbug.com/128692
- CloseOverlay();
-#else
- last_signin_error_ = error;
-
- // Don't show the gaia sign in page again since there is no way to show the
- // user an error message.
- CloseSyncSetup();
-#endif
-}
-
Profile* SyncSetupHandler::GetProfile() const {
return Profile::FromWebUI(web_ui());
}
@@ -669,27 +600,7 @@
ProfileSyncServiceFactory::GetForProfile(GetProfile()) : NULL;
}
-void SyncSetupHandler::SigninSuccess() {
- DCHECK(!backend_start_timer_);
- ProfileSyncService* service = GetSyncService();
-
-#if !defined(OS_CHROMEOS)
- CloseGaiaSigninPage();
-#endif
-
- // If we have signed in while sync is already setup, it must be due to some
- // kind of re-authentication flow. In that case, just close the signin dialog
- // rather than forcing the user to go through sync configuration.
- if (!service || service->HasSyncSetupCompleted()) {
- RecordSignin();
- CloseOverlay();
- } else {
- DisplayConfigureSync(false, false);
- }
-}
-
void SyncSetupHandler::HandleConfigure(const ListValue* args) {
- DCHECK(!signin_tracker_);
DCHECK(!sync_startup_tracker_);
std::string json;
if (!args->GetString(0, &json)) {
@@ -863,29 +774,18 @@
// Stop a timer to handle timeout in waiting for checking network connection.
backend_start_timer_.reset();
- // Clear the signin tracker before canceling sync setup, as it may incorrectly
- // flag a signin failure.
- bool was_signing_in = (signin_tracker_.get() != NULL);
- signin_tracker_.reset();
+ // Clear the sync startup tracker, since the setup wizard is being closed.
sync_startup_tracker_.reset();
- // TODO(atwilson): Move UMA tracking of signin events out of sync module.
ProfileSyncService* sync_service = GetSyncService();
if (IsActiveLogin()) {
// Don't log a cancel event if the sync setup dialog is being
// automatically closed due to an auth error.
if (!sync_service || (!sync_service->HasSyncSetupCompleted() &&
sync_service->GetAuthError().state() == GoogleServiceAuthError::NONE)) {
- if (was_signing_in) {
- // TODO(rsimha): Remove this. Sync should not be logging sign in events.
- ProfileSyncService::SyncEvent(
- ProfileSyncService::CANCEL_DURING_SIGNON);
- } else if (configuring_sync_) {
+ if (configuring_sync_) {
ProfileSyncService::SyncEvent(
ProfileSyncService::CANCEL_DURING_CONFIGURE);
- } else {
- ProfileSyncService::SyncEvent(
- ProfileSyncService::CANCEL_FROM_SIGNON_WITHOUT_AUTH);
}
// If the user clicked "Cancel" while setting up sync, disable sync
@@ -906,11 +806,6 @@
}
}
-#if !defined(OS_CHROMEOS)
- // Let the various services know that we're no longer active.
- CloseGaiaSigninPage();
-#endif
-
GetLoginUIService()->LoginUIClosed(this);
}
@@ -920,14 +815,6 @@
if (sync_service)
sync_service->SetSetupInProgress(false);
-#if !defined(OS_CHROMEOS)
- // Reset the attempted email address and error, otherwise the sync setup
- // overlay in the settings page will stay in whatever error state it was last
- // when it is reopened.
- last_attempted_user_email_.clear();
- last_signin_error_ = GoogleServiceAuthError::AuthErrorNone();
-#endif
-
configuring_sync_ = false;
}
@@ -951,20 +838,13 @@
SigninManagerBase* signin =
SigninManagerFactory::GetForProfile(GetProfile());
- if (signin->GetAuthenticatedUsername().empty()) {
- // User is not logged in (cases 1-2). Display login UI.
- DisplayGaiaLogin();
- return;
- }
-
- if (SigninGlobalError::GetForProfile(GetProfile())->HasMenuItem()) {
- // Login has been specially requested because previously working credentials
- // have expired (case 3). Load the sync setup page with a spinner dialog,
- // and then display the gaia auth page. The user may abandon re-auth by
- // clicking cancel on the spinner dialog or closing the gaia login tab.
- StringValue page("spinner");
- web_ui()->CallJavascriptFunction("SyncSetupOverlay.showSyncSetupPage",
- page);
+ if (signin->GetAuthenticatedUsername().empty() ||
+ SigninGlobalError::GetForProfile(GetProfile())->HasMenuItem()) {
+ // User is not logged in (cases 1-2), or login has been specially requested
+ // because previously working credentials have expired (case 3). Close sync
+ // setup including any visible overlays, and display the gaia auth page.
+ // Control will be returned to the sync settings page once auth is complete.
+ CloseOverlay();
DisplayGaiaLogin();
return;
}
@@ -991,13 +871,6 @@
void SyncSetupHandler::FocusUI() {
DCHECK(IsActiveLogin());
-#if !defined(OS_CHROMEOS)
- // Bring the GAIA tab to the foreground if there is one.
- if (signin_tracker_ && active_gaia_signin_tab_) {
- BringTabToFront(active_gaia_signin_tab_);
- return;
- }
-#endif
WebContents* web_contents = web_ui()->GetWebContents();
web_contents->GetDelegate()->ActivateContents(web_contents);
}
@@ -1007,62 +880,6 @@
CloseOverlay();
}
-#if !defined(OS_CHROMEOS)
-void SyncSetupHandler::DidStopLoading(
- content::RenderViewHost* render_view_host) {
- DCHECK(active_gaia_signin_tab_);
-
- // If the user lands on a page outside of Gaia, assume they have navigated
- // away and are no longer thinking about signing in with this tab. Treat
- // this as if the user closed the tab. However, don't actually close the tab
- // since the user is doing something with it. Disconnect and forget about it
- // before closing down the sync setup.
- // The one exception is the expected continue URL. If the user lands there,
- // this means sign in was successful. Ignore the source parameter in the
- // continue URL since this user may have changed the state of the
- // "Let me choose what to sync" checkbox.
- const GURL& url = active_gaia_signin_tab_->GetURL();
- const GURL continue_url =
- SyncPromoUI::GetNextPageURLForSyncPromoURL(
- SyncPromoUI::GetSyncPromoURL(SyncPromoUI::SOURCE_SETTINGS,
- false));
- GURL::Replacements replacements;
- replacements.ClearQuery();
-
- if (!gaia::IsGaiaSignonRealm(url.GetOrigin()) &&
- url.ReplaceComponents(replacements) !=
- continue_url.ReplaceComponents(replacements)) {
- content::WebContentsObserver::Observe(NULL);
- active_gaia_signin_tab_ = NULL;
- CloseOverlay();
- }
-}
-
-void SyncSetupHandler::WebContentsDestroyed(
- content::WebContents* web_contents) {
- DCHECK(active_gaia_signin_tab_);
- CloseOverlay();
-}
-
-// Private member functions.
-
-void SyncSetupHandler::CloseGaiaSigninPage() {
- if (active_gaia_signin_tab_) {
- content::WebContentsObserver::Observe(NULL);
-
- // This can be invoked from a webui handler in the GAIA page (for example,
- // if the user clicks 'cancel' in the enterprise signin dialog), so
- // closing this tab in mid-handler can cause crashes. Instead, close it
- // via a task so we know we aren't in the middle of any webui code.
- base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&CloseTab, base::Unretained(active_gaia_signin_tab_)));
-
- active_gaia_signin_tab_ = NULL;
- }
-}
-#endif
-
bool SyncSetupHandler::FocusExistingWizardIfPresent() {
LoginUIService* service = GetLoginUIService();
if (!service->current_login_ui())
diff --git a/chrome/browser/ui/webui/sync_setup_handler.h b/chrome/browser/ui/webui/sync_setup_handler.h
index 26aa049..2f562ac 100644
--- a/chrome/browser/ui/webui/sync_setup_handler.h
+++ b/chrome/browser/ui/webui/sync_setup_handler.h
@@ -8,11 +8,9 @@
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/timer/timer.h"
-#include "chrome/browser/signin/signin_tracker.h"
#include "chrome/browser/sync/sync_startup_tracker.h"
#include "chrome/browser/ui/webui/options/options_ui.h"
#include "chrome/browser/ui/webui/signin/login_ui_service.h"
-#include "content/public/browser/web_contents_observer.h"
class LoginUIService;
class ProfileManager;
@@ -24,11 +22,7 @@
}
class SyncSetupHandler : public options::OptionsPageUIHandler,
- public SigninTracker::Observer,
public SyncStartupTracker::Observer,
-#if !defined(OS_CHROMEOS)
- public content::WebContentsObserver,
-#endif
public LoginUIService::LoginUI {
public:
// Constructs a new SyncSetupHandler. |profile_manager| may be NULL.
@@ -40,10 +34,6 @@
OVERRIDE;
virtual void RegisterMessages() OVERRIDE;
- // SigninTracker::Observer implementation.
- virtual void SigninFailed(const GoogleServiceAuthError& error) OVERRIDE;
- virtual void SigninSuccess() OVERRIDE;
-
// SyncStartupTracker::Observer implementation;
virtual void SyncStartupCompleted() OVERRIDE;
virtual void SyncStartupFailed() OVERRIDE;
@@ -52,15 +42,6 @@
virtual void FocusUI() OVERRIDE;
virtual void CloseUI() OVERRIDE;
-#if !defined(OS_CHROMEOS)
- // No need to track signin windows on chromeos.
- // content::WebContentsObserver implementation.
- virtual void DidStopLoading(
- content::RenderViewHost* render_view_host) OVERRIDE;
- virtual void WebContentsDestroyed(
- content::WebContents* web_contents) OVERRIDE;
-#endif
-
static void GetStaticLocalizedValues(
base::DictionaryValue* localized_strings,
content::WebUI* web_ui);
@@ -101,11 +82,6 @@
SubmitAuthWithInvalidUsername);
bool is_configuring_sync() const { return configuring_sync_; }
- bool have_signin_tracker() const { return signin_tracker_; }
-
- // Overridden by subclasses (like SyncPromoHandler) to log stats about the
- // user's signin activity.
- virtual void RecordSignin();
// Display the configure sync UI. If |show_advanced| is true, skip directly
// to the "advanced settings" dialog, otherwise give the user the simpler
@@ -172,44 +148,14 @@
// sync setup flow.
void CloseOverlay();
-#if !defined(OS_CHROMEOS)
- // When using web-flow, closes the Gaia page used to collection user
- // credentials.
- void CloseGaiaSigninPage();
-#endif
-
// Helper object used to wait for the sync backend to startup.
scoped_ptr<SyncStartupTracker> sync_startup_tracker_;
- // The SigninTracker object used to determine when the user has fully signed
- // in (this requires waiting for various services to initialize and tracking
- // errors from multiple sources). Should only be non-null while the login UI
- // is visible.
- // TODO(atwilson): Remove references to this on ChromeOS since it will always
- // be null.
- scoped_ptr<SigninTracker> signin_tracker_;
-
// Set to true whenever the sync configure UI is visible. This is used to tell
// what stage of the setup wizard the user was in and to update the UMA
// histograms in the case that the user cancels out.
bool configuring_sync_;
-#if !defined(OS_CHROMEOS)
- // Cache of the last name the client attempted to authenticate.
- std::string last_attempted_user_email_;
-
- // The error from the last signin attempt.
- GoogleServiceAuthError last_signin_error_;
-
- // When setup starts with login UI, retry login if signing in failed.
- // When setup starts without login UI, do not retry login and fail.
- bool retry_on_signin_failure_;
-
- // When using web-flow, weak pointer to the tab that holds the Gaia sign in
- // page.
- content::WebContents* active_gaia_signin_tab_;
-#endif
-
// Weak reference to the profile manager.
ProfileManager* const profile_manager_;
diff --git a/chrome/browser/ui/webui/sync_setup_handler_unittest.cc b/chrome/browser/ui/webui/sync_setup_handler_unittest.cc
index d0c36e7..cc5379d 100644
--- a/chrome/browser/ui/webui/sync_setup_handler_unittest.cc
+++ b/chrome/browser/ui/webui/sync_setup_handler_unittest.cc
@@ -286,7 +286,6 @@
virtual Profile* GetProfile() const OVERRIDE { return profile_; }
using SyncSetupHandler::is_configuring_sync;
- using SyncSetupHandler::have_signin_tracker;
private:
#if !defined(OS_CHROMEOS)
@@ -430,12 +429,13 @@
EXPECT_CALL(*mock_pss_, HasSyncSetupCompleted())
.WillRepeatedly(Return(false));
handler_->HandleStartSignin(NULL);
- EXPECT_EQ(handler_.get(),
+
+ // Sync setup hands off control to the gaia login tab.
+ EXPECT_EQ(NULL,
LoginUIServiceFactory::GetForProfile(
profile_.get())->current_login_ui());
ASSERT_FALSE(handler_->is_configuring_sync());
- ASSERT_TRUE(handler_->have_signin_tracker());
handler_->CloseSyncSetup();
EXPECT_EQ(NULL,
@@ -567,7 +567,6 @@
.WillRepeatedly(Return(true));
SetDefaultExpectationsForConfigPage();
handler_->OpenSyncSetup();
- handler_->SigninSuccess();
// It's important to tell sync the user cancelled the setup flow before we
// tell it we're through with the setup progress.
@@ -638,7 +637,6 @@
handler_->OpenSyncSetup();
ASSERT_FALSE(handler_->is_configuring_sync());
- ASSERT_TRUE(handler_->have_signin_tracker());
}
// TODO(kochi): We need equivalent tests for ChromeOS.
@@ -653,7 +651,6 @@
handler_->OpenSyncSetup();
ASSERT_FALSE(handler_->is_configuring_sync());
- ASSERT_TRUE(handler_->have_signin_tracker());
}
TEST_F(SyncSetupHandlerNonCrosTest, GaiaErrorInitializingSync) {
@@ -667,7 +664,6 @@
handler_->OpenSyncSetup();
ASSERT_FALSE(handler_->is_configuring_sync());
- ASSERT_TRUE(handler_->have_signin_tracker());
}
#endif // #if !defined(OS_CHROMEOS)
@@ -931,12 +927,12 @@
// sync backend, and on desktop this displays the login dialog.
handler_->OpenSyncSetup();
- EXPECT_EQ(handler_.get(),
+ // Sync setup is closed when re-auth is in progress.
+ EXPECT_EQ(NULL,
LoginUIServiceFactory::GetForProfile(
profile_.get())->current_login_ui());
ASSERT_FALSE(handler_->is_configuring_sync());
- ASSERT_TRUE(handler_->have_signin_tracker());
#endif
}
diff --git a/chrome/browser/ui/webui/tab_modal_confirm_dialog_webui.cc b/chrome/browser/ui/webui/tab_modal_confirm_dialog_webui.cc
index 8c37a05..d5b8ed9 100644
--- a/chrome/browser/ui/webui/tab_modal_confirm_dialog_webui.cc
+++ b/chrome/browser/ui/webui/tab_modal_confirm_dialog_webui.cc
@@ -17,6 +17,7 @@
#include "chrome/browser/ui/tab_modal_confirm_dialog_delegate.h"
#include "chrome/browser/ui/webui/constrained_web_dialog_ui.h"
#include "chrome/common/url_constants.h"
+#include "components/web_modal/web_contents_modal_dialog_manager.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui_data_source.h"
#include "grit/browser_resources.h"
@@ -28,6 +29,7 @@
using content::WebContents;
using content::WebUIMessageHandler;
+using web_modal::WebContentsModalDialogManager;
// static
TabModalConfirmDialog* TabModalConfirmDialog::Create(
@@ -42,7 +44,8 @@
TabModalConfirmDialogWebUI::TabModalConfirmDialogWebUI(
TabModalConfirmDialogDelegate* delegate,
WebContents* web_contents)
- : delegate_(delegate) {
+ : web_contents_(web_contents),
+ delegate_(delegate) {
Profile* profile =
Profile::FromBrowserContext(web_contents->GetBrowserContext());
content::WebUIDataSource* data_source = content::WebUIDataSource::Create(
@@ -53,7 +56,7 @@
constrained_web_dialog_delegate_ =
CreateConstrainedWebDialog(profile, this, NULL, web_contents);
- delegate_->set_close_delegate(this);
+ delegate_->set_operations_delegate(this);
}
ui::ModalType TabModalConfirmDialogWebUI::GetDialogModalType() const {
@@ -95,7 +98,7 @@
NOTREACHED() << "Missing or unreadable response from dialog";
}
- delegate_->set_close_delegate(NULL);
+ delegate_->set_operations_delegate(NULL);
if (accepted)
delegate_->Accept();
else
@@ -120,3 +123,11 @@
void TabModalConfirmDialogWebUI::CloseDialog() {
constrained_web_dialog_delegate_->OnDialogCloseFromWebUI();
}
+
+void TabModalConfirmDialogWebUI::SetPreventCloseOnLoadStart(bool prevent) {
+ web_modal::WebContentsModalDialogManager* web_contents_modal_dialog_manager =
+ WebContentsModalDialogManager::FromWebContents(web_contents_);
+ web_contents_modal_dialog_manager->SetPreventCloseOnLoadStart(
+ constrained_web_dialog_delegate_->GetNativeDialog(),
+ prevent);
+}
diff --git a/chrome/browser/ui/webui/tab_modal_confirm_dialog_webui.h b/chrome/browser/ui/webui/tab_modal_confirm_dialog_webui.h
index c77ac74..592a9f2 100644
--- a/chrome/browser/ui/webui/tab_modal_confirm_dialog_webui.h
+++ b/chrome/browser/ui/webui/tab_modal_confirm_dialog_webui.h
@@ -59,6 +59,9 @@
// TabModalConfirmDialogCloseDelegate:
virtual void CloseDialog() OVERRIDE;
+ virtual void SetPreventCloseOnLoadStart(bool prevent) OVERRIDE;
+
+ content::WebContents* web_contents_;
scoped_ptr<TabModalConfirmDialogDelegate> delegate_;
diff --git a/chrome/browser/ui/webui/translate_internals/translate_internals_handler.h b/chrome/browser/ui/webui/translate_internals/translate_internals_handler.h
index bbb84ce..e6a3444 100644
--- a/chrome/browser/ui/webui/translate_internals/translate_internals_handler.h
+++ b/chrome/browser/ui/webui/translate_internals/translate_internals_handler.h
@@ -9,7 +9,7 @@
#include "chrome/browser/translate/translate_manager.h"
#include "content/public/browser/web_ui_message_handler.h"
-#include "webkit/plugins/webplugininfo.h"
+#include "content/public/common/webplugininfo.h"
struct LanguageDetectionDetails;
struct TranslateErrorDetails;
diff --git a/chrome/browser/ui/webui/translate_internals/translate_internals_ui.cc b/chrome/browser/ui/webui/translate_internals/translate_internals_ui.cc
index d7ebb10..be6c1ee 100644
--- a/chrome/browser/ui/webui/translate_internals/translate_internals_ui.cc
+++ b/chrome/browser/ui/webui/translate_internals/translate_internals_ui.cc
@@ -14,6 +14,7 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/translate_internals/translate_internals_handler.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/common/translate/language_detection_util.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
@@ -23,10 +24,6 @@
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
-#if !defined(OS_IOS)
-#include "third_party/cld/encodings/compact_lang_det/compact_lang_det.h"
-#endif
-
namespace {
// Sets the languages to |dict|. Each key is a language code and each value is
@@ -69,10 +66,8 @@
command_line.HasSwitch(switches::kEnableTranslateSettings);
source->AddBoolean("enable-translate-settings", enable_translate_settings);
-#if !defined(OS_IOS)
- std::string cld_version = CompactLangDet::DetectLanguageVersion();
+ std::string cld_version = LanguageDetectionUtil::GetCLDVersion();
source->AddString("cld-version", cld_version);
-#endif
return source;
}
diff --git a/chrome/browser/ui/webui/version_handler.cc b/chrome/browser/ui/webui/version_handler.cc
index d6064fe..065b4f2 100644
--- a/chrome/browser/ui/webui/version_handler.cc
+++ b/chrome/browser/ui/webui/version_handler.cc
@@ -129,9 +129,9 @@
#if defined(ENABLE_PLUGINS)
void VersionHandler::OnGotPlugins(
- const std::vector<webkit::WebPluginInfo>& plugins) {
+ const std::vector<content::WebPluginInfo>& plugins) {
// Obtain the version of the first enabled Flash plugin.
- std::vector<webkit::WebPluginInfo> info_array;
+ std::vector<content::WebPluginInfo> info_array;
content::PluginService::GetInstance()->GetPluginInfoArray(
GURL(), kFlashPluginSwfMimeType, false, &info_array, NULL);
string16 flash_version =
diff --git a/chrome/browser/ui/webui/version_handler.h b/chrome/browser/ui/webui/version_handler.h
index a8f5b11..2fc65d4 100644
--- a/chrome/browser/ui/webui/version_handler.h
+++ b/chrome/browser/ui/webui/version_handler.h
@@ -10,7 +10,7 @@
#include "base/memory/weak_ptr.h"
#include "base/values.h"
#include "content/public/browser/web_ui_message_handler.h"
-#include "webkit/plugins/webplugininfo.h"
+#include "content/public/common/webplugininfo.h"
// Handler class for Version page operations.
class VersionHandler : public content::WebUIMessageHandler {
@@ -34,7 +34,7 @@
// Callback for GetPlugins which responds to the page with the Flash version.
// This also initiates the OS Version load on ChromeOS.
- void OnGotPlugins(const std::vector<webkit::WebPluginInfo>& plugins);
+ void OnGotPlugins(const std::vector<content::WebPluginInfo>& plugins);
// Factory for the creating refs in callbacks.
base::WeakPtrFactory<VersionHandler> weak_ptr_factory_;
diff --git a/chrome/browser/ui/window_sizer/window_sizer_ash.cc b/chrome/browser/ui/window_sizer/window_sizer_ash.cc
index d954240..254d047 100644
--- a/chrome/browser/ui/window_sizer/window_sizer_ash.cc
+++ b/chrome/browser/ui/window_sizer/window_sizer_ash.cc
@@ -23,9 +23,9 @@
namespace {
-// When a window gets opened in default mode and the screen is less then this
-// width, the window will get opened in maximized mode. This value can be
-// reduced to a "tame" number if the feature is disabled.
+// When a window gets opened in default mode and the screen is less than or
+// equal to this width, the window will get opened in maximized mode. This value
+// can be reduced to a "tame" number if the feature is disabled.
const int kForceMaximizeWidthLimit = 1366;
const int kForceMaximizeWidthLimitDisabled = 640;
@@ -212,7 +212,7 @@
// When using "small screens" we want to always open in full screen mode.
if (passed_show_state == ui::SHOW_STATE_DEFAULT &&
!browser_->is_session_restore() &&
- work_area.width() < GetForceMaximizedWidthLimit() &&
+ work_area.width() <= GetForceMaximizedWidthLimit() &&
(!browser_->window() || !browser_->window()->IsFullscreen()) &&
(!browser_->fullscreen_controller() ||
!browser_->fullscreen_controller()->IsFullscreenForBrowser()))
diff --git a/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc b/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc
index fbe3d57..2790756 100644
--- a/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc
+++ b/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc
@@ -102,7 +102,8 @@
WindowSizerTestWithBrowser::~WindowSizerTestWithBrowser() {
}
-}
+} // namespace
+
// Test that the window is sized appropriately for the first run experience
// where the default window bounds calculation is invoked.
TEST_F(WindowSizerTest, DefaultSizeCase) {
@@ -584,45 +585,64 @@
scoped_ptr<Browser> browser(
chrome::CreateBrowserWithTestWindowForParams(&native_params));
+ // A common screen size for Chrome OS devices where this behavior is
+ // desirable.
+ const gfx::Rect p1366x768(0, 0, 1366, 768);
+
// If there is no previous state the window should get maximized if the
- // screen is smaller than our limit (1350 pixels width).
+ // screen is less than or equal to our limit (1366 pixels width).
gfx::Rect window_bounds;
ui::WindowShowState out_show_state1 = ui::SHOW_STATE_DEFAULT;
GetWindowBoundsAndShowState(
- p1024x768, // The screen resolution.
- p1024x768, // The monitor work area.
- gfx::Rect(), // The second monitor.
- gfx::Rect(), // The (persisted) bounds.
- p1024x768, // The overall work area.
- ui::SHOW_STATE_NORMAL, // The persisted show state.
- ui::SHOW_STATE_DEFAULT, // The last show state.
- DEFAULT, // No persisted values.
- browser.get(), // Use this browser.
- gfx::Rect(), // Don't request valid bounds.
- &window_bounds,
- &out_show_state1);
+ p1366x768, // The screen resolution.
+ p1366x768, // The monitor work area.
+ gfx::Rect(), // The second monitor.
+ gfx::Rect(), // The (persisted) bounds.
+ p1366x768, // The overall work area.
+ ui::SHOW_STATE_NORMAL, // The persisted show state.
+ ui::SHOW_STATE_DEFAULT, // The last show state.
+ DEFAULT, // No persisted values.
+ browser.get(), // Use this browser.
+ gfx::Rect(), // Don't request valid bounds.
+ &window_bounds,
+ &out_show_state1);
EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, out_show_state1);
// If there is a stored coordinate however, that should be taken instead.
ui::WindowShowState out_show_state2 = ui::SHOW_STATE_DEFAULT;
GetWindowBoundsAndShowState(
- p1024x768, // The screen resolution.
- p1024x768, // The monitor work area.
- gfx::Rect(), // The second monitor.
- gfx::Rect(50, 100, 300, 150), // The (persisted) bounds.
- p1024x768, // The overall work area.
- ui::SHOW_STATE_NORMAL, // The persisted show state.
- ui::SHOW_STATE_DEFAULT, // The last show state.
- PERSISTED, // Set the persisted values.
- browser.get(), // Use this browser.
- gfx::Rect(), // Don't request valid bounds.
- &window_bounds,
- &out_show_state2);
+ p1366x768, // The screen resolution.
+ p1366x768, // The monitor work area.
+ gfx::Rect(), // The second monitor.
+ gfx::Rect(50, 100, 300, 150), // The (persisted) bounds.
+ p1366x768, // The overall work area.
+ ui::SHOW_STATE_NORMAL, // The persisted show state.
+ ui::SHOW_STATE_DEFAULT, // The last show state.
+ PERSISTED, // Set the persisted values.
+ browser.get(), // Use this browser.
+ gfx::Rect(), // Don't request valid bounds.
+ &window_bounds,
+ &out_show_state2);
EXPECT_EQ(ui::SHOW_STATE_NORMAL, out_show_state2);
EXPECT_EQ("50,100 300x150", window_bounds.ToString());
- }
-
+ // A larger monitor should not trigger auto-maximize.
+ ui::WindowShowState out_show_state3 = ui::SHOW_STATE_DEFAULT;
+ GetWindowBoundsAndShowState(
+ p1600x1200, // The screen resolution.
+ p1600x1200, // The monitor work area.
+ gfx::Rect(), // The second monitor.
+ gfx::Rect(), // The (persisted) bounds.
+ p1600x1200, // The overall work area.
+ ui::SHOW_STATE_NORMAL, // The persisted show state.
+ ui::SHOW_STATE_DEFAULT, // The last show state.
+ DEFAULT, // No persisted values.
+ browser.get(), // Use this browser.
+ gfx::Rect(), // Don't request valid bounds.
+ &window_bounds,
+ &out_show_state3);
+ EXPECT_EQ(ui::SHOW_STATE_DEFAULT, out_show_state3);
+}
#if defined(OS_CHROMEOS)
#define MAYBE_PlaceNewWindowsOnMultipleDisplays PlaceNewWindowsOnMultipleDisplays
diff --git a/chrome/browser/upload_list.cc b/chrome/browser/upload_list.cc
deleted file mode 100644
index 3f618aa..0000000
--- a/chrome/browser/upload_list.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2013 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/upload_list.h"
-
-#include <algorithm>
-#include <iterator>
-
-#include "base/bind.h"
-#include "base/file_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
-#include "content/public/browser/browser_thread.h"
-
-using content::BrowserThread;
-
-UploadList::UploadInfo::UploadInfo(const std::string& c, const base::Time& t)
- : id(c), time(t) {}
-
-UploadList::UploadInfo::~UploadInfo() {}
-
-UploadList::UploadList(Delegate* delegate,
- const base::FilePath& upload_log_path)
- : delegate_(delegate),
- upload_log_path_(upload_log_path) {}
-
-UploadList::~UploadList() {}
-
-void UploadList::LoadUploadListAsynchronously() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- BrowserThread::PostBlockingPoolTask(
- FROM_HERE,
- base::Bind(&UploadList::LoadUploadListAndInformDelegateOfCompletion,
- this));
-}
-
-void UploadList::ClearDelegate() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- delegate_ = NULL;
-}
-
-void UploadList::LoadUploadListAndInformDelegateOfCompletion() {
- LoadUploadList();
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(&UploadList::InformDelegateOfCompletion, this));
-}
-
-void UploadList::LoadUploadList() {
- if (base::PathExists(upload_log_path_)) {
- std::string contents;
- file_util::ReadFileToString(upload_log_path_, &contents);
- std::vector<std::string> log_entries;
- base::SplitStringAlongWhitespace(contents, &log_entries);
- ParseLogEntries(log_entries);
- }
-}
-
-void UploadList::AppendUploadInfo(const UploadInfo& info) {
- uploads_.push_back(info);
-}
-
-void UploadList::ParseLogEntries(
- const std::vector<std::string>& log_entries) {
- std::vector<std::string>::const_reverse_iterator i;
- for (i = log_entries.rbegin(); i != log_entries.rend(); ++i) {
- std::vector<std::string> components;
- base::SplitString(*i, ',', &components);
- // Skip any blank (or corrupted) lines.
- if (components.size() != 2)
- continue;
- double seconds_since_epoch;
- if (!base::StringToDouble(components[0], &seconds_since_epoch))
- continue;
- UploadInfo info(components[1],
- base::Time::FromDoubleT(seconds_since_epoch));
- uploads_.push_back(info);
- }
-}
-
-void UploadList::InformDelegateOfCompletion() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (delegate_)
- delegate_->OnUploadListAvailable();
-}
-
-void UploadList::GetUploads(unsigned int max_count,
- std::vector<UploadInfo>* uploads) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- std::copy(uploads_.begin(),
- uploads_.begin() + std::min<size_t>(uploads_.size(), max_count),
- std::back_inserter(*uploads));
-}
diff --git a/chrome/browser/upload_list.h b/chrome/browser/upload_list.h
deleted file mode 100644
index 23c4ff5..0000000
--- a/chrome/browser/upload_list.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CHROME_BROWSER_UPLOAD_LIST_H_
-#define CHROME_BROWSER_UPLOAD_LIST_H_
-
-#include <string>
-#include <vector>
-
-#include "base/files/file_path.h"
-#include "base/gtest_prod_util.h"
-#include "base/memory/ref_counted.h"
-#include "base/time/time.h"
-
-// Loads and parses an upload list text file of the format
-// time,id
-// time,id
-// etc.
-// where each line represents an upload and "time" is Unix time. Must be used
-// from the UI thread. The loading and parsing is done on a blocking pool task
-// runner.
-class UploadList : public base::RefCountedThreadSafe<UploadList> {
- public:
- struct UploadInfo {
- UploadInfo(const std::string& c, const base::Time& t);
- ~UploadInfo();
-
- std::string id;
- base::Time time;
- };
-
- class Delegate {
- public:
- // Invoked when the upload list has been loaded. Will be called on the
- // UI thread.
- virtual void OnUploadListAvailable() = 0;
-
- protected:
- virtual ~Delegate() {}
- };
-
- // Creates a new upload list with the given callback delegate.
- UploadList(Delegate* delegate, const base::FilePath& upload_log_path);
-
- // Starts loading the upload list. OnUploadListAvailable will be called when
- // loading is complete.
- void LoadUploadListAsynchronously();
-
- // Clears the delegate, so that any outstanding asynchronous load will not
- // call the delegate on completion.
- void ClearDelegate();
-
- // Populates |uploads| with the |max_count| most recent uploads,
- // in reverse chronological order.
- // Must be called only after OnUploadListAvailable has been called.
- void GetUploads(unsigned int max_count, std::vector<UploadInfo>* uploads);
-
- protected:
- virtual ~UploadList();
-
- // Reads the upload log and stores the entries in |uploads_|.
- virtual void LoadUploadList();
-
- // Adds |info| to |uploads_|.
- void AppendUploadInfo(const UploadInfo& info);
-
- private:
- friend class base::RefCountedThreadSafe<UploadList>;
- FRIEND_TEST_ALL_PREFIXES(UploadListTest, ParseLogEntries);
-
- // Manages the background thread work for LoadUploadListAsynchronously().
- void LoadUploadListAndInformDelegateOfCompletion();
-
- // Calls the delegate's callback method, if there is a delegate.
- void InformDelegateOfCompletion();
-
- // Parses upload log lines, converting them to UploadInfo entries.
- void ParseLogEntries(const std::vector<std::string>& log_entries);
-
- std::vector<UploadInfo> uploads_;
- Delegate* delegate_;
- const base::FilePath upload_log_path_;
-
- DISALLOW_COPY_AND_ASSIGN(UploadList);
-};
-
-#endif // CHROME_BROWSER_UPLOAD_LIST_H_
diff --git a/chrome/browser/upload_list_unittest.cc b/chrome/browser/upload_list_unittest.cc
deleted file mode 100644
index 153f9db..0000000
--- a/chrome/browser/upload_list_unittest.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2013 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 <string>
-
-#include "base/files/file_path.h"
-#include "base/memory/ref_counted.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/time/time.h"
-#include "chrome/browser/upload_list.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-// Test that UploadList can parse a vector of log entry strings to a vector of
-// UploadInfo objects. See the UploadList declaration for a description of the
-// log entry string format.
-TEST(UploadListTest, ParseLogEntries) {
- const char kTestTime[] = "1234567890";
- const char kTestID[] = "0123456789abcdef";
- std::string test_entry = kTestTime;
- test_entry += ",";
- test_entry.append(kTestID, sizeof(kTestID));
-
- scoped_refptr<UploadList> upload_list =
- new UploadList(NULL, base::FilePath());
-
- // 1 entry.
- std::vector<std::string> log_entries;
- log_entries.push_back(test_entry);
- upload_list->ParseLogEntries(log_entries);
- EXPECT_EQ(1u, upload_list->uploads_.size());
- double time_double = upload_list->uploads_[0].time.ToDoubleT();
- EXPECT_STREQ(kTestTime, base::DoubleToString(time_double).c_str());
- EXPECT_STREQ(kTestID, upload_list->uploads_[0].id.c_str());
-
- // Add 3 more entries.
- log_entries.push_back(test_entry);
- log_entries.push_back(test_entry);
- upload_list->ParseLogEntries(log_entries);
- EXPECT_EQ(4u, upload_list->uploads_.size());
- time_double = upload_list->uploads_[3].time.ToDoubleT();
- EXPECT_STREQ(kTestTime, base::DoubleToString(time_double).c_str());
- EXPECT_STREQ(kTestID, upload_list->uploads_[3].id.c_str());
-}
diff --git a/chrome/browser/web_resource/promo_resource_service_unittest.cc b/chrome/browser/web_resource/promo_resource_service_unittest.cc
index 95e2a77..0f0ae62 100644
--- a/chrome/browser/web_resource/promo_resource_service_unittest.cc
+++ b/chrome/browser/web_resource/promo_resource_service_unittest.cc
@@ -27,7 +27,7 @@
#include "content/public/browser/notification_service.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/icu/public/i18n/unicode/smpdtfmt.h"
+#include "third_party/icu/source/i18n/unicode/smpdtfmt.h"
namespace {