Persist Chrome Default Directory (#69921)

This commit is contained in:
Gary Roumanis 2020-11-06 10:54:04 -08:00 committed by GitHub
parent a2fd69cdbf
commit 16daed86c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 48 deletions

View file

@ -296,60 +296,55 @@ class ChromiumLauncher {
}
}
// This is a directory which Chrome uses to store cookies, preferences and
// other session data.
String get _chromeDefaultPath => _fileSystem.path.join('Default');
// This is a JSON file which contains configuration from the browser session,
// such as window position. It is located under the Chrome data-dir folder.
String get _preferencesPath => _fileSystem.path.join('Default', 'preferences');
// The directory that Chrome uses to store local storage information for web apps.
String get _localStoragePath => _fileSystem.path.join('Default', 'Local Storage');
/// Copy Chrome user information from a Chrome session into a per-project
/// cache.
///
/// Note: more detailed docs of the Chrome user preferences store exists here:
/// https://www.chromium.org/developers/design-documents/preferences.
void _cacheUserSessionInformation(Directory userDataDir, Directory cacheDir) {
final File targetPreferencesFile = _fileSystem.file(_fileSystem.path.join(cacheDir?.path ?? '', _preferencesPath));
final File sourcePreferencesFile = _fileSystem.file(_fileSystem.path.join(userDataDir.path, _preferencesPath));
final Directory targetLocalStorageDir = _fileSystem.directory(_fileSystem.path.join(cacheDir?.path ?? '', _localStoragePath));
final Directory sourceLocalStorageDir = _fileSystem.directory(_fileSystem.path.join(userDataDir.path, _localStoragePath));
final Directory targetChromeDefault = _fileSystem.directory(_fileSystem.path.join(cacheDir?.path ?? '', _chromeDefaultPath));
final Directory sourceChromeDefault = _fileSystem.directory(_fileSystem.path.join(userDataDir.path, _chromeDefaultPath));
if (sourcePreferencesFile.existsSync()) {
targetPreferencesFile.parent.createSync(recursive: true);
// If the file contains a crash string, remove it to hide the popup on next run.
final String contents = sourcePreferencesFile.readAsStringSync();
targetPreferencesFile.writeAsStringSync(contents
.replaceFirst('"exit_type":"Crashed"', '"exit_type":"Normal"'));
}
if (sourceLocalStorageDir.existsSync()) {
targetLocalStorageDir.createSync(recursive: true);
if (sourceChromeDefault.existsSync()) {
targetChromeDefault.createSync(recursive: true);
try {
_fileSystemUtils.copyDirectorySync(sourceLocalStorageDir, targetLocalStorageDir);
_fileSystemUtils.copyDirectorySync(sourceChromeDefault, targetChromeDefault);
} on FileSystemException catch (err) {
// This is a best-effort update. Display the message in case the failure is relevant.
// one possible example is a file lock due to multiple running chrome instances.
_logger.printError('Failed to save Chrome preferences: $err');
}
}
final File targetPreferencesFile = _fileSystem.file(_fileSystem.path.join(cacheDir?.path ?? '', _preferencesPath));
final File sourcePreferencesFile = _fileSystem.file(_fileSystem.path.join(userDataDir.path, _preferencesPath));
if (sourcePreferencesFile.existsSync()) {
targetPreferencesFile.parent.createSync(recursive: true);
// If the file contains a crash string, remove it to hide the popup on next run.
final String contents = sourcePreferencesFile.readAsStringSync();
targetPreferencesFile.writeAsStringSync(contents
.replaceFirst('"exit_type":"Crashed"', '"exit_type":"Normal"'));
}
}
/// Restore Chrome user information from a per-project cache into Chrome's
/// user data directory.
void _restoreUserSessionInformation(Directory cacheDir, Directory userDataDir) {
final File sourcePreferencesFile = _fileSystem.file(_fileSystem.path.join(cacheDir.path ?? '', _preferencesPath));
final File targetPreferencesFile = _fileSystem.file(_fileSystem.path.join(userDataDir.path, _preferencesPath));
final Directory sourceLocalStorageDir = _fileSystem.directory(_fileSystem.path.join(cacheDir.path ?? '', _localStoragePath));
final Directory targetLocalStorageDir = _fileSystem.directory(_fileSystem.path.join(userDataDir.path, _localStoragePath));
final Directory sourceChromeDefault = _fileSystem.directory(_fileSystem.path.join(cacheDir.path ?? '', _chromeDefaultPath));
final Directory targetChromeDefault = _fileSystem.directory(_fileSystem.path.join(userDataDir.path, _chromeDefaultPath));
if (sourcePreferencesFile.existsSync()) {
targetPreferencesFile.parent.createSync(recursive: true);
sourcePreferencesFile.copySync(targetPreferencesFile.path);
}
if (sourceLocalStorageDir.existsSync()) {
targetLocalStorageDir.createSync(recursive: true);
_fileSystemUtils.copyDirectorySync(sourceLocalStorageDir, targetLocalStorageDir);
if (sourceChromeDefault.existsSync()) {
targetChromeDefault.createSync(recursive: true);
_fileSystemUtils.copyDirectorySync(sourceChromeDefault, targetChromeDefault);
}
}

View file

@ -5,7 +5,6 @@
import 'dart:async';
import 'package:file/memory.dart';
import 'package:file_testing/file_testing.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/os.dart';
@ -201,13 +200,10 @@ void main() {
..createSync(recursive: true)
..writeAsStringSync('"exit_type":"Crashed"');
final Directory localStorageContentsDirectory = dataDir
final Directory defaultContentDirectory = dataDir
.childDirectory('Default')
.childDirectory('Local Storage')
.childDirectory('leveldb');
localStorageContentsDirectory.createSync(recursive: true);
localStorageContentsDirectory.childFile('LOCK').writeAsBytesSync(<int>[]);
localStorageContentsDirectory.childFile('LOG').writeAsStringSync('contents');
.childDirectory('Foo');
defaultContentDirectory.createSync(recursive: true);
processManager.addCommand(FakeCommand(
command: const <String>[
@ -233,20 +229,14 @@ void main() {
// writes non-crash back to dart_tool
expect(preferencesFile.readAsStringSync(), '"exit_type":"Normal"');
// validate local storage
final Directory storageDir = fileSystem
// validate any Default content is copied
final Directory defaultContentDir = fileSystem
.directory('.tmp_rand0/flutter_tools_chrome_device.rand0')
.childDirectory('Default')
.childDirectory('Local Storage')
.childDirectory('leveldb');
.childDirectory('Foo');
expect(storageDir.existsSync(), true);
expect(storageDir.childFile('LOCK'), exists);
expect(storageDir.childFile('LOCK').readAsBytesSync(), hasLength(0));
expect(storageDir.childFile('LOG'), exists);
expect(storageDir.childFile('LOG').readAsStringSync(), 'contents');
expect(defaultContentDir.existsSync(), true);
});
testWithoutContext('can retry launch when glibc bug happens', () async {