mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
feat(tool): Respect user-data-dir flag from web-browser-flag (#169445)
### Respect user-data-dir flag from web-browser-flag Currently, it's already possible to pass `web-browser-flag` when launching Chrome, but the `user-data-dir` flag doesn't work as expected, and there are some reasons for that. In the implementation made in [PR #104935](https://github.com/flutter/flutter/pull/104935), the `web-browser-flag` is appended at the end of the Chrome launch arguments. For most scenarios, this works fine, as demonstrated in the Chrome unit test below: https://source.chromium.org/chromium/chromium/src/+/main:base/command_line_unittest.cc ``` TEST(CommandLineTest, MultipleSameSwitch) { const CommandLine::CharType* argv[] = { FILE_PATH_LITERAL("program"), FILE_PATH_LITERAL("--foo=one"), // --foo first time FILE_PATH_LITERAL("-baz"), FILE_PATH_LITERAL("--foo=two") // --foo second time }; CommandLine cl(std::size(argv), argv); EXPECT_TRUE(cl.HasSwitch("foo")); EXPECT_TRUE(cl.HasSwitch("baz")); EXPECT_EQ("two", cl.GetSwitchValueASCII("foo")); } ``` In this scenario, the parser will consider the last occurrence of a flag. However, this behavior does not apply to certain flags, because Chrome processes some of them based on the first occurrence, not the last. This is the case for `--user-data-dir`, which is parsed very early during Chrome startup. The proposed code checks whether `--user-data-dir` was provided via `web-browser-flag`, and if so, it uses that value instead of the default `%temp%\flutter_tools_chrome_device.xpto` temporary directory. This also resolve this comment: https://github.com/flutter/flutter/pull/104935#issuecomment-1694486157 Example: `launch.json` ``` { "version": "0.2.0", "configurations": [ { "name": "flutter", "request": "launch", "type": "dart" }, { "name": "flutter (profile mode)", "request": "launch", "type": "dart", "flutterMode": "profile" }, { "name": "flutter (release mode)", "request": "launch", "type": "dart", "flutterMode": "release" }, { "name": "Flutter for web (hot reloadable)", "type": "dart", "request": "launch", "program": "lib/main.dart", "args": [ "-d", "chrome", "--web-port=5000", "--web-experimental-hot-reload", "--web-browser-flag=--user-data-dir=D:\\_Desenv\\flutter_tests\\chrome_profile" ] } ] } ``` `chrome://version` | Before | After | |--------|--------| |  |  | Folder | Before | After | |--------|--------| |  |  | ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
parent
c1c38adec6
commit
aea660d5cd
@ -4,6 +4,7 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:process/process.dart';
|
||||
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart' hide StackTrace;
|
||||
@ -145,6 +146,31 @@ class ChromiumLauncher {
|
||||
/// The executable this launcher will use.
|
||||
String findExecutable() => _browserFinder(_platform, _fileSystem);
|
||||
|
||||
/// Creates a user data directory for Chrome based on provided flags or creates a temporary one.
|
||||
///
|
||||
/// This method handles the creation of Chrome's user data directory in two ways:
|
||||
/// 1. If webBrowserFlags contains a --user-data-dir flag, it uses that directory
|
||||
/// 2. Otherwise, it creates a temporary directory in the system's temp location
|
||||
///
|
||||
/// The user data directory is where Chrome stores user preferences, cookies,
|
||||
/// and other session data. Using a temporary directory ensures a clean state
|
||||
/// for each launch, while allowing custom directories through flags for
|
||||
/// persistent configurations.
|
||||
Directory _createUserDataDirectory(List<String> webBrowserFlags) {
|
||||
if (webBrowserFlags.isNotEmpty) {
|
||||
final String? userDataDirFlag = webBrowserFlags.firstWhereOrNull(
|
||||
(String flag) => flag.startsWith('--user-data-dir='),
|
||||
);
|
||||
|
||||
if (userDataDirFlag != null) {
|
||||
final Directory userDataDir = _fileSystem.directory(userDataDirFlag.split('=')[1]);
|
||||
webBrowserFlags.remove(userDataDirFlag);
|
||||
return userDataDir;
|
||||
}
|
||||
}
|
||||
return _fileSystem.systemTempDirectory.createTempSync('flutter_tools_chrome_device.');
|
||||
}
|
||||
|
||||
/// Launch a Chromium browser to a particular `host` page.
|
||||
///
|
||||
/// [headless] defaults to false, and controls whether we open a headless or
|
||||
@ -189,9 +215,7 @@ class ChromiumLauncher {
|
||||
}
|
||||
}
|
||||
|
||||
final Directory userDataDir = _fileSystem.systemTempDirectory.createTempSync(
|
||||
'flutter_tools_chrome_device.',
|
||||
);
|
||||
final Directory userDataDir = _createUserDataDirectory(webBrowserFlags);
|
||||
|
||||
if (cacheDir != null) {
|
||||
// Seed data dir with previous state.
|
||||
|
||||
@ -931,6 +931,30 @@ void main() {
|
||||
await chrome.close();
|
||||
},
|
||||
);
|
||||
|
||||
testWithoutContext('respects custom user data directory flag', () async {
|
||||
const String customUserDataDir = '/custom/chrome/data/dir';
|
||||
processManager.addCommand(
|
||||
const FakeCommand(
|
||||
command: <String>[
|
||||
'example_chrome',
|
||||
'--user-data-dir=$customUserDataDir',
|
||||
'--remote-debugging-port=12345',
|
||||
...kChromeArgs,
|
||||
'example_url',
|
||||
],
|
||||
stderr: kDevtoolsStderr,
|
||||
),
|
||||
);
|
||||
|
||||
await expectReturnsNormallyLater(
|
||||
chromeLauncher.launch(
|
||||
'example_url',
|
||||
skipCheck: true,
|
||||
webBrowserFlags: <String>['--user-data-dir=$customUserDataDir'],
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Fake chrome connection that fails to get tabs a few times.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user