1 // Copyright 2020 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef WEBLAYER_BROWSER_PERSISTENCE_BROWSER_PERSISTER_H_ 6 #define WEBLAYER_BROWSER_PERSISTENCE_BROWSER_PERSISTER_H_ 7 8 #include <stddef.h> 9 10 #include <map> 11 #include <memory> 12 #include <string> 13 #include <utility> 14 #include <vector> 15 16 #include "base/macros.h" 17 #include "base/memory/weak_ptr.h" 18 #include "base/scoped_observer.h" 19 #include "components/sessions/content/session_tab_helper_delegate.h" 20 #include "components/sessions/core/command_storage_manager_delegate.h" 21 #include "components/sessions/core/session_service_commands.h" 22 #include "weblayer/browser/tab_impl.h" 23 #include "weblayer/public/browser_observer.h" 24 25 class SessionID; 26 27 namespace sessions { 28 class SessionCommand; 29 } 30 31 namespace weblayer { 32 33 class BrowserImpl; 34 35 // BrowserPersister is responsible for maintaining the state of tabs in a 36 // single Browser so that they can be restored at a later date. The state is 37 // written to a file. To avoid having to write the complete state anytime 38 // something changes interesting events (represented as SessionCommands) are 39 // written to disk. To restore, the events are read back and the state 40 // recreated. At certain times the file is truncated and rebuilt from the 41 // current state. 42 class BrowserPersister : public sessions::CommandStorageManagerDelegate, 43 public sessions::SessionTabHelperDelegate, 44 public BrowserObserver, 45 public TabImpl::DataObserver { 46 public: 47 BrowserPersister(const base::FilePath& path, 48 BrowserImpl* browser, 49 const std::vector<uint8_t>& decryption_key); 50 51 BrowserPersister(const BrowserPersister&) = delete; 52 BrowserPersister& operator=(const BrowserPersister&) = delete; 53 54 ~BrowserPersister() override; 55 is_restore_in_progress()56 bool is_restore_in_progress() const { return is_restore_in_progress_; } 57 58 void SaveIfNecessary(); 59 60 // Returns the key used to encrypt the file. Empty if not encrypted. 61 // Encryption is done when saving and the profile is off the record. 62 const std::vector<uint8_t>& GetCryptoKey() const; 63 64 private: 65 friend class BrowserPersisterTestHelper; 66 67 using IdToRange = std::map<SessionID, std::pair<int, int>>; 68 69 // CommandStorageManagerDelegate: 70 bool ShouldUseDelayedSave() override; 71 void OnWillSaveCommands() override; 72 void OnGeneratedNewCryptoKey(const std::vector<uint8_t>& key) override; 73 74 // BrowserObserver; 75 void OnTabAdded(Tab* tab) override; 76 void OnTabRemoved(Tab* tab, bool active_tab_changed) override; 77 void OnActiveTabChanged(Tab* tab) override; 78 79 // TabImpl::DataObserver: 80 void OnDataChanged(TabImpl* tab, 81 const std::map<std::string, std::string>& data) override; 82 83 // sessions::SessionTabHelperDelegate: 84 void SetTabUserAgentOverride(const SessionID& window_id, 85 const SessionID& tab_id, 86 const sessions::SerializedUserAgentOverride& 87 user_agent_override) override; 88 void SetSelectedNavigationIndex(const SessionID& window_id, 89 const SessionID& tab_id, 90 int index) override; 91 void UpdateTabNavigation( 92 const SessionID& window_id, 93 const SessionID& tab_id, 94 const sessions::SerializedNavigationEntry& navigation) override; 95 void TabNavigationPathPruned(const SessionID& window_id, 96 const SessionID& tab_id, 97 int index, 98 int count) override; 99 void TabNavigationPathEntriesDeleted(const SessionID& window_id, 100 const SessionID& tab_id) override; 101 102 // Schedules recreating the file on the next save. 103 void ScheduleRebuildOnNextSave(); 104 105 // Called with the contents of the previous session. 106 void OnGotCurrentSessionCommands( 107 std::vector<std::unique_ptr<sessions::SessionCommand>> commands); 108 109 // Schedules commands to recreate the state of the specified tab. 110 void BuildCommandsForTab(TabImpl* tab, int index_in_window); 111 112 // Schedules commands to recreate the state of |browser_|. 113 void BuildCommandsForBrowser(); 114 115 // Schedules the specified command. 116 void ScheduleCommand(std::unique_ptr<sessions::SessionCommand> command); 117 118 void ProcessRestoreCommands( 119 const std::vector<std::unique_ptr<sessions::SessionWindow>>& windows); 120 121 BrowserImpl* browser_; 122 123 // ID used for the browser. The sessions code requires each tab to be 124 // associated with a browser. 125 const SessionID browser_session_id_; 126 127 std::unique_ptr<sessions::CommandStorageManager> command_storage_manager_; 128 129 // Maps from session tab id to the range of navigation entries that has 130 // been written to disk. 131 IdToRange tab_to_available_range_; 132 133 // Force session commands to be rebuild before next save event. 134 bool rebuild_on_next_save_; 135 136 std::vector<uint8_t> crypto_key_; 137 138 ScopedObserver<TabImpl, 139 TabImpl::DataObserver, 140 &TabImpl::AddDataObserver, 141 &TabImpl::RemoveDataObserver> 142 data_observer_{this}; 143 144 // True while asynchronously reading the state to restore. 145 bool is_restore_in_progress_ = true; 146 147 base::WeakPtrFactory<BrowserPersister> weak_factory_{this}; 148 }; 149 150 } // namespace weblayer 151 152 #endif // WEBLAYER_BROWSER_PERSISTENCE_BROWSER_PERSISTER_H_ 153