Web Content zoom settings should not apply to login/lock screen

Add scheme to HostZoomMap, use it to specify unmodifiable zoom level for internal ui pages.

Reason : Currently, zoom settings are remebered on a per-host basis, and ignore scheme.
It works nice for http/https access for the same host, but it is not possible to distinguish between
internal ui (with chrome:// scheme) and some intranet sites (having https://login/ does not seem unlikely).

BUG=164269


Review URL: https://chromiumcodereview.appspot.com/11866004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@187331 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/content/browser/host_zoom_map_impl.cc b/content/browser/host_zoom_map_impl.cc
index aa5a870..a60a923 100644
--- a/content/browser/host_zoom_map_impl.cc
+++ b/content/browser/host_zoom_map_impl.cc
@@ -54,20 +54,42 @@
   HostZoomMapImpl* copy = static_cast<HostZoomMapImpl*>(copy_interface);
   base::AutoLock auto_lock(lock_);
   base::AutoLock copy_auto_lock(copy->lock_);
-  for (HostZoomLevels::const_iterator i(copy->host_zoom_levels_.begin());
-       i != copy->host_zoom_levels_.end(); ++i) {
-    host_zoom_levels_[i->first] = i->second;
+  host_zoom_levels_.
+      insert(copy->host_zoom_levels_.begin(), copy->host_zoom_levels_.end());
+  for (SchemeHostZoomLevels::const_iterator i(copy->
+           scheme_host_zoom_levels_.begin());
+       i != copy->scheme_host_zoom_levels_.end(); ++i) {
+    scheme_host_zoom_levels_[i->first] = HostZoomLevels();
+    scheme_host_zoom_levels_[i->first].
+        insert(i->second.begin(), i->second.end());
   }
   default_zoom_level_ = copy->default_zoom_level_;
 }
 
-double HostZoomMapImpl::GetZoomLevel(const std::string& host) const {
+double HostZoomMapImpl::GetZoomLevelForHost(const std::string& host) const {
   base::AutoLock auto_lock(lock_);
   HostZoomLevels::const_iterator i(host_zoom_levels_.find(host));
   return (i == host_zoom_levels_.end()) ? default_zoom_level_ : i->second;
 }
 
-void HostZoomMapImpl::SetZoomLevel(const std::string& host, double level) {
+double HostZoomMapImpl::GetZoomLevelForHostAndScheme(
+    const std::string& scheme,
+    const std::string& host) const {
+  {
+    base::AutoLock auto_lock(lock_);
+    SchemeHostZoomLevels::const_iterator scheme_iterator(
+        scheme_host_zoom_levels_.find(scheme));
+    if (scheme_iterator != scheme_host_zoom_levels_.end()) {
+      HostZoomLevels::const_iterator i(scheme_iterator->second.find(host));
+      if (i != scheme_iterator->second.end())
+        return i->second;
+    }
+  }
+  return GetZoomLevelForHost(host);
+}
+
+void HostZoomMapImpl::SetZoomLevelForHost(const std::string& host,
+                                          double level) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
   {
@@ -86,12 +108,46 @@
     if (HostZoomMap::GetForBrowserContext(
             render_process_host->GetBrowserContext()) == this) {
       render_process_host->Send(
-          new ViewMsg_SetZoomLevelForCurrentURL(host, level));
+          new ViewMsg_SetZoomLevelForCurrentURL(std::string(), host, level));
+    }
+  }
+  HostZoomMap::ZoomLevelChange change;
+  change.mode = HostZoomMap::ZOOM_CHANGED_FOR_HOST;
+  change.host = host;
+  change.zoom_level = level;
+
+  for (size_t i = 0; i < zoom_level_changed_callbacks_.size(); i++)
+    zoom_level_changed_callbacks_[i].Run(change);
+}
+
+void HostZoomMapImpl::SetZoomLevelForHostAndScheme(const std::string& scheme,
+                                                   const std::string& host,
+                                                   double level) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  {
+    base::AutoLock auto_lock(lock_);
+    scheme_host_zoom_levels_[scheme][host] = level;
+  }
+
+  // Notify renderers from this browser context.
+  for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator());
+       !i.IsAtEnd(); i.Advance()) {
+    RenderProcessHost* render_process_host = i.GetCurrentValue();
+    if (HostZoomMap::GetForBrowserContext(
+            render_process_host->GetBrowserContext()) == this) {
+      render_process_host->Send(
+          new ViewMsg_SetZoomLevelForCurrentURL(scheme, host, level));
     }
   }
 
+  HostZoomMap::ZoomLevelChange change;
+  change.mode = HostZoomMap::ZOOM_CHANGED_FOR_SCHEME_AND_HOST;
+  change.host = host;
+  change.scheme = scheme;
+  change.zoom_level = level;
+
   for (size_t i = 0; i < zoom_level_changed_callbacks_.size(); i++)
-    zoom_level_changed_callbacks_[i].Run(host);
+    zoom_level_changed_callbacks_[i].Run(change);
 }
 
 double HostZoomMapImpl::GetDefaultZoomLevel() const {
@@ -159,8 +215,12 @@
     }
   }
 
+  HostZoomMap::ZoomLevelChange change;
+  change.mode = HostZoomMap::ZOOM_CHANGED_TEMPORARY_ZOOM;
+  change.zoom_level = level;
+
   for (size_t i = 0; i < zoom_level_changed_callbacks_.size(); i++)
-    zoom_level_changed_callbacks_[i].Run(std::string());
+    zoom_level_changed_callbacks_[i].Run(change);
 }
 
 void HostZoomMapImpl::Observe(int type,
diff --git a/content/browser/host_zoom_map_impl.h b/content/browser/host_zoom_map_impl.h
index 4e6eff4d..216c83eb 100644
--- a/content/browser/host_zoom_map_impl.h
+++ b/content/browser/host_zoom_map_impl.h
@@ -30,8 +30,16 @@
 
   // HostZoomMap implementation:
   virtual void CopyFrom(HostZoomMap* copy) OVERRIDE;
-  virtual double GetZoomLevel(const std::string& host) const OVERRIDE;
-  virtual void SetZoomLevel(const std::string& host, double level) OVERRIDE;
+  virtual double GetZoomLevelForHostAndScheme(
+      const std::string& scheme,
+      const std::string& host) const OVERRIDE;
+  virtual void SetZoomLevelForHost(
+      const std::string& host,
+      double level) OVERRIDE;
+  virtual void SetZoomLevelForHostAndScheme(
+      const std::string& scheme,
+      const std::string& host,
+      double level) OVERRIDE;
   virtual double GetDefaultZoomLevel() const OVERRIDE;
   virtual void SetDefaultZoomLevel(double level) OVERRIDE;
   virtual void AddZoomLevelChangedCallback(
@@ -61,13 +69,17 @@
                        const NotificationDetails& details) OVERRIDE;
 
  private:
+  double GetZoomLevelForHost(const std::string& host) const;
+
   typedef std::map<std::string, double> HostZoomLevels;
+  typedef std::map<std::string, HostZoomLevels> SchemeHostZoomLevels;
 
   // Callbacks called when zoom level changes.
   std::vector<ZoomLevelChangedCallback> zoom_level_changed_callbacks_;
 
   // Copy of the pref data, so that we can read it on the IO thread.
   HostZoomLevels host_zoom_levels_;
+  SchemeHostZoomLevels scheme_host_zoom_levels_;
   double default_zoom_level_;
 
   struct TemporaryZoomLevel {
diff --git a/content/browser/host_zoom_map_impl_unittest.cc b/content/browser/host_zoom_map_impl_unittest.cc
index 9f51369..055e061 100644
--- a/content/browser/host_zoom_map_impl_unittest.cc
+++ b/content/browser/host_zoom_map_impl_unittest.cc
@@ -26,10 +26,35 @@
   HostZoomMapImpl host_zoom_map;
 
   double zoomed = 2.5;
-  host_zoom_map.SetZoomLevel("zoomed.com", zoomed);
+  host_zoom_map.SetZoomLevelForHost("zoomed.com", zoomed);
 
-  EXPECT_DOUBLE_EQ(host_zoom_map.GetZoomLevel("normal.com"), 0);
-  EXPECT_DOUBLE_EQ(host_zoom_map.GetZoomLevel("zoomed.com"), zoomed);
+  EXPECT_DOUBLE_EQ(0,
+      host_zoom_map.GetZoomLevelForHostAndScheme("http", "normal.com"));
+  EXPECT_DOUBLE_EQ(zoomed,
+      host_zoom_map.GetZoomLevelForHostAndScheme("http", "zoomed.com"));
+}
+
+TEST_F(HostZoomMapTest, GetSetZoomLevelWithScheme) {
+  HostZoomMapImpl host_zoom_map;
+
+  double zoomed = 2.5;
+  double default_zoom = 1.5;
+
+  host_zoom_map.SetZoomLevelForHostAndScheme("chrome", "login", 0);
+
+  host_zoom_map.SetDefaultZoomLevel(default_zoom);
+
+  EXPECT_DOUBLE_EQ(0,
+      host_zoom_map.GetZoomLevelForHostAndScheme("chrome", "login"));
+  EXPECT_DOUBLE_EQ(default_zoom,
+      host_zoom_map.GetZoomLevelForHostAndScheme("http", "login"));
+
+  host_zoom_map.SetZoomLevelForHost("login", zoomed);
+
+  EXPECT_DOUBLE_EQ(0,
+      host_zoom_map.GetZoomLevelForHostAndScheme("chrome", "login"));
+  EXPECT_DOUBLE_EQ(zoomed,
+      host_zoom_map.GetZoomLevelForHostAndScheme("http", "login"));
 }
 
 }  // namespace content
diff --git a/content/browser/loader/async_resource_handler.cc b/content/browser/loader/async_resource_handler.cc
index da6fa8ea..fbb1c8a1 100644
--- a/content/browser/loader/async_resource_handler.cc
+++ b/content/browser/loader/async_resource_handler.cc
@@ -184,8 +184,9 @@
     const GURL& request_url = request_->url();
     filter_->Send(new ViewMsg_SetZoomLevelForLoadingURL(
         info->GetRouteID(),
-        request_url, host_zoom_map->GetZoomLevel(net::GetHostOrSpecFromURL(
-            request_url))));
+        request_url, host_zoom_map->GetZoomLevelForHostAndScheme(
+            request_url.scheme(),
+            net::GetHostOrSpecFromURL(request_url))));
   }
 
   response->head.request_start = request_->creation_time();
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index 7346c33..75c0fec 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -1930,7 +1930,8 @@
   HostZoomMapImpl* host_zoom_map = static_cast<HostZoomMapImpl*>(
       HostZoomMap::GetForBrowserContext(GetProcess()->GetBrowserContext()));
   if (remember) {
-    host_zoom_map->SetZoomLevel(net::GetHostOrSpecFromURL(url), zoom_level);
+    host_zoom_map->
+        SetZoomLevelForHost(net::GetHostOrSpecFromURL(url), zoom_level);
   } else {
     host_zoom_map->SetTemporaryZoomLevel(
         GetProcess()->GetID(), GetRoutingID(), zoom_level);
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 7211c544..5583b66e 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1905,7 +1905,8 @@
     // Since zoom map is updated using rewritten URL, use rewritten URL
     // to get the zoom level.
     url = active_entry ? active_entry->GetURL() : GURL::EmptyGURL();
-    zoom_level = zoom_map->GetZoomLevel(net::GetHostOrSpecFromURL(url));
+    zoom_level = zoom_map->GetZoomLevelForHostAndScheme(url.scheme(),
+        net::GetHostOrSpecFromURL(url));
   }
   return zoom_level;
 }