summaryrefslogtreecommitdiffstats
path: root/athena/content/app_activity.cc
blob: e557b619514f1d72a68b4990b2095a8374793dce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "athena/content/app_activity.h"

#include "athena/activity/public/activity_manager.h"
#include "athena/content/app_activity_registry.h"
#include "athena/content/public/app_registry.h"
#include "content/public/browser/web_contents.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(const std::string& app_id)
    : app_id_(app_id),
      web_view_(NULL),
      current_state_(ACTIVITY_UNLOADED),
      app_activity_registry_(NULL) {
}

ActivityViewModel* AppActivity::GetActivityViewModel() {
  return this;
}

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:
      MakeVisible();
      return;
    case ACTIVITY_INVISIBLE:
      if (current_state == ACTIVITY_VISIBLE)
        MakeInvisible();
      break;
    case ACTIVITY_BACKGROUND_LOW_PRIORITY:
      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);
      // TODO(skuhne): Do this.
      break;
    case ACTIVITY_UNLOADED:
      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;
  }
}

Activity::ActivityState AppActivity::GetCurrentState() {
  DCHECK(web_view_ || ACTIVITY_UNLOADED == current_state_);
  return current_state_;
}

bool AppActivity::IsVisible() {
  return web_view_ &&
         web_view_->visible() &&
         current_state_ != ACTIVITY_UNLOADED;
}

Activity::ActivityMediaState AppActivity::GetMediaState() {
  // TODO(skuhne): The function GetTabMediaStateForContents(WebContents),
  // and the AudioStreamMonitor needs to be moved from Chrome into contents to
  // make it more modular and so that we can use it from here.
  return Activity::ACTIVITY_MEDIA_STATE_NONE;
}

aura::Window* AppActivity::GetWindow() {
  return !web_view_ ? NULL : web_view_->GetWidget()->GetNativeWindow();
}

void AppActivity::Init() {
  DCHECK(app_activity_registry_);
  Activity* app_proxy = app_activity_registry_->unloaded_activity_proxy();
  if (app_proxy) {
    // TODO(skuhne): This should call the WindowListProvider to re-arrange.
    // Note: At this time the |AppActivity| did not get registered to the
    // |ResourceManager| - so we can move it around if needed.
    aura::Window* proxy_window = app_proxy->GetWindow();
    proxy_window->parent()->StackChildBelow(GetWindow(), proxy_window);
    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 {
  // TODO(sad): Compute the color from the favicon.
  return SK_ColorGRAY;
}

base::string16 AppActivity::GetTitle() const {
  return web_view_->GetWebContents()->GetTitle();
}

bool AppActivity::UsesFrame() const {
  return false;
}

views::View* AppActivity::GetContentsView() {
  if (!web_view_) {
    // TODO(oshima): use apps::NativeAppWindowViews
    content::WebContents* web_contents = GetWebContents();
    web_view_ = new views::WebView(web_contents->GetBrowserContext());
    web_view_->SetWebContents(web_contents);
    // Make sure the content gets properly shown.
    if (current_state_ == ACTIVITY_VISIBLE) {
      MakeVisible();
    } else if (current_state_ == ACTIVITY_INVISIBLE) {
      MakeInvisible();
    } else {
      // If not previously specified, we change the state now to invisible..
      SetCurrentState(ACTIVITY_INVISIBLE);
    }
    Observe(web_contents);
    RegisterActivity();
  }
  return web_view_;
}

void AppActivity::CreateOverviewModeImage() {
  // TODO(skuhne): Implement this!
}

gfx::ImageSkia AppActivity::GetOverviewModeImage() {
  return overview_mode_image_;
}

void AppActivity::PrepareContentsForOverview() {
  // Turn on fast resizing to avoid re-laying out the web contents when
  // entering / exiting overview mode.
  web_view_->SetFastResize(true);
}

void AppActivity::ResetContentsView() {
  web_view_->SetFastResize(false);
  web_view_->Layout();
}

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,
                              bool explicit_set) {
  ActivityManager::Get()->UpdateActivity(this);
}

void AppActivity::DidUpdateFaviconURL(
    const std::vector<content::FaviconURL>& candidates) {
  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 = 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::MakeVisible() {
  // TODO(skuhne): Once we know how to handle the Overview mode, this has to
  // be moved into an ActivityContentController which is used by all activities.
  // Make the content visible.
  // TODO(skuhne): If this can be combined with web_activity, move this into a
  // separate class.
  web_view_->SetVisible(true);
  web_view_->GetWebContents()->GetNativeView()->Show();

  // Remove our proxy image.
  // TODO(skuhne): Once we have figured out how to do overview mode that code
  // needs to go here.
  overview_mode_image_ = gfx::ImageSkia();
}

void AppActivity::MakeInvisible() {
  // TODO(skuhne): Once we know how to handle the Overview mode, this has to
  // be moved into an ActivityContentController which is used by all activities.
  // TODO(skuhne): If this can be combined with web_activity, move this into a
  // separate class.
  DCHECK(web_view_->visible());
  // Create our proxy image.
  if (current_state_ == ACTIVITY_VISIBLE) {
    // Create a proxy image of the current visible content.
    // TODO(skuhne): Do this once we figure out how to do overview mode.
    overview_mode_image_ = gfx::ImageSkia();
  }
  // Now we can hide this.
  // Note: This might have to be done asynchronously after the readback took
  // place.
  web_view_->SetVisible(false);
  web_view_->GetWebContents()->GetNativeView()->Hide();
}

}  // namespace athena