summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/cocoa/extensions/browser_actions_controller.mm10
-rw-r--r--chrome/browser/extensions/browser_action_apitest.cc122
-rw-r--r--chrome/browser/extensions/browser_action_test_util_views.cc2
-rw-r--r--chrome/browser/extensions/extension_prefs.cc14
-rw-r--r--chrome/browser/extensions/extension_prefs.h4
-rw-r--r--chrome/browser/extensions/extension_toolbar_model.cc25
-rw-r--r--chrome/browser/extensions/extension_toolbar_model.h5
-rw-r--r--chrome/browser/extensions/extension_toolbar_model_unittest.cc7
-rw-r--r--chrome/browser/extensions/extensions_service.cc10
-rw-r--r--chrome/browser/extensions/extensions_service.h4
-rwxr-xr-xchrome/browser/extensions/incognito_noscript_apitest.cc55
-rw-r--r--chrome/browser/extensions/user_script_master.cc20
-rw-r--r--chrome/browser/extensions/user_script_master.h6
-rw-r--r--chrome/browser/gtk/browser_actions_toolbar_gtk.cc23
-rw-r--r--chrome/browser/gtk/browser_actions_toolbar_gtk.h5
-rw-r--r--chrome/browser/net/chrome_url_request_context.cc36
-rw-r--r--chrome/browser/net/chrome_url_request_context.h4
-rw-r--r--chrome/browser/profile.cc21
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.cc3
-rw-r--r--chrome/browser/views/browser_actions_container.cc26
-rw-r--r--chrome/browser/views/browser_actions_container.h9
-rw-r--r--chrome/common/extensions/extension.cc4
-rw-r--r--chrome/common/extensions/extension.h1
-rw-r--r--chrome/common/extensions/user_script.cc15
-rw-r--r--chrome/common/extensions/user_script.h8
-rw-r--r--chrome/common/render_messages_internal.h5
-rw-r--r--chrome/renderer/render_thread.cc4
-rw-r--r--chrome/renderer/render_thread.h3
-rw-r--r--chrome/renderer/user_script_slave.cc10
-rw-r--r--chrome/renderer/user_script_slave.h7
-rw-r--r--chrome/test/data/extensions/api_test/browser_action/add_popup/manifest.json3
-rwxr-xr-xchrome/test/data/extensions/api_test/browser_action/basics/manifest.json3
-rwxr-xr-xchrome/test/data/extensions/api_test/browser_action/popup/manifest.json3
-rwxr-xr-xchrome/test/data/extensions/api_test/incognito_no_script/manifest.json2
34 files changed, 376 insertions, 103 deletions
diff --git a/chrome/browser/cocoa/extensions/browser_actions_controller.mm b/chrome/browser/cocoa/extensions/browser_actions_controller.mm
index cc73d61..c3cd111 100644
--- a/chrome/browser/cocoa/extensions/browser_actions_controller.mm
+++ b/chrome/browser/cocoa/extensions/browser_actions_controller.mm
@@ -30,6 +30,7 @@ NSString* const kBrowserActionsChangedNotification = @"BrowserActionsChanged";
- (void)removeActionButtonForExtension:(Extension*)extension;
- (void)repositionActionButtons;
- (int)currentTabId;
+- (bool)shouldDisplayBrowserAction:(Extension*)extension;
@end
// A helper class to proxy extension notifications to the view controller's
@@ -139,6 +140,9 @@ class ExtensionsServiceObserverBridge : public NotificationObserver,
if (!extension->browser_action())
return;
+ if (![self shouldDisplayBrowserAction:extension])
+ return;
+
// Show the container if it's the first button. Otherwise it will be shown
// already.
if ([buttons_ count] == 0)
@@ -266,4 +270,10 @@ class ExtensionsServiceObserverBridge : public NotificationObserver,
return [buttonOrder_ objectAtIndex:(NSUInteger)index];
}
+- (bool)shouldDisplayBrowserAction:(Extension*)extension {
+ return (!profile_->IsOffTheRecord() ||
+ profile_->GetExtensionsService()->
+ IsIncognitoEnabled(extension->id()));
+}
+
@end
diff --git a/chrome/browser/extensions/browser_action_apitest.cc b/chrome/browser/extensions/browser_action_apitest.cc
index eafa655..a8cd84c 100644
--- a/chrome/browser/extensions/browser_action_apitest.cc
+++ b/chrome/browser/extensions/browser_action_apitest.cc
@@ -19,7 +19,9 @@
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension_action.h"
+#include "chrome/common/url_constants.h"
#include "chrome/test/ui_test_utils.h"
static const int kTimeoutMs = 60 * 1000; // 1 minute
@@ -44,6 +46,9 @@ class BrowserActionApiTest : public ExtensionApiTest {
};
IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, Basic) {
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableExperimentalExtensionApis);
+
StartHTTPServer();
ASSERT_TRUE(RunExtensionTest("browser_action/basics")) << message_;
Extension* extension = GetSingleLoadedExtension();
@@ -143,6 +148,9 @@ IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, TabSpecificBrowserActionState) {
}
IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, BrowserActionPopup) {
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableExperimentalExtensionApis);
+
ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
"browser_action/popup")));
Extension* extension = GetSingleLoadedExtension();
@@ -176,6 +184,9 @@ IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, BrowserActionPopup) {
// Test that calling chrome.browserAction.setPopup() can enable and change
// a popup.
IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, BrowserActionAddPopup) {
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableExperimentalExtensionApis);
+
ASSERT_TRUE(RunExtensionTest("browser_action/add_popup")) << message_;
Extension* extension = GetSingleLoadedExtension();
ASSERT_TRUE(extension) << message_;
@@ -261,3 +272,114 @@ IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, BrowserActionRemovePopup) {
<< "Browser action popup default should not be changed by setting "
<< "a specific tab id.";
}
+
+IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, IncognitoBasic) {
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableExperimentalExtensionApis);
+
+ StartHTTPServer();
+
+ ASSERT_TRUE(RunExtensionTest("browser_action/basics")) << message_;
+ Extension* extension = GetSingleLoadedExtension();
+ ASSERT_TRUE(extension) << message_;
+
+ // Test that there is a browser action in the toolbar.
+ ASSERT_EQ(1, GetBrowserActionsBar().NumberOfBrowserActions());
+
+ // Open an incognito window and test that the browser action isn't there by
+ // default.
+ Profile* incognito_profile = browser()->profile()->GetOffTheRecordProfile();
+ Browser* incognito_browser = Browser::Create(incognito_profile);
+
+ ASSERT_EQ(0,
+ BrowserActionTestUtil(incognito_browser).NumberOfBrowserActions());
+
+ // Now enable the extension in incognito mode, and test that the browser
+ // action shows up. Note that we don't update the existing window at the
+ // moment, so we just create a new one.
+ browser()->profile()->GetExtensionsService()->extension_prefs()->
+ SetIsIncognitoEnabled(extension->id(), true);
+
+ incognito_browser->CloseWindow();
+ incognito_browser = Browser::Create(incognito_profile);
+ ASSERT_EQ(1,
+ BrowserActionTestUtil(incognito_browser).NumberOfBrowserActions());
+
+ // TODO(mpcomplete): simulate a click and have it do the right thing in
+ // incognito.
+}
+
+// TODO(mpcomplete): enable this when Mac gets dragging support.
+#if defined(OS_MACOSX)
+IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, DISABLED_IncognitoDragging) {
+#else
+IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, IncognitoDragging) {
+#endif
+ ExtensionsService* service = browser()->profile()->GetExtensionsService();
+
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableExperimentalExtensionApis);
+
+ // The tooltips for each respective browser action.
+ const char kTooltipA[] = "Make this page red";
+ const char kTooltipB[] = "grow";
+ const char kTooltipC[] = "Test setPopup()";
+ ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
+ "browser_action/basics")));
+ ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
+ "browser_action/popup")));
+ ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII(
+ "browser_action/add_popup")));
+
+ // Test that there are 3 browser actions in the toolbar.
+ ASSERT_EQ(3u, service->extensions()->size());
+ ASSERT_EQ(3, GetBrowserActionsBar().NumberOfBrowserActions());
+
+ // Now enable 2 of the extensions in incognito mode, and test that the browser
+ // actions show up.
+ service->extension_prefs()->SetIsIncognitoEnabled(
+ service->extensions()->at(0)->id(), true);
+ service->extension_prefs()->SetIsIncognitoEnabled(
+ service->extensions()->at(2)->id(), true);
+
+ Profile* incognito_profile = browser()->profile()->GetOffTheRecordProfile();
+ Browser* incognito_browser = Browser::Create(incognito_profile);
+ BrowserActionTestUtil incognito_bar(incognito_browser);
+
+ // Navigate just to have a tab in this window, otherwise wonky things happen.
+ ui_test_utils::OpenURLOffTheRecord(browser()->profile(),
+ GURL(chrome::kChromeUIExtensionsURL));
+
+ ASSERT_EQ(2, incognito_bar.NumberOfBrowserActions());
+
+ // Ensure that the browser actions are in the right order (ABC).
+ EXPECT_EQ(kTooltipA, GetBrowserActionsBar().GetTooltip(0));
+ EXPECT_EQ(kTooltipB, GetBrowserActionsBar().GetTooltip(1));
+ EXPECT_EQ(kTooltipC, GetBrowserActionsBar().GetTooltip(2));
+
+ EXPECT_EQ(kTooltipA, incognito_bar.GetTooltip(0));
+ EXPECT_EQ(kTooltipC, incognito_bar.GetTooltip(1));
+
+ // Now rearrange them and ensure that they are rearranged correctly in both
+ // regular and incognito mode.
+
+ // ABC -> CAB
+ service->toolbar_model()->MoveBrowserAction(service->extensions()->at(2), 0);
+
+ EXPECT_EQ(kTooltipC, GetBrowserActionsBar().GetTooltip(0));
+ EXPECT_EQ(kTooltipA, GetBrowserActionsBar().GetTooltip(1));
+ EXPECT_EQ(kTooltipB, GetBrowserActionsBar().GetTooltip(2));
+
+ EXPECT_EQ(kTooltipC, incognito_bar.GetTooltip(0));
+ EXPECT_EQ(kTooltipA, incognito_bar.GetTooltip(1));
+
+ // CAB -> CBA
+ service->toolbar_model()->MoveBrowserAction(service->extensions()->at(1), 1);
+
+ EXPECT_EQ(kTooltipC, GetBrowserActionsBar().GetTooltip(0));
+ EXPECT_EQ(kTooltipB, GetBrowserActionsBar().GetTooltip(1));
+ EXPECT_EQ(kTooltipA, GetBrowserActionsBar().GetTooltip(2));
+
+ EXPECT_EQ(kTooltipC, incognito_bar.GetTooltip(0));
+ EXPECT_EQ(kTooltipA, incognito_bar.GetTooltip(1));
+}
diff --git a/chrome/browser/extensions/browser_action_test_util_views.cc b/chrome/browser/extensions/browser_action_test_util_views.cc
index 9af266d..c116f22 100644
--- a/chrome/browser/extensions/browser_action_test_util_views.cc
+++ b/chrome/browser/extensions/browser_action_test_util_views.cc
@@ -41,7 +41,7 @@ void BrowserActionTestUtil::Press(int index) {
std::string BrowserActionTestUtil::GetTooltip(int index) {
std::wstring text;
- GetContainer(browser_)->GetBrowserActionViewAt(0)->button()->
+ GetContainer(browser_)->GetBrowserActionViewAt(index)->button()->
GetTooltipText(0, 0, &text);
return WideToUTF8(text);
}
diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc
index 6d92ad2..3aeda24 100644
--- a/chrome/browser/extensions/extension_prefs.cc
+++ b/chrome/browser/extensions/extension_prefs.cc
@@ -49,6 +49,10 @@ const wchar_t kExtensionToolbar[] = L"extensions.toolbar";
// server's perspective) an extension last included a "ping" parameter during
// its update check.
const wchar_t kLastPingDay[] = L"lastpingday";
+
+// A preference that, if true, will allow this extension to run in incognito
+// mode.
+const wchar_t kPrefIncognitoEnabled[] = L"incognito";
}
////////////////////////////////////////////////////////////////////////////////
@@ -257,6 +261,16 @@ void ExtensionPrefs::SetLastPingDay(const std::string& extension_id,
prefs_->ScheduleSavePersistentPrefs();
}
+bool ExtensionPrefs::IsIncognitoEnabled(const std::string& extension_id) {
+ return ReadExtensionPrefBoolean(extension_id, kPrefIncognitoEnabled);
+}
+
+void ExtensionPrefs::SetIsIncognitoEnabled(const std::string& extension_id,
+ bool enabled) {
+ UpdateExtensionPref(extension_id, kPrefIncognitoEnabled,
+ Value::CreateBooleanValue(enabled));
+ prefs_->SavePersistentPrefs();
+}
void ExtensionPrefs::GetKilledExtensionIds(std::set<std::string>* killed_ids) {
const DictionaryValue* dict = prefs_->GetDictionary(kExtensionsPref);
diff --git a/chrome/browser/extensions/extension_prefs.h b/chrome/browser/extensions/extension_prefs.h
index d8d3694..77f64901 100644
--- a/chrome/browser/extensions/extension_prefs.h
+++ b/chrome/browser/extensions/extension_prefs.h
@@ -94,6 +94,10 @@ class ExtensionPrefs {
// the client's.
void SetLastPingDay(const std::string& extension_id, const base::Time& time);
+ // Returns true if the user enabled this extension to be loaded in incognito
+ // mode.
+ bool IsIncognitoEnabled(const std::string& extension_id);
+ void SetIsIncognitoEnabled(const std::string& extension_id, bool enabled);
// Saves ExtensionInfo for each installed extension with the path to the
// version directory and the location. Blacklisted extensions won't be saved
diff --git a/chrome/browser/extensions/extension_toolbar_model.cc b/chrome/browser/extensions/extension_toolbar_model.cc
index 4c9bd39..f243949 100644
--- a/chrome/browser/extensions/extension_toolbar_model.cc
+++ b/chrome/browser/extensions/extension_toolbar_model.cc
@@ -187,3 +187,28 @@ void ExtensionToolbarModel::UpdatePrefs() {
ids.push_back((*iter)->id());
service_->extension_prefs()->SetToolbarOrder(ids);
}
+
+int ExtensionToolbarModel::IncognitoIndexToOriginal(int incognito_index) {
+ int original_index = 0, i = 0;
+ for (ExtensionList::iterator iter = begin(); iter != end();
+ ++iter, ++original_index) {
+ if (service_->IsIncognitoEnabled((*iter)->id())) {
+ if (incognito_index == i)
+ break;
+ ++i;
+ }
+ }
+ return original_index;
+}
+
+int ExtensionToolbarModel::OriginalIndexToIncognito(int original_index) {
+ int incognito_index = 0, i = 0;
+ for (ExtensionList::iterator iter = begin(); iter != end();
+ ++iter, ++i) {
+ if (original_index == i)
+ break;
+ if (service_->IsIncognitoEnabled((*iter)->id()))
+ ++incognito_index;
+ }
+ return incognito_index;
+}
diff --git a/chrome/browser/extensions/extension_toolbar_model.h b/chrome/browser/extensions/extension_toolbar_model.h
index 1718050..a4c7855 100644
--- a/chrome/browser/extensions/extension_toolbar_model.h
+++ b/chrome/browser/extensions/extension_toolbar_model.h
@@ -50,6 +50,11 @@ class ExtensionToolbarModel : public NotificationObserver {
return toolitems_.end();
}
+ // Utility functions for converting between an index into the list of
+ // incognito-enabled browser actions, and the list of all browser actions.
+ int IncognitoIndexToOriginal(int incognito_index);
+ int OriginalIndexToIncognito(int original_index);
+
private:
// NotificationObserver implementation.
virtual void Observe(NotificationType type,
diff --git a/chrome/browser/extensions/extension_toolbar_model_unittest.cc b/chrome/browser/extensions/extension_toolbar_model_unittest.cc
index 79b9efb..031672e 100644
--- a/chrome/browser/extensions/extension_toolbar_model_unittest.cc
+++ b/chrome/browser/extensions/extension_toolbar_model_unittest.cc
@@ -7,6 +7,7 @@
#include "chrome/browser/extensions/extension_toolbar_model.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/profile.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/test/in_process_browser_test.h"
// An InProcessBrowserTest for testing the ExtensionToolbarModel.
@@ -65,6 +66,9 @@ class ExtensionToolbarModelTest : public ExtensionBrowserTest,
};
IN_PROC_BROWSER_TEST_F(ExtensionToolbarModelTest, Basic) {
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableExperimentalExtensionApis);
+
// Load an extension with no browser action.
ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test")
.AppendASCII("browser_action")
@@ -102,6 +106,9 @@ IN_PROC_BROWSER_TEST_F(ExtensionToolbarModelTest, Basic) {
}
IN_PROC_BROWSER_TEST_F(ExtensionToolbarModelTest, ReorderAndReinsert) {
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableExperimentalExtensionApis);
+
// Load an extension with a browser action.
FilePath extension_a_path(test_data_dir_.AppendASCII("api_test")
.AppendASCII("browser_action")
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index 7dddfa9..476f640 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -529,6 +529,16 @@ base::Time ExtensionsService::LastPingDay(const std::string& extension_id) {
return extension_prefs_->LastPingDay(extension_id);
}
+bool ExtensionsService::IsIncognitoEnabled(const std::string& extension_id) {
+ Extension* extension = GetExtensionById(extension_id, true);
+ if (!extension)
+ return false;
+
+ return extension_prefs_->IsIncognitoEnabled(extension_id) &&
+ extension->HasApiPermission(Extension::kExperimentalPermission) &&
+ extension->HasApiPermission(Extension::kIncognitoPermission);
+}
+
void ExtensionsService::CheckForExternalUpdates() {
// This installs or updates externally provided extensions.
// TODO(aa): Why pass this list into the provider, why not just filter it
diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h
index 5b4d37e..078ac01 100644
--- a/chrome/browser/extensions/extensions_service.h
+++ b/chrome/browser/extensions/extensions_service.h
@@ -106,6 +106,10 @@ class ExtensionsService
const base::Time& time);
virtual base::Time LastPingDay(const std::string& extension_id);
+ // Returns true if this extension can run in an incognito window. The
+ // decision is based on both user consent and the extension having the right
+ // permission.
+ bool IsIncognitoEnabled(const std::string& extension_id);
const FilePath& install_directory() const { return install_directory_; }
diff --git a/chrome/browser/extensions/incognito_noscript_apitest.cc b/chrome/browser/extensions/incognito_noscript_apitest.cc
index fa78e67..1a63d88 100755
--- a/chrome/browser/extensions/incognito_noscript_apitest.cc
+++ b/chrome/browser/extensions/incognito_noscript_apitest.cc
@@ -6,8 +6,11 @@
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/extensions/extension_browsertest.h"
+#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/user_script_master.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/ui_test_utils.h"
#include "net/base/mock_host_resolver.h"
@@ -18,28 +21,50 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, IncognitoNoScript) {
// Loads a simple extension which attempts to change the title of every page
// that loads to "modified".
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableExperimentalExtensionApis);
FilePath extension_path = test_data_dir_.AppendASCII("api_test")
.AppendASCII("incognito_no_script");
ASSERT_TRUE(LoadExtension(extension_path));
// Open incognito window and navigate to test page.
- Browser::OpenURLOffTheRecord(browser()->profile(),
- GURL("http://www.foo.com:1337/files/extensions/test_file.html"));
- Profile* off_the_record_profile =
- browser()->profile()->GetOffTheRecordProfile();
- Browser* otr_browser = Browser::Create(off_the_record_profile);
- otr_browser->AddTabWithURL(
- GURL("http://www.foo.com:1337/files/extensions/test_file.html"),
- GURL(),
- PageTransition::LINK,
- true,
- -1,
- false,
- NULL);
- otr_browser->window()->Show();
- ui_test_utils::WaitForNavigationInCurrentTab(otr_browser);
+ ui_test_utils::OpenURLOffTheRecord(browser()->profile(),
+ GURL("http://www.example.com:1337/files/extensions/test_file.html"));
+ Browser* otr_browser = BrowserList::FindBrowserWithType(
+ browser()->profile()->GetOffTheRecordProfile(), Browser::TYPE_NORMAL);
string16 title;
ui_test_utils::GetCurrentTabTitle(otr_browser, &title);
ASSERT_EQ("Unmodified", UTF16ToASCII(title));
}
+
+IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, IncognitoYesScript) {
+ host_resolver()->AddRule("*", "127.0.0.1");
+ StartHTTPServer();
+
+ // Loads a simple extension which attempts to change the title of every page
+ // that loads to "modified".
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableExperimentalExtensionApis);
+ FilePath extension_path = test_data_dir_.AppendASCII("api_test")
+ .AppendASCII("incognito_no_script");
+ ASSERT_TRUE(LoadExtension(extension_path));
+
+ // Now enable the extension in incognito mode, and ensure that page titles
+ // are modified.
+ ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ service->extension_prefs()->SetIsIncognitoEnabled(
+ service->extensions()->at(0)->id(), true);
+ browser()->profile()->GetUserScriptMaster()->ReloadExtensionForTesting(
+ service->extensions()->at(0));
+
+ // Open incognito window and navigate to test page.
+ ui_test_utils::OpenURLOffTheRecord(browser()->profile(),
+ GURL("http://www.example.com:1337/files/extensions/test_file.html"));
+ Browser* otr_browser = BrowserList::FindBrowserWithType(
+ browser()->profile()->GetOffTheRecordProfile(), Browser::TYPE_NORMAL);
+
+ string16 title;
+ ui_test_utils::GetCurrentTabTitle(otr_browser, &title);
+ ASSERT_EQ("modified", UTF16ToASCII(title));
+}
diff --git a/chrome/browser/extensions/user_script_master.cc b/chrome/browser/extensions/user_script_master.cc
index 3478b68..a7d69f6 100644
--- a/chrome/browser/extensions/user_script_master.cc
+++ b/chrome/browser/extensions/user_script_master.cc
@@ -16,6 +16,7 @@
#include "base/thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/profile.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/url_constants.h"
@@ -333,17 +334,15 @@ void UserScriptMaster::Observe(NotificationType type,
StartScan();
break;
case NotificationType::EXTENSION_LOADED: {
- // TODO(aa): Fix race here. A page could need a content script on startup,
- // before the extension has loaded. We need to freeze the renderer in
- // that case.
- // See: http://code.google.com/p/chromium/issues/detail?id=11547.
-
// Add any content scripts inside the extension.
Extension* extension = Details<Extension>(details).ptr();
+ bool incognito_enabled = profile_->GetExtensionsService()->
+ IsIncognitoEnabled(extension->id());
const UserScriptList& scripts = extension->content_scripts();
for (UserScriptList::const_iterator iter = scripts.begin();
iter != scripts.end(); ++iter) {
lone_scripts_.push_back(*iter);
+ lone_scripts_.back().set_incognito_enabled(incognito_enabled);
}
if (extensions_service_ready_)
StartScan();
@@ -379,3 +378,14 @@ void UserScriptMaster::StartScan() {
script_reloader_->StartScan(user_script_dir_, lone_scripts_);
}
+
+void UserScriptMaster::ReloadExtensionForTesting(Extension* extension) {
+ bool incognito_enabled = profile_->GetExtensionsService()->
+ IsIncognitoEnabled(extension->id());
+ for (UserScriptList::iterator iter = lone_scripts_.begin();
+ iter != lone_scripts_.end(); ++iter) {
+ if (iter->extension_id() == extension->id())
+ (*iter).set_incognito_enabled(incognito_enabled);
+ }
+ StartScan();
+}
diff --git a/chrome/browser/extensions/user_script_master.h b/chrome/browser/extensions/user_script_master.h
index 0423305..19562f0 100644
--- a/chrome/browser/extensions/user_script_master.h
+++ b/chrome/browser/extensions/user_script_master.h
@@ -17,6 +17,7 @@ namespace base {
class StringPiece;
}
+class Extension;
class Profile;
// Manages a segment of shared memory that contains the user scripts the user
@@ -46,6 +47,11 @@ class UserScriptMaster : public base::RefCountedThreadSafe<UserScriptMaster>,
// Returns the path to the directory user scripts are stored in.
FilePath user_script_dir() const { return user_script_dir_; }
+ // Note: this is only for testing. This will reload the scripts associated
+ // with the given extension. This is only temporary until we get better
+ // machinery in place for toggling incognito-enabled extensions.
+ void ReloadExtensionForTesting(Extension* extension);
+
protected:
friend class base::RefCountedThreadSafe<UserScriptMaster>;
diff --git a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
index ef115be..c1921cd 100644
--- a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
+++ b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc
@@ -332,6 +332,12 @@ void BrowserActionsToolbarGtk::CreateAllButtons() {
void BrowserActionsToolbarGtk::CreateButtonForExtension(Extension* extension,
int index) {
+ if (!ShouldDisplayBrowserAction(extension))
+ return;
+
+ if (profile_->IsOffTheRecord())
+ index = model_->OriginalIndexToIncognito(index);
+
RemoveButtonForExtension(extension);
linked_ptr<BrowserActionButton> button(
new BrowserActionButton(this, extension));
@@ -374,6 +380,14 @@ void BrowserActionsToolbarGtk::UpdateVisibility() {
gtk_widget_show(widget());
}
+bool BrowserActionsToolbarGtk::ShouldDisplayBrowserAction(
+ Extension* extension) {
+ // Only display incognito-enabled extensions while in incognito mode.
+ return (!profile_->IsOffTheRecord() ||
+ profile_->GetExtensionsService()->
+ IsIncognitoEnabled(extension->id()));
+}
+
void BrowserActionsToolbarGtk::HidePopup() {
ExtensionPopupGtk* popup = ExtensionPopupGtk::get_current_extension_popup();
if (popup)
@@ -402,10 +416,14 @@ void BrowserActionsToolbarGtk::BrowserActionMoved(Extension* extension,
BrowserActionButton* button = extension_button_map_[extension->id()].get();
if (!button) {
- NOTREACHED();
+ if (ShouldDisplayBrowserAction(extension))
+ NOTREACHED();
return;
}
+ if (profile_->IsOffTheRecord())
+ index = model_->OriginalIndexToIncognito(index);
+
gtk_box_reorder_child(GTK_BOX(hbox_.get()), button->widget(), index);
}
@@ -428,6 +446,9 @@ gboolean BrowserActionsToolbarGtk::OnDragMotion(GtkWidget* widget,
return FALSE;
drop_index_ = x < kButtonSize ? 0 : x / (kButtonSize + kButtonPadding);
+ if (profile_->IsOffTheRecord())
+ drop_index_ = model_->IncognitoIndexToOriginal(drop_index_);
+
// We will go ahead and reorder the child in order to provide visual feedback
// to the user. We don't inform the model that it has moved until the drag
// ends.
diff --git a/chrome/browser/gtk/browser_actions_toolbar_gtk.h b/chrome/browser/gtk/browser_actions_toolbar_gtk.h
index 39daf78..1356320 100644
--- a/chrome/browser/gtk/browser_actions_toolbar_gtk.h
+++ b/chrome/browser/gtk/browser_actions_toolbar_gtk.h
@@ -69,6 +69,11 @@ class BrowserActionsToolbarGtk : public ExtensionToolbarModel::Observer {
// Hide the extension popup, if any.
void HidePopup();
+ // Returns true if this extension should be shown in this toolbar. This can
+ // return false if we are in an incognito window and the extension is disabled
+ // for incognito.
+ bool ShouldDisplayBrowserAction(Extension* extension);
+
// ExtensionToolbarModel::Observer implementation.
virtual void BrowserActionAdded(Extension* extension, int index);
virtual void BrowserActionRemoved(Extension* extension);
diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc
index e206121..3faa8d3 100644
--- a/chrome/browser/net/chrome_url_request_context.cc
+++ b/chrome/browser/net/chrome_url_request_context.cc
@@ -283,32 +283,6 @@ ChromeURLRequestContext* FactoryForOffTheRecord::Create() {
return context;
}
-// Factory that creates the ChromeURLRequestContext for extensions in incognito
-// mode.
-class FactoryForOffTheRecordExtensions
- : public ChromeURLRequestContextFactory {
- public:
- explicit FactoryForOffTheRecordExtensions(Profile* profile)
- : ChromeURLRequestContextFactory(profile) {}
-
- virtual ChromeURLRequestContext* Create();
-};
-
-ChromeURLRequestContext* FactoryForOffTheRecordExtensions::Create() {
- ChromeURLRequestContext* context = new ChromeURLRequestContext;
- ApplyProfileParametersToContext(context);
-
- net::CookieMonster* cookie_monster = new net::CookieMonster(NULL);
-
- // Enable cookies for extension URLs only.
- const char* schemes[] = {chrome::kExtensionScheme};
- cookie_monster->SetCookieableSchemes(schemes, 1);
- context->set_cookie_store(cookie_monster);
- // No dynamic cookie policy for extensions.
-
- return context;
-}
-
// Factory that creates the ChromeURLRequestContext for media.
class FactoryForMedia : public ChromeURLRequestContextFactory {
public:
@@ -501,16 +475,6 @@ ChromeURLRequestContextGetter::CreateOffTheRecord(Profile* profile) {
profile, new FactoryForOffTheRecord(profile));
}
-// static
-ChromeURLRequestContextGetter*
-ChromeURLRequestContextGetter::CreateOffTheRecordForExtensions(
- Profile* profile) {
- DCHECK(profile->IsOffTheRecord());
- return new ChromeURLRequestContextGetter(
- profile,
- new FactoryForOffTheRecordExtensions(profile));
-}
-
void ChromeURLRequestContextGetter::CleanupOnUIThread() {
CheckCurrentlyOnMainThread();
diff --git a/chrome/browser/net/chrome_url_request_context.h b/chrome/browser/net/chrome_url_request_context.h
index 99aed21..df9b64a 100644
--- a/chrome/browser/net/chrome_url_request_context.h
+++ b/chrome/browser/net/chrome_url_request_context.h
@@ -280,10 +280,6 @@ class ChromeURLRequestContextGetter : public URLRequestContextGetter,
// called on the UI thread.
static ChromeURLRequestContextGetter* CreateOffTheRecord(Profile* profile);
- // Create an instance of request context for OTR profile for extensions.
- static ChromeURLRequestContextGetter* CreateOffTheRecordForExtensions(
- Profile* profile);
-
// Clean up UI thread resources. This is expected to get called on the UI
// thread before the instance is deleted on the IO thread.
void CleanupOnUIThread();
diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc
index a1594b2..a83ad4a 100644
--- a/chrome/browser/profile.cc
+++ b/chrome/browser/profile.cc
@@ -196,7 +196,6 @@ class OffTheRecordProfileImpl : public Profile,
public:
explicit OffTheRecordProfileImpl(Profile* real_profile)
: profile_(real_profile),
- extensions_request_context_(NULL),
start_time_(Time::Now()) {
request_context_ = ChromeURLRequestContextGetter::CreateOffTheRecord(this);
@@ -209,7 +208,6 @@ class OffTheRecordProfileImpl : public Profile,
virtual ~OffTheRecordProfileImpl() {
CleanupRequestContext(request_context_);
- CleanupRequestContext(extensions_request_context_);
}
virtual ProfileId GetRuntimeId() {
@@ -248,23 +246,25 @@ class OffTheRecordProfileImpl : public Profile,
}
virtual ExtensionsService* GetExtensionsService() {
- return NULL;
+ return GetOriginalProfile()->GetExtensionsService();
}
virtual UserScriptMaster* GetUserScriptMaster() {
- return NULL;
+ return GetOriginalProfile()->GetUserScriptMaster();
}
virtual ExtensionDevToolsManager* GetExtensionDevToolsManager() {
+ // TODO(mpcomplete): figure out whether we should return the original
+ // profile's version.
return NULL;
}
virtual ExtensionProcessManager* GetExtensionProcessManager() {
- return NULL;
+ return GetOriginalProfile()->GetExtensionProcessManager();
}
virtual ExtensionMessageService* GetExtensionMessageService() {
- return NULL;
+ return GetOriginalProfile()->GetExtensionMessageService();
}
virtual SSLHostState* GetSSLHostState() {
@@ -389,12 +389,7 @@ class OffTheRecordProfileImpl : public Profile,
}
URLRequestContextGetter* GetRequestContextForExtensions() {
- if (!extensions_request_context_) {
- extensions_request_context_ =
- ChromeURLRequestContextGetter::CreateOffTheRecordForExtensions(this);
- }
-
- return extensions_request_context_;
+ return GetOriginalProfile()->GetRequestContextForExtensions();
}
virtual net::SSLConfigService* GetSSLConfigService() {
@@ -527,8 +522,6 @@ class OffTheRecordProfileImpl : public Profile,
// The context to use for requests made from this OTR session.
scoped_refptr<ChromeURLRequestContextGetter> request_context_;
- scoped_refptr<ChromeURLRequestContextGetter> extensions_request_context_;
-
// The download manager that only stores downloaded items in memory.
scoped_refptr<DownloadManager> download_manager_;
diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc
index f567b99..1822c07 100644
--- a/chrome/browser/renderer_host/browser_render_process_host.cc
+++ b/chrome/browser/renderer_host/browser_render_process_host.cc
@@ -622,7 +622,8 @@ void BrowserRenderProcessHost::SendUserScriptsUpdate(
}
if (base::SharedMemory::IsHandleValid(handle_for_process)) {
- Send(new ViewMsg_UserScripts_UpdatedScripts(handle_for_process));
+ Send(new ViewMsg_UserScripts_UpdatedScripts(handle_for_process,
+ profile()->IsOffTheRecord()));
}
}
diff --git a/chrome/browser/views/browser_actions_container.cc b/chrome/browser/views/browser_actions_container.cc
index d089a40..5a1ae90 100644
--- a/chrome/browser/views/browser_actions_container.cc
+++ b/chrome/browser/views/browser_actions_container.cc
@@ -450,6 +450,9 @@ void BrowserActionsContainer::CreateBrowserActionViews() {
DCHECK(browser_action_views_.empty());
for (ExtensionList::iterator iter = model_->begin();
iter != model_->end(); ++iter) {
+ if (!ShouldDisplayBrowserAction(*iter))
+ continue;
+
BrowserActionView* view = new BrowserActionView(*iter, this);
browser_action_views_.push_back(view);
AddChildView(view);
@@ -673,6 +676,7 @@ void BrowserActionsContainer::ViewHierarchyChanged(bool is_add,
bool BrowserActionsContainer::GetDropFormats(
int* formats, std::set<OSExchangeData::CustomFormat>* custom_formats) {
custom_formats->insert(BrowserActionDragData::GetBrowserActionCustomFormat());
+
return true;
}
@@ -771,6 +775,9 @@ int BrowserActionsContainer::OnPerformDrop(
if (i > data.index())
--i;
+ if (profile_->IsOffTheRecord())
+ i = model_->IncognitoIndexToOriginal(i);
+
model_->MoveBrowserAction(dragging, i);
OnDragExited(); // Perform clean up after dragging.
@@ -933,6 +940,12 @@ void BrowserActionsContainer::BrowserActionAdded(Extension* extension,
CloseMenus();
+ if (!ShouldDisplayBrowserAction(extension))
+ return;
+
+ if (profile_->IsOffTheRecord())
+ index = model_->OriginalIndexToIncognito(index);
+
// Before we change anything, determine the number of visible browser actions.
size_t visible_actions = VisibleBrowserActions();
@@ -1011,6 +1024,12 @@ void BrowserActionsContainer::BrowserActionRemoved(Extension* extension) {
void BrowserActionsContainer::BrowserActionMoved(Extension* extension,
int index) {
+ if (!ShouldDisplayBrowserAction(extension))
+ return;
+
+ if (profile_->IsOffTheRecord())
+ index = model_->OriginalIndexToIncognito(index);
+
DCHECK(index >= 0 && index < static_cast<int>(browser_action_views_.size()));
DeleteBrowserActionViews();
@@ -1104,3 +1123,10 @@ void BrowserActionsContainer::NotifyMenuDeleted(
DCHECK(controller == overflow_menu_);
overflow_menu_ = NULL;
}
+
+bool BrowserActionsContainer::ShouldDisplayBrowserAction(Extension* extension) {
+ // Only display incognito-enabled extensions while in incognito mode.
+ return (!profile_->IsOffTheRecord() ||
+ profile_->GetExtensionsService()->
+ IsIncognitoEnabled(extension->id()));
+}
diff --git a/chrome/browser/views/browser_actions_container.h b/chrome/browser/views/browser_actions_container.h
index a7a5b59ac..1ace12d 100644
--- a/chrome/browser/views/browser_actions_container.h
+++ b/chrome/browser/views/browser_actions_container.h
@@ -399,7 +399,14 @@ class BrowserActionsContainer
// all the padding that we normally show if there are icons.
int ContainerMinSize() const;
- // The vector of browser actions (icons/image buttons for each action).
+ // Returns true if this extension should be shown in this toolbar. This can
+ // return false if we are in an incognito window and the extension is disabled
+ // for incognito.
+ bool ShouldDisplayBrowserAction(Extension* extension);
+
+ // The vector of browser actions (icons/image buttons for each action). Note
+ // that not every BrowserAction in the ToolbarModel will necessarily be in
+ // this collection. Some extensions may be disabled in incognito windows.
BrowserActionViews browser_action_views_;
NotificationRegistrar registrar_;
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
index eef996e..c5e733b 100644
--- a/chrome/common/extensions/extension.cc
+++ b/chrome/common/extensions/extension.cc
@@ -117,12 +117,14 @@ const char* Extension::kTabPermission = "tabs";
const char* Extension::kBookmarkPermission = "bookmarks";
const char* Extension::kNotificationPermission = "notifications";
const char* Extension::kExperimentalPermission = "experimental";
+const char* Extension::kIncognitoPermission = "incognito";
const char* Extension::kPermissionNames[] = {
Extension::kTabPermission,
Extension::kBookmarkPermission,
Extension::kNotificationPermission,
- Extension::kExperimentalPermission
+ Extension::kExperimentalPermission,
+ Extension::kIncognitoPermission
};
const size_t Extension::kNumPermissions =
arraysize(Extension::kPermissionNames);
diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h
index 25093ff..1445943 100644
--- a/chrome/common/extensions/extension.h
+++ b/chrome/common/extensions/extension.h
@@ -79,6 +79,7 @@ class Extension {
static const char* kBookmarkPermission;
static const char* kNotificationPermission;
static const char* kExperimentalPermission;
+ static const char* kIncognitoPermission;
static const char* kPermissionNames[];
static const size_t kNumPermissions;
diff --git a/chrome/common/extensions/user_script.cc b/chrome/common/extensions/user_script.cc
index 7a48c14..5ed2040 100644
--- a/chrome/common/extensions/user_script.cc
+++ b/chrome/common/extensions/user_script.cc
@@ -75,17 +75,12 @@ void UserScript::File::Unpickle(const ::Pickle& pickle, void** iter) {
}
void UserScript::Pickle(::Pickle* pickle) const {
- // Write the run location.
+ // Write simple types.
pickle->WriteInt(run_location());
-
- // Write the extension id.
pickle->WriteString(extension_id());
-
- // Write Greasemonkey emulation.
pickle->WriteBool(emulate_greasemonkey());
-
- // Write match all frames
pickle->WriteBool(match_all_frames());
+ pickle->WriteBool(is_incognito_enabled());
// Write globs.
std::vector<std::string>::const_iterator glob;
@@ -127,14 +122,10 @@ void UserScript::Unpickle(const ::Pickle& pickle, void** iter) {
CHECK(run_location >= 0 && run_location < RUN_LOCATION_LAST);
run_location_ = static_cast<RunLocation>(run_location);
- // Read the extension ID.
CHECK(pickle.ReadString(iter, &extension_id_));
-
- // Read Greasemonkey emulation.
CHECK(pickle.ReadBool(iter, &emulate_greasemonkey_));
-
- // Read match all frames
CHECK(pickle.ReadBool(iter, &match_all_frames_));
+ CHECK(pickle.ReadBool(iter, &incognito_enabled_));
// Read globs.
size_t num_globs = 0;
diff --git a/chrome/common/extensions/user_script.h b/chrome/common/extensions/user_script.h
index 9fbbe89..ed84009 100644
--- a/chrome/common/extensions/user_script.h
+++ b/chrome/common/extensions/user_script.h
@@ -102,7 +102,7 @@ class UserScript {
// Greasemonkey and probably more useful for typical scripts.
UserScript()
: run_location_(DOCUMENT_IDLE), emulate_greasemonkey_(false),
- match_all_frames_(false) {
+ match_all_frames_(false), incognito_enabled_(false) {
}
const std::string& name_space() const { return name_space_; }
@@ -162,6 +162,9 @@ class UserScript {
const std::string& extension_id() const { return extension_id_; }
void set_extension_id(const std::string& id) { extension_id_ = id; }
+ bool is_incognito_enabled() const { return incognito_enabled_; }
+ void set_incognito_enabled(bool enabled) { incognito_enabled_ = enabled; }
+
bool is_standalone() const { return extension_id_.empty(); }
// Returns true if the script should be applied to the specified URL, false
@@ -217,6 +220,9 @@ class UserScript {
// Whether the user script should run in all frames, or only just the top one.
// Defaults to false.
bool match_all_frames_;
+
+ // True if the script should be injected into an incognito tab.
+ bool incognito_enabled_;
};
typedef std::vector<UserScript> UserScriptList;
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 3a58772..a37ba09 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -239,8 +239,9 @@ IPC_BEGIN_MESSAGES(View)
// Notification that the user scripts have been updated. It has one
// SharedMemoryHandle argument consisting of the pickled script data. This
// handle is valid in the context of the renderer.
- IPC_MESSAGE_CONTROL1(ViewMsg_UserScripts_UpdatedScripts,
- base::SharedMemoryHandle)
+ IPC_MESSAGE_CONTROL2(ViewMsg_UserScripts_UpdatedScripts,
+ base::SharedMemoryHandle,
+ bool /* only_inject_incognito */)
// Sent when the user wants to search for a word on the page (find in page).
IPC_MESSAGE_ROUTED3(ViewMsg_Find,
diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc
index 1f61c23..7914507 100644
--- a/chrome/renderer/render_thread.cc
+++ b/chrome/renderer/render_thread.cc
@@ -320,9 +320,9 @@ void RenderThread::OnSetZoomLevelForCurrentHost(const std::string& host,
}
void RenderThread::OnUpdateUserScripts(
- base::SharedMemoryHandle scripts) {
+ base::SharedMemoryHandle scripts, bool only_inject_incognito) {
DCHECK(base::SharedMemory::IsHandleValid(scripts)) << "Bad scripts handle";
- user_script_slave_->UpdateScripts(scripts);
+ user_script_slave_->UpdateScripts(scripts, only_inject_incognito);
UpdateActiveExtensions();
}
diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h
index 4f992e4..0336ba8 100644
--- a/chrome/renderer/render_thread.h
+++ b/chrome/renderer/render_thread.h
@@ -162,7 +162,8 @@ class RenderThread : public RenderThreadBase,
void OnSetZoomLevelForCurrentHost(const std::string& host, int zoom_level);
void OnSetContentSettingsForCurrentHost(
const std::string& host, const ContentSettings& content_settings);
- void OnUpdateUserScripts(base::SharedMemoryHandle table);
+ void OnUpdateUserScripts(base::SharedMemoryHandle table,
+ bool only_inject_incognito);
void OnSetExtensionFunctionNames(const std::vector<std::string>& names);
void OnPageActionsUpdated(const std::string& extension_id,
const std::vector<std::string>& page_actions);
diff --git a/chrome/renderer/user_script_slave.cc b/chrome/renderer/user_script_slave.cc
index a06d856..0c0574b 100644
--- a/chrome/renderer/user_script_slave.cc
+++ b/chrome/renderer/user_script_slave.cc
@@ -68,7 +68,8 @@ void UserScriptSlave::GetActiveExtensions(std::set<std::string>* extension_ids)
}
}
-bool UserScriptSlave::UpdateScripts(base::SharedMemoryHandle shared_memory) {
+bool UserScriptSlave::UpdateScripts(base::SharedMemoryHandle shared_memory,
+ bool only_inject_incognito) {
scripts_.clear();
// Create the shared memory object (read only).
@@ -101,6 +102,13 @@ bool UserScriptSlave::UpdateScripts(base::SharedMemoryHandle shared_memory) {
UserScript* script = scripts_.back();
script->Unpickle(pickle, &iter);
+ if (only_inject_incognito && !script->is_incognito_enabled()) {
+ // This script shouldn't run in an incognito tab.
+ delete script;
+ scripts_.pop_back();
+ continue;
+ }
+
// Note that this is a pointer into shared memory. We don't own it. It gets
// cleared up when the last renderer or browser process drops their
// reference to the shared memory.
diff --git a/chrome/renderer/user_script_slave.h b/chrome/renderer/user_script_slave.h
index cf8fb8d..4cbbfd2 100644
--- a/chrome/renderer/user_script_slave.h
+++ b/chrome/renderer/user_script_slave.h
@@ -31,8 +31,11 @@ class UserScriptSlave {
// Returns the unique set of extension IDs this UserScriptSlave knows about.
void GetActiveExtensions(std::set<std::string>* extension_ids);
- // Update the parsed scripts from shared memory.
- bool UpdateScripts(base::SharedMemoryHandle shared_memory);
+ // Update the parsed scripts from shared memory. If |only_inject_incognito|
+ // is true, we will only use the scripts that have been marked as enabled for
+ // incognito mode.
+ bool UpdateScripts(base::SharedMemoryHandle shared_memory,
+ bool only_inject_incognito);
// Inject the appropriate scripts into a frame based on its URL.
// TODO(aa): Extract a UserScriptFrame interface out of this to improve
diff --git a/chrome/test/data/extensions/api_test/browser_action/add_popup/manifest.json b/chrome/test/data/extensions/api_test/browser_action/add_popup/manifest.json
index c7ddb6a..697d2ce 100644
--- a/chrome/test/data/extensions/api_test/browser_action/add_popup/manifest.json
+++ b/chrome/test/data/extensions/api_test/browser_action/add_popup/manifest.json
@@ -3,7 +3,8 @@
"version": "1.0",
"background_page": "background.html",
"permissions": [
- "tabs", "http://*/*"
+ "tabs", "http://*/*",
+ "experimental", "incognito"
],
"browser_action": {
"default_title": "Test setPopup()",
diff --git a/chrome/test/data/extensions/api_test/browser_action/basics/manifest.json b/chrome/test/data/extensions/api_test/browser_action/basics/manifest.json
index 9604839..9d9e9c1 100755
--- a/chrome/test/data/extensions/api_test/browser_action/basics/manifest.json
+++ b/chrome/test/data/extensions/api_test/browser_action/basics/manifest.json
@@ -3,7 +3,8 @@
"version": "1.0",
"background_page": "background.html",
"permissions": [
- "tabs", "http://*/*"
+ "tabs", "http://*/*",
+ "experimental", "incognito"
],
"browser_action": {
"default_title": "Make this page red",
diff --git a/chrome/test/data/extensions/api_test/browser_action/popup/manifest.json b/chrome/test/data/extensions/api_test/browser_action/popup/manifest.json
index f353316..fe2ad11 100755
--- a/chrome/test/data/extensions/api_test/browser_action/popup/manifest.json
+++ b/chrome/test/data/extensions/api_test/browser_action/popup/manifest.json
@@ -2,6 +2,9 @@
"name": "Popup tester",
"version": "0.1",
"description": "apitest for popups",
+ "permissions": [
+ "experimental", "incognito"
+ ],
"browser_action": {
"name": "grow",
"icons": ["chromium.png"],
diff --git a/chrome/test/data/extensions/api_test/incognito_no_script/manifest.json b/chrome/test/data/extensions/api_test/incognito_no_script/manifest.json
index 7c6156e..e8f013c 100755
--- a/chrome/test/data/extensions/api_test/incognito_no_script/manifest.json
+++ b/chrome/test/data/extensions/api_test/incognito_no_script/manifest.json
@@ -2,7 +2,7 @@
"name": "incognito no script",
"version": "0.1",
"description": "Checks that content scripts do not inject js into incognito browsers.",
- "permissions": ["http://*/*", "https://*/*"],
+ "permissions": ["http://*/*", "https://*/*", "experimental", "incognito"],
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],