Home | History | Annotate | Download | only in content
      1 // Copyright 2014 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 "athena/content/app_activity.h"
      6 
      7 #include "athena/activity/public/activity_manager.h"
      8 #include "athena/content/app_activity_registry.h"
      9 #include "athena/content/content_proxy.h"
     10 #include "athena/content/public/app_registry.h"
     11 #include "athena/wm/public/window_list_provider.h"
     12 #include "athena/wm/public/window_manager.h"
     13 #include "content/public/browser/web_contents.h"
     14 #include "extensions/browser/app_window/app_window.h"
     15 #include "ui/aura/window.h"
     16 #include "ui/views/controls/webview/webview.h"
     17 #include "ui/views/widget/widget.h"
     18 
     19 namespace athena {
     20 
     21 // TODO(mukai): specifies the same accelerators of WebActivity.
     22 AppActivity::AppActivity(extensions::AppWindow* app_window,
     23                          views::WebView* web_view)
     24     : app_id_(app_window->extension_id()),
     25       web_view_(web_view),
     26       current_state_(ACTIVITY_UNLOADED),
     27       app_activity_registry_(NULL) {
     28   DCHECK_EQ(app_window->web_contents(), web_view->GetWebContents());
     29   Observe(app_window->web_contents());
     30 }
     31 
     32 scoped_ptr<ContentProxy> AppActivity::GetContentProxy() {
     33   // Note: After this call, the content is still valid because the contents
     34   // destruction will destroy this |AppActivity| object.
     35   if (content_proxy_.get())
     36     content_proxy_->OnPreContentDestroyed();
     37   return content_proxy_.Pass();
     38 }
     39 
     40 ActivityViewModel* AppActivity::GetActivityViewModel() {
     41   return this;
     42 }
     43 
     44 void AppActivity::SetCurrentState(Activity::ActivityState state) {
     45   DCHECK_NE(state, current_state_);
     46   ActivityState current_state = current_state_;
     47   // Remember the last requested state now so that a call to GetCurrentState()
     48   // returns the new state.
     49   current_state_ = state;
     50 
     51   switch (state) {
     52     case ACTIVITY_VISIBLE:
     53       HideContentProxy();
     54       return;
     55     case ACTIVITY_INVISIBLE:
     56       if (current_state == ACTIVITY_VISIBLE)
     57         ShowContentProxy();
     58       break;
     59     case ACTIVITY_BACKGROUND_LOW_PRIORITY:
     60       DCHECK(ACTIVITY_VISIBLE == current_state ||
     61              ACTIVITY_INVISIBLE == current_state);
     62       // TODO(skuhne): Do this.
     63       break;
     64     case ACTIVITY_PERSISTENT:
     65       DCHECK_EQ(ACTIVITY_BACKGROUND_LOW_PRIORITY, current_state);
     66       // TODO(skuhne): Do this.
     67       break;
     68     case ACTIVITY_UNLOADED:
     69       DCHECK_NE(ACTIVITY_UNLOADED, current_state);
     70       // This will cause the application to shut down, close its windows and
     71       // delete this object. Instead a |AppActivityProxy| will be created as
     72       // place holder.
     73       if (app_activity_registry_)
     74         app_activity_registry_->Unload();
     75       break;
     76   }
     77 }
     78 
     79 Activity::ActivityState AppActivity::GetCurrentState() {
     80   DCHECK(web_view_ || ACTIVITY_UNLOADED == current_state_);
     81   return current_state_;
     82 }
     83 
     84 bool AppActivity::IsVisible() {
     85   return web_view_ &&
     86          web_view_->visible() &&
     87          current_state_ != ACTIVITY_UNLOADED;
     88 }
     89 
     90 Activity::ActivityMediaState AppActivity::GetMediaState() {
     91   // TODO(skuhne): The function GetTabMediaStateForContents(WebContents),
     92   // and the AudioStreamMonitor needs to be moved from Chrome into contents to
     93   // make it more modular and so that we can use it from here.
     94   return Activity::ACTIVITY_MEDIA_STATE_NONE;
     95 }
     96 
     97 aura::Window* AppActivity::GetWindow() {
     98   return !web_view_ ? NULL : web_view_->GetWidget()->GetNativeWindow();
     99 }
    100 
    101 content::WebContents* AppActivity::GetWebContents() {
    102   return !web_view_ ? NULL : web_view_->GetWebContents();
    103 }
    104 
    105 void AppActivity::Init() {
    106   DCHECK(app_activity_registry_);
    107   Activity* app_proxy = app_activity_registry_->unloaded_activity_proxy();
    108   if (app_proxy) {
    109     // Note: At this time the |AppActivity| did not get registered to the
    110     // |ResourceManager| - so we can move it around if needed.
    111     WindowListProvider* window_list_provider =
    112         WindowManager::Get()->GetWindowListProvider();
    113     window_list_provider->StackWindowFrontOf(app_proxy->GetWindow(),
    114                                              GetWindow());
    115     Activity::Delete(app_proxy);
    116     // With the removal the object, the proxy should be deleted.
    117     DCHECK(!app_activity_registry_->unloaded_activity_proxy());
    118   }
    119 }
    120 
    121 SkColor AppActivity::GetRepresentativeColor() const {
    122   // TODO(sad): Compute the color from the favicon.
    123   return SK_ColorGRAY;
    124 }
    125 
    126 base::string16 AppActivity::GetTitle() const {
    127   return web_view_->GetWebContents()->GetTitle();
    128 }
    129 
    130 gfx::ImageSkia AppActivity::GetIcon() const {
    131   return gfx::ImageSkia();
    132 }
    133 
    134 bool AppActivity::UsesFrame() const {
    135   return false;
    136 }
    137 
    138 views::Widget* AppActivity::CreateWidget() {
    139   // Make sure the content gets properly shown.
    140   if (current_state_ == ACTIVITY_VISIBLE) {
    141     HideContentProxy();
    142   } else if (current_state_ == ACTIVITY_INVISIBLE) {
    143     ShowContentProxy();
    144   } else {
    145     // If not previously specified, we change the state now to invisible..
    146     SetCurrentState(ACTIVITY_INVISIBLE);
    147   }
    148   RegisterActivity();
    149   return web_view_->GetWidget();
    150 }
    151 
    152 views::View* AppActivity::GetContentsView() {
    153   return web_view_;
    154 }
    155 
    156 gfx::ImageSkia AppActivity::GetOverviewModeImage() {
    157   if (content_proxy_.get())
    158     return content_proxy_->GetContentImage();
    159   return gfx::ImageSkia();
    160 }
    161 
    162 void AppActivity::PrepareContentsForOverview() {
    163   // Turn on fast resizing to avoid re-laying out the web contents when
    164   // entering / exiting overview mode and the content is visible.
    165   if (!content_proxy_.get())
    166     web_view_->SetFastResize(true);
    167 }
    168 
    169 void AppActivity::ResetContentsView() {
    170   // Turn on fast resizing to avoid re-laying out the web contents when
    171   // entering / exiting overview mode and the content is visible.
    172   if (!content_proxy_.get()) {
    173     web_view_->SetFastResize(false);
    174     web_view_->Layout();
    175   }
    176 }
    177 
    178 AppActivity::AppActivity(const std::string& app_id)
    179     : app_id_(app_id),
    180       web_view_(NULL),
    181       current_state_(ACTIVITY_UNLOADED),
    182       app_activity_registry_(NULL) {
    183 }
    184 
    185 AppActivity::~AppActivity() {
    186   // If this activity is registered, we unregister it now.
    187   if (app_activity_registry_)
    188     app_activity_registry_->UnregisterAppActivity(this);
    189 }
    190 
    191 void AppActivity::TitleWasSet(content::NavigationEntry* entry,
    192                               bool explicit_set) {
    193   ActivityManager::Get()->UpdateActivity(this);
    194 }
    195 
    196 void AppActivity::DidUpdateFaviconURL(
    197     const std::vector<content::FaviconURL>& candidates) {
    198   ActivityManager::Get()->UpdateActivity(this);
    199 }
    200 
    201 // Register an |activity| with an application.
    202 // Note: This should only get called once for an |app_window| of the
    203 // |activity|.
    204 void AppActivity::RegisterActivity() {
    205   content::WebContents* web_contents = web_view_->GetWebContents();
    206   AppRegistry* app_registry = AppRegistry::Get();
    207   // Get the application's registry.
    208   app_activity_registry_ = app_registry->GetAppActivityRegistry(
    209       app_id_, web_contents->GetBrowserContext());
    210   DCHECK(app_activity_registry_);
    211   // Register the activity.
    212   app_activity_registry_->RegisterAppActivity(this);
    213 }
    214 
    215 void AppActivity::HideContentProxy() {
    216   content_proxy_.reset();
    217 }
    218 
    219 void AppActivity::ShowContentProxy() {
    220   if (!content_proxy_.get() && web_view_)
    221     content_proxy_.reset(new ContentProxy(web_view_, this));
    222 }
    223 
    224 }  // namespace athena
    225