0

Save the launch info in LaunchPlatformAppWithFileHandler.

The file app calls LaunchPlatformAppWithFileHandler to launch the
Chrome app to open the file:
https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ash/file_manager/file_tasks.cc;l=583?q=LaunchPlatformAppWithFileHandler&sq=&ss=chromium%2Fchromium%2Fsrc

Modify LaunchPlatformAppWithFileHandler to call the full restore
interface to save the launch info.

Modify the full restsore component to save the parameter of
LaunchPlatformAppWithFileHandler.

Modify LaunchSystemWebAppOrChromeApp to call
LaunchPlatformAppWithFileHandler to restore/launch the Chrome app to
to open the file if `handler_id` has a value.

BUG=1230978

Change-Id: Icb9900369f209bb912b98ab7e4671f71147b6337
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3052330
Commit-Queue: Nancy Wang <nancylingwang@chromium.org>
Reviewed-by: Dominick Ng <dominickn@chromium.org>
Cr-Commit-Position: refs/heads/master@{#905122}
This commit is contained in:
Nancy Wang
2021-07-26 03:37:01 +00:00
committed by Chromium LUCI CQ
parent 2c38b6bad3
commit 4740d26573
9 changed files with 106 additions and 1 deletions

@ -49,7 +49,10 @@ static_library("apps") {
]
if (is_chromeos_ash) {
deps += [ "//components/user_manager" ]
deps += [
"//components/full_restore",
"//components/user_manager",
]
}
}

@ -2,6 +2,7 @@ include_rules = [
"+content/public/browser",
"+content/public/common",
"+content/public/test",
"+components/full_restore",
"+components/services/app_service/public",
"+components/keyed_service",
"+components/user_manager",

@ -50,6 +50,8 @@
#include "url/gurl.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "components/full_restore/app_launch_info.h"
#include "components/full_restore/full_restore_utils.h"
#include "components/user_manager/user_manager.h"
#endif
@ -475,6 +477,12 @@ void LaunchPlatformAppWithFileHandler(
const Extension* app,
const std::string& handler_id,
const std::vector<base::FilePath>& entry_paths) {
#if BUILDFLAG(IS_CHROMEOS_ASH)
auto launch_info = std::make_unique<full_restore::AppLaunchInfo>(
app->id(), handler_id, entry_paths);
full_restore::SaveAppLaunchInfo(context->GetPath(), std::move(launch_info));
#endif
scoped_refptr<PlatformAppPathLauncher> launcher =
new PlatformAppPathLauncher(context, app, entry_paths);
launcher->LaunchWithHandler(handler_id);

@ -7,6 +7,7 @@
#include <utility>
#include <vector>
#include "apps/launcher.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/threading/thread_task_runner_handle.h"
@ -17,7 +18,9 @@
#include "chrome/browser/profiles/profile.h"
#include "components/full_restore/full_restore_read_handler.h"
#include "components/services/app_service/public/cpp/types_util.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
namespace chromeos {
@ -179,6 +182,19 @@ void AppLaunchHandler::LaunchSystemWebAppOrChromeApp(
for (const auto& it : launch_list) {
RecordRestoredAppLaunch(GetHistogrameAppType(app_type));
if (it.second->handler_id.has_value()) {
const extensions::Extension* extension =
extensions::ExtensionRegistry::Get(profile_)->GetInstalledExtension(
app_id);
if (extension) {
DCHECK(it.second->file_paths.has_value());
apps::LaunchPlatformAppWithFileHandler(profile_, extension,
it.second->handler_id.value(),
it.second->file_paths.value());
}
continue;
}
DCHECK(it.second->container.has_value());
DCHECK(it.second->disposition.has_value());
DCHECK(it.second->display_id.has_value());

@ -59,6 +59,11 @@ AppLaunchInfo::AppLaunchInfo(const std::string& app_id,
display_id(display_id),
intent(std::move(intent)) {}
AppLaunchInfo::AppLaunchInfo(const std::string& app_id,
const std::string& handler_id,
std::vector<base::FilePath> files)
: app_id(app_id), handler_id(handler_id), file_paths(std::move(files)) {}
AppLaunchInfo::~AppLaunchInfo() = default;
} // namespace full_restore

@ -47,6 +47,10 @@ struct COMPONENT_EXPORT(FULL_RESTORE) AppLaunchInfo {
int32_t arc_session_id,
int64_t display_id);
AppLaunchInfo(const std::string& app_id,
const std::string& handler_id,
std::vector<base::FilePath> launch_files);
AppLaunchInfo(const AppLaunchInfo&) = delete;
AppLaunchInfo& operator=(const AppLaunchInfo&) = delete;
@ -59,6 +63,7 @@ struct COMPONENT_EXPORT(FULL_RESTORE) AppLaunchInfo {
absl::optional<int32_t> disposition;
absl::optional<int32_t> arc_session_id;
absl::optional<int64_t> display_id;
absl::optional<std::string> handler_id;
absl::optional<std::vector<GURL>> urls;
absl::optional<int32_t> active_tab_index;
absl::optional<std::vector<base::FilePath>> file_paths;

@ -20,6 +20,7 @@ constexpr char kEventFlagKey[] = "event_flag";
constexpr char kContainerKey[] = "container";
constexpr char kDispositionKey[] = "disposition";
constexpr char kDisplayIdKey[] = "display_id";
constexpr char kHandlerIdKey[] = "handler_id";
constexpr char kUrlsKey[] = "urls";
constexpr char kActiveTabIndexKey[] = "active_tab_index";
constexpr char kIntentKey[] = "intent";
@ -86,6 +87,15 @@ absl::optional<uint32_t> GetUIntValueFromDict(const base::DictionaryValue& dict,
return result;
}
absl::optional<std::string> GetStringValueFromDict(
const base::DictionaryValue& dict,
const std::string& key_name) {
if (!dict.HasKey(key_name))
return absl::nullopt;
const std::string* value = dict.FindStringKey(key_name);
return value ? absl::optional<std::string>(*value) : absl::nullopt;
}
absl::optional<std::u16string> GetU16StringValueFromDict(
const base::DictionaryValue& dict,
const std::string& key_name) {
@ -239,6 +249,7 @@ AppRestoreData::AppRestoreData(base::Value&& value) {
container = GetIntValueFromDict(*data_dict, kContainerKey);
disposition = GetIntValueFromDict(*data_dict, kDispositionKey);
display_id = GetDisplayIdFromDict(*data_dict);
handler_id = GetStringValueFromDict(*data_dict, kHandlerIdKey);
urls = GetUrlsFromDict(*data_dict);
active_tab_index = GetIntValueFromDict(*data_dict, kActiveTabIndexKey);
file_paths = GetFilePathsFromDict(*data_dict);
@ -272,6 +283,7 @@ AppRestoreData::AppRestoreData(std::unique_ptr<AppLaunchInfo> app_launch_info) {
container = std::move(app_launch_info->container);
disposition = std::move(app_launch_info->disposition);
display_id = std::move(app_launch_info->display_id);
handler_id = std::move(app_launch_info->handler_id);
urls = std::move(app_launch_info->urls);
active_tab_index = std::move(app_launch_info->active_tab_index);
file_paths = std::move(app_launch_info->file_paths);
@ -296,6 +308,9 @@ std::unique_ptr<AppRestoreData> AppRestoreData::Clone() const {
if (display_id.has_value())
data->display_id = display_id.value();
if (handler_id.has_value())
data->handler_id = handler_id.value();
if (urls.has_value())
data->urls = urls.value();
@ -367,6 +382,9 @@ base::Value AppRestoreData::ConvertToValue() const {
base::NumberToString(display_id.value()));
}
if (handler_id.has_value())
launch_info_dict.SetStringKey(kHandlerIdKey, handler_id.value());
if (urls.has_value() && !urls.value().empty()) {
base::Value urls_list(base::Value::Type::LIST);
for (auto& url : urls.value())
@ -513,6 +531,7 @@ std::unique_ptr<AppLaunchInfo> AppRestoreData::GetAppLaunchInfo(
app_launch_info->container = container;
app_launch_info->disposition = disposition;
app_launch_info->display_id = display_id;
app_launch_info->handler_id = handler_id;
app_launch_info->urls = urls;
app_launch_info->file_paths = file_paths;
if (intent.has_value())

@ -83,6 +83,7 @@ struct COMPONENT_EXPORT(FULL_RESTORE) AppRestoreData {
absl::optional<int32_t> container;
absl::optional<int32_t> disposition;
absl::optional<int64_t> display_id;
absl::optional<std::string> handler_id;
absl::optional<std::vector<GURL>> urls;
absl::optional<int32_t> active_tab_index;
absl::optional<apps::mojom::IntentPtr> intent;

@ -48,6 +48,11 @@ constexpr int32_t kArcSessionId2 = kArcSessionIdOffsetForRestoredLaunching + 1;
constexpr int32_t kArcTaskId1 = 666;
constexpr int32_t kArcTaskId2 = 888;
constexpr char kFilePath1[] = "path1";
constexpr char kFilePath2[] = "path2";
constexpr char kHandlerId[] = "audio";
constexpr char kExampleUrl1[] = "https://www.example1.com";
constexpr char kExampleUrl2[] = "https://www.example2.com";
@ -221,6 +226,16 @@ class FullRestoreReadAndSaveTest : public testing::Test {
full_restore::SaveAppLaunchInfo(file_path, std::move(launch_info));
}
void AddChromeAppLaunchInfo(const base::FilePath& file_path) {
std::unique_ptr<AppLaunchInfo> app_launch_info =
std::make_unique<AppLaunchInfo>(
kAppId, kHandlerId,
std::vector<base::FilePath>{base::FilePath(kFilePath1),
base::FilePath(kFilePath2)});
app_launch_info->window_id = kId1;
full_restore::SaveAppLaunchInfo(file_path, std::move(app_launch_info));
}
void CreateWindowInfo(int32_t id,
int32_t index,
ash::AppType app_type = ash::AppType::BROWSER) {
@ -654,4 +669,36 @@ TEST_F(FullRestoreReadAndSaveTest, ReadBrowserRestoreData) {
EXPECT_EQ(data->active_tab_index.value(), active_tab_index);
}
TEST_F(FullRestoreReadAndSaveTest, ReadChromeAppRestoreData) {
FullRestoreSaveHandler* save_handler = FullRestoreSaveHandler::GetInstance();
base::OneShotTimer* timer = save_handler->GetTimerForTesting();
// Add Chrome app launch info.
AddChromeAppLaunchInfo(GetPath());
EXPECT_TRUE(timer->IsRunning());
timer->FireNow();
task_environment().RunUntilIdle();
// Now read from the file.
ReadFromFile(GetPath());
const auto* restore_data = GetRestoreData(GetPath());
ASSERT_TRUE(restore_data);
const auto& launch_list = restore_data->app_id_to_launch_list();
EXPECT_EQ(1u, launch_list.size());
const auto launch_list_it = launch_list.find(kAppId);
EXPECT_TRUE(launch_list_it != launch_list.end());
EXPECT_EQ(1u, launch_list_it->second.size());
const auto app_restore_data_it = launch_list_it->second.find(kId1);
EXPECT_TRUE(app_restore_data_it != launch_list_it->second.end());
const auto& data = app_restore_data_it->second;
EXPECT_TRUE(data->handler_id.has_value());
EXPECT_EQ(kHandlerId, data->handler_id.value());
EXPECT_TRUE(data->file_paths.has_value());
EXPECT_EQ(2u, data->file_paths.value().size());
EXPECT_EQ(base::FilePath(kFilePath1), data->file_paths.value()[0]);
EXPECT_EQ(base::FilePath(kFilePath2), data->file_paths.value()[1]);
}
} // namespace full_restore