Commit 59a1ae7c authored by Christopher Cameron's avatar Christopher Cameron Committed by Commit Bot

Remove profile information from app shims

When an app is profile-agnostic, change the Info.plist to:
- Not embed the profile name in the kCFBundleIdentifierKey value
- Not specify the kCrAppModeProfileDirKey value at all
- Not specify the kCrAppModeProfileNameKey value at all
- Strip the profile path out of the kCrAppModeUserDataDirKey value
  - Note that the user data dir still references the launching user's
    home directory, so these shims cannot be moved to /Applications.
  - That is tracked in the separate https://crbug.com/1021237

When searching for an app shim via bundle identifier, allow profile-
agnostic apps to use either the profile-scoped or profile-agnostic
shim. This will allow users to continue using pre-existing shims. A
follow-on patch will add UMAs to query how often this occurs, so we can
decide when to remove that code.

This is all still behind a flag.

Bug: 1001222
Change-Id: I2515fb179b6fde5ffa3b04c32e50fb93c6329860
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1894164
Commit-Queue: ccameron <ccameron@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Cr-Commit-Position: refs/heads/master@{#712700}
parent 6c02a4d2
...@@ -119,11 +119,16 @@ class WebAppShortcutCreator { ...@@ -119,11 +119,16 @@ class WebAppShortcutCreator {
FRIEND_TEST_ALL_PREFIXES(WebAppShortcutCreatorTest, FRIEND_TEST_ALL_PREFIXES(WebAppShortcutCreatorTest,
UpdateBookmarkAppShortcut); UpdateBookmarkAppShortcut);
// Return true if the bundle for this app should be profile-agnostic.
bool IsMultiProfile() const;
// Returns the bundle identifier to use for this app bundle. // Returns the bundle identifier to use for this app bundle.
std::string GetBundleIdentifier() const; std::string GetBundleIdentifier() const;
// Returns the bundle identifier for the internal copy of the bundle. // Returns the profile-scoped app bundle identifier. For multi-profile apps,
std::string GetInternalBundleIdentifier() const; // this will give the bundle identifier for shims that were created before
// multi-profile support was added.
std::string GetProfileScopedBundleIdentifier() const;
// Copies the app loader template into a temporary directory and fills in all // Copies the app loader template into a temporary directory and fills in all
// relevant information. This works around a Finder bug where the app's icon // relevant information. This works around a Finder bug where the app's icon
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/feature_list.h"
#include "base/files/file_enumerator.h" #include "base/files/file_enumerator.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h" #include "base/files/scoped_temp_dir.h"
...@@ -45,6 +46,7 @@ ...@@ -45,6 +46,7 @@
#include "chrome/browser/shell_integration.h" #include "chrome/browser/shell_integration.h"
#include "chrome/common/channel_info.h" #include "chrome/common/channel_info.h"
#include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#import "chrome/common/mac/app_mode_common.h" #import "chrome/common/mac/app_mode_common.h"
...@@ -612,6 +614,29 @@ std::unique_ptr<web_app::ShortcutInfo> BuildShortcutInfoFromBundle( ...@@ -612,6 +614,29 @@ std::unique_ptr<web_app::ShortcutInfo> BuildShortcutInfoFromBundle(
return shortcut_info; return shortcut_info;
} }
base::FilePath GetMultiProfileAppDataDir(base::FilePath app_data_dir) {
// The kCrAppModeUserDataDirKey is expected to be a path in kWebAppDirname,
// and the true user data dir is extracted by going three directories up.
// For profile-agnostic apps, remove this reference to the profile name.
// TODO(https://crbug.com/1021237): Do not specify kCrAppModeUserDataDirKey
// if Chrome is using the default user data dir.
// Strip the app name directory.
base::FilePath app_name_dir = app_data_dir.BaseName();
app_data_dir = app_data_dir.DirName();
// Strip kWebAppDirname.
base::FilePath web_app_dir = app_data_dir.BaseName();
app_data_dir = app_data_dir.DirName();
// Strip the profile and replace it with kNewProfilePath.
app_data_dir = app_data_dir.DirName();
const std::string kNewProfilePath("-");
return app_data_dir.Append(kNewProfilePath)
.Append(web_app_dir)
.Append(app_name_dir);
}
} // namespace } // namespace
namespace web_app { namespace web_app {
...@@ -931,12 +956,19 @@ bool WebAppShortcutCreator::UpdatePlist(const base::FilePath& app_path) const { ...@@ -931,12 +956,19 @@ bool WebAppShortcutCreator::UpdatePlist(const base::FilePath& app_path) const {
forKey:app_mode::kCFBundleShortVersionStringKey]; forKey:app_mode::kCFBundleShortVersionStringKey];
[plist setObject:base::SysUTF8ToNSString(GetBundleIdentifier()) [plist setObject:base::SysUTF8ToNSString(GetBundleIdentifier())
forKey:base::mac::CFToNSCast(kCFBundleIdentifierKey)]; forKey:base::mac::CFToNSCast(kCFBundleIdentifierKey)];
[plist setObject:base::mac::FilePathToNSString(app_data_dir_) if (IsMultiProfile()) {
forKey:app_mode::kCrAppModeUserDataDirKey]; base::FilePath data_dir = GetMultiProfileAppDataDir(app_data_dir_);
[plist setObject:base::mac::FilePathToNSString(info_->profile_path.BaseName()) [plist setObject:base::mac::FilePathToNSString(data_dir)
forKey:app_mode::kCrAppModeProfileDirKey]; forKey:app_mode::kCrAppModeUserDataDirKey];
[plist setObject:base::SysUTF8ToNSString(info_->profile_name) } else {
forKey:app_mode::kCrAppModeProfileNameKey]; [plist setObject:base::mac::FilePathToNSString(app_data_dir_)
forKey:app_mode::kCrAppModeUserDataDirKey];
[plist
setObject:base::mac::FilePathToNSString(info_->profile_path.BaseName())
forKey:app_mode::kCrAppModeProfileDirKey];
[plist setObject:base::SysUTF8ToNSString(info_->profile_name)
forKey:app_mode::kCrAppModeProfileNameKey];
}
[plist setObject:[NSNumber numberWithBool:YES] [plist setObject:[NSNumber numberWithBool:YES]
forKey:app_mode::kLSHasLocalizedDisplayNameKey]; forKey:app_mode::kLSHasLocalizedDisplayNameKey];
[plist setObject:[NSNumber numberWithBool:YES] [plist setObject:[NSNumber numberWithBool:YES]
...@@ -963,7 +995,8 @@ bool WebAppShortcutCreator::UpdateDisplayName( ...@@ -963,7 +995,8 @@ bool WebAppShortcutCreator::UpdateDisplayName(
NSString* bundle_name = base::SysUTF16ToNSString(info_->title); NSString* bundle_name = base::SysUTF16ToNSString(info_->title);
NSString* display_name = base::SysUTF16ToNSString(info_->title); NSString* display_name = base::SysUTF16ToNSString(info_->title);
if (HasExistingExtensionShimForDifferentProfile( if (!IsMultiProfile() &&
HasExistingExtensionShimForDifferentProfile(
GetChromeAppsFolder(), info_->extension_id, info_->profile_path)) { GetChromeAppsFolder(), info_->extension_id, info_->profile_path)) {
display_name = [bundle_name display_name = [bundle_name
stringByAppendingString:base::SysUTF8ToNSString( stringByAppendingString:base::SysUTF8ToNSString(
...@@ -1002,13 +1035,27 @@ bool WebAppShortcutCreator::UpdateIcon(const base::FilePath& app_path) const { ...@@ -1002,13 +1035,27 @@ bool WebAppShortcutCreator::UpdateIcon(const base::FilePath& app_path) const {
std::vector<base::FilePath> WebAppShortcutCreator::GetAppBundlesByIdUnsorted() std::vector<base::FilePath> WebAppShortcutCreator::GetAppBundlesByIdUnsorted()
const { const {
const std::string bundle_id = GetBundleIdentifier(); base::scoped_nsobject<NSMutableArray> urls([[NSMutableArray alloc] init]);
base::ScopedCFTypeRef<CFStringRef> bundle_id_cf(
base::SysUTF8ToCFStringRef(bundle_id)); // If in multi-profile mode, search using the profile-scoped bundle id, in
// case the user has an old shim hanging around.
if (IsMultiProfile()) {
base::ScopedCFTypeRef<CFStringRef> bundle_id_cf(
base::SysUTF8ToCFStringRef(GetProfileScopedBundleIdentifier()));
base::scoped_nsobject<NSArray> bundle_urls(base::mac::CFToNSCast(
LSCopyApplicationURLsForBundleIdentifier(bundle_id_cf.get(), nullptr)));
[urls addObjectsFromArray:bundle_urls];
}
// Retrieve the URLs found by LaunchServices. // Search using LaunchServices using the default bundle id.
base::scoped_nsobject<NSArray> urls(base::mac::CFToNSCast( const std::string bundle_id = GetBundleIdentifier();
LSCopyApplicationURLsForBundleIdentifier(bundle_id_cf.get(), nullptr))); {
base::ScopedCFTypeRef<CFStringRef> bundle_id_cf(
base::SysUTF8ToCFStringRef(bundle_id));
base::scoped_nsobject<NSArray> bundle_urls(base::mac::CFToNSCast(
LSCopyApplicationURLsForBundleIdentifier(bundle_id_cf.get(), nullptr)));
[urls addObjectsFromArray:bundle_urls];
}
// Store only those results corresponding to this user data dir. // Store only those results corresponding to this user data dir.
std::vector<base::FilePath> paths; std::vector<base::FilePath> paths;
...@@ -1070,7 +1117,23 @@ std::vector<base::FilePath> WebAppShortcutCreator::GetAppBundlesById() const { ...@@ -1070,7 +1117,23 @@ std::vector<base::FilePath> WebAppShortcutCreator::GetAppBundlesById() const {
return paths; return paths;
} }
bool WebAppShortcutCreator::IsMultiProfile() const {
// Only PWAs and bookmark apps are multi-profile capable.
if (!info_->url.is_valid())
return false;
return base::FeatureList::IsEnabled(features::kAppShimMultiProfile);
}
std::string WebAppShortcutCreator::GetBundleIdentifier() const { std::string WebAppShortcutCreator::GetBundleIdentifier() const {
if (IsMultiProfile()) {
std::string bundle_id =
base::mac::BaseBundleID() + std::string(".app.") + info_->extension_id;
return bundle_id;
}
return GetProfileScopedBundleIdentifier();
}
std::string WebAppShortcutCreator::GetProfileScopedBundleIdentifier() const {
// Replace spaces in the profile path with hyphen. // Replace spaces in the profile path with hyphen.
std::string normalized_profile_path; std::string normalized_profile_path;
base::ReplaceChars(info_->profile_path.BaseName().value(), " ", "-", base::ReplaceChars(info_->profile_path.BaseName().value(), " ", "-",
...@@ -1083,10 +1146,6 @@ std::string WebAppShortcutCreator::GetBundleIdentifier() const { ...@@ -1083,10 +1146,6 @@ std::string WebAppShortcutCreator::GetBundleIdentifier() const {
return bundle_id; return bundle_id;
} }
std::string WebAppShortcutCreator::GetInternalBundleIdentifier() const {
return GetBundleIdentifier() + "-internal";
}
void WebAppShortcutCreator::RevealAppShimInFinder() const { void WebAppShortcutCreator::RevealAppShimInFinder() const {
// Note that RevealAppShimInFinder is called immediately after requesting to // Note that RevealAppShimInFinder is called immediately after requesting to
// build the app shim. This almost always happens before the app shim has // build the app shim. This almost always happens before the app shim has
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment