Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / launch_util.cc
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_service.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 "components/user_prefs/pref_registry_syncable.h"
15 #include "extensions/browser/extension_prefs.h"
16 #include "extensions/browser/pref_names.h"
17 #include "extensions/common/extension.h"
18
19 #if defined(OS_WIN)
20 #include "win8/util/win8_util.h"
21 #endif
22
23 #if defined(USE_ASH)
24 #include "ash/shell.h"
25 #endif
26
27 namespace extensions {
28 namespace {
29
30 // A preference set by the the NTP to persist the desired launch container type
31 // used for apps.
32 const char kPrefLaunchType[] = "launchType";
33
34 }  // namespace
35
36 namespace launch_util {
37
38 // static
39 void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
40   registry->RegisterIntegerPref(
41       pref_names::kBookmarkAppCreationLaunchType,
42       LAUNCH_TYPE_WINDOW,
43       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
44 }
45
46 }  // namespace launch_util
47
48 LaunchType GetLaunchType(const ExtensionPrefs* prefs,
49                          const Extension* extension) {
50   LaunchType result = LAUNCH_TYPE_DEFAULT;
51
52   // Launch hosted apps as windows by default for streamlined hosted apps.
53   if (CommandLine::ForCurrentProcess()->
54           HasSwitch(switches::kEnableStreamlinedHostedApps) &&
55       extension->id() != extension_misc::kChromeAppId) {
56     result = LAUNCH_TYPE_WINDOW;
57   }
58
59   int value = GetLaunchTypePrefValue(prefs, extension->id());
60   if (value >= LAUNCH_TYPE_FIRST && value < NUM_LAUNCH_TYPES)
61     result = static_cast<LaunchType>(value);
62
63 #if defined(OS_MACOSX)
64     // App windows are not yet supported on mac.  Pref sync could make
65     // the launch type LAUNCH_TYPE_WINDOW, even if there is no UI to set it
66     // on mac.
67     if (!extension->is_platform_app() && result == LAUNCH_TYPE_WINDOW)
68       result = LAUNCH_TYPE_REGULAR;
69 #endif
70
71 #if defined(OS_WIN)
72     // We don't support app windows in Windows 8 single window Metro mode.
73     if (win8::IsSingleWindowMetroMode() && result == LAUNCH_TYPE_WINDOW)
74       result = LAUNCH_TYPE_REGULAR;
75 #endif  // OS_WIN
76
77   return result;
78 }
79
80 LaunchType GetLaunchTypePrefValue(const ExtensionPrefs* prefs,
81                                   const std::string& extension_id) {
82   int value = LAUNCH_TYPE_INVALID;
83   return prefs->ReadPrefAsInteger(extension_id, kPrefLaunchType, &value)
84       ? static_cast<LaunchType>(value) : LAUNCH_TYPE_INVALID;
85 }
86
87 void SetLaunchType(ExtensionService* service,
88                    const std::string& extension_id,
89                    LaunchType launch_type) {
90   DCHECK(launch_type >= LAUNCH_TYPE_FIRST && launch_type < NUM_LAUNCH_TYPES);
91
92   service->extension_prefs()->UpdateExtensionPref(extension_id, kPrefLaunchType,
93       new base::FundamentalValue(static_cast<int>(launch_type)));
94
95   // Sync the launch type.
96   const Extension* extension = service->GetInstalledExtension(extension_id);
97   if (extension) {
98     ExtensionSyncService::Get(service->profile())->
99         SyncExtensionChangeIfNeeded(*extension);
100   }
101 }
102
103 LaunchContainer GetLaunchContainer(const ExtensionPrefs* prefs,
104                                    const Extension* extension) {
105   LaunchContainer manifest_launch_container =
106       AppLaunchInfo::GetLaunchContainer(extension);
107
108   const LaunchContainer kInvalidLaunchContainer =
109       static_cast<LaunchContainer>(-1);
110
111   LaunchContainer result = kInvalidLaunchContainer;
112
113   if (manifest_launch_container == LAUNCH_CONTAINER_PANEL) {
114     // Apps with app.launch.container = 'panel' should always respect the
115     // manifest setting.
116     result = manifest_launch_container;
117   } else if (manifest_launch_container == LAUNCH_CONTAINER_TAB) {
118     // Look for prefs that indicate the user's choice of launch container. The
119     // app's menu on the NTP provides a UI to set this preference.
120     LaunchType prefs_launch_type = GetLaunchType(prefs, extension);
121
122     if (prefs_launch_type == LAUNCH_TYPE_WINDOW) {
123       // If the pref is set to launch a window (or no pref is set, and
124       // window opening is the default), make the container a window.
125       result = LAUNCH_CONTAINER_WINDOW;
126 #if defined(USE_ASH)
127     } else if (prefs_launch_type == LAUNCH_TYPE_FULLSCREEN &&
128                chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH) {
129       // LAUNCH_TYPE_FULLSCREEN launches in a maximized app window in ash.
130       // For desktop chrome AURA on all platforms we should open the
131       // application in full screen mode in the current tab, on the same
132       // lines as non AURA chrome.
133       result = LAUNCH_CONTAINER_WINDOW;
134 #endif
135     } else {
136       // All other launch types (tab, pinned, fullscreen) are
137       // implemented as tabs in a window.
138       result = LAUNCH_CONTAINER_TAB;
139     }
140   } else {
141     // If a new value for app.launch.container is added, logic for it should be
142     // added here. LAUNCH_CONTAINER_WINDOW is not present because there is no
143     // way to set it in a manifest.
144     NOTREACHED() << manifest_launch_container;
145   }
146
147   // All paths should set |result|.
148   if (result == kInvalidLaunchContainer) {
149     DLOG(FATAL) << "Failed to set a launch container.";
150     result = LAUNCH_CONTAINER_TAB;
151   }
152
153   return result;
154 }
155
156 bool HasPreferredLaunchContainer(const ExtensionPrefs* prefs,
157                                  const Extension* extension) {
158   int value = -1;
159   LaunchContainer manifest_launch_container =
160       AppLaunchInfo::GetLaunchContainer(extension);
161   return manifest_launch_container == LAUNCH_CONTAINER_TAB &&
162       prefs->ReadPrefAsInteger(extension->id(), kPrefLaunchType, &value);
163 }
164
165 }  // namespace extensions