1// Copyright 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#ifndef CHROME_BROWSER_APPS_EPHEMERAL_APP_LAUNCHER_H_
6#define CHROME_BROWSER_APPS_EPHEMERAL_APP_LAUNCHER_H_
7
8#include <string>
9#include <vector>
10
11#include "base/basictypes.h"
12#include "base/callback.h"
13#include "base/scoped_observer.h"
14#include "chrome/browser/extensions/webstore_standalone_installer.h"
15#include "chrome/browser/ui/extensions/extension_enable_flow_delegate.h"
16#include "content/public/browser/web_contents_observer.h"
17
18class ExtensionEnableFlow;
19class Profile;
20
21namespace content {
22class WebContents;
23}
24
25namespace extensions {
26class Extension;
27class ExtensionInstallChecker;
28class ExtensionRegistry;
29}
30
31// EphemeralAppLauncher manages the launching of ephemeral apps. It handles
32// display of a prompt, initiates install of the app (if necessary) and finally
33// launches the app.
34class EphemeralAppLauncher : public extensions::WebstoreStandaloneInstaller,
35                             public content::WebContentsObserver,
36                             public ExtensionEnableFlowDelegate {
37 public:
38  typedef base::Callback<void(extensions::webstore_install::Result result,
39                              const std::string& error)> LaunchCallback;
40
41  // Returns true if launching ephemeral apps is enabled.
42  static bool IsFeatureEnabled();
43
44  // Create for the app launcher.
45  static scoped_refptr<EphemeralAppLauncher> CreateForLauncher(
46      const std::string& webstore_item_id,
47      Profile* profile,
48      gfx::NativeWindow parent_window,
49      const LaunchCallback& callback);
50
51  // Create for a web contents.
52  static scoped_refptr<EphemeralAppLauncher> CreateForWebContents(
53      const std::string& webstore_item_id,
54      content::WebContents* web_contents,
55      const LaunchCallback& callback);
56
57  // Initiate app launch.
58  void Start();
59
60 protected:
61  EphemeralAppLauncher(const std::string& webstore_item_id,
62                       Profile* profile,
63                       gfx::NativeWindow parent_window,
64                       const LaunchCallback& callback);
65  EphemeralAppLauncher(const std::string& webstore_item_id,
66                       content::WebContents* web_contents,
67                       const LaunchCallback& callback);
68
69  virtual ~EphemeralAppLauncher();
70
71  // Creates an install checker. Allows tests to mock the install checker.
72  virtual scoped_ptr<extensions::ExtensionInstallChecker>
73      CreateInstallChecker();
74
75  // WebstoreStandaloneInstaller implementation overridden in tests.
76  virtual scoped_ptr<ExtensionInstallPrompt> CreateInstallUI() OVERRIDE;
77  virtual scoped_ptr<extensions::WebstoreInstaller::Approval> CreateApproval()
78      const OVERRIDE;
79
80 private:
81  friend class base::RefCountedThreadSafe<EphemeralAppLauncher>;
82  friend class EphemeralAppLauncherTest;
83
84  // Returns true if an app that is already installed in extension system can
85  // be launched.
86  bool CanLaunchInstalledApp(const extensions::Extension* extension,
87                             extensions::webstore_install::Result* reason,
88                             std::string* error);
89
90  // Initiates the enable flow for an app before it can be launched.
91  void EnableInstalledApp(const extensions::Extension* extension);
92
93  // After the ephemeral installation or enable flow are complete, attempts to
94  // launch the app and notify the client of the outcome.
95  void MaybeLaunchApp();
96
97  // Launches an app. At this point, it is assumed that the app is enabled and
98  // can be launched.
99  void LaunchApp(const extensions::Extension* extension) const;
100
101  // Navigates to the launch URL of a hosted app in a new browser tab.
102  bool LaunchHostedApp(const extensions::Extension* extension) const;
103
104  // Notifies the client of the launch outcome.
105  void InvokeCallback(extensions::webstore_install::Result result,
106                      const std::string& error);
107
108  // Aborts the ephemeral install and notifies the client of the outcome.
109  void AbortLaunch(extensions::webstore_install::Result result,
110                   const std::string& error);
111
112  // Determines whether the app can be installed ephemerally.
113  void CheckEphemeralInstallPermitted();
114
115  // Install checker callback.
116  void OnInstallChecked(int check_failures);
117
118  // WebstoreStandaloneInstaller implementation.
119  virtual void InitInstallData(
120      extensions::ActiveInstallData* install_data) const OVERRIDE;
121  virtual bool CheckRequestorAlive() const OVERRIDE;
122  virtual const GURL& GetRequestorURL() const OVERRIDE;
123  virtual bool ShouldShowPostInstallUI() const OVERRIDE;
124  virtual bool ShouldShowAppInstalledBubble() const OVERRIDE;
125  virtual content::WebContents* GetWebContents() const OVERRIDE;
126  virtual scoped_refptr<ExtensionInstallPrompt::Prompt> CreateInstallPrompt()
127      const OVERRIDE;
128  virtual bool CheckInlineInstallPermitted(
129      const base::DictionaryValue& webstore_data,
130      std::string* error) const OVERRIDE;
131  virtual bool CheckRequestorPermitted(
132      const base::DictionaryValue& webstore_data,
133      std::string* error) const OVERRIDE;
134  virtual void OnManifestParsed() OVERRIDE;
135  virtual void CompleteInstall(extensions::webstore_install::Result result,
136                               const std::string& error) OVERRIDE;
137
138  // content::WebContentsObserver implementation.
139  virtual void WebContentsDestroyed() OVERRIDE;
140
141  // ExtensionEnableFlowDelegate implementation.
142  virtual void ExtensionEnableFlowFinished() OVERRIDE;
143  virtual void ExtensionEnableFlowAborted(bool user_initiated) OVERRIDE;
144
145  LaunchCallback launch_callback_;
146
147  gfx::NativeWindow parent_window_;
148  scoped_ptr<content::WebContents> dummy_web_contents_;
149
150  scoped_ptr<ExtensionEnableFlow> extension_enable_flow_;
151
152  scoped_ptr<extensions::ExtensionInstallChecker> install_checker_;
153
154  DISALLOW_COPY_AND_ASSIGN(EphemeralAppLauncher);
155};
156
157#endif  // CHROME_BROWSER_APPS_EPHEMERAL_APP_LAUNCHER_H_
158