• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 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 #include "chrome/browser/extensions/launch_util.h"
6 
7 #include "base/command_line.h"
8 #include "base/values.h"
9 #include "chrome/browser/extensions/extension_prefs.h"
10 #include "chrome/browser/ui/host_desktop.h"
11 #include "chrome/common/chrome_switches.h"
12 #include "chrome/common/extensions/extension_constants.h"
13 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
14 #include "extensions/common/extension.h"
15 
16 #if defined(OS_WIN)
17 #include "win8/util/win8_util.h"
18 #endif
19 
20 #if defined(USE_ASH)
21 #include "ash/shell.h"
22 #endif
23 
24 namespace extensions {
25 namespace {
26 
27 // A preference set by the the NTP to persist the desired launch container type
28 // used for apps.
29 const char kPrefLaunchType[] = "launchType";
30 
31 }  // namespace
32 
GetLaunchType(const ExtensionPrefs * prefs,const Extension * extension)33 LaunchType GetLaunchType(const ExtensionPrefs* prefs,
34                          const Extension* extension) {
35   int value = -1;
36   LaunchType result = LAUNCH_TYPE_DEFAULT;
37 
38   // Launch hosted apps as windows by default for streamlined hosted apps.
39   if (CommandLine::ForCurrentProcess()->
40           HasSwitch(switches::kEnableStreamlinedHostedApps) &&
41       extension->id() != extension_misc::kChromeAppId) {
42     result = LAUNCH_TYPE_WINDOW;
43   }
44 
45   if (prefs->ReadPrefAsInteger(extension->id(), kPrefLaunchType, &value) &&
46       (value == LAUNCH_TYPE_PINNED ||
47        value == LAUNCH_TYPE_REGULAR ||
48        value == LAUNCH_TYPE_FULLSCREEN ||
49        value == LAUNCH_TYPE_WINDOW)) {
50     result = static_cast<LaunchType>(value);
51   }
52 #if defined(OS_MACOSX)
53     // App windows are not yet supported on mac.  Pref sync could make
54     // the launch type LAUNCH_TYPE_WINDOW, even if there is no UI to set it
55     // on mac.
56     if (!extension->is_platform_app() && result == LAUNCH_TYPE_WINDOW)
57       result = LAUNCH_TYPE_REGULAR;
58 #endif
59 
60 #if defined(OS_WIN)
61     // We don't support app windows in Windows 8 single window Metro mode.
62     if (win8::IsSingleWindowMetroMode() && result == LAUNCH_TYPE_WINDOW)
63       result = LAUNCH_TYPE_REGULAR;
64 #endif  // OS_WIN
65 
66   return result;
67 }
68 
SetLaunchType(ExtensionPrefs * prefs,const std::string & extension_id,LaunchType launch_type)69 void SetLaunchType(ExtensionPrefs* prefs,
70                    const std::string& extension_id,
71                    LaunchType launch_type) {
72   prefs->UpdateExtensionPref(extension_id, kPrefLaunchType,
73       new base::FundamentalValue(static_cast<int>(launch_type)));
74 }
75 
GetLaunchContainer(const ExtensionPrefs * prefs,const Extension * extension)76 LaunchContainer GetLaunchContainer(const ExtensionPrefs* prefs,
77                                    const Extension* extension) {
78   LaunchContainer manifest_launch_container =
79       AppLaunchInfo::GetLaunchContainer(extension);
80 
81   const LaunchContainer kInvalidLaunchContainer =
82       static_cast<LaunchContainer>(-1);
83 
84   LaunchContainer result = kInvalidLaunchContainer;
85 
86   if (manifest_launch_container == LAUNCH_CONTAINER_PANEL) {
87     // Apps with app.launch.container = 'panel' should always respect the
88     // manifest setting.
89     result = manifest_launch_container;
90   } else if (manifest_launch_container == LAUNCH_CONTAINER_TAB) {
91     // Look for prefs that indicate the user's choice of launch container. The
92     // app's menu on the NTP provides a UI to set this preference.
93     LaunchType prefs_launch_type = GetLaunchType(prefs, extension);
94 
95     if (prefs_launch_type == LAUNCH_TYPE_WINDOW) {
96       // If the pref is set to launch a window (or no pref is set, and
97       // window opening is the default), make the container a window.
98       result = LAUNCH_CONTAINER_WINDOW;
99 #if defined(USE_ASH)
100     } else if (prefs_launch_type == LAUNCH_TYPE_FULLSCREEN &&
101                chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH) {
102       // LAUNCH_TYPE_FULLSCREEN launches in a maximized app window in ash.
103       // For desktop chrome AURA on all platforms we should open the
104       // application in full screen mode in the current tab, on the same
105       // lines as non AURA chrome.
106       result = LAUNCH_CONTAINER_WINDOW;
107 #endif
108     } else {
109       // All other launch types (tab, pinned, fullscreen) are
110       // implemented as tabs in a window.
111       result = LAUNCH_CONTAINER_TAB;
112     }
113   } else {
114     // If a new value for app.launch.container is added, logic for it should be
115     // added here. LAUNCH_CONTAINER_WINDOW is not present because there is no
116     // way to set it in a manifest.
117     NOTREACHED() << manifest_launch_container;
118   }
119 
120   // All paths should set |result|.
121   if (result == kInvalidLaunchContainer) {
122     DLOG(FATAL) << "Failed to set a launch container.";
123     result = LAUNCH_CONTAINER_TAB;
124   }
125 
126   return result;
127 }
128 
HasPreferredLaunchContainer(const ExtensionPrefs * prefs,const Extension * extension)129 bool HasPreferredLaunchContainer(const ExtensionPrefs* prefs,
130                                  const Extension* extension) {
131   int value = -1;
132   LaunchContainer manifest_launch_container =
133       AppLaunchInfo::GetLaunchContainer(extension);
134   return manifest_launch_container == LAUNCH_CONTAINER_TAB &&
135       prefs->ReadPrefAsInteger(extension->id(), kPrefLaunchType, &value);
136 }
137 
138 }  // namespace extensions
139