Commit 809151ab authored by Christopher Cameron's avatar Christopher Cameron Committed by Commit Bot

MacPWAs: Use AppShimRegistry to populate Profiles menu

Prior to this change, we were asynchronously poking around in the
filesystem to see what apps are installs for which profiles. Just use
the AppShimRegistry.

Delete all of the asynchronous profile loading code, and rename
some of the menu functions to be more clear in their meaning.

TBR=dominickn

Bug: 1001213
Change-Id: I27ec96b2ddcfcd0169fa7663a30b8dc8eb113819
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1929846Reviewed-by: default avatarccameron <ccameron@chromium.org>
Commit-Queue: ccameron <ccameron@chromium.org>
Cr-Commit-Position: refs/heads/master@{#719226}
parent e3ab674b
...@@ -254,9 +254,6 @@ struct ExtensionAppShimHandler::AppState { ...@@ -254,9 +254,6 @@ struct ExtensionAppShimHandler::AppState {
// The profile state for the profiles currently running this app. // The profile state for the profiles currently running this app.
std::map<Profile*, std::unique_ptr<ProfileState>> profiles; std::map<Profile*, std::unique_ptr<ProfileState>> profiles;
// The set of profiles for which this app is installed.
std::set<base::FilePath> installed_profiles;
private: private:
DISALLOW_COPY_AND_ASSIGN(AppState); DISALLOW_COPY_AND_ASSIGN(AppState);
}; };
...@@ -301,14 +298,6 @@ Profile* ExtensionAppShimHandler::Delegate::ProfileForPath( ...@@ -301,14 +298,6 @@ Profile* ExtensionAppShimHandler::Delegate::ProfileForPath(
return profile && profile_manager->IsValidProfile(profile) ? profile : NULL; return profile && profile_manager->IsValidProfile(profile) ? profile : NULL;
} }
void ExtensionAppShimHandler::Delegate::GetProfilesForAppAsync(
const std::string& app_id,
const std::vector<base::FilePath>& profile_paths_to_check,
base::OnceCallback<void(const std::vector<base::FilePath>&)> callback) {
web_app::GetProfilesForAppShim(app_id, profile_paths_to_check,
std::move(callback));
}
void ExtensionAppShimHandler::Delegate::LoadProfileAsync( void ExtensionAppShimHandler::Delegate::LoadProfileAsync(
const base::FilePath& full_path, const base::FilePath& full_path,
base::OnceCallback<void(Profile*)> callback) { base::OnceCallback<void(Profile*)> callback) {
...@@ -1070,9 +1059,11 @@ void ExtensionAppShimHandler::OnBrowserSetLastActive(Browser* browser) { ...@@ -1070,9 +1059,11 @@ void ExtensionAppShimHandler::OnBrowserSetLastActive(Browser* browser) {
// is next to the new-active item). // is next to the new-active item).
if (avatar_menu_) if (avatar_menu_)
avatar_menu_->ActiveBrowserChanged(browser); avatar_menu_->ActiveBrowserChanged(browser);
UpdateProfileMenuItems(); UpdateAllProfileMenus();
}
// Update all multi-profile apps' profile menus. void ExtensionAppShimHandler::UpdateAllProfileMenus() {
RebuildProfileMenuItemsFromAvatarMenu();
for (auto& iter_app : apps_) { for (auto& iter_app : apps_) {
AppState* app_state = iter_app.second.get(); AppState* app_state = iter_app.second.get();
if (app_state->IsMultiProfile()) if (app_state->IsMultiProfile())
...@@ -1080,7 +1071,7 @@ void ExtensionAppShimHandler::OnBrowserSetLastActive(Browser* browser) { ...@@ -1080,7 +1071,7 @@ void ExtensionAppShimHandler::OnBrowserSetLastActive(Browser* browser) {
} }
} }
void ExtensionAppShimHandler::UpdateProfileMenuItems() { void ExtensionAppShimHandler::RebuildProfileMenuItemsFromAvatarMenu() {
if (!avatar_menu_) { if (!avatar_menu_) {
ProfileManager* profile_manager = g_browser_process->profile_manager(); ProfileManager* profile_manager = g_browser_process->profile_manager();
avatar_menu_ = std::make_unique<AvatarMenu>( avatar_menu_ = std::make_unique<AvatarMenu>(
...@@ -1105,44 +1096,7 @@ void ExtensionAppShimHandler::OnAvatarMenuChanged(AvatarMenu* menu) { ...@@ -1105,44 +1096,7 @@ void ExtensionAppShimHandler::OnAvatarMenuChanged(AvatarMenu* menu) {
// Rebuild the profile menu to reflect changes (e.g, added or removed // Rebuild the profile menu to reflect changes (e.g, added or removed
// profiles). // profiles).
DCHECK_EQ(avatar_menu_.get(), menu); DCHECK_EQ(avatar_menu_.get(), menu);
UpdateProfileMenuItems(); UpdateAllProfileMenus();
// Because profiles may have been added or removed, for each app, update the
// list of profiles for which that app is installed.
for (auto& iter_app : apps_) {
const std::string& app_id = iter_app.first;
AppState* app_state = iter_app.second.get();
if (!app_state->IsMultiProfile())
continue;
GetProfilesForAppAsync(
iter_app.first,
base::BindOnce(&ExtensionAppShimHandler::OnGotProfilesForApp,
weak_factory_.GetWeakPtr(), app_id));
}
}
void ExtensionAppShimHandler::GetProfilesForAppAsync(
const std::string& app_id,
base::OnceCallback<void(const std::vector<base::FilePath>&)> callback) {
std::vector<base::FilePath> profile_paths_to_check;
for (const auto& item : profile_menu_items_)
profile_paths_to_check.push_back(item->profile_path);
delegate_->GetProfilesForAppAsync(app_id, profile_paths_to_check,
std::move(callback));
}
void ExtensionAppShimHandler::OnGotProfilesForApp(
const std::string& app_id,
const std::vector<base::FilePath>& profiles) {
auto found_app = apps_.find(app_id);
if (found_app == apps_.end())
return;
AppState* app_state = found_app->second.get();
DCHECK(app_state->IsMultiProfile());
app_state->installed_profiles.clear();
for (const auto& profile_path : profiles)
app_state->installed_profiles.insert(profile_path);
UpdateAppProfileMenu(app_state);
} }
void ExtensionAppShimHandler::UpdateAppProfileMenu(AppState* app_state) { void ExtensionAppShimHandler::UpdateAppProfileMenu(AppState* app_state) {
...@@ -1150,8 +1104,10 @@ void ExtensionAppShimHandler::UpdateAppProfileMenu(AppState* app_state) { ...@@ -1150,8 +1104,10 @@ void ExtensionAppShimHandler::UpdateAppProfileMenu(AppState* app_state) {
// Include in |items| the profiles from |profile_menu_items_| for which this // Include in |items| the profiles from |profile_menu_items_| for which this
// app is installed, sorted by |menu_index|. // app is installed, sorted by |menu_index|.
std::vector<chrome::mojom::ProfileMenuItemPtr> items; std::vector<chrome::mojom::ProfileMenuItemPtr> items;
auto installed_profiles =
AppShimRegistry::Get()->GetInstalledProfilesForApp(app_state->app_id);
for (const auto& item : profile_menu_items_) { for (const auto& item : profile_menu_items_) {
if (app_state->installed_profiles.count(item->profile_path)) if (installed_profiles.count(item->profile_path))
items.push_back(item->Clone()); items.push_back(item->Clone());
} }
std::sort(items.begin(), items.end(), ProfileMenuItemComparator); std::sort(items.begin(), items.end(), ProfileMenuItemComparator);
...@@ -1195,6 +1151,10 @@ ExtensionAppShimHandler::GetOrCreateProfileState( ...@@ -1195,6 +1151,10 @@ ExtensionAppShimHandler::GetOrCreateProfileState(
} }
AppState* app_state = found_app->second.get(); AppState* app_state = found_app->second.get();
// Initialize the profile menu.
if (is_multi_profile)
UpdateAppProfileMenu(app_state);
auto found_profile = app_state->profiles.find(profile); auto found_profile = app_state->profiles.find(profile);
if (found_profile == app_state->profiles.end()) { if (found_profile == app_state->profiles.end()) {
std::unique_ptr<AppShimHost> single_profile_host; std::unique_ptr<AppShimHost> single_profile_host;
...@@ -1208,16 +1168,6 @@ ExtensionAppShimHandler::GetOrCreateProfileState( ...@@ -1208,16 +1168,6 @@ ExtensionAppShimHandler::GetOrCreateProfileState(
app_state->profiles app_state->profiles
.insert(std::make_pair(profile, std::move(new_profile_state))) .insert(std::make_pair(profile, std::move(new_profile_state)))
.first; .first;
// Update the profile menu as each new profile uses this app. Note that
// ideally this should be done when when |multi_profile_host| is created
// above, and should be updated when apps are installed or uninstalled
// (but do not).
if (app_state->IsMultiProfile()) {
UpdateProfileMenuItems();
GetProfilesForAppAsync(
app_id, base::BindOnce(&ExtensionAppShimHandler::OnGotProfilesForApp,
weak_factory_.GetWeakPtr(), app_id));
}
} }
return found_profile->second.get(); return found_profile->second.get();
} }
......
...@@ -57,13 +57,6 @@ class ExtensionAppShimHandler : public AppShimHostBootstrap::Client, ...@@ -57,13 +57,6 @@ class ExtensionAppShimHandler : public AppShimHostBootstrap::Client,
// Return the profile for |path|, only if it is already loaded. // Return the profile for |path|, only if it is already loaded.
virtual Profile* ProfileForPath(const base::FilePath& path); virtual Profile* ProfileForPath(const base::FilePath& path);
// Call |callback| with the list of profiles for which this app is
// installed.
virtual void GetProfilesForAppAsync(
const std::string& app_id,
const std::vector<base::FilePath>& profile_paths_to_check,
base::OnceCallback<void(const std::vector<base::FilePath>&)>);
// Load a profile and call |callback| when completed or failed. // Load a profile and call |callback| when completed or failed.
virtual void LoadProfileAsync(const base::FilePath& path, virtual void LoadProfileAsync(const base::FilePath& path,
base::OnceCallback<void(Profile*)> callback); base::OnceCallback<void(Profile*)> callback);
...@@ -201,8 +194,12 @@ class ExtensionAppShimHandler : public AppShimHostBootstrap::Client, ...@@ -201,8 +194,12 @@ class ExtensionAppShimHandler : public AppShimHostBootstrap::Client,
void set_delegate(Delegate* delegate); void set_delegate(Delegate* delegate);
content::NotificationRegistrar& registrar() { return registrar_; } content::NotificationRegistrar& registrar() { return registrar_; }
// Called when profile menu items may have changed. Rebuilds the profile
// menu item list and sends updated lists to all apps.
void UpdateAllProfileMenus();
// Update |profile_menu_items_| from |avatar_menu_|. Virtual for tests. // Update |profile_menu_items_| from |avatar_menu_|. Virtual for tests.
virtual void UpdateProfileMenuItems(); virtual void RebuildProfileMenuItemsFromAvatarMenu();
// The list of all profiles that might appear in the menu. // The list of all profiles that might appear in the menu.
std::vector<chrome::mojom::ProfileMenuItemPtr> profile_menu_items_; std::vector<chrome::mojom::ProfileMenuItemPtr> profile_menu_items_;
...@@ -264,17 +261,6 @@ class ExtensionAppShimHandler : public AppShimHostBootstrap::Client, ...@@ -264,17 +261,6 @@ class ExtensionAppShimHandler : public AppShimHostBootstrap::Client,
const std::string& app_id, const std::string& app_id,
LoadProfileAppCallback callback); LoadProfileAppCallback callback);
// Check to see for which profile paths in |profile_menu_items_| the app with
// |app_id| is installed, and return them as the argument to |callback|.
void GetProfilesForAppAsync(
const std::string& app_id,
base::OnceCallback<void(const std::vector<base::FilePath>&)> callback);
// Callback for the call to asynchronously query which profiles have an app
// installed.
void OnGotProfilesForApp(const std::string& app_id,
const std::vector<base::FilePath>& profiles);
// Update the profiles menu for the specified host. // Update the profiles menu for the specified host.
void UpdateAppProfileMenu(AppState* app_state); void UpdateAppProfileMenu(AppState* app_state);
......
...@@ -51,15 +51,6 @@ class MockDelegate : public ExtensionAppShimHandler::Delegate { ...@@ -51,15 +51,6 @@ class MockDelegate : public ExtensionAppShimHandler::Delegate {
public: public:
virtual ~MockDelegate() { DCHECK(load_profile_callbacks_.empty()); } virtual ~MockDelegate() { DCHECK(load_profile_callbacks_.empty()); }
void GetProfilesForAppAsync(
const std::string& app_id,
const std::vector<base::FilePath>& profile_paths_to_check,
base::OnceCallback<void(const std::vector<base::FilePath>&)> callback)
override {
get_profiles_for_app_callbacks_.push_back(
base::BindOnce(std::move(callback), profile_paths_to_check));
}
MOCK_METHOD1(ProfileForPath, Profile*(const base::FilePath&)); MOCK_METHOD1(ProfileForPath, Profile*(const base::FilePath&));
void LoadProfileAsync(const base::FilePath& path, void LoadProfileAsync(const base::FilePath& path,
base::OnceCallback<void(Profile*)> callback) override { base::OnceCallback<void(Profile*)> callback) override {
...@@ -141,22 +132,12 @@ class MockDelegate : public ExtensionAppShimHandler::Delegate { ...@@ -141,22 +132,12 @@ class MockDelegate : public ExtensionAppShimHandler::Delegate {
return load_profile_callbacks_.erase(path); return load_profile_callbacks_.erase(path);
} }
bool RunGetProfilesForAppCallback() {
if (get_profiles_for_app_callbacks_.empty())
return false;
std::move(get_profiles_for_app_callbacks_.front()).Run();
get_profiles_for_app_callbacks_.pop_front();
return true;
}
private: private:
ShimLaunchedCallback* launch_shim_callback_capture_ = nullptr; ShimLaunchedCallback* launch_shim_callback_capture_ = nullptr;
ShimTerminatedCallback* terminated_shim_callback_capture_ = nullptr; ShimTerminatedCallback* terminated_shim_callback_capture_ = nullptr;
std::map<base::FilePath, base::OnceCallback<void(Profile*)>> std::map<base::FilePath, base::OnceCallback<void(Profile*)>>
load_profile_callbacks_; load_profile_callbacks_;
std::unique_ptr<AppShimHost> host_for_create_ = nullptr; std::unique_ptr<AppShimHost> host_for_create_ = nullptr;
std::list<base::OnceClosure> get_profiles_for_app_callbacks_;
bool allow_shim_to_connect_ = true; bool allow_shim_to_connect_ = true;
}; };
...@@ -183,7 +164,7 @@ class TestingExtensionAppShimHandler : public ExtensionAppShimHandler { ...@@ -183,7 +164,7 @@ class TestingExtensionAppShimHandler : public ExtensionAppShimHandler {
new_profile_menu_items_ = std::move(new_profile_menu_items); new_profile_menu_items_ = std::move(new_profile_menu_items);
OnAvatarMenuChanged(nullptr); OnAvatarMenuChanged(nullptr);
} }
void UpdateProfileMenuItems() override { void RebuildProfileMenuItemsFromAvatarMenu() override {
profile_menu_items_.clear(); profile_menu_items_.clear();
for (const auto& item : new_profile_menu_items_) for (const auto& item : new_profile_menu_items_)
profile_menu_items_.push_back(item.Clone()); profile_menu_items_.push_back(item.Clone());
...@@ -416,19 +397,16 @@ class ExtensionAppShimHandlerTestBase : public testing::Test { ...@@ -416,19 +397,16 @@ class ExtensionAppShimHandlerTestBase : public testing::Test {
handler_->SetProfileMenuItems(std::move(items)); handler_->SetProfileMenuItems(std::move(items));
} }
printf("Adding A: %s\n", profile_path_a_.value().c_str());
EXPECT_CALL(*delegate_, IsProfileLockedForPath(profile_path_a_)) EXPECT_CALL(*delegate_, IsProfileLockedForPath(profile_path_a_))
.WillRepeatedly(Return(false)); .WillRepeatedly(Return(false));
EXPECT_CALL(*delegate_, ProfileForPath(profile_path_a_)) EXPECT_CALL(*delegate_, ProfileForPath(profile_path_a_))
.WillRepeatedly(Return(&profile_a_)); .WillRepeatedly(Return(&profile_a_));
printf("Adding B: %s\n", profile_path_b_.value().c_str());
EXPECT_CALL(*delegate_, IsProfileLockedForPath(profile_path_b_)) EXPECT_CALL(*delegate_, IsProfileLockedForPath(profile_path_b_))
.WillRepeatedly(Return(false)); .WillRepeatedly(Return(false));
EXPECT_CALL(*delegate_, ProfileForPath(profile_path_b_)) EXPECT_CALL(*delegate_, ProfileForPath(profile_path_b_))
.WillRepeatedly(Return(&profile_b_)); .WillRepeatedly(Return(&profile_b_));
printf("Adding C: %s\n", profile_path_c_.value().c_str());
EXPECT_CALL(*delegate_, IsProfileLockedForPath(profile_path_c_)) EXPECT_CALL(*delegate_, IsProfileLockedForPath(profile_path_c_))
.WillRepeatedly(Return(false)); .WillRepeatedly(Return(false));
EXPECT_CALL(*delegate_, ProfileForPath(profile_path_c_)) EXPECT_CALL(*delegate_, ProfileForPath(profile_path_c_))
...@@ -1063,7 +1041,6 @@ TEST_F(ExtensionAppShimHandlerTestMultiProfile, MultiProfileSelectMenu) { ...@@ -1063,7 +1041,6 @@ TEST_F(ExtensionAppShimHandlerTestMultiProfile, MultiProfileSelectMenu) {
} }
TEST_F(ExtensionAppShimHandlerTestMultiProfile, ProfileMenuOneProfile) { TEST_F(ExtensionAppShimHandlerTestMultiProfile, ProfileMenuOneProfile) {
// Set this app to be installed for profile A.
{ {
auto item_a = chrome::mojom::ProfileMenuItem::New(); auto item_a = chrome::mojom::ProfileMenuItem::New();
item_a->profile_path = profile_path_a_; item_a->profile_path = profile_path_a_;
...@@ -1074,12 +1051,15 @@ TEST_F(ExtensionAppShimHandlerTestMultiProfile, ProfileMenuOneProfile) { ...@@ -1074,12 +1051,15 @@ TEST_F(ExtensionAppShimHandlerTestMultiProfile, ProfileMenuOneProfile) {
handler_->SetProfileMenuItems(std::move(items)); handler_->SetProfileMenuItems(std::move(items));
} }
// Set this app to be installed for profile A.
AppShimRegistry::Get()->OnAppInstalledForProfile(kTestAppIdA,
profile_path_a_);
// When the app activates, a host is created. This will trigger building // When the app activates, a host is created. This will trigger building
// the avatar menu. // the avatar menu.
delegate_->SetHostForCreate(std::move(host_aa_unique_)); delegate_->SetHostForCreate(std::move(host_aa_unique_));
EXPECT_CALL(*delegate_, DoLaunchShim(&profile_a_, extension_a_.get(), false)); EXPECT_CALL(*delegate_, DoLaunchShim(&profile_a_, extension_a_.get(), false));
handler_->OnAppActivated(&profile_a_, kTestAppIdA); handler_->OnAppActivated(&profile_a_, kTestAppIdA);
EXPECT_TRUE(delegate_->RunGetProfilesForAppCallback());
EXPECT_EQ(host_aa_.get(), handler_->FindHost(&profile_a_, kTestAppIdA)); EXPECT_EQ(host_aa_.get(), handler_->FindHost(&profile_a_, kTestAppIdA));
// Launch the shim. // Launch the shim.
...@@ -1092,7 +1072,6 @@ TEST_F(ExtensionAppShimHandlerTestMultiProfile, ProfileMenuOneProfile) { ...@@ -1092,7 +1072,6 @@ TEST_F(ExtensionAppShimHandlerTestMultiProfile, ProfileMenuOneProfile) {
const auto& menu_items = host_aa_->test_app_shim_->profile_menu_items_; const auto& menu_items = host_aa_->test_app_shim_->profile_menu_items_;
// We should have no menu items, because there is only one installed profile. // We should have no menu items, because there is only one installed profile.
EXPECT_FALSE(delegate_->RunGetProfilesForAppCallback());
EXPECT_TRUE(menu_items.empty()); EXPECT_TRUE(menu_items.empty());
// Add profile B to the avatar menu and call the avatar menu observer update // Add profile B to the avatar menu and call the avatar menu observer update
...@@ -1111,19 +1090,18 @@ TEST_F(ExtensionAppShimHandlerTestMultiProfile, ProfileMenuOneProfile) { ...@@ -1111,19 +1090,18 @@ TEST_F(ExtensionAppShimHandlerTestMultiProfile, ProfileMenuOneProfile) {
items.push_back(std::move(item_b)); items.push_back(std::move(item_b));
handler_->SetProfileMenuItems(std::move(items)); handler_->SetProfileMenuItems(std::move(items));
} }
EXPECT_TRUE(delegate_->RunGetProfilesForAppCallback());
EXPECT_FALSE(delegate_->RunGetProfilesForAppCallback());
// We should now have 2 menu items. They should be sorted by menu_index, // We should still only have no menu items, because the app is not installed
// making b be before a. // for multiple profiles.
EXPECT_TRUE(menu_items.empty());
// Now install for profile B.
AppShimRegistry::Get()->OnAppInstalledForProfile(kTestAppIdA,
profile_path_b_);
handler_->OnAppActivated(&profile_b_, kTestAppIdA);
EXPECT_EQ(menu_items.size(), 2u); EXPECT_EQ(menu_items.size(), 2u);
EXPECT_EQ(menu_items[0]->profile_path, profile_path_b_); EXPECT_EQ(menu_items[0]->profile_path, profile_path_b_);
EXPECT_EQ(menu_items[1]->profile_path, profile_path_a_); EXPECT_EQ(menu_items[1]->profile_path, profile_path_a_);
// Activate profile B. This should trigger re-building the avatar menu.
handler_->OnAppActivated(&profile_b_, kTestAppIdA);
EXPECT_TRUE(delegate_->RunGetProfilesForAppCallback());
EXPECT_FALSE(delegate_->RunGetProfilesForAppCallback());
} }
TEST_F(ExtensionAppShimHandlerTestMultiProfile, FindProfileFromBadProfile) { TEST_F(ExtensionAppShimHandlerTestMultiProfile, FindProfileFromBadProfile) {
......
...@@ -32,17 +32,6 @@ bool MaybeRebuildShortcut(const base::CommandLine& command_line); ...@@ -32,17 +32,6 @@ bool MaybeRebuildShortcut(const base::CommandLine& command_line);
void RevealAppShimInFinderForApp(Profile* profile, void RevealAppShimInFinderForApp(Profile* profile,
const extensions::Extension* app); const extensions::Extension* app);
// Callback made by GetProfilesForAppShim.
using GetProfilesForAppShimCallback =
base::OnceCallback<void(const std::vector<base::FilePath>&)>;
// Call |callback| with the subset of |profile_paths_to_check| for which the app
// with |app_id| in installed.
void GetProfilesForAppShim(
const std::string& app_id,
const std::vector<base::FilePath>& profile_paths_to_check,
GetProfilesForAppShimCallback callback);
} // namespace web_app } // namespace web_app
#endif // CHROME_BROWSER_WEB_APPLICATIONS_EXTENSIONS_WEB_APP_EXTENSION_SHORTCUT_MAC_H_ #endif // CHROME_BROWSER_WEB_APPLICATIONS_EXTENSIONS_WEB_APP_EXTENSION_SHORTCUT_MAC_H_
...@@ -153,38 +153,6 @@ void UpdateShortcutsForAllApps(Profile* profile, base::OnceClosure callback) { ...@@ -153,38 +153,6 @@ void UpdateShortcutsForAllApps(Profile* profile, base::OnceClosure callback) {
} }
} }
void GetProfilesForAppShim(
const std::string& app_id,
const std::vector<base::FilePath>& profile_paths_to_check,
GetProfilesForAppShimCallback callback) {
auto io_thread_lambda =
[](const std::string& app_id,
const std::vector<base::FilePath>& profile_paths_to_check,
GetProfilesForAppShimCallback callback) {
base::ScopedBlockingCall scoped_blocking_call(
FROM_HERE, base::BlockingType::MAY_BLOCK);
// Determine if an extension is installed for a profile by whether or
// not the subpath Extensions/|app_id| exists. We do this instead of
// checking the Profile's properties because the Profile may not be
// loaded yet.
std::vector<base::FilePath> profile_paths_with_app;
for (const auto& profile_path : profile_paths_to_check) {
base::FilePath extension_path =
profile_path.AppendASCII(extensions::kInstallDirectoryName)
.AppendASCII(app_id);
if (base::PathExists(extension_path))
profile_paths_with_app.push_back(profile_path);
}
base::PostTask(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(std::move(callback), profile_paths_with_app));
};
internals::GetShortcutIOTaskRunner()->PostTask(
FROM_HERE, base::BindOnce(io_thread_lambda, app_id,
profile_paths_to_check, std::move(callback)));
}
} // namespace web_app } // namespace web_app
namespace chrome { namespace chrome {
......
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