#include "athena/content/app_activity.h"
#include "athena/activity/public/activity_manager.h"
+#include "athena/content/app_activity_registry.h"
+#include "athena/content/content_proxy.h"
+#include "athena/content/public/app_registry.h"
+#include "athena/wm/public/window_list_provider.h"
+#include "athena/wm/public/window_manager.h"
#include "content/public/browser/web_contents.h"
-#include "extensions/shell/browser/shell_app_window.h"
+#include "extensions/browser/app_window/app_window.h"
+#include "ui/aura/window.h"
#include "ui/views/controls/webview/webview.h"
+#include "ui/views/widget/widget.h"
namespace athena {
// TODO(mukai): specifies the same accelerators of WebActivity.
-AppActivity::AppActivity(extensions::ShellAppWindow* app_window)
- : app_window_(app_window),
- web_view_(NULL),
- current_state_(ACTIVITY_UNLOADED) {
- DCHECK(app_window_);
+AppActivity::AppActivity(extensions::AppWindow* app_window,
+ views::WebView* web_view)
+ : app_id_(app_window->extension_id()),
+ web_view_(web_view),
+ current_state_(ACTIVITY_UNLOADED),
+ app_activity_registry_(NULL) {
+ DCHECK_EQ(app_window->web_contents(), web_view->GetWebContents());
+ Observe(app_window->web_contents());
}
-AppActivity::~AppActivity() {
- if (GetCurrentState() != ACTIVITY_UNLOADED)
- SetCurrentState(ACTIVITY_UNLOADED);
+scoped_ptr<ContentProxy> AppActivity::GetContentProxy() {
+ // Note: After this call, the content is still valid because the contents
+ // destruction will destroy this |AppActivity| object.
+ if (content_proxy_.get())
+ content_proxy_->OnPreContentDestroyed();
+ return content_proxy_.Pass();
}
ActivityViewModel* AppActivity::GetActivityViewModel() {
}
void AppActivity::SetCurrentState(Activity::ActivityState state) {
+ DCHECK_NE(state, current_state_);
+ ActivityState current_state = current_state_;
+ // Remember the last requested state now so that a call to GetCurrentState()
+ // returns the new state.
+ current_state_ = state;
+
switch (state) {
case ACTIVITY_VISIBLE:
- // Fall through (for the moment).
+ HideContentProxy();
+ return;
case ACTIVITY_INVISIBLE:
- // By clearing the overview mode image we allow the content to be shown.
- overview_mode_image_ = gfx::ImageSkia();
- // TODO(skuhne): Find out how to reload an app from the extension system.
+ if (current_state == ACTIVITY_VISIBLE)
+ ShowContentProxy();
break;
case ACTIVITY_BACKGROUND_LOW_PRIORITY:
- DCHECK(ACTIVITY_VISIBLE == current_state_ ||
- ACTIVITY_INVISIBLE == current_state_);
+ DCHECK(ACTIVITY_VISIBLE == current_state ||
+ ACTIVITY_INVISIBLE == current_state);
// TODO(skuhne): Do this.
break;
case ACTIVITY_PERSISTENT:
- DCHECK_EQ(ACTIVITY_BACKGROUND_LOW_PRIORITY, current_state_);
+ DCHECK_EQ(ACTIVITY_BACKGROUND_LOW_PRIORITY, current_state);
// TODO(skuhne): Do this.
break;
case ACTIVITY_UNLOADED:
- DCHECK_NE(ACTIVITY_UNLOADED, current_state_);
- // TODO(skuhne): Find out how to evict an app from the extension system.
- // web_view_->EvictContent();
+ DCHECK_NE(ACTIVITY_UNLOADED, current_state);
+ // This will cause the application to shut down, close its windows and
+ // delete this object. Instead a |AppActivityProxy| will be created as
+ // place holder.
+ if (app_activity_registry_)
+ app_activity_registry_->Unload();
break;
}
- // Remember the last requested state.
- current_state_ = state;
}
Activity::ActivityState AppActivity::GetCurrentState() {
- // TODO(skuhne): Check here also eviction status.
- if (!web_view_) {
- DCHECK_EQ(ACTIVITY_UNLOADED, current_state_);
- return ACTIVITY_UNLOADED;
- }
- // TODO(skuhne): This should be controlled by an observer and should not
- // reside here.
- if (IsVisible() && current_state_ != ACTIVITY_VISIBLE)
- SetCurrentState(ACTIVITY_VISIBLE);
- // Note: If the activity is not visible it does not necessarily mean that it
- // does not have GPU compositor resources (yet).
+ DCHECK(web_view_ || ACTIVITY_UNLOADED == current_state_);
return current_state_;
}
bool AppActivity::IsVisible() {
- return web_view_ && web_view_->IsDrawn();
+ return web_view_ &&
+ web_view_->visible() &&
+ current_state_ != ACTIVITY_UNLOADED;
}
Activity::ActivityMediaState AppActivity::GetMediaState() {
return Activity::ACTIVITY_MEDIA_STATE_NONE;
}
+aura::Window* AppActivity::GetWindow() {
+ return !web_view_ ? NULL : web_view_->GetWidget()->GetNativeWindow();
+}
+
+content::WebContents* AppActivity::GetWebContents() {
+ return !web_view_ ? NULL : web_view_->GetWebContents();
+}
+
void AppActivity::Init() {
+ DCHECK(app_activity_registry_);
+ Activity* app_proxy = app_activity_registry_->unloaded_activity_proxy();
+ if (app_proxy) {
+ // Note: At this time the |AppActivity| did not get registered to the
+ // |ResourceManager| - so we can move it around if needed.
+ WindowListProvider* window_list_provider =
+ WindowManager::Get()->GetWindowListProvider();
+ window_list_provider->StackWindowFrontOf(app_proxy->GetWindow(),
+ GetWindow());
+ Activity::Delete(app_proxy);
+ // With the removal the object, the proxy should be deleted.
+ DCHECK(!app_activity_registry_->unloaded_activity_proxy());
+ }
}
SkColor AppActivity::GetRepresentativeColor() const {
return web_view_->GetWebContents()->GetTitle();
}
+gfx::ImageSkia AppActivity::GetIcon() const {
+ return gfx::ImageSkia();
+}
+
bool AppActivity::UsesFrame() const {
return false;
}
-views::View* AppActivity::GetContentsView() {
- if (!web_view_) {
- // TODO(oshima): use apps::NativeAppWindowViews
- content::WebContents* web_contents =
- app_window_->GetAssociatedWebContents();
- web_view_ = new views::WebView(web_contents->GetBrowserContext());
- web_view_->SetWebContents(web_contents);
+views::Widget* AppActivity::CreateWidget() {
+ // Make sure the content gets properly shown.
+ if (current_state_ == ACTIVITY_VISIBLE) {
+ HideContentProxy();
+ } else if (current_state_ == ACTIVITY_INVISIBLE) {
+ ShowContentProxy();
+ } else {
+ // If not previously specified, we change the state now to invisible..
SetCurrentState(ACTIVITY_INVISIBLE);
- Observe(web_contents);
- overview_mode_image_ = gfx::ImageSkia();
}
- return web_view_;
+ RegisterActivity();
+ return web_view_->GetWidget();
}
-void AppActivity::CreateOverviewModeImage() {
- // TODO(skuhne): Implement this!
+views::View* AppActivity::GetContentsView() {
+ return web_view_;
}
gfx::ImageSkia AppActivity::GetOverviewModeImage() {
- return overview_mode_image_;
+ if (content_proxy_.get())
+ return content_proxy_->GetContentImage();
+ return gfx::ImageSkia();
+}
+
+void AppActivity::PrepareContentsForOverview() {
+ // Turn on fast resizing to avoid re-laying out the web contents when
+ // entering / exiting overview mode and the content is visible.
+ if (!content_proxy_.get())
+ web_view_->SetFastResize(true);
+}
+
+void AppActivity::ResetContentsView() {
+ // Turn on fast resizing to avoid re-laying out the web contents when
+ // entering / exiting overview mode and the content is visible.
+ if (!content_proxy_.get()) {
+ web_view_->SetFastResize(false);
+ web_view_->Layout();
+ }
+}
+
+AppActivity::AppActivity(const std::string& app_id)
+ : app_id_(app_id),
+ web_view_(NULL),
+ current_state_(ACTIVITY_UNLOADED),
+ app_activity_registry_(NULL) {
+}
+
+AppActivity::~AppActivity() {
+ // If this activity is registered, we unregister it now.
+ if (app_activity_registry_)
+ app_activity_registry_->UnregisterAppActivity(this);
}
void AppActivity::TitleWasSet(content::NavigationEntry* entry,
ActivityManager::Get()->UpdateActivity(this);
}
+// Register an |activity| with an application.
+// Note: This should only get called once for an |app_window| of the
+// |activity|.
+void AppActivity::RegisterActivity() {
+ content::WebContents* web_contents = web_view_->GetWebContents();
+ AppRegistry* app_registry = AppRegistry::Get();
+ // Get the application's registry.
+ app_activity_registry_ = app_registry->GetAppActivityRegistry(
+ app_id_, web_contents->GetBrowserContext());
+ DCHECK(app_activity_registry_);
+ // Register the activity.
+ app_activity_registry_->RegisterAppActivity(this);
+}
+
+void AppActivity::HideContentProxy() {
+ content_proxy_.reset();
+}
+
+void AppActivity::ShowContentProxy() {
+ if (!content_proxy_.get() && web_view_)
+ content_proxy_.reset(new ContentProxy(web_view_, this));
+}
+
} // namespace athena