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/activity/public/activity_factory.h"
6#include "athena/activity/public/activity_manager.h"
7#include "athena/content/public/web_contents_view_delegate_creator.h"
8#include "athena/env/public/athena_env.h"
9#include "athena/extensions/public/extensions_delegate.h"
10#include "athena/main/athena_content_client.h"
11#include "athena/main/athena_renderer_pdf_helper.h"
12#include "athena/main/public/athena_launcher.h"
13#include "athena/screen/public/screen_manager.h"
14#include "base/command_line.h"
15#include "base/files/file_util.h"
16#include "base/path_service.h"
17#include "components/pdf/renderer/ppb_pdf_impl.h"
18#include "content/public/app/content_main.h"
19#include "content/public/browser/browser_thread.h"
20#include "extensions/browser/app_window/app_window.h"
21#include "extensions/browser/app_window/app_window_client.h"
22#include "extensions/shell/app/shell_main_delegate.h"
23#include "extensions/shell/browser/desktop_controller.h"
24#include "extensions/shell/browser/shell_app_delegate.h"
25#include "extensions/shell/browser/shell_browser_main_delegate.h"
26#include "extensions/shell/browser/shell_content_browser_client.h"
27#include "extensions/shell/browser/shell_extension_system.h"
28#include "extensions/shell/browser/shell_native_app_window.h"
29#include "extensions/shell/common/shell_content_client.h"
30#include "extensions/shell/common/switches.h"
31#include "extensions/shell/renderer/shell_content_renderer_client.h"
32#include "ppapi/c/private/ppb_pdf.h"
33#include "ui/aura/window_tree_host.h"
34#include "ui/base/resource/resource_bundle.h"
35#include "ui/wm/core/visibility_controller.h"
36
37namespace {
38
39// We want to load the sample calculator app by default, for a while. Expecting
40// to run athena_main at src/
41const char kDefaultAppPath[] =
42    "chrome/common/extensions/docs/examples/apps/calculator/app";
43
44}  // namespace
45
46class AthenaDesktopController : public extensions::DesktopController {
47 public:
48  AthenaDesktopController() {}
49  virtual ~AthenaDesktopController() {}
50
51 private:
52  // extensions::DesktopController:
53  virtual aura::WindowTreeHost* GetHost() OVERRIDE {
54    return athena::AthenaEnv::Get()->GetHost();
55  }
56
57  // Creates a new app window and adds it to the desktop. The desktop maintains
58  // ownership of the window.
59  // TODO(jamescook|oshima): Is this function needed?
60  virtual extensions::AppWindow* CreateAppWindow(
61      content::BrowserContext* context,
62      const extensions::Extension* extension) OVERRIDE {
63    NOTIMPLEMENTED();
64    return NULL;
65  }
66
67  // Adds the window to the desktop.
68  virtual void AddAppWindow(aura::Window* window) OVERRIDE {
69    NOTIMPLEMENTED();
70  }
71
72  // Closes and destroys the app windows.
73  virtual void CloseAppWindows() OVERRIDE {}
74
75  DISALLOW_COPY_AND_ASSIGN(AthenaDesktopController);
76};
77
78class AthenaBrowserMainDelegate : public extensions::ShellBrowserMainDelegate {
79 public:
80  AthenaBrowserMainDelegate() {}
81  virtual ~AthenaBrowserMainDelegate() {}
82
83  // extensions::ShellBrowserMainDelegate:
84  virtual void Start(content::BrowserContext* context) OVERRIDE {
85    base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
86
87    base::FilePath app_dir = base::FilePath::FromUTF8Unsafe(
88        command_line->HasSwitch(extensions::switches::kAppShellAppPath)
89            ? command_line->GetSwitchValueNative(
90                  extensions::switches::kAppShellAppPath)
91            : kDefaultAppPath);
92
93    base::FilePath app_absolute_dir = base::MakeAbsoluteFilePath(app_dir);
94    if (base::DirectoryExists(app_absolute_dir)) {
95      extensions::ShellExtensionSystem* extension_system =
96          static_cast<extensions::ShellExtensionSystem*>(
97              extensions::ExtensionSystem::Get(context));
98      extension_system->LoadApp(app_absolute_dir);
99    }
100
101    athena::StartAthenaEnv(content::BrowserThread::GetBlockingPool()->
102        GetTaskRunnerWithShutdownBehavior(
103            base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
104    athena::ExtensionsDelegate::CreateExtensionsDelegateForShell(context);
105    athena::CreateVirtualKeyboardWithContext(context);
106    athena::StartAthenaSessionWithContext(context);
107  }
108
109  virtual void Shutdown() OVERRIDE {
110    athena::AthenaEnv::Get()->OnTerminating();
111    athena::ShutdownAthena();
112  }
113
114  virtual extensions::DesktopController* CreateDesktopController() OVERRIDE {
115    return new AthenaDesktopController();
116  }
117
118 private:
119  DISALLOW_COPY_AND_ASSIGN(AthenaBrowserMainDelegate);
120};
121
122class AthenaContentBrowserClient
123    : public extensions::ShellContentBrowserClient {
124 public:
125  AthenaContentBrowserClient()
126      : extensions::ShellContentBrowserClient(new AthenaBrowserMainDelegate()) {
127  }
128  virtual ~AthenaContentBrowserClient() {}
129
130  // content::ContentBrowserClient:
131  virtual content::WebContentsViewDelegate* GetWebContentsViewDelegate(
132      content::WebContents* web_contents) OVERRIDE {
133    return athena::CreateWebContentsViewDelegate(web_contents);
134  }
135
136 private:
137  DISALLOW_COPY_AND_ASSIGN(AthenaContentBrowserClient);
138};
139
140class AthenaContentRendererClient
141    : public extensions::ShellContentRendererClient {
142 public:
143  AthenaContentRendererClient() {}
144  virtual ~AthenaContentRendererClient() {}
145
146  // content::ContentRendererClient:
147  virtual void RenderFrameCreated(content::RenderFrame* render_frame) OVERRIDE {
148    new athena::AthenaRendererPDFHelper(render_frame);
149    extensions::ShellContentRendererClient::RenderFrameCreated(render_frame);
150  }
151
152  virtual const void* CreatePPAPIInterface(
153      const std::string& interface_name) OVERRIDE {
154    if (interface_name == PPB_PDF_INTERFACE)
155      return pdf::PPB_PDF_Impl::GetInterface();
156    return extensions::ShellContentRendererClient::CreatePPAPIInterface(
157        interface_name);
158  }
159};
160
161class AthenaMainDelegate : public extensions::ShellMainDelegate {
162 public:
163  AthenaMainDelegate() {}
164  virtual ~AthenaMainDelegate() {}
165
166 private:
167  // extensions::ShellMainDelegate:
168  virtual content::ContentClient* CreateContentClient() OVERRIDE {
169    return new athena::AthenaContentClient();
170  }
171  virtual content::ContentBrowserClient* CreateShellContentBrowserClient()
172      OVERRIDE {
173    return new AthenaContentBrowserClient();
174  }
175
176  virtual content::ContentRendererClient* CreateShellContentRendererClient()
177      OVERRIDE {
178    return new AthenaContentRendererClient();
179  }
180
181  virtual void InitializeResourceBundle() OVERRIDE {
182    base::FilePath pak_dir;
183    PathService::Get(base::DIR_MODULE, &pak_dir);
184    base::FilePath pak_file =
185        pak_dir.Append(FILE_PATH_LITERAL("athena_resources.pak"));
186    ui::ResourceBundle::InitSharedInstanceWithPakPath(pak_file);
187  }
188
189  DISALLOW_COPY_AND_ASSIGN(AthenaMainDelegate);
190};
191
192int main(int argc, const char** argv) {
193  AthenaMainDelegate delegate;
194  content::ContentMainParams params(&delegate);
195
196  params.argc = argc;
197  params.argv = argv;
198
199  return content::ContentMain(params);
200}
201