1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/launch_util.h"
#include <memory>
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/extension_sync_service.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/web_applications/extensions/bookmark_app_util.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/pref_names.h"
#include "extensions/common/extension.h"
namespace extensions {
namespace {
// A preference set by the the NTP to persist the desired launch container type
// used for apps.
const char kPrefLaunchType[] = "launchType";
} // namespace
namespace launch_util {
// static
void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterIntegerPref(pref_names::kBookmarkAppCreationLaunchType,
LAUNCH_TYPE_WINDOW);
}
} // namespace launch_util
LaunchType GetLaunchType(const ExtensionPrefs* prefs,
const Extension* extension) {
LaunchType result = LAUNCH_TYPE_DEFAULT;
int value = GetLaunchTypePrefValue(prefs, extension->id());
if (value >= LAUNCH_TYPE_FIRST && value < NUM_LAUNCH_TYPES)
result = static_cast<LaunchType>(value);
// Force hosted apps that are not locally installed to open in tabs.
if (extension->is_hosted_app() &&
!BookmarkAppIsLocallyInstalled(prefs, extension)) {
result = LAUNCH_TYPE_REGULAR;
}
#if defined(OS_MACOSX)
// Disable opening as window on Mac if:
// 1. the extension isn't a platform app, AND
// 2. the intended result is open as window, AND
// 3. CanHostedAppsOpenInWindows() is false
if (!extension->is_platform_app() && result == LAUNCH_TYPE_WINDOW &&
!extensions::util::CanHostedAppsOpenInWindows()) {
result = LAUNCH_TYPE_REGULAR;
}
#else
if (extensions::util::IsNewBookmarkAppsEnabled()) {
if (result == LAUNCH_TYPE_PINNED)
result = LAUNCH_TYPE_REGULAR;
if (result == LAUNCH_TYPE_FULLSCREEN)
result = LAUNCH_TYPE_WINDOW;
}
#endif
return result;
}
LaunchType GetLaunchTypePrefValue(const ExtensionPrefs* prefs,
const std::string& extension_id) {
int value = LAUNCH_TYPE_INVALID;
return prefs->ReadPrefAsInteger(extension_id, kPrefLaunchType, &value)
? static_cast<LaunchType>(value) : LAUNCH_TYPE_INVALID;
}
void SetLaunchType(content::BrowserContext* context,
const std::string& extension_id,
LaunchType launch_type) {
DCHECK(launch_type >= LAUNCH_TYPE_FIRST && launch_type < NUM_LAUNCH_TYPES);
ExtensionPrefs::Get(context)->UpdateExtensionPref(
extension_id, kPrefLaunchType,
std::make_unique<base::Value>(static_cast<int>(launch_type)));
// Sync the launch type.
const Extension* extension =
ExtensionRegistry::Get(context)
->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING);
if (extension)
ExtensionSyncService::Get(context)->SyncExtensionChangeIfNeeded(*extension);
}
LaunchContainer GetLaunchContainer(const ExtensionPrefs* prefs,
const Extension* extension) {
LaunchContainer manifest_launch_container =
AppLaunchInfo::GetLaunchContainer(extension);
base::Optional<LaunchContainer> result;
if (manifest_launch_container == LAUNCH_CONTAINER_PANEL_DEPRECATED) {
result = manifest_launch_container;
} else if (manifest_launch_container == LAUNCH_CONTAINER_TAB) {
// Look for prefs that indicate the user's choice of launch container. The
// app's menu on the NTP provides a UI to set this preference.
LaunchType prefs_launch_type = GetLaunchType(prefs, extension);
if (prefs_launch_type == LAUNCH_TYPE_WINDOW) {
// If the pref is set to launch a window (or no pref is set, and
// window opening is the default), make the container a window.
result = LAUNCH_CONTAINER_WINDOW;
#if defined(OS_CHROMEOS)
} else if (prefs_launch_type == LAUNCH_TYPE_FULLSCREEN) {
// LAUNCH_TYPE_FULLSCREEN launches in a maximized app window in ash.
// For desktop chrome AURA on all platforms we should open the
// application in full screen mode in the current tab, on the same
// lines as non AURA chrome.
result = LAUNCH_CONTAINER_WINDOW;
#endif
} else {
// All other launch types (tab, pinned, fullscreen) are
// implemented as tabs in a window.
result = LAUNCH_CONTAINER_TAB;
}
} else {
// If a new value for app.launch.container is added, logic for it should be
// added here. LAUNCH_CONTAINER_WINDOW is not present because there is no
// way to set it in a manifest.
NOTREACHED() << manifest_launch_container;
}
// All paths should set |result|.
if (!result) {
DLOG(FATAL) << "Failed to set a launch container.";
result = LAUNCH_CONTAINER_TAB;
}
return *result;
}
bool HasPreferredLaunchContainer(const ExtensionPrefs* prefs,
const Extension* extension) {
int value = -1;
LaunchContainer manifest_launch_container =
AppLaunchInfo::GetLaunchContainer(extension);
return manifest_launch_container == LAUNCH_CONTAINER_TAB &&
prefs->ReadPrefAsInteger(extension->id(), kPrefLaunchType, &value);
}
bool LaunchesInWindow(content::BrowserContext* context,
const Extension* extension) {
return GetLaunchType(ExtensionPrefs::Get(context), extension) ==
LAUNCH_TYPE_WINDOW;
}
} // namespace extensions
|