blob: a439ffaf566544fe3297cef04bd4349dc276fc3f [file] [log] [blame]
Avi Drissman4a8573c2022-09-09 19:35:541// Copyright 2013 The Chromium Authors
[email protected]31e4d8f2013-12-05 11:32:542// 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
Jinho Bangb5216cec2018-01-17 19:43:117#include <memory>
8
[email protected]31e4d8f2013-12-05 11:32:549#include "base/values.h"
avia2f4804a2015-12-24 23:11:1310#include "build/build_config.h"
Yuta Hijikata1290fee22020-11-25 09:46:2811#include "build/chromeos_buildflags.h"
Glen Robertson80d92742024-05-17 05:33:4112#include "chrome/browser/extensions/bookmark_app_util.h"
[email protected]dccba4f82014-05-29 00:52:5613#include "chrome/browser/extensions/extension_sync_service.h"
[email protected]15aadda2013-12-13 15:10:0914#include "chrome/common/extensions/extension_constants.h"
[email protected]31e4d8f2013-12-05 11:32:5415#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
[email protected]f0c8c4992014-05-15 17:37:2616#include "components/pref_registry/pref_registry_syncable.h"
[email protected]489db0842014-01-22 18:20:0317#include "extensions/browser/extension_prefs.h"
macourteau86b29d82015-01-23 13:24:4518#include "extensions/browser/extension_registry.h"
[email protected]05d3647e2014-02-11 04:59:0919#include "extensions/browser/pref_names.h"
[email protected]31e4d8f2013-12-05 11:32:5420#include "extensions/common/extension.h"
21
[email protected]31e4d8f2013-12-05 11:32:5422namespace extensions {
23namespace {
24
25// A preference set by the the NTP to persist the desired launch container type
26// used for apps.
27const char kPrefLaunchType[] = "launchType";
28
29} // namespace
30
31LaunchType GetLaunchType(const ExtensionPrefs* prefs,
32 const Extension* extension) {
Solomon Kinardf5eca782023-03-29 19:52:0333 if (!extension) {
Hidehiko Abe8c6343b2022-02-14 04:15:0334 return LAUNCH_TYPE_INVALID;
Solomon Kinardf5eca782023-03-29 19:52:0335 }
[email protected]31e4d8f2013-12-05 11:32:5436 LaunchType result = LAUNCH_TYPE_DEFAULT;
37
[email protected]a9f74a62014-01-10 06:48:3638 int value = GetLaunchTypePrefValue(prefs, extension->id());
39 if (value >= LAUNCH_TYPE_FIRST && value < NUM_LAUNCH_TYPES)
[email protected]31e4d8f2013-12-05 11:32:5440 result = static_cast<LaunchType>(value);
[email protected]a9f74a62014-01-10 06:48:3641
Ben Wells6dcbe652018-08-24 12:59:0942 // Force hosted apps that are not locally installed to open in tabs.
43 if (extension->is_hosted_app() &&
44 !BookmarkAppIsLocallyInstalled(prefs, extension)) {
45 result = LAUNCH_TYPE_REGULAR;
Christopher Camerone1385742019-04-05 20:37:2546 } else if (result == LAUNCH_TYPE_PINNED) {
jackhou8b77ff0fc2015-02-17 00:53:5547 result = LAUNCH_TYPE_REGULAR;
Christopher Camerone1385742019-04-05 20:37:2548 } else if (result == LAUNCH_TYPE_FULLSCREEN) {
49 result = LAUNCH_TYPE_WINDOW;
dominickn2b10cbd2015-08-20 02:09:1850 }
[email protected]31e4d8f2013-12-05 11:32:5451 return result;
52}
53
[email protected]a9f74a62014-01-10 06:48:3654LaunchType GetLaunchTypePrefValue(const ExtensionPrefs* prefs,
55 const std::string& extension_id) {
56 int value = LAUNCH_TYPE_INVALID;
57 return prefs->ReadPrefAsInteger(extension_id, kPrefLaunchType, &value)
58 ? static_cast<LaunchType>(value) : LAUNCH_TYPE_INVALID;
59}
60
macourteau86b29d82015-01-23 13:24:4561void SetLaunchType(content::BrowserContext* context,
[email protected]31e4d8f2013-12-05 11:32:5462 const std::string& extension_id,
63 LaunchType launch_type) {
[email protected]a9f74a62014-01-10 06:48:3664 DCHECK(launch_type >= LAUNCH_TYPE_FIRST && launch_type < NUM_LAUNCH_TYPES);
65
macourteau86b29d82015-01-23 13:24:4566 ExtensionPrefs::Get(context)->UpdateExtensionPref(
67 extension_id, kPrefLaunchType,
David Bertoni517c487b2023-02-25 05:58:3168 base::Value(static_cast<int>(launch_type)));
[email protected]a9f74a62014-01-10 06:48:3669
70 // Sync the launch type.
macourteau86b29d82015-01-23 13:24:4571 const Extension* extension =
72 ExtensionRegistry::Get(context)
73 ->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING);
74 if (extension)
75 ExtensionSyncService::Get(context)->SyncExtensionChangeIfNeeded(*extension);
[email protected]31e4d8f2013-12-05 11:32:5476}
77
Nancy Wangdcfd56a02022-07-04 17:16:0078apps::LaunchContainer GetLaunchContainer(const ExtensionPrefs* prefs,
79 const Extension* extension) {
80 apps::LaunchContainer manifest_launch_container =
[email protected]31e4d8f2013-12-05 11:32:5481 AppLaunchInfo::GetLaunchContainer(extension);
82
Arthur Sonzognife132ee2024-01-15 11:01:0483 std::optional<apps::LaunchContainer> result;
[email protected]31e4d8f2013-12-05 11:32:5484
Eric Willigers618e1302019-06-23 23:03:4785 if (manifest_launch_container ==
Nancy Wangdcfd56a02022-07-04 17:16:0086 apps::LaunchContainer::kLaunchContainerPanelDeprecated) {
Hiroshige Hayashizakia4756d22020-04-01 06:48:5587 result = manifest_launch_container;
88 } else if (manifest_launch_container ==
Nancy Wangdcfd56a02022-07-04 17:16:0089 apps::LaunchContainer::kLaunchContainerTab) {
[email protected]31e4d8f2013-12-05 11:32:5490 // Look for prefs that indicate the user's choice of launch container. The
91 // app's menu on the NTP provides a UI to set this preference.
92 LaunchType prefs_launch_type = GetLaunchType(prefs, extension);
93
94 if (prefs_launch_type == LAUNCH_TYPE_WINDOW) {
95 // If the pref is set to launch a window (or no pref is set, and
96 // window opening is the default), make the container a window.
Nancy Wangdcfd56a02022-07-04 17:16:0097 result = apps::LaunchContainer::kLaunchContainerWindow;
David Bertoni53445f62024-10-11 19:50:5498#if BUILDFLAG(IS_CHROMEOS)
scottmgd12621f2016-03-18 16:14:2799 } else if (prefs_launch_type == LAUNCH_TYPE_FULLSCREEN) {
[email protected]31e4d8f2013-12-05 11:32:54100 // LAUNCH_TYPE_FULLSCREEN launches in a maximized app window in ash.
101 // For desktop chrome AURA on all platforms we should open the
102 // application in full screen mode in the current tab, on the same
103 // lines as non AURA chrome.
Nancy Wangdcfd56a02022-07-04 17:16:00104 result = apps::LaunchContainer::kLaunchContainerWindow;
[email protected]31e4d8f2013-12-05 11:32:54105#endif
106 } else {
107 // All other launch types (tab, pinned, fullscreen) are
108 // implemented as tabs in a window.
Nancy Wangdcfd56a02022-07-04 17:16:00109 result = apps::LaunchContainer::kLaunchContainerTab;
[email protected]31e4d8f2013-12-05 11:32:54110 }
111 } else {
112 // If a new value for app.launch.container is added, logic for it should be
Nancy Wangdcfd56a02022-07-04 17:16:00113 // added here. apps::LaunchContainer::kLaunchContainerWindow is not
Devlin Cronined380dc42022-01-17 01:23:47114 // present because there is no way to set it in a manifest.
Peter Boström0b2c27d2024-05-14 20:42:56115 NOTREACHED_IN_MIGRATION() << static_cast<int>(manifest_launch_container);
[email protected]31e4d8f2013-12-05 11:32:54116 }
117
118 // All paths should set |result|.
Hans Wennborgd3f6afb2017-12-09 00:16:37119 if (!result) {
[email protected]31e4d8f2013-12-05 11:32:54120 DLOG(FATAL) << "Failed to set a launch container.";
Nancy Wangdcfd56a02022-07-04 17:16:00121 result = apps::LaunchContainer::kLaunchContainerTab;
[email protected]31e4d8f2013-12-05 11:32:54122 }
123
Hans Wennborgd3f6afb2017-12-09 00:16:37124 return *result;
[email protected]31e4d8f2013-12-05 11:32:54125}
126
127bool HasPreferredLaunchContainer(const ExtensionPrefs* prefs,
128 const Extension* extension) {
129 int value = -1;
Nancy Wangdcfd56a02022-07-04 17:16:00130 apps::LaunchContainer manifest_launch_container =
[email protected]31e4d8f2013-12-05 11:32:54131 AppLaunchInfo::GetLaunchContainer(extension);
Devlin Cronined380dc42022-01-17 01:23:47132 return manifest_launch_container ==
Nancy Wangdcfd56a02022-07-04 17:16:00133 apps::LaunchContainer::kLaunchContainerTab &&
Eric Willigers618e1302019-06-23 23:03:47134 prefs->ReadPrefAsInteger(extension->id(), kPrefLaunchType, &value);
[email protected]31e4d8f2013-12-05 11:32:54135}
136
benwells0a78dba2015-05-06 23:11:08137bool LaunchesInWindow(content::BrowserContext* context,
138 const Extension* extension) {
139 return GetLaunchType(ExtensionPrefs::Get(context), extension) ==
140 LAUNCH_TYPE_WINDOW;
141}
142
[email protected]31e4d8f2013-12-05 11:32:54143} // namespace extensions