15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_SESSIONS_SESSION_BACKEND_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_SESSIONS_SESSION_BACKEND_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/task/cancelable_task_tracker.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/base_session_service.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/session_command.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace base { 17effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass File; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SessionBackend ------------------------------------------------------------- 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SessionBackend is the backend used by BaseSessionService. It is responsible 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for maintaining two files: 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// . The current file, which is the file commands passed to AppendCommands 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// get written to. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// . The last file. When created the current file is moved to the last 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// file. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Each file contains an arbitrary set of commands supplied from 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BaseSessionService. A command consists of a unique id and a stream of bytes. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SessionBackend does not use the id in anyway, that is used by 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BaseSessionService. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SessionBackend : public base::RefCountedThreadSafe<SessionBackend> { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef SessionCommand::id_type id_type; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef SessionCommand::size_type size_type; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initial size of the buffer used in reading the file. This is exposed 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for testing. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kFileReadBufferSize; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a SessionBackend. This method is invoked on the MAIN thread, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and does no IO. The real work is done from Init, which is invoked on 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the file thread. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |path_to_dir| gives the path the files are written two, and |type| 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // indicates which service is using this backend. |type| is used to determine 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the name of the files to use as well as for logging. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionBackend(BaseSessionService::SessionType type, 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& path_to_dir); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Moves the current file to the last file, and recreates the current file. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: this is invoked before every command, and does nothing if we've 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // already Init'ed. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Init(); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool inited() const { return inited_; } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Appends the specified commands to the current file. If reset_first is 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // true the the current file is recreated. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: this deletes SessionCommands in commands as well as the supplied 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // vector. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AppendCommands(std::vector<SessionCommand*>* commands, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool reset_first); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invoked from the service to read the commands that make up the last 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // session, invokes ReadLastSessionCommandsImpl to do the work. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReadLastSessionCommands( 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::CancelableTaskTracker::IsCanceledCallback& is_canceled, 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BaseSessionService::InternalGetCommandsCallback& callback); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reads the commands from the last file. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On success, the read commands are added to commands. It is up to the 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // caller to delete the commands. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadLastSessionCommandsImpl(std::vector<SessionCommand*>* commands); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Deletes the file containing the commands for the last session. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DeleteLastSession(); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Moves the current session to the last and resets the current. This is 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // called during startup and if the user launchs the app and no tabbed 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // browsers are running. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void MoveCurrentSessionToLastSession(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reads the commands from the current file. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On success, the read commands are added to commands. It is up to the 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // caller to delete the commands. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReadCurrentSessionCommandsImpl(std::vector<SessionCommand*>* commands); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCountedThreadSafe<SessionBackend>; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~SessionBackend(); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If current_session_file_ is open, it is truncated so that it is essentially 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // empty (only contains the header). If current_session_file_ isn't open, it 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is is opened and the header is written to it. After this 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // current_session_file_ contains no commands. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: current_session_file_ may be NULL if the file couldn't be opened or 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the header couldn't be written. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ResetFile(); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Opens the current file and writes the header. On success a handle to 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the file is returned. 108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::File* OpenAndWriteHeader(const base::FilePath& path); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Appends the specified commands to the specified file. 111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch bool AppendCommandsToFile(base::File* file, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<SessionCommand*>& commands); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BaseSessionService::SessionType type_; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the path to the last file. 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath GetLastSessionPath(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the path to the current file. 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath GetCurrentSessionPath(); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Directory files are relative to. 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath path_to_dir_; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Whether the previous target file is valid. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool last_session_valid_; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle to the target file. 129effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_ptr<base::File> current_session_file_; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Whether we've inited. Remember, the constructor is run on the 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Main thread, all others on the IO thread, hence lazy initialization. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool inited_; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If true, the file is empty (no commands have been added to it). 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool empty_file_; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SessionBackend); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CHROME_BROWSER_SESSIONS_SESSION_BACKEND_H_ 142