Home | History | Annotate | Download | only in ui
      1 // Copyright (c) 2013 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/chromeos/ui/app_launch_view.h"
      6 
      7 #include "ash/shell.h"
      8 #include "ash/shell_delegate.h"
      9 #include "ash/shell_window_ids.h"
     10 #include "base/bind.h"
     11 #include "base/logging.h"
     12 #include "base/values.h"
     13 #include "chrome/browser/ui/webui/chromeos/app_launch_ui.h"
     14 #include "chrome/common/url_constants.h"
     15 #include "content/public/browser/browser_context.h"
     16 #include "content/public/browser/browser_thread.h"
     17 #include "content/public/browser/render_view_host.h"
     18 #include "content/public/browser/render_widget_host_view.h"
     19 #include "content/public/browser/web_contents.h"
     20 #include "grit/generated_resources.h"
     21 #include "third_party/skia/include/core/SkBitmap.h"
     22 #include "ui/aura/root_window.h"
     23 #include "ui/base/l10n/l10n_util.h"
     24 #include "ui/gfx/screen.h"
     25 #include "ui/views/controls/webview/webview.h"
     26 #include "ui/views/layout/fill_layout.h"
     27 #include "ui/views/widget/widget.h"
     28 
     29 using content::BrowserThread;
     30 
     31 namespace chromeos {
     32 
     33 internal::AppLaunchView* g_instance = NULL;
     34 
     35 void ShowAppLaunchSplashScreen(const std::string& app_id) {
     36   // TODO(zelidrag): Come up with a better UI for this purpose.
     37   internal::AppLaunchView::ShowAppLaunchSplashScreen(app_id);
     38 }
     39 
     40 void UpdateAppLaunchSplashScreenState(AppLaunchState state) {
     41   internal::AppLaunchView::UpdateAppLaunchState(state);
     42 }
     43 
     44 void CloseAppLaunchSplashScreen() {
     45   internal::AppLaunchView::CloseAppLaunchSplashScreen();
     46 }
     47 
     48 namespace internal {
     49 
     50 int GetProgressMessageFromState(AppLaunchState state) {
     51   switch (state) {
     52     case APP_LAUNCH_STATE_LOADING_AUTH_FILE:
     53     case APP_LAUNCH_STATE_LOADING_TOKEN_SERVICE:
     54       // TODO(zelidrag): Add better string for this one than "Please wait..."
     55       return IDS_SYNC_SETUP_SPINNER_TITLE;
     56     case APP_LAUNCH_STATE_PREPARING_NETWORK:
     57       return IDS_APP_START_NETWORK_WAIT_MESSAGE;
     58     case APP_LAUNCH_STATE_INSTALLING_APPLICATION:
     59       return IDS_APP_START_APP_WAIT_MESSAGE;
     60   }
     61   return IDS_APP_START_NETWORK_WAIT_MESSAGE;
     62 }
     63 
     64 // static
     65 void AppLaunchView::ShowAppLaunchSplashScreen(const std::string& app_id) {
     66   if (!g_instance) {
     67     g_instance = new AppLaunchView(app_id);
     68     g_instance->Show();
     69   }
     70 }
     71 
     72 void AppLaunchView::UpdateAppLaunchState(AppLaunchState state) {
     73   if (g_instance)
     74     g_instance->UpdateState(state);
     75 }
     76 
     77 
     78 // static
     79 void AppLaunchView::CloseAppLaunchSplashScreen() {
     80   if (g_instance) {
     81     g_instance->GetWidget()->Close();
     82     g_instance = NULL;
     83   }
     84 }
     85 
     86 ////////////////////////////////////////////////////////////////////////////////
     87 // AppLaunchView, views::WidgetDelegateView implementation.
     88 views::View* AppLaunchView::GetContentsView() {
     89   return this;
     90 }
     91 
     92 ////////////////////////////////////////////////////////////////////////////////
     93 // AppLaunchView, content::WebContentsObserver implementation.
     94 void AppLaunchView::RenderProcessGone(
     95     base::TerminationStatus status) {
     96   LOG(ERROR) << "Splash screen terminated with status " << status;
     97   AppLaunchView::CloseAppLaunchSplashScreen();
     98 }
     99 
    100 ////////////////////////////////////////////////////////////////////////////////
    101 // AppLaunchView private methods.
    102 AppLaunchView::AppLaunchView(const std::string& app_id)
    103     : app_launch_webview_(NULL),
    104       container_window_(NULL),
    105       app_id_(app_id),
    106       state_(APP_LAUNCH_STATE_LOADING_AUTH_FILE),
    107       app_launch_ui_(NULL) {
    108 }
    109 
    110 AppLaunchView::~AppLaunchView() {
    111 }
    112 
    113 void AppLaunchView::Show() {
    114   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    115   // Add the WebView to our view.
    116   AddChildWebContents();
    117   // Initialize container window.
    118   InitializeWindow();
    119   // Show the window.
    120   ShowWindow();
    121 }
    122 
    123 void AppLaunchView::AddChildWebContents() {
    124   content::BrowserContext* context =
    125       ash::Shell::GetInstance()->delegate()->GetCurrentBrowserContext();
    126   app_launch_webview_ = new views::WebView(context);
    127   SetLayoutManager(new views::FillLayout);
    128   AddChildView(app_launch_webview_);
    129 
    130   LoadSplashScreen();
    131   content::WebContentsObserver::Observe(
    132       app_launch_webview_->GetWebContents());
    133 }
    134 
    135 void AppLaunchView::UpdateState(AppLaunchState state) {
    136   if (state == state_)
    137     return;
    138 
    139   state_ = state;
    140   if (!app_launch_ui_)
    141     return;
    142 
    143   app_launch_ui_->SetLaunchText(
    144       l10n_util::GetStringUTF8(GetProgressMessageFromState(state_)));
    145 }
    146 
    147 void AppLaunchView::LoadSplashScreen() {
    148   std::string url = chrome::kChromeUIAppLaunchURL;
    149   url += "?app=" + app_id_;
    150 
    151   app_launch_webview_->GetWebContents()->GetController().LoadURL(
    152       GURL(url),
    153       content::Referrer(),
    154       content::PAGE_TRANSITION_AUTO_TOPLEVEL,
    155       std::string());
    156 
    157   app_launch_ui_ = static_cast<AppLaunchUI*>(
    158       app_launch_webview_->GetWebContents()->GetWebUI()->GetController());
    159 
    160   // Use a background with transparency to trigger transparency in Webkit.
    161   SkBitmap background;
    162   background.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
    163   background.allocPixels();
    164   background.eraseARGB(0x00, 0x00, 0x00, 0x00);
    165   content::RenderViewHost* host =
    166       app_launch_webview_->GetWebContents()->GetRenderViewHost();
    167   host->GetView()->SetBackground(background);
    168 }
    169 
    170 void AppLaunchView::InitializeWindow() {
    171   DCHECK(!container_window_);
    172   aura::RootWindow* root_window = ash::Shell::GetPrimaryRootWindow();
    173 
    174   // We want to be the fullscreen topmost child of the root window.
    175   // There should be nothing ever really that should show up on top of us.
    176   container_window_ = new views::Widget();
    177   views::Widget::InitParams params(
    178       views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
    179   params.delegate = this;
    180   params.parent = ash::Shell::GetContainer(
    181       root_window,
    182       ash::internal::kShellWindowId_LockScreenContainer);
    183   params.show_state = ui::SHOW_STATE_FULLSCREEN;
    184   container_window_->Init(params);
    185 }
    186 
    187 void AppLaunchView::ShowWindow() {
    188   DCHECK(container_window_);
    189   container_window_->Show();
    190 }
    191 
    192 }  // namespace internal
    193 
    194 }  // namespace chromeos
    195