Home | History | Annotate | Download | only in views
      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 "ui/app_list/views/app_list_view.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "base/command_line.h"
     10 #include "base/metrics/histogram.h"
     11 #include "base/strings/string_util.h"
     12 #include "base/win/windows_version.h"
     13 #include "ui/app_list/app_list_constants.h"
     14 #include "ui/app_list/app_list_model.h"
     15 #include "ui/app_list/app_list_switches.h"
     16 #include "ui/app_list/app_list_view_delegate.h"
     17 #include "ui/app_list/speech_ui_model.h"
     18 #include "ui/app_list/views/app_list_background.h"
     19 #include "ui/app_list/views/app_list_folder_view.h"
     20 #include "ui/app_list/views/app_list_main_view.h"
     21 #include "ui/app_list/views/app_list_view_observer.h"
     22 #include "ui/app_list/views/apps_container_view.h"
     23 #include "ui/app_list/views/contents_view.h"
     24 #include "ui/app_list/views/search_box_view.h"
     25 #include "ui/app_list/views/speech_view.h"
     26 #include "ui/app_list/views/start_page_view.h"
     27 #include "ui/base/ui_base_switches.h"
     28 #include "ui/compositor/layer.h"
     29 #include "ui/compositor/layer_animation_observer.h"
     30 #include "ui/compositor/scoped_layer_animation_settings.h"
     31 #include "ui/gfx/canvas.h"
     32 #include "ui/gfx/image/image_skia.h"
     33 #include "ui/gfx/insets.h"
     34 #include "ui/gfx/path.h"
     35 #include "ui/gfx/skia_util.h"
     36 #include "ui/resources/grit/ui_resources.h"
     37 #include "ui/views/bubble/bubble_frame_view.h"
     38 #include "ui/views/controls/image_view.h"
     39 #include "ui/views/controls/textfield/textfield.h"
     40 #include "ui/views/layout/fill_layout.h"
     41 #include "ui/views/widget/widget.h"
     42 
     43 #if defined(USE_AURA)
     44 #include "ui/aura/window.h"
     45 #include "ui/aura/window_tree_host.h"
     46 #include "ui/views/bubble/bubble_window_targeter.h"
     47 #if defined(OS_WIN)
     48 #include "ui/base/win/shell.h"
     49 #endif
     50 #if !defined(OS_CHROMEOS)
     51 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
     52 #endif
     53 #endif  // defined(USE_AURA)
     54 
     55 namespace app_list {
     56 
     57 namespace {
     58 
     59 // The margin from the edge to the speech UI.
     60 const int kSpeechUIMargin = 12;
     61 
     62 // The vertical position for the appearing animation of the speech UI.
     63 const float kSpeechUIAppearingPosition = 12;
     64 
     65 // The distance between the arrow tip and edge of the anchor view.
     66 const int kArrowOffset = 10;
     67 
     68 // Determines whether the current environment supports shadows bubble borders.
     69 bool SupportsShadow() {
     70 #if defined(OS_WIN)
     71   // Shadows are not supported on Windows without Aero Glass.
     72   if (!ui::win::IsAeroGlassEnabled() ||
     73       CommandLine::ForCurrentProcess()->HasSwitch(
     74           ::switches::kDisableDwmComposition)) {
     75     return false;
     76   }
     77 #elif defined(OS_LINUX) && !defined(OS_CHROMEOS)
     78   // Shadows are not supported on (non-ChromeOS) Linux.
     79   return false;
     80 #endif
     81   return true;
     82 }
     83 
     84 // The background for the App List overlay, which appears as a white rounded
     85 // rectangle with the given radius and the same size as the target view.
     86 class AppListOverlayBackground : public views::Background {
     87  public:
     88   AppListOverlayBackground(int corner_radius)
     89       : corner_radius_(corner_radius) {};
     90   virtual ~AppListOverlayBackground() {};
     91 
     92   // Overridden from views::Background:
     93   virtual void Paint(gfx::Canvas* canvas, views::View* view) const OVERRIDE {
     94     SkPaint paint;
     95     paint.setStyle(SkPaint::kFill_Style);
     96     paint.setColor(SK_ColorWHITE);
     97     canvas->DrawRoundRect(view->GetContentsBounds(), corner_radius_, paint);
     98   }
     99 
    100  private:
    101   const int corner_radius_;
    102 
    103   DISALLOW_COPY_AND_ASSIGN(AppListOverlayBackground);
    104 };
    105 
    106 }  // namespace
    107 
    108 // An animation observer to hide the view at the end of the animation.
    109 class HideViewAnimationObserver : public ui::ImplicitAnimationObserver {
    110  public:
    111   HideViewAnimationObserver()
    112       : frame_(NULL),
    113         target_(NULL) {
    114   }
    115 
    116   virtual ~HideViewAnimationObserver() {
    117     if (target_)
    118       StopObservingImplicitAnimations();
    119   }
    120 
    121   void SetTarget(views::View* target) {
    122     if (target_)
    123       StopObservingImplicitAnimations();
    124     target_ = target;
    125   }
    126 
    127   void set_frame(views::BubbleFrameView* frame) { frame_ = frame; }
    128 
    129  private:
    130   // Overridden from ui::ImplicitAnimationObserver:
    131   virtual void OnImplicitAnimationsCompleted() OVERRIDE {
    132     if (target_) {
    133       target_->SetVisible(false);
    134       target_ = NULL;
    135 
    136       // Should update the background by invoking SchedulePaint().
    137       if (frame_)
    138         frame_->SchedulePaint();
    139     }
    140   }
    141 
    142   views::BubbleFrameView* frame_;
    143   views::View* target_;
    144 
    145   DISALLOW_COPY_AND_ASSIGN(HideViewAnimationObserver);
    146 };
    147 
    148 ////////////////////////////////////////////////////////////////////////////////
    149 // AppListView:
    150 
    151 AppListView::AppListView(AppListViewDelegate* delegate)
    152     : delegate_(delegate),
    153       app_list_main_view_(NULL),
    154       speech_view_(NULL),
    155       experimental_banner_view_(NULL),
    156       overlay_view_(NULL),
    157       animation_observer_(new HideViewAnimationObserver()) {
    158   CHECK(delegate);
    159 
    160   delegate_->AddObserver(this);
    161   delegate_->GetSpeechUI()->AddObserver(this);
    162 }
    163 
    164 AppListView::~AppListView() {
    165   delegate_->GetSpeechUI()->RemoveObserver(this);
    166   delegate_->RemoveObserver(this);
    167   animation_observer_.reset();
    168   // Remove child views first to ensure no remaining dependencies on delegate_.
    169   RemoveAllChildViews(true);
    170 }
    171 
    172 void AppListView::InitAsBubbleAttachedToAnchor(
    173     gfx::NativeView parent,
    174     int initial_apps_page,
    175     views::View* anchor,
    176     const gfx::Vector2d& anchor_offset,
    177     views::BubbleBorder::Arrow arrow,
    178     bool border_accepts_events) {
    179   SetAnchorView(anchor);
    180   InitAsBubbleInternal(
    181       parent, initial_apps_page, arrow, border_accepts_events, anchor_offset);
    182 }
    183 
    184 void AppListView::InitAsBubbleAtFixedLocation(
    185     gfx::NativeView parent,
    186     int initial_apps_page,
    187     const gfx::Point& anchor_point_in_screen,
    188     views::BubbleBorder::Arrow arrow,
    189     bool border_accepts_events) {
    190   SetAnchorView(NULL);
    191   SetAnchorRect(gfx::Rect(anchor_point_in_screen, gfx::Size()));
    192   InitAsBubbleInternal(
    193       parent, initial_apps_page, arrow, border_accepts_events, gfx::Vector2d());
    194 }
    195 
    196 void AppListView::SetBubbleArrow(views::BubbleBorder::Arrow arrow) {
    197   GetBubbleFrameView()->bubble_border()->set_arrow(arrow);
    198   SizeToContents();  // Recalcuates with new border.
    199   GetBubbleFrameView()->SchedulePaint();
    200 }
    201 
    202 void AppListView::SetAnchorPoint(const gfx::Point& anchor_point) {
    203   SetAnchorRect(gfx::Rect(anchor_point, gfx::Size()));
    204 }
    205 
    206 void AppListView::SetDragAndDropHostOfCurrentAppList(
    207     ApplicationDragAndDropHost* drag_and_drop_host) {
    208   app_list_main_view_->SetDragAndDropHostOfCurrentAppList(drag_and_drop_host);
    209 }
    210 
    211 void AppListView::ShowWhenReady() {
    212   app_list_main_view_->ShowAppListWhenReady();
    213 }
    214 
    215 void AppListView::Close() {
    216   app_list_main_view_->Close();
    217   delegate_->Dismiss();
    218 }
    219 
    220 void AppListView::UpdateBounds() {
    221   SizeToContents();
    222 }
    223 
    224 void AppListView::SetAppListOverlayVisible(bool visible) {
    225   DCHECK(overlay_view_);
    226 
    227   // Display the overlay immediately so we can begin the animation.
    228   overlay_view_->SetVisible(true);
    229 
    230   ui::ScopedLayerAnimationSettings settings(
    231       overlay_view_->layer()->GetAnimator());
    232   settings.SetTweenType(gfx::Tween::LINEAR);
    233 
    234   // If we're dismissing the overlay, hide the view at the end of the animation.
    235   if (!visible) {
    236     // Since only one animation is visible at a time, it's safe to re-use
    237     // animation_observer_ here.
    238     animation_observer_->set_frame(NULL);
    239     animation_observer_->SetTarget(overlay_view_);
    240     settings.AddObserver(animation_observer_.get());
    241   }
    242 
    243   const float kOverlayFadeInMilliseconds = 125;
    244   settings.SetTransitionDuration(
    245       base::TimeDelta::FromMilliseconds(kOverlayFadeInMilliseconds));
    246 
    247   const float kOverlayOpacity = 0.75f;
    248   overlay_view_->layer()->SetOpacity(visible ? kOverlayOpacity : 0.0f);
    249 }
    250 
    251 bool AppListView::ShouldCenterWindow() const {
    252   return delegate_->ShouldCenterWindow();
    253 }
    254 
    255 gfx::Size AppListView::GetPreferredSize() const {
    256   return app_list_main_view_->GetPreferredSize();
    257 }
    258 
    259 void AppListView::Paint(gfx::Canvas* canvas, const views::CullSet& cull_set) {
    260   views::BubbleDelegateView::Paint(canvas, cull_set);
    261   if (!next_paint_callback_.is_null()) {
    262     next_paint_callback_.Run();
    263     next_paint_callback_.Reset();
    264   }
    265 }
    266 
    267 void AppListView::OnThemeChanged() {
    268 #if defined(OS_WIN)
    269   GetWidget()->Close();
    270 #endif
    271 }
    272 
    273 bool AppListView::ShouldHandleSystemCommands() const {
    274   return true;
    275 }
    276 
    277 void AppListView::Prerender() {
    278   app_list_main_view_->Prerender();
    279 }
    280 
    281 void AppListView::OnProfilesChanged() {
    282   app_list_main_view_->search_box_view()->InvalidateMenu();
    283 }
    284 
    285 void AppListView::OnShutdown() {
    286   // Nothing to do on views - the widget will soon be closed, which will tear
    287   // everything down.
    288 }
    289 
    290 void AppListView::SetProfileByPath(const base::FilePath& profile_path) {
    291   delegate_->SetProfileByPath(profile_path);
    292   app_list_main_view_->ModelChanged();
    293 }
    294 
    295 void AppListView::AddObserver(AppListViewObserver* observer) {
    296   observers_.AddObserver(observer);
    297 }
    298 
    299 void AppListView::RemoveObserver(AppListViewObserver* observer) {
    300   observers_.RemoveObserver(observer);
    301 }
    302 
    303 // static
    304 void AppListView::SetNextPaintCallback(const base::Closure& callback) {
    305   next_paint_callback_ = callback;
    306 }
    307 
    308 #if defined(OS_WIN)
    309 HWND AppListView::GetHWND() const {
    310   gfx::NativeWindow window =
    311       GetWidget()->GetTopLevelWidget()->GetNativeWindow();
    312   return window->GetHost()->GetAcceleratedWidget();
    313 }
    314 #endif
    315 
    316 PaginationModel* AppListView::GetAppsPaginationModel() {
    317   return app_list_main_view_->contents_view()
    318       ->apps_container_view()
    319       ->apps_grid_view()
    320       ->pagination_model();
    321 }
    322 
    323 void AppListView::InitAsBubbleInternal(gfx::NativeView parent,
    324                                        int initial_apps_page,
    325                                        views::BubbleBorder::Arrow arrow,
    326                                        bool border_accepts_events,
    327                                        const gfx::Vector2d& anchor_offset) {
    328   base::Time start_time = base::Time::Now();
    329 
    330   app_list_main_view_ =
    331       new AppListMainView(delegate_, initial_apps_page, parent);
    332   AddChildView(app_list_main_view_);
    333   app_list_main_view_->SetPaintToLayer(true);
    334   app_list_main_view_->SetFillsBoundsOpaquely(false);
    335   app_list_main_view_->layer()->SetMasksToBounds(true);
    336 
    337   // Speech recognition is available only when the start page exists.
    338   if (delegate_ && delegate_->IsSpeechRecognitionEnabled()) {
    339     speech_view_ = new SpeechView(delegate_);
    340     speech_view_->SetVisible(false);
    341     speech_view_->SetPaintToLayer(true);
    342     speech_view_->SetFillsBoundsOpaquely(false);
    343     speech_view_->layer()->SetOpacity(0.0f);
    344     AddChildView(speech_view_);
    345   }
    346 
    347   if (app_list::switches::IsExperimentalAppListEnabled()) {
    348     // Draw a banner in the corner of the experimental app list.
    349     experimental_banner_view_ = new views::ImageView;
    350     const gfx::ImageSkia& experimental_icon =
    351         *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
    352             IDR_APP_LIST_EXPERIMENTAL_ICON);
    353     experimental_banner_view_->SetImage(experimental_icon);
    354     experimental_banner_view_->SetPaintToLayer(true);
    355     experimental_banner_view_->SetFillsBoundsOpaquely(false);
    356     AddChildView(experimental_banner_view_);
    357   }
    358 
    359   OnProfilesChanged();
    360   set_color(kContentsBackgroundColor);
    361   set_margins(gfx::Insets());
    362   set_parent_window(parent);
    363   set_close_on_deactivate(false);
    364   set_close_on_esc(false);
    365   set_anchor_view_insets(gfx::Insets(kArrowOffset + anchor_offset.y(),
    366                                      kArrowOffset + anchor_offset.x(),
    367                                      kArrowOffset - anchor_offset.y(),
    368                                      kArrowOffset - anchor_offset.x()));
    369   set_border_accepts_events(border_accepts_events);
    370   set_shadow(SupportsShadow() ? views::BubbleBorder::BIG_SHADOW
    371                               : views::BubbleBorder::NO_SHADOW_OPAQUE_BORDER);
    372   views::BubbleDelegateView::CreateBubble(this);
    373   SetBubbleArrow(arrow);
    374 
    375 #if defined(USE_AURA)
    376   aura::Window* window = GetWidget()->GetNativeWindow();
    377   window->layer()->SetMasksToBounds(true);
    378   GetBubbleFrameView()->set_background(new AppListBackground(
    379       GetBubbleFrameView()->bubble_border()->GetBorderCornerRadius(),
    380       app_list_main_view_));
    381   set_background(NULL);
    382   window->SetEventTargeter(scoped_ptr<ui::EventTargeter>(
    383       new views::BubbleWindowTargeter(this)));
    384 #else
    385   set_background(new AppListBackground(
    386       GetBubbleFrameView()->bubble_border()->GetBorderCornerRadius(),
    387       app_list_main_view_));
    388 
    389   // On non-aura the bubble has two widgets, and it's possible for the border
    390   // to be shown independently in odd situations. Explicitly hide the bubble
    391   // widget to ensure that any WM_WINDOWPOSCHANGED messages triggered by the
    392   // window manager do not have the SWP_SHOWWINDOW flag set which would cause
    393   // the border to be shown. See http://crbug.com/231687 .
    394   GetWidget()->Hide();
    395 #endif
    396 
    397   // To make the overlay view, construct a view with a white background, rather
    398   // than a white rectangle in it. This is because we need overlay_view_ to be
    399   // drawn to its own layer (so it appears correctly in the foreground).
    400   overlay_view_ = new views::View();
    401   overlay_view_->SetPaintToLayer(true);
    402   overlay_view_->SetBoundsRect(GetContentsBounds());
    403   overlay_view_->SetVisible(false);
    404   overlay_view_->layer()->SetOpacity(0.0f);
    405   // On platforms that don't support a shadow, the rounded border of the app
    406   // list is constructed _inside_ the view, so a rectangular background goes
    407   // over the border in the rounded corners. To fix this, give the background a
    408   // corner radius 1px smaller than the outer border, so it just reaches but
    409   // doesn't cover it.
    410   const int kOverlayCornerRadius =
    411       GetBubbleFrameView()->bubble_border()->GetBorderCornerRadius();
    412   overlay_view_->set_background(new AppListOverlayBackground(
    413       kOverlayCornerRadius - (SupportsShadow() ? 0 : 1)));
    414   AddChildView(overlay_view_);
    415 
    416   if (delegate_)
    417     delegate_->ViewInitialized();
    418 
    419   UMA_HISTOGRAM_TIMES("Apps.AppListCreationTime",
    420                       base::Time::Now() - start_time);
    421 }
    422 
    423 void AppListView::OnBeforeBubbleWidgetInit(
    424     views::Widget::InitParams* params,
    425     views::Widget* widget) const {
    426 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
    427   if (delegate_ && delegate_->ForceNativeDesktop())
    428     params->native_widget = new views::DesktopNativeWidgetAura(widget);
    429 #endif
    430 #if defined(OS_WIN)
    431   // Windows 7 and higher offer pinning to the taskbar, but we need presence
    432   // on the taskbar for the user to be able to pin us. So, show the window on
    433   // the taskbar for these versions of Windows.
    434   if (base::win::GetVersion() >= base::win::VERSION_WIN7)
    435     params->force_show_in_taskbar = true;
    436 #elif defined(OS_LINUX)
    437   // Set up a custom WM_CLASS for the app launcher window. This allows task
    438   // switchers in X11 environments to distinguish it from main browser windows.
    439   params->wm_class_name = kAppListWMClass;
    440   // Show the window in the taskbar, even though it is a bubble, which would not
    441   // normally be shown.
    442   params->force_show_in_taskbar = true;
    443 #endif
    444 }
    445 
    446 views::View* AppListView::GetInitiallyFocusedView() {
    447   return app_list::switches::IsExperimentalAppListEnabled()
    448              ? app_list_main_view_->contents_view()
    449                    ->start_page_view()
    450                    ->dummy_search_box_view()
    451                    ->search_box()
    452              : app_list_main_view_->search_box_view()->search_box();
    453 }
    454 
    455 gfx::ImageSkia AppListView::GetWindowIcon() {
    456   if (delegate_)
    457     return delegate_->GetWindowIcon();
    458 
    459   return gfx::ImageSkia();
    460 }
    461 
    462 bool AppListView::WidgetHasHitTestMask() const {
    463   return true;
    464 }
    465 
    466 void AppListView::GetWidgetHitTestMask(gfx::Path* mask) const {
    467   DCHECK(mask);
    468   mask->addRect(gfx::RectToSkRect(
    469       GetBubbleFrameView()->GetContentsBounds()));
    470 }
    471 
    472 bool AppListView::AcceleratorPressed(const ui::Accelerator& accelerator) {
    473   // The accelerator is added by BubbleDelegateView.
    474   if (accelerator.key_code() == ui::VKEY_ESCAPE) {
    475     if (app_list_main_view_->search_box_view()->HasSearch()) {
    476       app_list_main_view_->search_box_view()->ClearSearch();
    477     } else if (app_list_main_view_->contents_view()
    478                    ->apps_container_view()
    479                    ->IsInFolderView()) {
    480       app_list_main_view_->contents_view()
    481           ->apps_container_view()
    482           ->app_list_folder_view()
    483           ->CloseFolderPage();
    484       return true;
    485     } else {
    486       GetWidget()->Deactivate();
    487       Close();
    488     }
    489     return true;
    490   }
    491 
    492   return false;
    493 }
    494 
    495 void AppListView::Layout() {
    496   const gfx::Rect contents_bounds = GetContentsBounds();
    497   app_list_main_view_->SetBoundsRect(contents_bounds);
    498 
    499   if (speech_view_) {
    500     gfx::Rect speech_bounds = contents_bounds;
    501     int preferred_height = speech_view_->GetPreferredSize().height();
    502     speech_bounds.Inset(kSpeechUIMargin, kSpeechUIMargin);
    503     speech_bounds.set_height(std::min(speech_bounds.height(),
    504                                       preferred_height));
    505     speech_bounds.Inset(-speech_view_->GetInsets());
    506     speech_view_->SetBoundsRect(speech_bounds);
    507   }
    508 
    509   if (experimental_banner_view_) {
    510     // Position the experimental banner in the lower right corner.
    511     gfx::Rect image_bounds = experimental_banner_view_->GetImageBounds();
    512     image_bounds.set_origin(
    513         gfx::Point(contents_bounds.width() - image_bounds.width(),
    514                    contents_bounds.height() - image_bounds.height()));
    515     experimental_banner_view_->SetBoundsRect(image_bounds);
    516   }
    517 }
    518 
    519 void AppListView::SchedulePaintInRect(const gfx::Rect& rect) {
    520   BubbleDelegateView::SchedulePaintInRect(rect);
    521   if (GetBubbleFrameView())
    522     GetBubbleFrameView()->SchedulePaint();
    523 }
    524 
    525 void AppListView::OnWidgetDestroying(views::Widget* widget) {
    526   BubbleDelegateView::OnWidgetDestroying(widget);
    527   if (delegate_ && widget == GetWidget())
    528     delegate_->ViewClosing();
    529 }
    530 
    531 void AppListView::OnWidgetActivationChanged(views::Widget* widget,
    532                                             bool active) {
    533   // Do not called inherited function as the bubble delegate auto close
    534   // functionality is not used.
    535   if (widget == GetWidget())
    536     FOR_EACH_OBSERVER(AppListViewObserver, observers_,
    537                       OnActivationChanged(widget, active));
    538 }
    539 
    540 void AppListView::OnWidgetVisibilityChanged(views::Widget* widget,
    541                                             bool visible) {
    542   BubbleDelegateView::OnWidgetVisibilityChanged(widget, visible);
    543 
    544   if (widget != GetWidget())
    545     return;
    546 
    547   if (!visible)
    548     app_list_main_view_->ResetForShow();
    549 }
    550 
    551 void AppListView::OnSpeechRecognitionStateChanged(
    552     SpeechRecognitionState new_state) {
    553   if (!speech_view_)
    554     return;
    555 
    556   bool will_appear = (new_state == SPEECH_RECOGNITION_RECOGNIZING ||
    557                       new_state == SPEECH_RECOGNITION_IN_SPEECH ||
    558                       new_state == SPEECH_RECOGNITION_NETWORK_ERROR);
    559   // No change for this class.
    560   if (speech_view_->visible() == will_appear)
    561     return;
    562 
    563   if (will_appear)
    564     speech_view_->Reset();
    565 
    566   animation_observer_->set_frame(GetBubbleFrameView());
    567   gfx::Transform speech_transform;
    568   speech_transform.Translate(
    569       0, SkFloatToMScalar(kSpeechUIAppearingPosition));
    570   if (will_appear)
    571     speech_view_->layer()->SetTransform(speech_transform);
    572 
    573   {
    574     ui::ScopedLayerAnimationSettings main_settings(
    575         app_list_main_view_->layer()->GetAnimator());
    576     if (will_appear) {
    577       animation_observer_->SetTarget(app_list_main_view_);
    578       main_settings.AddObserver(animation_observer_.get());
    579     }
    580     app_list_main_view_->layer()->SetOpacity(will_appear ? 0.0f : 1.0f);
    581   }
    582 
    583   {
    584     ui::ScopedLayerAnimationSettings speech_settings(
    585         speech_view_->layer()->GetAnimator());
    586     if (!will_appear) {
    587       animation_observer_->SetTarget(speech_view_);
    588       speech_settings.AddObserver(animation_observer_.get());
    589     }
    590 
    591     speech_view_->layer()->SetOpacity(will_appear ? 1.0f : 0.0f);
    592     if (will_appear)
    593       speech_view_->layer()->SetTransform(gfx::Transform());
    594     else
    595       speech_view_->layer()->SetTransform(speech_transform);
    596   }
    597 
    598   if (will_appear)
    599     speech_view_->SetVisible(true);
    600   else
    601     app_list_main_view_->SetVisible(true);
    602 }
    603 
    604 }  // namespace app_list
    605