// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/web/navigation/synthesized_session_restore.h"
#import "base/feature_list.h"
#import "base/ios/ios_util.h"
#import "base/metrics/histogram_macros.h"
#import "base/strings/sys_string_conversions.h"
#import "ios/web/common/features.h"
#import "ios/web/navigation/navigation_item_impl.h"
#import "ios/web/navigation/synthesized_history_entry_data.h"
#import "ios/web/public/navigation/navigation_item.h"
#import "ios/web/public/navigation/navigation_manager.h"
#import "ios/web/public/navigation/referrer.h"
#import "ios/web/public/web_client.h"
#import "ios/web/public/web_state.h"
namespace {
// Session history entry data keys.
NSString* const kEntryData = @"SessionHistoryEntryData";
NSString* const kEntryOriginalURL = @"SessionHistoryEntryOriginalURL";
NSString* const kEntryExternalURLPolicy =
@"SessionHistoryEntryShouldOpenExternalURLsPolicyKey";
NSString* const kEntryTitle = @"SessionHistoryEntryTitle";
NSString* const kEntryURL = @"SessionHistoryEntryURL";
// Session history keys.
NSString* const kSessionHistory = @"SessionHistory";
NSString* const kSessionHistoryCurrentIndex = @"SessionHistoryCurrentIndex";
NSString* const kSessionHistoryEntries = @"SessionHistoryEntries";
NSString* const kSessionHistoryVersion = @"SessionHistoryVersion";
NSString* const kIsAppInitiated = @"IsAppInitiated";
} // namespace
namespace web {
NSData* SynthesizedSessionRestore(
int last_committed_item_index,
const std::vector<std::unique_ptr<NavigationItem>>& items,
bool off_the_record) {
DCHECK(last_committed_item_index >= 0 &&
last_committed_item_index < static_cast<int>(items.size()));
NSNumber* const external_url_policy = off_the_record ? @0 : @1;
NSMutableArray* entries =
[[NSMutableArray alloc] initWithCapacity:items.size()];
for (size_t i = 0; i < items.size(); i++) {
NavigationItem* item = items[i].get();
// SessionHistoryEntryData, and NSDictionaries below, come from:
// https://github.com/WebKit/WebKit/blob/674bd0ec/Source/WebKit/UIProcess/mac/LegacySessionStateCoding.cpp
SynthesizedHistoryEntryData entry_data;
entry_data.SetReferrer(item->GetReferrer().url);
[entries addObject:@{
kEntryData : entry_data.AsNSData(),
kEntryOriginalURL : base::SysUTF8ToNSString(item->GetURL().spec()),
kEntryExternalURLPolicy : external_url_policy,
kEntryTitle : base::SysUTF16ToNSString(item->GetTitle()),
kEntryURL : base::SysUTF8ToNSString(item->GetURL().spec()),
}];
}
NSDictionary* state_dictionary = @{
kSessionHistory : @{
kSessionHistoryCurrentIndex : @(last_committed_item_index),
kSessionHistoryEntries : entries,
kSessionHistoryVersion : @1,
},
kIsAppInitiated : @NO,
};
static constexpr uint8_t version[] = {0, 0, 0, 2};
NSMutableData* interaction_data = [NSMutableData data];
[interaction_data appendData:[NSData dataWithBytes:&version
length:sizeof(version)]];
NSData* property_list_data = [NSPropertyListSerialization
dataWithPropertyList:state_dictionary
format:NSPropertyListBinaryFormat_v1_0
options:0
error:nil];
[interaction_data appendData:property_list_data];
return interaction_data;
}
} // namespace web