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.
5 #include "chrome/browser/extensions/launch_util.h"
7 #include "base/values.h"
8 #include "chrome/browser/extensions/extension_sync_service.h"
9 #include "chrome/browser/extensions/extension_util.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/ui/host_desktop.h"
12 #include "chrome/common/extensions/extension_constants.h"
13 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
14 #include "components/pref_registry/pref_registry_syncable.h"
15 #include "extensions/browser/extension_prefs.h"
16 #include "extensions/browser/extension_registry.h"
17 #include "extensions/browser/pref_names.h"
18 #include "extensions/common/extension.h"
21 #include "ash/shell.h"
24 namespace extensions
{
27 // A preference set by the the NTP to persist the desired launch container type
29 const char kPrefLaunchType
[] = "launchType";
33 namespace launch_util
{
36 void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable
* registry
) {
37 registry
->RegisterIntegerPref(pref_names::kBookmarkAppCreationLaunchType
,
41 } // namespace launch_util
43 LaunchType
GetLaunchType(const ExtensionPrefs
* prefs
,
44 const Extension
* extension
) {
45 LaunchType result
= LAUNCH_TYPE_DEFAULT
;
47 int value
= GetLaunchTypePrefValue(prefs
, extension
->id());
48 if (value
>= LAUNCH_TYPE_FIRST
&& value
< NUM_LAUNCH_TYPES
)
49 result
= static_cast<LaunchType
>(value
);
51 #if defined(OS_MACOSX)
52 // Disable opening as window on Mac if:
53 // 1. the extension isn't a platform app, AND
54 // 2. the intended result is open as window, AND
55 // 3. CanHostedAppsOpenInWindows() is false
56 if (!extension
->is_platform_app() && result
== LAUNCH_TYPE_WINDOW
&&
57 !extensions::util::CanHostedAppsOpenInWindows()) {
58 result
= LAUNCH_TYPE_REGULAR
;
61 if (extensions::util::IsNewBookmarkAppsEnabled()) {
62 if (result
== LAUNCH_TYPE_PINNED
)
63 result
= LAUNCH_TYPE_REGULAR
;
64 if (result
== LAUNCH_TYPE_FULLSCREEN
)
65 result
= LAUNCH_TYPE_WINDOW
;
72 LaunchType
GetLaunchTypePrefValue(const ExtensionPrefs
* prefs
,
73 const std::string
& extension_id
) {
74 int value
= LAUNCH_TYPE_INVALID
;
75 return prefs
->ReadPrefAsInteger(extension_id
, kPrefLaunchType
, &value
)
76 ? static_cast<LaunchType
>(value
) : LAUNCH_TYPE_INVALID
;
79 void SetLaunchType(content::BrowserContext
* context
,
80 const std::string
& extension_id
,
81 LaunchType launch_type
) {
82 DCHECK(launch_type
>= LAUNCH_TYPE_FIRST
&& launch_type
< NUM_LAUNCH_TYPES
);
84 ExtensionPrefs::Get(context
)->UpdateExtensionPref(
85 extension_id
, kPrefLaunchType
,
86 new base::FundamentalValue(static_cast<int>(launch_type
)));
88 // Sync the launch type.
89 const Extension
* extension
=
90 ExtensionRegistry::Get(context
)
91 ->GetExtensionById(extension_id
, ExtensionRegistry::EVERYTHING
);
93 ExtensionSyncService::Get(context
)->SyncExtensionChangeIfNeeded(*extension
);
96 LaunchContainer
GetLaunchContainer(const ExtensionPrefs
* prefs
,
97 const Extension
* extension
) {
98 LaunchContainer manifest_launch_container
=
99 AppLaunchInfo::GetLaunchContainer(extension
);
101 const LaunchContainer kInvalidLaunchContainer
=
102 static_cast<LaunchContainer
>(-1);
104 LaunchContainer result
= kInvalidLaunchContainer
;
106 if (manifest_launch_container
== LAUNCH_CONTAINER_PANEL
) {
107 // Apps with app.launch.container = 'panel' should always respect the
109 result
= manifest_launch_container
;
110 } else if (manifest_launch_container
== LAUNCH_CONTAINER_TAB
) {
111 // Look for prefs that indicate the user's choice of launch container. The
112 // app's menu on the NTP provides a UI to set this preference.
113 LaunchType prefs_launch_type
= GetLaunchType(prefs
, extension
);
115 if (prefs_launch_type
== LAUNCH_TYPE_WINDOW
) {
116 // If the pref is set to launch a window (or no pref is set, and
117 // window opening is the default), make the container a window.
118 result
= LAUNCH_CONTAINER_WINDOW
;
120 } else if (prefs_launch_type
== LAUNCH_TYPE_FULLSCREEN
&&
121 chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH
) {
122 // LAUNCH_TYPE_FULLSCREEN launches in a maximized app window in ash.
123 // For desktop chrome AURA on all platforms we should open the
124 // application in full screen mode in the current tab, on the same
125 // lines as non AURA chrome.
126 result
= LAUNCH_CONTAINER_WINDOW
;
129 // All other launch types (tab, pinned, fullscreen) are
130 // implemented as tabs in a window.
131 result
= LAUNCH_CONTAINER_TAB
;
134 // If a new value for app.launch.container is added, logic for it should be
135 // added here. LAUNCH_CONTAINER_WINDOW is not present because there is no
136 // way to set it in a manifest.
137 NOTREACHED() << manifest_launch_container
;
140 // All paths should set |result|.
141 if (result
== kInvalidLaunchContainer
) {
142 DLOG(FATAL
) << "Failed to set a launch container.";
143 result
= LAUNCH_CONTAINER_TAB
;
149 bool HasPreferredLaunchContainer(const ExtensionPrefs
* prefs
,
150 const Extension
* extension
) {
152 LaunchContainer manifest_launch_container
=
153 AppLaunchInfo::GetLaunchContainer(extension
);
154 return manifest_launch_container
== LAUNCH_CONTAINER_TAB
&&
155 prefs
->ReadPrefAsInteger(extension
->id(), kPrefLaunchType
, &value
);
158 bool LaunchesInWindow(content::BrowserContext
* context
,
159 const Extension
* extension
) {
160 return GetLaunchType(ExtensionPrefs::Get(context
), extension
) ==
164 } // namespace extensions