summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authoralbertb@google.com <albertb@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-01 18:44:38 +0000
committeralbertb@google.com <albertb@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-01 18:44:38 +0000
commit3acb70efe8e81a9a9851f1b1c700dad3e6d94045 (patch)
treebb50ea9d245a8829b016b7015c74ef91bf93385d /chrome
parent0e5d08b9b0b2476600975106026331488deee938 (diff)
downloadchromium_src-3acb70efe8e81a9a9851f1b1c700dad3e6d94045.zip
chromium_src-3acb70efe8e81a9a9851f1b1c700dad3e6d94045.tar.gz
chromium_src-3acb70efe8e81a9a9851f1b1c700dad3e6d94045.tar.bz2
Added a new method to SessionService that returns a snapshot of the current
session. The snapshot is computed directly from memory or, if there are pending closed windows, by reading the session commands from disk. BUG=35040 TEST=unit tests Review URL: http://codereview.chromium.org/661055 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40284 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/sessions/base_session_service.cc17
-rw-r--r--chrome/browser/sessions/base_session_service.h6
-rw-r--r--chrome/browser/sessions/session_backend.cc18
-rw-r--r--chrome/browser/sessions/session_backend.h13
-rw-r--r--chrome/browser/sessions/session_restore.cc2
-rw-r--r--chrome/browser/sessions/session_service.cc58
-rw-r--r--chrome/browser/sessions/session_service.h16
-rw-r--r--chrome/browser/sessions/session_service_unittest.cc34
8 files changed, 143 insertions, 21 deletions
diff --git a/chrome/browser/sessions/base_session_service.cc b/chrome/browser/sessions/base_session_service.cc
index a8be23d..acd685b 100644
--- a/chrome/browser/sessions/base_session_service.cc
+++ b/chrome/browser/sessions/base_session_service.cc
@@ -267,3 +267,20 @@ BaseSessionService::Handle BaseSessionService::ScheduleGetLastSessionCommands(
}
return request->handle();
}
+
+BaseSessionService::Handle
+ BaseSessionService::ScheduleGetCurrentSessionCommands(
+ InternalGetCommandsRequest* request,
+ CancelableRequestConsumerBase* consumer) {
+ scoped_refptr<InternalGetCommandsRequest> request_wrapper(request);
+ AddRequest(request, consumer);
+ if (backend_thread()) {
+ backend_thread()->message_loop()->PostTask(FROM_HERE,
+ NewRunnableMethod(backend(),
+ &SessionBackend::ReadCurrentSessionCommands,
+ request_wrapper));
+ } else {
+ backend()->ReadCurrentSessionCommands(request);
+ }
+ return request->handle();
+}
diff --git a/chrome/browser/sessions/base_session_service.h b/chrome/browser/sessions/base_session_service.h
index e6ba7d8..39dbeca 100644
--- a/chrome/browser/sessions/base_session_service.h
+++ b/chrome/browser/sessions/base_session_service.h
@@ -152,6 +152,12 @@ class BaseSessionService : public CancelableRequestProvider,
InternalGetCommandsRequest* request,
CancelableRequestConsumerBase* consumer);
+ // Invokes ReadCurrentSessionCommands with request on the backend thread.
+ // If testing, ReadLastSessionCommands is invoked directly.
+ Handle ScheduleGetCurrentSessionCommands(
+ InternalGetCommandsRequest* request,
+ CancelableRequestConsumerBase* consumer);
+
// Max number of navigation entries in each direction we'll persist.
static const int max_persist_navigation_count;
diff --git a/chrome/browser/sessions/session_backend.cc b/chrome/browser/sessions/session_backend.cc
index 6658673..f9de317 100644
--- a/chrome/browser/sessions/session_backend.cc
+++ b/chrome/browser/sessions/session_backend.cc
@@ -281,6 +281,24 @@ void SessionBackend::MoveCurrentSessionToLastSession() {
ResetFile();
}
+void SessionBackend::ReadCurrentSessionCommands(
+ scoped_refptr<BaseSessionService::InternalGetCommandsRequest> request) {
+ if (request->canceled())
+ return;
+ Init();
+ ReadCurrentSessionCommandsImpl(&(request->commands));
+ request->ForwardResult(
+ BaseSessionService::InternalGetCommandsRequest::TupleType(
+ request->handle(), request));
+}
+
+bool SessionBackend::ReadCurrentSessionCommandsImpl(
+ std::vector<SessionCommand*>* commands) {
+ Init();
+ SessionFileReader file_reader(GetCurrentSessionPath());
+ return file_reader.Read(type_, commands);
+}
+
bool SessionBackend::AppendCommandsToFile(net::FileStream* file,
const std::vector<SessionCommand*>& commands) {
for (std::vector<SessionCommand*>::const_iterator i = commands.begin();
diff --git a/chrome/browser/sessions/session_backend.h b/chrome/browser/sessions/session_backend.h
index 51485c8..91c9bb7 100644
--- a/chrome/browser/sessions/session_backend.h
+++ b/chrome/browser/sessions/session_backend.h
@@ -62,7 +62,7 @@ class SessionBackend : public base::RefCountedThreadSafe<SessionBackend> {
bool reset_first);
// Invoked from the service to read the commands that make up the last
- // session, invokes ReadSessionImpl to do the work.
+ // session, invokes ReadLastSessionCommandsImpl to do the work.
void ReadLastSessionCommands(
scoped_refptr<BaseSessionService::InternalGetCommandsRequest> request);
@@ -80,6 +80,17 @@ class SessionBackend : public base::RefCountedThreadSafe<SessionBackend> {
// browsers are running.
void MoveCurrentSessionToLastSession();
+ // Invoked from the service to read the commands that make up the current
+ // session, invokes ReadCurrentSessionCommandsImpl to do the work.
+ void ReadCurrentSessionCommands(
+ scoped_refptr<BaseSessionService::InternalGetCommandsRequest> request);
+
+ // Reads the commands from the current file.
+ //
+ // On success, the read commands are added to commands. It is up to the
+ // caller to delete the commands.
+ bool ReadCurrentSessionCommandsImpl(std::vector<SessionCommand*>* commands);
+
private:
friend class base::RefCountedThreadSafe<SessionBackend>;
diff --git a/chrome/browser/sessions/session_restore.cc b/chrome/browser/sessions/session_restore.cc
index 3776666..99451b2 100644
--- a/chrome/browser/sessions/session_restore.cc
+++ b/chrome/browser/sessions/session_restore.cc
@@ -189,7 +189,7 @@ class SessionRestoreImpl : public NotificationObserver {
void Restore() {
SessionService* session_service = profile_->GetSessionService();
DCHECK(session_service);
- SessionService::LastSessionCallback* callback =
+ SessionService::SessionCallback* callback =
NewCallback(this, &SessionRestoreImpl::OnGotSession);
session_service->GetLastSession(&request_consumer_, callback);
diff --git a/chrome/browser/sessions/session_service.cc b/chrome/browser/sessions/session_service.cc
index 6c5b3d9..0031f618 100644
--- a/chrome/browser/sessions/session_service.cc
+++ b/chrome/browser/sessions/session_service.cc
@@ -67,23 +67,23 @@ namespace {
// first and then the caller. This is done so that the SessionWindows can be
// recreated from the SessionCommands and the SessionWindows passed to the
// caller. The following class is used for this.
-class InternalLastSessionRequest
+class InternalSessionRequest
: public BaseSessionService::InternalGetCommandsRequest {
public:
- InternalLastSessionRequest(
+ InternalSessionRequest(
CallbackType* callback,
- SessionService::LastSessionCallback* real_callback)
+ SessionService::SessionCallback* real_callback)
: BaseSessionService::InternalGetCommandsRequest(callback),
real_callback(real_callback) {
}
- // The callback supplied to GetLastSession.
- scoped_ptr<SessionService::LastSessionCallback> real_callback;
+ // The callback supplied to GetLastSession and GetCurrentSession.
+ scoped_ptr<SessionService::SessionCallback> real_callback;
private:
- ~InternalLastSessionRequest() {}
+ ~InternalSessionRequest() {}
- DISALLOW_COPY_AND_ASSIGN(InternalLastSessionRequest);
+ DISALLOW_COPY_AND_ASSIGN(InternalSessionRequest);
};
// Various payload structures.
@@ -385,13 +385,41 @@ void SessionService::SetSelectedTabInWindow(const SessionID& window_id,
SessionService::Handle SessionService::GetLastSession(
CancelableRequestConsumerBase* consumer,
- LastSessionCallback* callback) {
+ SessionCallback* callback) {
return ScheduleGetLastSessionCommands(
- new InternalLastSessionRequest(
- NewCallback(this, &SessionService::OnGotLastSessionCommands),
+ new InternalSessionRequest(
+ NewCallback(this, &SessionService::OnGotSessionCommands),
callback), consumer);
}
+SessionService::Handle SessionService::GetCurrentSession(
+ CancelableRequestConsumerBase* consumer,
+ SessionCallback* callback) {
+ if (pending_window_close_ids_.empty()) {
+ // If there are no pending window closes, we can get the current session
+ // from memory.
+ InternalSessionRequest* request = new InternalSessionRequest(
+ NewCallback(this, &SessionService::OnGotSessionCommands),
+ callback);
+ AddRequest(request, consumer);
+ IdToRange tab_to_available_range;
+ std::set<SessionID::id_type> windows_to_track;
+ BuildCommandsFromBrowsers(&(request->commands),
+ &tab_to_available_range,
+ &windows_to_track);
+ request->ForwardResult(
+ BaseSessionService::InternalGetCommandsRequest::TupleType(
+ request->handle(), request));
+ return request->handle();
+ } else {
+ // If there are pending window closes, read the current session from disk.
+ return ScheduleGetCurrentSessionCommands(
+ new InternalSessionRequest(
+ NewCallback(this, &SessionService::OnGotSessionCommands),
+ callback), consumer);
+ }
+}
+
void SessionService::Init() {
// Register for the notifications we're interested in.
registrar_.Add(this, NotificationType::TAB_PARENTED,
@@ -650,7 +678,7 @@ SessionCommand* SessionService::CreatePinnedStateCommand(
return command;
}
-void SessionService::OnGotLastSessionCommands(
+void SessionService::OnGotSessionCommands(
Handle handle,
scoped_refptr<InternalGetCommandsRequest> request) {
if (request->canceled())
@@ -658,10 +686,10 @@ void SessionService::OnGotLastSessionCommands(
ScopedVector<SessionWindow> valid_windows;
RestoreSessionFromCommands(
request->commands, &(valid_windows.get()));
- static_cast<InternalLastSessionRequest*>(request.get())->
+ static_cast<InternalSessionRequest*>(request.get())->
real_callback->RunWithParams(
- LastSessionCallback::TupleType(request->handle(),
- &(valid_windows.get())));
+ SessionCallback::TupleType(request->handle(),
+ &(valid_windows.get())));
}
void SessionService::RestoreSessionFromCommands(
@@ -1045,7 +1073,7 @@ void SessionService::BuildCommandsForBrowser(
for (int i = 0; i < browser->tab_count(); ++i) {
TabContents* tab = browser->GetTabContentsAt(i);
DCHECK(tab);
- if (tab->profile() == profile()) {
+ if (tab->profile() == profile() || profile() == NULL) {
BuildCommandsForTab(browser->session_id(), &tab->controller(), i,
browser->tabstrip_model()->IsTabPinned(i),
commands, tab_to_available_range);
diff --git a/chrome/browser/sessions/session_service.h b/chrome/browser/sessions/session_service.h
index 018263e..a950224 100644
--- a/chrome/browser/sessions/session_service.h
+++ b/chrome/browser/sessions/session_service.h
@@ -137,7 +137,7 @@ class SessionService : public BaseSessionService,
//
// The time gives the time the session was closed.
typedef Callback2<Handle, std::vector<SessionWindow*>*>::Type
- LastSessionCallback;
+ SessionCallback;
// Fetches the contents of the last session, notifying the callback when
// done. If the callback is supplied an empty vector of SessionWindows
@@ -147,7 +147,17 @@ class SessionService : public BaseSessionService,
// callback invokes OnGotSessionCommands from which we map the
// SessionCommands to browser state, then notify the callback.
Handle GetLastSession(CancelableRequestConsumerBase* consumer,
- LastSessionCallback* callback);
+ SessionCallback* callback);
+
+ // Fetches the contents of the current session, notifying the callback when
+ // done. If the callback is supplied an empty vector of SessionWindows
+ // it means the session could not be restored.
+ //
+ // The created request does NOT directly invoke the callback, rather the
+ // callback invokes OnGotSessionCommands from which we map the
+ // SessionCommands to browser state, then notify the callback.
+ Handle GetCurrentSession(CancelableRequestConsumerBase* consumer,
+ SessionCallback* callback);
private:
typedef std::map<SessionID::id_type,std::pair<int,int> > IdToRange;
@@ -211,7 +221,7 @@ class SessionService : public BaseSessionService,
// Callback form the backend for getting the commands from the previous
// or save file. Converts the commands in SessionWindows and notifies
// the real callback.
- void OnGotLastSessionCommands(
+ void OnGotSessionCommands(
Handle handle,
scoped_refptr<InternalGetCommandsRequest> request);
diff --git a/chrome/browser/sessions/session_service_unittest.cc b/chrome/browser/sessions/session_service_unittest.cc
index 8d2a9da..20451b6 100644
--- a/chrome/browser/sessions/session_service_unittest.cc
+++ b/chrome/browser/sessions/session_service_unittest.cc
@@ -16,15 +16,17 @@
#include "chrome/browser/sessions/session_types.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/common/chrome_paths.h"
+#include "chrome/test/browser_with_test_window_test.h"
#include "chrome/test/file_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
-class SessionServiceTest : public testing::Test {
+class SessionServiceTest : public BrowserWithTestWindowTest {
public:
SessionServiceTest() : window_bounds(0, 1, 2, 3) {}
protected:
virtual void SetUp() {
+ BrowserWithTestWindowTest::SetUp();
std::string b = Int64ToString(base::Time::Now().ToInternalValue());
PathService::Get(base::DIR_TEMP, &path_);
@@ -585,3 +587,33 @@ TEST_F(SessionServiceTest, PinnedTrue) {
EXPECT_TRUE(CreateAndWriteSessionWithOneTab(true, true));
}
+
+class GetCurrentSessionCallbackHandler {
+ public:
+ void OnGotSession(int handle, std::vector<SessionWindow*>* windows) {
+ EXPECT_EQ(1U, windows->size());
+ EXPECT_EQ(2U, (*windows)[0]->tabs.size());
+ EXPECT_EQ(2U, (*windows)[0]->tabs[0]->navigations.size());
+ EXPECT_EQ(GURL("http://bar/1"),
+ (*windows)[0]->tabs[0]->navigations[0].url());
+ EXPECT_EQ(GURL("http://bar/2"),
+ (*windows)[0]->tabs[0]->navigations[1].url());
+ EXPECT_EQ(2U, (*windows)[0]->tabs[1]->navigations.size());
+ EXPECT_EQ(GURL("http://foo/1"),
+ (*windows)[0]->tabs[1]->navigations[0].url());
+ EXPECT_EQ(GURL("http://foo/2"),
+ (*windows)[0]->tabs[1]->navigations[1].url());
+ }
+};
+
+TEST_F(SessionServiceTest, GetCurrentSession) {
+ AddTab(browser(), GURL("http://foo/1"));
+ NavigateAndCommitActiveTab(GURL("http://foo/2"));
+ AddTab(browser(), GURL("http://bar/1"));
+ NavigateAndCommitActiveTab(GURL("http://bar/2"));
+
+ CancelableRequestConsumer consumer;
+ GetCurrentSessionCallbackHandler handler;
+ service()->GetCurrentSession(&consumer,
+ NewCallback(&handler, &GetCurrentSessionCallbackHandler::OnGotSession));
+}