Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / frame / browser_non_client_frame_view_ash.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h"
6
7 #include "ash/ash_switches.h"
8 #include "ash/wm/caption_buttons/frame_caption_button_container_view.h"
9 #include "ash/wm/frame_border_hit_test_controller.h"
10 #include "ash/wm/header_painter.h"
11 #include "base/command_line.h"
12 #include "chrome/browser/themes/theme_properties.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/views/avatar_label.h"
15 #include "chrome/browser/ui/views/avatar_menu_button.h"
16 #include "chrome/browser/ui/views/frame/browser_frame.h"
17 #include "chrome/browser/ui/views/frame/browser_view.h"
18 #include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
19 #include "chrome/browser/ui/views/tab_icon_view.h"
20 #include "chrome/browser/ui/views/tabs/tab_strip.h"
21 #include "chrome/common/chrome_switches.h"
22 #include "content/public/browser/web_contents.h"
23 #include "grit/ash_resources.h"
24 #include "grit/theme_resources.h"
25 #include "ui/aura/client/aura_constants.h"
26 #include "ui/aura/window.h"
27 #include "ui/base/accessibility/accessible_view_state.h"
28 #include "ui/base/hit_test.h"
29 #include "ui/base/l10n/l10n_util.h"
30 #include "ui/base/layout.h"
31 #include "ui/base/resource/resource_bundle.h"
32 #include "ui/base/theme_provider.h"
33 #include "ui/compositor/layer_animator.h"
34 #include "ui/gfx/canvas.h"
35 #include "ui/gfx/image/image_skia.h"
36 #include "ui/gfx/rect_conversions.h"
37 #include "ui/views/controls/label.h"
38 #include "ui/views/layout/layout_constants.h"
39 #include "ui/views/widget/widget.h"
40 #include "ui/views/widget/widget_delegate.h"
41
42 namespace {
43
44 // The avatar ends 2 px above the bottom of the tabstrip (which, given the
45 // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the
46 // user).
47 const int kAvatarBottomSpacing = 2;
48 // There are 2 px on each side of the avatar (between the frame border and
49 // it on the left, and between it and the tabstrip on the right).
50 const int kAvatarSideSpacing = 2;
51 // Space between left edge of window and tabstrip.
52 const int kTabstripLeftSpacing = 0;
53 // Space between right edge of tabstrip and maximize button.
54 const int kTabstripRightSpacing = 10;
55 // Height of the shadow of the content area, at the top of the toolbar.
56 const int kContentShadowHeight = 1;
57 // Space between top of window and top of tabstrip for tall headers, such as
58 // for restored windows, apps, etc.
59 const int kTabstripTopSpacingTall = 7;
60 // Space between top of window and top of tabstrip for short headers, such as
61 // for maximized windows, pop-ups, etc.
62 const int kTabstripTopSpacingShort = 0;
63 // Height of the shadow in the tab image, used to ensure clicks in the shadow
64 // area still drag restored windows.  This keeps the clickable area large enough
65 // to hit easily.
66 const int kTabShadowHeight = 4;
67
68 }  // namespace
69
70 ///////////////////////////////////////////////////////////////////////////////
71 // BrowserNonClientFrameViewAsh, public:
72
73 // static
74 const char BrowserNonClientFrameViewAsh::kViewClassName[] =
75     "BrowserNonClientFrameViewAsh";
76
77 BrowserNonClientFrameViewAsh::BrowserNonClientFrameViewAsh(
78     BrowserFrame* frame, BrowserView* browser_view)
79     : BrowserNonClientFrameView(frame, browser_view),
80       caption_button_container_(NULL),
81       window_icon_(NULL),
82       header_painter_(new ash::HeaderPainter),
83       frame_border_hit_test_controller_(
84           new ash::FrameBorderHitTestController(frame)) {
85 }
86
87 BrowserNonClientFrameViewAsh::~BrowserNonClientFrameViewAsh() {
88 }
89
90 void BrowserNonClientFrameViewAsh::Init() {
91   caption_button_container_ = new ash::FrameCaptionButtonContainerView(frame(),
92       ash::FrameCaptionButtonContainerView::MINIMIZE_ALLOWED);
93   AddChildView(caption_button_container_);
94
95   // Initializing the TabIconView is expensive, so only do it if we need to.
96   if (browser_view()->ShouldShowWindowIcon()) {
97     window_icon_ = new TabIconView(this, NULL);
98     window_icon_->set_is_light(true);
99     AddChildView(window_icon_);
100     window_icon_->Update();
101   }
102
103   // Create incognito icon if necessary.
104   UpdateAvatarInfo();
105
106   // HeaderPainter handles layout.
107   header_painter_->Init(frame(), this, window_icon_, caption_button_container_);
108 }
109
110 ///////////////////////////////////////////////////////////////////////////////
111 // BrowserNonClientFrameView overrides:
112
113 gfx::Rect BrowserNonClientFrameViewAsh::GetBoundsForTabStrip(
114     views::View* tabstrip) const {
115   if (!tabstrip)
116     return gfx::Rect();
117
118   // When the tab strip is painted in the immersive fullscreen light bar style,
119   // the caption buttons and the avatar button are not visible. However, their
120   // bounds are still used to compute the tab strip bounds so that the tabs have
121   // the same horizontal position when the tab strip is painted in the immersive
122   // light bar style as when the top-of-window views are revealed.
123   int left_inset = GetTabStripLeftInset();
124   int right_inset = GetTabStripRightInset();
125   return gfx::Rect(left_inset,
126                    GetTopInset(),
127                    std::max(0, width() - left_inset - right_inset),
128                    tabstrip->GetPreferredSize().height());
129 }
130
131 int BrowserNonClientFrameViewAsh::GetTopInset() const {
132   if (!ShouldPaint() || UseImmersiveLightbarHeaderStyle())
133     return 0;
134
135   if (browser_view()->IsTabStripVisible()) {
136     if (frame()->IsMaximized() || frame()->IsFullscreen())
137       return kTabstripTopSpacingShort;
138     else
139       return kTabstripTopSpacingTall;
140   }
141
142   int caption_buttons_bottom = caption_button_container_->bounds().bottom();
143
144   // The toolbar partially overlaps the caption buttons.
145   if (browser_view()->IsToolbarVisible())
146     return caption_buttons_bottom - kContentShadowHeight;
147
148   int separator_thickness = UsePackagedAppHeaderStyle() ?
149       header_painter_->HeaderContentSeparatorSize() : kClientEdgeThickness;
150   return caption_buttons_bottom + separator_thickness;
151 }
152
153 int BrowserNonClientFrameViewAsh::GetThemeBackgroundXInset() const {
154   return header_painter_->GetThemeBackgroundXInset();
155 }
156
157 void BrowserNonClientFrameViewAsh::UpdateThrobber(bool running) {
158   if (window_icon_)
159     window_icon_->Update();
160 }
161
162 ///////////////////////////////////////////////////////////////////////////////
163 // views::NonClientFrameView overrides:
164
165 gfx::Rect BrowserNonClientFrameViewAsh::GetBoundsForClientView() const {
166   // The ClientView must be flush with the top edge of the widget so that the
167   // web contents can take up the entire screen in immersive fullscreen (with
168   // or without the top-of-window views revealed). When in immersive fullscreen
169   // and the top-of-window views are revealed, the TopContainerView paints the
170   // window header by redirecting paints from its background to
171   // BrowserNonClientFrameViewAsh.
172   return ash::HeaderPainter::GetBoundsForClientView(0, bounds());
173 }
174
175 gfx::Rect BrowserNonClientFrameViewAsh::GetWindowBoundsForClientBounds(
176     const gfx::Rect& client_bounds) const {
177   return ash::HeaderPainter::GetWindowBoundsForClientBounds(0, client_bounds);
178 }
179
180 int BrowserNonClientFrameViewAsh::NonClientHitTest(const gfx::Point& point) {
181   int hit_test = ash::FrameBorderHitTestController::NonClientHitTest(this,
182       header_painter_.get(), point);
183
184   // See if the point is actually within the avatar menu button or within
185   // the avatar label.
186   if (hit_test == HTCAPTION && ((avatar_button() &&
187        avatar_button()->GetMirroredBounds().Contains(point)) ||
188       (avatar_label() && avatar_label()->GetMirroredBounds().Contains(point))))
189       return HTCLIENT;
190
191   // When the window is restored we want a large click target above the tabs
192   // to drag the window, so redirect clicks in the tab's shadow to caption.
193   if (hit_test == HTCLIENT &&
194       !(frame()->IsMaximized() || frame()->IsFullscreen())) {
195     // Convert point to client coordinates.
196     gfx::Point client_point(point);
197     View::ConvertPointToTarget(this, frame()->client_view(), &client_point);
198     // Report hits in shadow at top of tabstrip as caption.
199     gfx::Rect tabstrip_bounds(browser_view()->tabstrip()->bounds());
200     if (client_point.y() < tabstrip_bounds.y() + kTabShadowHeight)
201       hit_test = HTCAPTION;
202   }
203   return hit_test;
204 }
205
206 void BrowserNonClientFrameViewAsh::GetWindowMask(const gfx::Size& size,
207                                                  gfx::Path* window_mask) {
208   // Aura does not use window masks.
209 }
210
211 void BrowserNonClientFrameViewAsh::ResetWindowControls() {
212   // Hide the caption buttons in immersive fullscreen when the tab light bar
213   // is visible because it's confusing when the user hovers or clicks in the
214   // top-right of the screen and hits one.
215   bool button_visibility = !UseImmersiveLightbarHeaderStyle();
216   caption_button_container_->SetVisible(button_visibility);
217
218   caption_button_container_->ResetWindowControls();
219 }
220
221 void BrowserNonClientFrameViewAsh::UpdateWindowIcon() {
222   if (window_icon_)
223     window_icon_->SchedulePaint();
224 }
225
226 void BrowserNonClientFrameViewAsh::UpdateWindowTitle() {
227   if (!frame()->IsFullscreen())
228     header_painter_->SchedulePaintForTitle(BrowserFrame::GetTitleFontList());
229 }
230
231 ///////////////////////////////////////////////////////////////////////////////
232 // views::View overrides:
233
234 void BrowserNonClientFrameViewAsh::OnPaint(gfx::Canvas* canvas) {
235   if (!ShouldPaint())
236     return;
237
238   if (UseImmersiveLightbarHeaderStyle()) {
239     PaintImmersiveLightbarStyleHeader(canvas);
240     return;
241   }
242
243   // The primary header image changes based on window activation state and
244   // theme, so we look it up for each paint.
245   int theme_frame_image_id = GetThemeFrameImageId();
246   int theme_frame_overlay_image_id = GetThemeFrameOverlayImageId();
247
248   ui::ThemeProvider* theme_provider = GetThemeProvider();
249   if (!theme_provider->HasCustomImage(theme_frame_image_id) &&
250       (theme_frame_overlay_image_id == 0 ||
251        !theme_provider->HasCustomImage(theme_frame_overlay_image_id))) {
252     if (frame()->IsMaximized() || frame()->IsFullscreen())
253       theme_frame_image_id = IDR_AURA_WINDOW_HEADER_BASE_MINIMAL;
254   }
255   header_painter_->PaintHeader(
256       canvas,
257       theme_frame_image_id,
258       theme_frame_overlay_image_id);
259   if (browser_view()->ShouldShowWindowTitle())
260     header_painter_->PaintTitleBar(canvas, BrowserFrame::GetTitleFontList());
261   if (browser_view()->IsToolbarVisible())
262     PaintToolbarBackground(canvas);
263   else
264     PaintContentEdge(canvas);
265 }
266
267 void BrowserNonClientFrameViewAsh::Layout() {
268   // The header must be laid out before computing |header_height| because the
269   // computation of |header_height| for app and popup windows depends on the
270   // position of the window controls.
271   header_painter_->LayoutHeader(UsePackagedAppHeaderStyle() ||
272                                 frame()->IsMaximized() ||
273                                 frame()->IsFullscreen());
274
275   int header_height = 0;
276   if (browser_view()->IsTabStripVisible()) {
277     header_height = GetTopInset() +
278         browser_view()->tabstrip()->GetPreferredSize().height();
279   } else if (browser_view()->IsToolbarVisible()) {
280     // Set the header's height so that it overlaps with the toolbar because the
281     // top few pixels of the toolbar are not opaque.
282     header_height = GetTopInset() + kFrameShadowThickness * 2;
283   } else {
284     header_height = GetTopInset();
285   }
286   header_painter_->set_header_height(header_height);
287   if (avatar_button())
288     LayoutAvatar();
289   BrowserNonClientFrameView::Layout();
290 }
291
292 const char* BrowserNonClientFrameViewAsh::GetClassName() const {
293   return kViewClassName;
294 }
295
296 bool BrowserNonClientFrameViewAsh::HitTestRect(const gfx::Rect& rect) const {
297   if (!views::View::HitTestRect(rect)) {
298     // |rect| is outside BrowserNonClientFrameViewAsh's bounds.
299     return false;
300   }
301
302   TabStrip* tabstrip = browser_view()->tabstrip();
303   if (tabstrip && browser_view()->IsTabStripVisible()) {
304     // Claim |rect| only if it is above the bottom of the tabstrip in a non-tab
305     // portion.
306     gfx::RectF rect_in_tabstrip_coords_f(rect);
307     View::ConvertRectToTarget(this, tabstrip, &rect_in_tabstrip_coords_f);
308     gfx::Rect rect_in_tabstrip_coords = gfx::ToEnclosingRect(
309         rect_in_tabstrip_coords_f);
310
311      if (rect_in_tabstrip_coords.y() > tabstrip->height())
312        return false;
313
314     return !tabstrip->HitTestRect(rect_in_tabstrip_coords) ||
315         tabstrip->IsRectInWindowCaption(rect_in_tabstrip_coords);
316   }
317
318   // Claim |rect| if it is above the top of the topmost view in the client area.
319   return rect.y() < GetTopInset();
320 }
321
322 void BrowserNonClientFrameViewAsh::GetAccessibleState(
323     ui::AccessibleViewState* state) {
324   state->role = ui::AccessibilityTypes::ROLE_TITLEBAR;
325 }
326
327 gfx::Size BrowserNonClientFrameViewAsh::GetMinimumSize() {
328   gfx::Size min_client_view_size(frame()->client_view()->GetMinimumSize());
329   int min_width = std::max(header_painter_->GetMinimumHeaderWidth(),
330                            min_client_view_size.width());
331   if (browser_view()->IsTabStripVisible()) {
332     // Ensure that the minimum width is enough to hold a minimum width tab strip
333     // at its usual insets.
334     int min_tabstrip_width =
335         browser_view()->tabstrip()->GetMinimumSize().width();
336     min_width = std::max(min_width,
337         min_tabstrip_width + GetTabStripLeftInset() + GetTabStripRightInset());
338   }
339   return gfx::Size(min_width, min_client_view_size.height());
340 }
341
342 void BrowserNonClientFrameViewAsh::OnThemeChanged() {
343   BrowserNonClientFrameView::OnThemeChanged();
344   header_painter_->OnThemeChanged();
345 }
346
347 ///////////////////////////////////////////////////////////////////////////////
348 // chrome::TabIconViewModel overrides:
349
350 bool BrowserNonClientFrameViewAsh::ShouldTabIconViewAnimate() const {
351   // This function is queried during the creation of the window as the
352   // TabIconView we host is initialized, so we need to NULL check the selected
353   // WebContents because in this condition there is not yet a selected tab.
354   content::WebContents* current_tab = browser_view()->GetActiveWebContents();
355   return current_tab ? current_tab->IsLoading() : false;
356 }
357
358 gfx::ImageSkia BrowserNonClientFrameViewAsh::GetFaviconForTabIconView() {
359   views::WidgetDelegate* delegate = frame()->widget_delegate();
360   if (!delegate)
361     return gfx::ImageSkia();
362   return delegate->GetWindowIcon();
363 }
364
365 ///////////////////////////////////////////////////////////////////////////////
366 // BrowserNonClientFrameViewAsh, private:
367
368 int BrowserNonClientFrameViewAsh::GetTabStripLeftInset() const {
369   return avatar_button() ? kAvatarSideSpacing +
370       browser_view()->GetOTRAvatarIcon().width() + kAvatarSideSpacing :
371       kTabstripLeftSpacing;
372 }
373
374 int BrowserNonClientFrameViewAsh::GetTabStripRightInset() const {
375   return header_painter_->GetRightInset() + kTabstripRightSpacing;
376 }
377
378 bool BrowserNonClientFrameViewAsh::UseImmersiveLightbarHeaderStyle() const {
379   ImmersiveModeController* immersive_controller =
380       browser_view()->immersive_mode_controller();
381   return immersive_controller->IsEnabled() &&
382       !immersive_controller->IsRevealed() &&
383       browser_view()->IsTabStripVisible();
384 }
385
386 bool BrowserNonClientFrameViewAsh::UsePackagedAppHeaderStyle() const {
387   // Non streamlined hosted apps do not have a toolbar or tabstrip. Their header
388   // should look the same as the header for packaged apps. Streamlined hosted
389   // apps have a toolbar so should use the browser header style.
390   return browser_view()->browser()->is_app() &&
391       !CommandLine::ForCurrentProcess()->HasSwitch(
392           switches::kEnableStreamlinedHostedApps);
393 }
394
395 void BrowserNonClientFrameViewAsh::LayoutAvatar() {
396   DCHECK(avatar_button());
397   DCHECK(browser_view()->IsTabStripVisible());
398   gfx::ImageSkia incognito_icon = browser_view()->GetOTRAvatarIcon();
399
400   int avatar_bottom = GetTopInset() +
401       browser_view()->GetTabStripHeight() - kAvatarBottomSpacing;
402   int avatar_restored_y = avatar_bottom - incognito_icon.height();
403   int avatar_y = (frame()->IsMaximized() || frame()->IsFullscreen()) ?
404       GetTopInset() + kContentShadowHeight : avatar_restored_y;
405
406   // Hide the incognito icon in immersive fullscreen when the tab light bar is
407   // visible because the header is too short for the icognito icon to be
408   // recognizable.
409   bool avatar_visible = !UseImmersiveLightbarHeaderStyle();
410   int avatar_height = avatar_visible ? avatar_bottom - avatar_y : 0;
411
412   gfx::Rect avatar_bounds(kAvatarSideSpacing,
413                           avatar_y,
414                           incognito_icon.width(),
415                           avatar_height);
416   avatar_button()->SetBoundsRect(avatar_bounds);
417   avatar_button()->SetVisible(avatar_visible);
418 }
419
420 bool BrowserNonClientFrameViewAsh::ShouldPaint() const {
421   if (!frame()->IsFullscreen())
422     return true;
423
424   // We need to paint when in immersive fullscreen and either:
425   // - The top-of-window views are revealed.
426   // - The lightbar style tabstrip is visible.
427   ImmersiveModeController* immersive_mode_controller =
428       browser_view()->immersive_mode_controller();
429   return immersive_mode_controller->IsEnabled() &&
430       (immersive_mode_controller->IsRevealed() ||
431        UseImmersiveLightbarHeaderStyle());
432 }
433
434 void BrowserNonClientFrameViewAsh::PaintImmersiveLightbarStyleHeader(
435     gfx::Canvas* canvas) {
436   // The light bar header is not themed because theming it does not look good.
437   gfx::ImageSkia* frame_image = GetThemeProvider()->GetImageSkiaNamed(
438       IDR_AURA_WINDOW_HEADER_BASE_MINIMAL);
439   canvas->TileImageInt(*frame_image, 0, 0, width(), frame_image->height());
440 }
441
442 void BrowserNonClientFrameViewAsh::PaintToolbarBackground(gfx::Canvas* canvas) {
443   gfx::Rect toolbar_bounds(browser_view()->GetToolbarBounds());
444   if (toolbar_bounds.IsEmpty())
445     return;
446   gfx::Point toolbar_origin(toolbar_bounds.origin());
447   View::ConvertPointToTarget(browser_view(), this, &toolbar_origin);
448   toolbar_bounds.set_origin(toolbar_origin);
449
450   int x = toolbar_bounds.x();
451   int w = toolbar_bounds.width();
452   int y = toolbar_bounds.y();
453   int h = toolbar_bounds.height();
454
455   // Gross hack: We split the toolbar images into two pieces, since sometimes
456   // (popup mode) the toolbar isn't tall enough to show the whole image.  The
457   // split happens between the top shadow section and the bottom gradient
458   // section so that we never break the gradient.
459   // NOTE(pkotwicz): If the computation for |bottom_y| is changed, Layout() must
460   // be changed as well.
461   int split_point = kFrameShadowThickness * 2;
462   int bottom_y = y + split_point;
463   ui::ThemeProvider* tp = GetThemeProvider();
464   int bottom_edge_height = h - split_point;
465
466   canvas->FillRect(gfx::Rect(x, bottom_y, w, bottom_edge_height),
467                    tp->GetColor(ThemeProperties::COLOR_TOOLBAR));
468
469   // Paint the main toolbar image.  Since this image is also used to draw the
470   // tab background, we must use the tab strip offset to compute the image
471   // source y position.  If you have to debug this code use an image editor
472   // to paint a diagonal line through the toolbar image and ensure it lines up
473   // across the tab and toolbar.
474   gfx::ImageSkia* theme_toolbar = tp->GetImageSkiaNamed(IDR_THEME_TOOLBAR);
475   canvas->TileImageInt(
476       *theme_toolbar,
477       x + GetThemeBackgroundXInset(),
478       bottom_y - GetTopInset(),
479       x, bottom_y,
480       w, theme_toolbar->height());
481
482   // The content area line has a shadow that extends a couple of pixels above
483   // the toolbar bounds.
484   const int kContentShadowHeight = 2;
485   gfx::ImageSkia* toolbar_top = tp->GetImageSkiaNamed(IDR_TOOLBAR_SHADE_TOP);
486   canvas->TileImageInt(*toolbar_top,
487                        0, 0,
488                        x, y - kContentShadowHeight,
489                        w, split_point + kContentShadowHeight + 1);
490
491   // Draw the "lightening" shade line around the edges of the toolbar.
492   gfx::ImageSkia* toolbar_left = tp->GetImageSkiaNamed(IDR_TOOLBAR_SHADE_LEFT);
493   canvas->TileImageInt(*toolbar_left,
494                        0, 0,
495                        x + kClientEdgeThickness,
496                        y + kClientEdgeThickness + kContentShadowHeight,
497                        toolbar_left->width(), theme_toolbar->height());
498   gfx::ImageSkia* toolbar_right =
499       tp->GetImageSkiaNamed(IDR_TOOLBAR_SHADE_RIGHT);
500   canvas->TileImageInt(*toolbar_right,
501                        0, 0,
502                        w - toolbar_right->width() - 2 * kClientEdgeThickness,
503                        y + kClientEdgeThickness + kContentShadowHeight,
504                        toolbar_right->width(), theme_toolbar->height());
505
506   // Draw the content/toolbar separator.
507   canvas->FillRect(
508       gfx::Rect(x + kClientEdgeThickness,
509                 toolbar_bounds.bottom() - kClientEdgeThickness,
510                 w - (2 * kClientEdgeThickness),
511                 kClientEdgeThickness),
512       ThemeProperties::GetDefaultColor(
513           ThemeProperties::COLOR_TOOLBAR_SEPARATOR));
514 }
515
516 void BrowserNonClientFrameViewAsh::PaintContentEdge(gfx::Canvas* canvas) {
517   if (UsePackagedAppHeaderStyle()) {
518     header_painter_->PaintHeaderContentSeparator(canvas);
519   } else {
520     canvas->FillRect(gfx::Rect(0, caption_button_container_->bounds().bottom(),
521                                width(), kClientEdgeThickness),
522         ThemeProperties::GetDefaultColor(
523             ThemeProperties::COLOR_TOOLBAR_SEPARATOR));
524   }
525 }
526
527 int BrowserNonClientFrameViewAsh::GetThemeFrameImageId() const {
528   bool is_incognito = !browser_view()->IsRegularOrGuestSession();
529   if (browser_view()->IsBrowserTypeNormal()) {
530     // Use the standard resource ids to allow users to theme the frames.
531     if (ShouldPaintAsActive()) {
532       return is_incognito ?
533           IDR_THEME_FRAME_INCOGNITO : IDR_THEME_FRAME;
534     }
535     return is_incognito ?
536         IDR_THEME_FRAME_INCOGNITO_INACTIVE : IDR_THEME_FRAME_INACTIVE;
537   }
538   // Never theme app and popup windows.
539   if (ShouldPaintAsActive()) {
540     return is_incognito ?
541         IDR_AURA_WINDOW_HEADER_BASE_INCOGNITO_ACTIVE :
542         IDR_AURA_WINDOW_HEADER_BASE_ACTIVE;
543   }
544   return is_incognito ?
545       IDR_AURA_WINDOW_HEADER_BASE_INCOGNITO_INACTIVE :
546       IDR_AURA_WINDOW_HEADER_BASE_INACTIVE;
547 }
548
549 int BrowserNonClientFrameViewAsh::GetThemeFrameOverlayImageId() const {
550   ui::ThemeProvider* tp = GetThemeProvider();
551   if (tp->HasCustomImage(IDR_THEME_FRAME_OVERLAY) &&
552       browser_view()->IsBrowserTypeNormal() &&
553       !browser_view()->IsOffTheRecord()) {
554     return ShouldPaintAsActive() ?
555         IDR_THEME_FRAME_OVERLAY : IDR_THEME_FRAME_OVERLAY_INACTIVE;
556   }
557   return 0;
558 }