Commit 81a6856f authored by Mohammad Refaat's avatar Mohammad Refaat Committed by Commit Bot

Reland "Add Crash Restoration support for multi-window"

This reverts commit 55996955.

Reason for revert: Fixed the crash, which was caused by deleting
the temp folder.

Original change's description:
> Revert "Add Crash Restoration support for multi-window"
>
> This reverts commit 64875586.
>
> Reason for revert: Speculatively reverting due to https://crbug.com/1132229.
>
> Original change's description:
> > Add Crash Restoration support for multi-window
> >
> > After a crash info bar will be presented on all foreground scenes
> > if the user choose to restore all foreground windows will be restored.
> > if not all windows tabs for all windows which were opened on the last
> > run will be added to the recent closed tabs.
> >
> > Bug: 1126311, 1114179
> > Change-Id: I80623012dc132e2702004d2dbc0bbcb410a7d91c
> > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2415929
> > Commit-Queue: Mohammad Refaat <mrefaat@chromium.org>
> > Reviewed-by: Mark Cogan <marq@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#810406}
>
> TBR=marq@chromium.org,mrefaat@chromium.org
>
> Change-Id: I4045617e7eb138e0212f8b1d1062df7ce0b45f74
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: 1126311
> Bug: 1114179
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2428972
> Reviewed-by: Jan Wilken Dörrie <jdoerrie@chromium.org>
> Commit-Queue: Jan Wilken Dörrie <jdoerrie@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#810536}

TBR=marq@chromium.org,mrefaat@chromium.org,jdoerrie@chromium.org


Bug: 1126311, 1132229
Bug: 1114179
Change-Id: I911b88c3b57b54aff678648d2da7a6b03038610f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2431454Reviewed-by: default avatarMark Cogan <marq@chromium.org>
Reviewed-by: default avatarJan Wilken Dörrie <jdoerrie@chromium.org>
Reviewed-by: default avatarMohammad Refaat <mrefaat@chromium.org>
Commit-Queue: Mohammad Refaat <mrefaat@chromium.org>
Cr-Commit-Position: refs/heads/master@{#811813}
parent dda72628
......@@ -469,8 +469,16 @@ void MainControllerAuthenticationServiceDelegate::ClearBrowsingData(
// browser state.
BOOL needRestoration = NO;
if (isPostCrashLaunch) {
needRestoration = [CrashRestoreHelper
moveAsideSessionInformationForBrowserState:chromeBrowserState];
if (IsMultiwindowSupported()) {
NSSet<NSString*>* sessions =
[[PreviousSessionInfo sharedInstance] connectedSceneSessionsIDs];
needRestoration =
[CrashRestoreHelper moveAsideSessions:sessions
forBrowserState:chromeBrowserState];
} else {
needRestoration = [CrashRestoreHelper
moveAsideSessionInformationForBrowserState:chromeBrowserState];
}
}
[[PreviousSessionInfo sharedInstance] resetConnectedSceneSessionIDs];
......
......@@ -75,6 +75,7 @@ source_set("crash_report_internal") {
"//ios/chrome/browser/sessions:serialisation",
"//ios/chrome/browser/sessions:session_service",
"//ios/chrome/browser/ui/infobars:feature_flags",
"//ios/chrome/browser/ui/main:scene_state_header",
"//ios/chrome/browser/ui/util:multiwindow_util",
"//ios/chrome/browser/web:tab_id_tab_helper",
"//ios/chrome/browser/web_state_list",
......@@ -108,6 +109,7 @@ source_set("unit_tests") {
"//ios/chrome/browser/metrics:previous_session_info",
"//ios/chrome/browser/sessions:serialisation",
"//ios/chrome/browser/sessions:session_service",
"//ios/chrome/browser/ui/util:multiwindow_util",
"//ios/chrome/browser/web_state_list:test_support",
"//ios/chrome/browser/web_state_list:web_state_list",
"//ios/chrome/test/ocmock",
......
......@@ -15,12 +15,21 @@ class ChromeBrowserState;
- (instancetype)initWithBrowser:(Browser*)browser;
// Saves the session information stored on disk in temporary files and will
// then delete those from their default location. This will ensure that the
// user will then start from scratch, while allowing restoring their old
// sessions. This method has to be called before the browser is created, or the
// session information will be overwritten.
// Returns |YES| if the deletetion and backup was successful.
// Saves the session information stored on disk for sessions with |sessionIDs|
// in temporary files and will then delete those from their default location.
// This will ensure that the user will then start from scratch, while allowing
// restoring their old sessions. This method has to be called before the browser
// is created, or the session information will be overwritten.
// |sessionIDs| can be nil when multiple windows are not supported, and in that
// case only the default session will be moved.
// Returns |YES| if the at least one session deletion was successful.
+ (BOOL)moveAsideSessions:(NSSet<NSString*>*)sessionIDs
forBrowserState:(ChromeBrowserState*)browserState;
// Move the session information for Legacy non multiwindow supported OS.
// This method deletes the session from its default location, while
// allowing restoring it back later.
// Returns |YES| if the delettion and backup was successful.
+ (BOOL)moveAsideSessionInformationForBrowserState:
(ChromeBrowserState*)browserState;
......
......@@ -27,12 +27,17 @@
#include "ios/chrome/browser/infobars/infobar_manager_impl.h"
#include "ios/chrome/browser/infobars/infobar_utils.h"
#import "ios/chrome/browser/main/browser.h"
#import "ios/chrome/browser/main/browser_list.h"
#import "ios/chrome/browser/main/browser_list_factory.h"
#include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h"
#import "ios/chrome/browser/sessions/session_ios.h"
#import "ios/chrome/browser/sessions/session_restoration_browser_agent.h"
#import "ios/chrome/browser/sessions/session_service_ios.h"
#import "ios/chrome/browser/sessions/session_window_ios.h"
#import "ios/chrome/browser/ui/infobars/infobar_feature.h"
#import "ios/chrome/browser/ui/main/scene_state.h"
#import "ios/chrome/browser/ui/main/scene_state_browser_agent.h"
#import "ios/chrome/browser/ui/util/multi_window_support.h"
#include "ios/chrome/browser/web_state_list/web_state_list.h"
#include "ios/chrome/grit/ios_theme_resources.h"
#import "ios/web/public/web_state.h"
......@@ -54,16 +59,32 @@
// case of success, NO otherwise.
+ (BOOL)deleteSessionForBrowserState:(ChromeBrowserState*)browserState
backupFile:(NSString*)file;
// Returns the path where the sessions for the main browser state are backed up.
+ (NSString*)sessionBackupPath;
// Returns the path where the sessions with |sessionID| for the main browser
// state are backed up.
+ (NSString*)backupPathForSessionID:(NSString*)sessionID;
// Returns a list of IDs for all backed up sessions.
+ (NSArray<NSString*>*)backedupSessionIDs;
// Restores the sessions after a crash. It should only be called if
// |moveAsideSessionInformation| for the browser state of the current browser
// was successful.
// |moveAsideSessions:forBrowserState| for the browser state of the current
// browser was successful.
- (BOOL)restoreSessionsAfterCrash;
// The Browser instance associated with this crash restore helper.
@property(nonatomic) Browser* browser;
@end
namespace {
NSString* const kSessionBackupFileName =
@"session.bak"; // The session file name on disk.
NSString* const kSessionBackupDirectoryName =
@"Sessions"; // The name for directory which contains all session backup
// subdirectories for multiple sessions.
class InfoBarManagerObserverBridge : infobars::InfoBarManager::Observer {
public:
InfoBarManagerObserverBridge(infobars::InfoBarManager* infoBarManager,
......@@ -240,6 +261,72 @@ int SessionCrashedInfoBarDelegate::GetIconId() const {
_infoBarBridge.reset(new InfoBarManagerObserverBridge(infoBarManager, self));
}
+ (BOOL)deleteSessions:(NSSet<NSString*>*)sessionIDs
forBrowserState:(ChromeBrowserState*)browserState
shouldBackup:(BOOL)shouldBackup {
BOOL partialSuccess = NO;
NSString* stashPath =
base::SysUTF8ToNSString(browserState->GetStatePath().value());
NSString* backupPath = nil;
for (NSString* sessionID in sessionIDs) {
NSString* sessionPath =
[SessionServiceIOS sessionPathForSessionID:sessionID
directory:stashPath];
if (shouldBackup)
backupPath = [self backupPathForSessionID:sessionID];
partialSuccess |= [[self class] deleteSessionFromPath:sessionPath
backupFile:backupPath];
}
return partialSuccess;
}
+ (BOOL)deleteSessionFromPath:(NSString*)sessionPath
backupFile:(NSString*)backupPath {
NSFileManager* fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:sessionPath])
return NO;
if (backupPath) {
NSError* error = nil;
BOOL fileOperationSuccess = [fileManager removeItemAtPath:backupPath
error:&error];
NSInteger errorCode = fileOperationSuccess ? 0 : [error code];
base::UmaHistogramSparse("TabRestore.error_remove_backup_at_path",
errorCode);
if (!fileOperationSuccess && errorCode != NSFileNoSuchFileError) {
return NO;
}
// Create the backup directory, if it doesn't exist.
NSString* directory = [backupPath stringByDeletingLastPathComponent];
[fileManager createDirectoryAtPath:directory
withIntermediateDirectories:YES
attributes:nil
error:&error];
fileOperationSuccess = [fileManager moveItemAtPath:sessionPath
toPath:backupPath
error:&error];
errorCode = fileOperationSuccess ? 0 : [error code];
base::UmaHistogramSparse("TabRestore.error_move_session_at_path_to_backup",
errorCode);
if (!fileOperationSuccess) {
return NO;
}
} else {
NSError* error;
BOOL fileOperationSuccess = [fileManager removeItemAtPath:sessionPath
error:&error];
NSInteger errorCode = fileOperationSuccess ? 0 : [error code];
base::UmaHistogramSparse("TabRestore.error_remove_session_at_path",
errorCode);
if (!fileOperationSuccess) {
return NO;
}
}
return YES;
}
+ (BOOL)deleteSessionForBrowserState:(ChromeBrowserState*)browserState
backupFile:(NSString*)file {
NSString* stashPath =
......@@ -258,6 +345,7 @@ int SessionCrashedInfoBarDelegate::GetIconId() const {
if (!fileOperationSuccess && errorCode != NSFileNoSuchFileError) {
return NO;
}
fileOperationSuccess =
[fileManager moveItemAtPath:sessionPath toPath:file error:&error];
errorCode = fileOperationSuccess ? 0 : [error code];
......@@ -280,36 +368,133 @@ int SessionCrashedInfoBarDelegate::GetIconId() const {
return YES;
}
+ (NSString*)sessionBackupPath {
+ (NSString*)backupPathForSessionID:(NSString*)sessionID {
NSString* tmpDirectory = NSTemporaryDirectory();
if (!sessionID || !sessionID.length)
return [tmpDirectory stringByAppendingPathComponent:kSessionBackupFileName];
return [NSString pathWithComponents:@[
tmpDirectory, kSessionBackupDirectoryName, sessionID, kSessionBackupFileName
]];
}
+ (NSString*)backupSessionsDirectoryPath {
NSString* tmpDirectory = NSTemporaryDirectory();
return [tmpDirectory stringByAppendingPathComponent:@"session.bak"];
return
[tmpDirectory stringByAppendingPathComponent:kSessionBackupDirectoryName];
}
+ (NSArray<NSString*>*)backedupSessionPaths {
if (!IsMultiwindowSupported())
return @[ [[self class] backupPathForSessionID:nil] ];
NSString* sessionsDirectoryPath = [[self class] backupSessionsDirectoryPath];
NSArray<NSString*>* sessionsIDs = [[NSFileManager defaultManager]
contentsOfDirectoryAtPath:sessionsDirectoryPath
error:nil];
NSMutableArray<NSString*>* sessionFilePaths =
[[NSMutableArray alloc] initWithCapacity:sessionsIDs.count];
for (NSString* sessionID in sessionsIDs) {
[sessionFilePaths
addObject:[[self class] backupPathForSessionID:sessionID]];
}
return sessionFilePaths;
}
+ (NSArray<NSString*>*)backedupSessionIDs {
if (!IsMultiwindowSupported())
return @[ @"" ];
NSString* sessionsDirectoryPath = [[self class] backupSessionsDirectoryPath];
return [[NSFileManager defaultManager]
contentsOfDirectoryAtPath:sessionsDirectoryPath
error:nil];
}
+ (BOOL)moveAsideSessionInformationForBrowserState:
(ChromeBrowserState*)browserState {
DCHECK(!IsMultiwindowSupported());
// This may be the first time that the OTR browser state is being accessed, so
// ensure that the OTR ChromeBrowserState is created first.
ChromeBrowserState* otrBrowserState =
browserState->GetOffTheRecordChromeBrowserState();
[self deleteSessionForBrowserState:otrBrowserState backupFile:nil];
return [self deleteSessionForBrowserState:browserState
backupFile:[self sessionBackupPath]];
backupFile:[self backupPathForSessionID:nil]];
}
+ (BOOL)moveAsideSessions:(NSSet<NSString*>*)sessionIDs
forBrowserState:(ChromeBrowserState*)browserState {
// This may be the first time that the OTR browser state is being accessed, so
// ensure that the OTR ChromeBrowserState is created first.
ChromeBrowserState* otrBrowserState =
browserState->GetOffTheRecordChromeBrowserState();
[self deleteSessions:sessionIDs
forBrowserState:otrBrowserState
shouldBackup:NO];
return [self deleteSessions:sessionIDs
forBrowserState:browserState
shouldBackup:YES];
}
- (BOOL)restoreSessionsAfterCrash {
CrashRestoreHelper* strongSelf = self;
DCHECK(!_sessionRestored);
_sessionRestored = YES;
_infoBarBridge.reset();
BrowserList* browserList = BrowserListFactory::GetForBrowserState(
strongSelf.browser->GetBrowserState());
breakpad_helper::WillStartCrashRestoration();
BOOL success = NO;
// First restore all conected sessions.
NSFileManager* fileManager = [NSFileManager defaultManager];
NSError* error = nil;
std::set<Browser*> regularBrowsers = browserList->AllRegularBrowsers();
for (Browser* browser : regularBrowsers) {
NSString* sessionID = SceneStateBrowserAgent::FromBrowser(browser)
->GetSceneState()
.sceneSessionID;
NSString* sessionPath =
[[strongSelf class] backupPathForSessionID:sessionID];
SessionIOS* session =
[[SessionServiceIOS sharedService] loadSessionFromPath:sessionPath];
if (!session)
continue;
success |= SessionRestorationBrowserAgent::FromBrowser(browser)
->RestoreSessionWindow(session.sessionWindows[0]);
// remove the backup directory for this session as it will not be moved
// back to its original browser state direcotry.
if (IsMultiwindowSupported()) {
[fileManager
removeItemAtPath:[sessionPath stringByDeletingLastPathComponent]
error:&error];
}
}
SessionIOS* session = [[SessionServiceIOS sharedService]
loadSessionFromPath:[[self class] sessionBackupPath]];
if (!session)
return NO;
// If this is not multiwindow platform, there are no more sessions to deal
// with.
if (!IsMultiwindowSupported())
return success;
// Now put non restored sessions files to its original location in the browser
// state directory.
Browser* anyBrowser = *regularBrowsers.begin();
NSString* stashPath = base::SysUTF8ToNSString(
anyBrowser->GetBrowserState()->GetStatePath().value());
NSArray<NSString*>* backedupSessionIDs =
[[strongSelf class] backedupSessionIDs];
for (NSString* sessionID in backedupSessionIDs) {
NSString* originalSessionPath =
[SessionServiceIOS sessionPathForSessionID:sessionID
directory:stashPath];
[fileManager
moveItemAtPath:[[strongSelf class] backupPathForSessionID:sessionID]
toPath:originalSessionPath
error:&error];
}
DCHECK_EQ(session.sessionWindows.count, 1u);
breakpad_helper::WillStartCrashRestoration();
return SessionRestorationBrowserAgent::FromBrowser(_browser)
->RestoreSessionWindow(session.sessionWindows[0]);
return success;
}
- (void)infoBarRemoved:(infobars::InfoBar*)infobar {
......@@ -325,25 +510,35 @@ int SessionCrashedInfoBarDelegate::GetIconId() const {
// the recently closed tabs.
_sessionRestored = YES;
SessionIOS* session = [[SessionServiceIOS sharedService]
loadSessionFromPath:[[self class] sessionBackupPath]];
DCHECK_EQ(session.sessionWindows.count, 1u);
NSArray<CRWSessionStorage*>* sessions = session.sessionWindows[0].sessions;
if (!sessions.count)
return;
sessions::TabRestoreService* const tabRestoreService =
IOSChromeTabRestoreServiceFactory::GetForBrowserState(
_browser->GetBrowserState());
tabRestoreService->LoadTabsFromLastSession();
web::WebState::CreateParams params(_browser->GetBrowserState());
for (CRWSessionStorage* session in sessions) {
auto live_tab = std::make_unique<sessions::RestoreIOSLiveTab>(session);
// Add all tabs at the 0 position as the position is relative to an old
// tabModel.
tabRestoreService->CreateHistoricalTab(live_tab.get(), 0);
NSArray<NSString*>* sessionsIDs = [[self class] backedupSessionIDs];
NSFileManager* fileManager = [NSFileManager defaultManager];
NSError* error = nil;
for (NSString* sessionID in sessionsIDs) {
NSString* sessionPath = [[self class] backupPathForSessionID:sessionID];
SessionIOS* session =
[[SessionServiceIOS sharedService] loadSessionFromPath:sessionPath];
NSArray<CRWSessionStorage*>* sessions = session.sessionWindows[0].sessions;
if (!sessions.count)
continue;
sessions::TabRestoreService* const tabRestoreService =
IOSChromeTabRestoreServiceFactory::GetForBrowserState(
_browser->GetBrowserState());
tabRestoreService->LoadTabsFromLastSession();
web::WebState::CreateParams params(_browser->GetBrowserState());
for (CRWSessionStorage* session in sessions) {
auto live_tab = std::make_unique<sessions::RestoreIOSLiveTab>(session);
// Add all tabs at the 0 position as the position is relative to an old
// tabModel.
tabRestoreService->CreateHistoricalTab(live_tab.get(), 0);
}
if (IsMultiwindowSupported()) {
[fileManager
removeItemAtPath:[sessionPath stringByDeletingLastPathComponent]
error:&error];
}
}
return;
}
......
......@@ -14,6 +14,7 @@
#include "ios/chrome/browser/crash_report/crash_restore_helper.h"
#import "ios/chrome/browser/main/test_browser.h"
#import "ios/chrome/browser/sessions/session_service_ios.h"
#import "ios/chrome/browser/ui/util/multi_window_support.h"
#include "ios/web/public/test/web_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -28,7 +29,7 @@
using testing::Return;
@interface CrashRestoreHelper (Test)
+ (NSString*)sessionBackupPath;
+ (NSString*)backupPathForSessionID:(NSString*)sessionID;
@end
namespace {
......@@ -45,6 +46,73 @@ class CrashRestoreHelperTest : public PlatformTest {
}
protected:
// Creates the session for |session_id|, if |session_id| is nil a session
// will be created in the default location.
// Returns |true| if the creation was successful.
bool CreateSession(NSString* session_id) {
NSFileManager* file_manager = [NSFileManager defaultManager];
ChromeBrowserState* browser_states[] = {
chrome_browser_state_.get(),
off_the_record_chrome_browser_state_,
};
NSString* backup_path =
[CrashRestoreHelper backupPathForSessionID:session_id];
[file_manager removeItemAtPath:backup_path error:nil];
NSData* data = [NSData dataWithBytes:"hello" length:5];
for (size_t index = 0; index < base::size(browser_states); ++index) {
NSString* state_path = base::SysUTF8ToNSString(
browser_states[index]->GetStatePath().value());
NSString* session_path =
[SessionServiceIOS sessionPathForSessionID:session_id
directory:state_path];
NSString* directory = [session_path stringByDeletingLastPathComponent];
if (![file_manager fileExistsAtPath:directory]) {
[file_manager createDirectoryAtPath:directory
withIntermediateDirectories:YES
attributes:nil
error:nil];
}
[file_manager createFileAtPath:session_path contents:data attributes:nil];
if (![file_manager fileExistsAtPath:session_path])
return false;
}
return true;
}
// Returns |true| if session for |session_id| was erased from its default
// location. if |session_id| is nil, the default session location is used.
bool IsSessionErased(NSString* session_id) {
NSFileManager* file_manager = [NSFileManager defaultManager];
ChromeBrowserState* browser_states[] = {
chrome_browser_state_.get(),
off_the_record_chrome_browser_state_,
};
for (size_t index = 0; index < base::size(browser_states); ++index) {
NSString* state_path = base::SysUTF8ToNSString(
browser_states[index]->GetStatePath().value());
NSString* session_path =
[SessionServiceIOS sessionPathForSessionID:session_id
directory:state_path];
if ([file_manager fileExistsAtPath:session_path])
return false;
}
return true;
}
// Returns |true| if the session with |session_id| was backed up correctly,
// and deletes the backup file. if |session_id| is nil, the default backup
// session location is used.
bool CheckAndDeleteSessionBackedUp(NSString* session_id) {
NSFileManager* file_manager = [NSFileManager defaultManager];
NSString* backup_path =
[CrashRestoreHelper backupPathForSessionID:session_id];
if (![file_manager fileExistsAtPath:backup_path])
return false;
[file_manager removeItemAtPath:backup_path error:nil];
return true;
}
web::WebTaskEnvironment task_environment_;
std::unique_ptr<TestChromeBrowserState> chrome_browser_state_;
std::unique_ptr<TestBrowser> test_browser_;
......@@ -52,39 +120,33 @@ class CrashRestoreHelperTest : public PlatformTest {
CrashRestoreHelper* helper_;
};
TEST_F(CrashRestoreHelperTest, MoveAsideTest) {
NSString* backup_path = [CrashRestoreHelper sessionBackupPath];
NSFileManager* file_manager = [NSFileManager defaultManager];
[file_manager removeItemAtPath:backup_path error:NULL];
NSData* data = [NSData dataWithBytes:"hello" length:5];
ChromeBrowserState* browser_states[] = {
chrome_browser_state_.get(),
off_the_record_chrome_browser_state_,
};
for (size_t index = 0; index < base::size(browser_states); ++index) {
NSString* state_path =
base::SysUTF8ToNSString(browser_states[index]->GetStatePath().value());
NSString* session_path =
[SessionServiceIOS sessionPathForDirectory:state_path];
[file_manager createFileAtPath:session_path contents:data attributes:nil];
ASSERT_EQ(YES, [file_manager fileExistsAtPath:session_path]);
}
// Tests that moving session work correctly when multiple windows are not
// supported.
TEST_F(CrashRestoreHelperTest, MoveAsideSingleSession) {
// This test is only enabled when multi-window is disabled.
if (IsMultiwindowSupported())
return;
ASSERT_TRUE(CreateSession(nil));
[CrashRestoreHelper
moveAsideSessionInformationForBrowserState:chrome_browser_state_.get()];
EXPECT_TRUE(IsSessionErased(nil));
EXPECT_EQ(YES, CheckAndDeleteSessionBackedUp(nil));
}
for (size_t index = 0; index < base::size(browser_states); ++index) {
NSString* state_path =
base::SysUTF8ToNSString(browser_states[index]->GetStatePath().value());
NSString* session_path =
[SessionServiceIOS sessionPathForDirectory:state_path];
EXPECT_EQ(NO, [file_manager fileExistsAtPath:session_path]);
// Tests that moving session work correctly when multiple windows are supported.
TEST_F(CrashRestoreHelperTest, MoveAsideMultipleSessions) {
NSSet<NSString*>* session_ids =
[NSSet setWithObjects:@"session_1", @"session_2", nil];
for (NSString* session_id in session_ids) {
ASSERT_TRUE(CreateSession(session_id));
}
EXPECT_EQ(YES, [file_manager fileExistsAtPath:backup_path]);
[file_manager removeItemAtPath:backup_path error:NULL];
[CrashRestoreHelper moveAsideSessions:session_ids
forBrowserState:chrome_browser_state_.get()];
for (NSString* session_id in session_ids) {
EXPECT_TRUE(IsSessionErased(session_id));
EXPECT_EQ(YES, CheckAndDeleteSessionBackedUp(session_id));
}
}
} // namespace
......@@ -112,6 +112,11 @@ enum class DeviceBatteryState {
// Reset to NO after resetSessionRestorationFlag call.
@property(nonatomic, readonly) BOOL terminatedDuringSessionRestoration;
// The list of the session IDs for all the connected scenes, used for crash
// restoration.
@property(nonatomic, readonly)
NSMutableSet<NSString*>* connectedSceneSessionsIDs;
// Singleton PreviousSessionInfo. During the lifetime of the app, the returned
// object is the same, and describes the previous session, even after a new
// session has started (by calling beginRecordingCurrentSession).
......
......@@ -116,10 +116,6 @@ NSString* const kPreviousSessionInfoConnectedSceneSessionIDs =
// Can be greater than one if multiple sessions are being restored in parallel.
@property(atomic, assign) int numberOfSessionsBeingRestored;
// The list of the session IDs for all the connected scenes, used for crash
// restoration.
@property(nonatomic, strong) NSMutableSet<NSString*>* connectedSceneSessionsIDs;
// Redefined to be read-write.
@property(nonatomic, assign) NSInteger availableDeviceStorage;
@property(nonatomic, assign) float deviceBatteryLevel;
......@@ -134,6 +130,7 @@ NSString* const kPreviousSessionInfoConnectedSceneSessionIDs =
@property(nonatomic, strong) NSString* OSVersion;
@property(nonatomic, strong) NSDate* sessionEndTime;
@property(nonatomic, assign) BOOL terminatedDuringSessionRestoration;
@property(nonatomic, strong) NSMutableSet<NSString*>* connectedSceneSessionsIDs;
@end
......
......@@ -13,6 +13,10 @@
@class SessionIOS;
@class SessionIOSFactory;
namespace session_constants {
NSString* const kSessionsDirectory = @"Sessions";
}
// A singleton service for saving the current session. Can either save on a
// delay or immediately. Saving is always performed on a separate thread.
@interface SessionServiceIOS : NSObject
......@@ -52,6 +56,10 @@
- (void)deleteSessions:(NSArray<NSString*>*)sessionIDs
fromBrowserStateDirectory:(NSString*)directory;
// Returns the path of the session with |sessionID| within a |directory|.
+ (NSString*)sessionPathForSessionID:(NSString*)sessionID
directory:(NSString*)directory;
// Returns the path of the session file for |directory|.
+ (NSString*)sessionPathForDirectory:(NSString*)directory;
......
......@@ -48,6 +48,8 @@ NSString* const kRootObjectKey = @"root"; // Key for the root object.
NSString* const kSessionDirectory =
@"Sessions"; // The directory name inside BrowserState directory which
// contain all sessions directories.
NSString* const kSessionFileName =
@"session.plist"; // The session file name on disk.
}
@implementation NSKeyedUnarchiver (CrLegacySessionCompatibility)
......@@ -190,7 +192,16 @@ NSString* const kSessionDirectory =
}
+ (NSString*)sessionPathForDirectory:(NSString*)directory {
return [directory stringByAppendingPathComponent:@"session.plist"];
return [directory stringByAppendingPathComponent:kSessionFileName];
}
+ (NSString*)sessionPathForSessionID:(NSString*)sessionID
directory:(NSString*)directory {
if (!sessionID)
return [[self class] sessionPathForDirectory:directory];
return [NSString pathWithComponents:@[
directory, kSessionDirectory, sessionID, kSessionFileName
]];
}
#pragma mark - Private methods
......
......@@ -181,7 +181,7 @@ source_set("main") {
"//ios/chrome/browser/ui/thumb_strip:feature_flags",
"//ios/chrome/browser/ui/translate:legacy_translate",
"//ios/chrome/browser/ui/util:multiwindow_util",
"//ios/chrome/browser/url_loading",
"//ios/chrome/browser/url_loading:url_loading_params_header",
"//ios/chrome/browser/web",
"//ios/chrome/browser/web:tab_helper_delegates",
"//ios/chrome/browser/web:web_internal",
......
......@@ -76,6 +76,9 @@ typedef NS_ENUM(NSUInteger, SceneActivationLevel) {
@property(nonatomic, strong, readonly) id<BrowserInterfaceProvider>
interfaceProvider;
// The persistent identifier for the scene session.
@property(nonatomic, readonly) NSString* sceneSessionID;
// True if First Run UI (terms of service & sync sign-in) is being presented
// in a modal dialog.
@property(nonatomic, assign) BOOL presentingFirstRunUI;
......
......@@ -96,6 +96,14 @@
return _window;
}
- (NSString*)sceneSessionID {
NSString* sessionID = nil;
if (@available(ios 13, *)) {
sessionID = _scene.session.persistentIdentifier;
}
return sessionID;
}
- (void)setActivationLevel:(SceneActivationLevel)newLevel {
if (_activationLevel == newLevel) {
return;
......
......@@ -48,6 +48,16 @@ source_set("url_loading") {
]
}
source_set("url_loading_params_header") {
configs += [ "//build/config/compiler:enable_arc" ]
sources = [ "url_loading_params.h" ]
deps = [
"//ios/chrome/browser/ui/commands",
"//ios/web/public",
"//ui/base",
]
}
source_set("test_support") {
configs += [ "//build/config/compiler:enable_arc" ]
testonly = true
......
......@@ -15,7 +15,7 @@ source_set("window_activities") {
":ios_move_tab_activity_type_buildflags",
"//base",
"//ios/chrome/browser:chrome_url_constants",
"//ios/chrome/browser/url_loading",
"//ios/chrome/browser/url_loading:url_loading_params_header",
"//ios/web/public/navigation",
"//net",
"//url",
......
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