1 // Copyright 2013 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.
5 #include "chrome/browser/android/recently_closed_tabs_bridge.h"
7 #include "base/android/jni_string.h"
8 #include "chrome/browser/android/tab_android.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/profiles/profile_android.h"
11 #include "chrome/browser/sessions/session_restore.h"
12 #include "chrome/browser/sessions/tab_restore_service_factory.h"
13 #include "components/sessions/core/tab_restore_service.h"
14 #include "content/public/browser/web_contents.h"
15 #include "jni/RecentlyClosedBridge_jni.h"
17 using base::android::AttachCurrentThread
;
18 using base::android::ConvertUTF16ToJavaString
;
19 using base::android::ConvertUTF8ToJavaString
;
20 using base::android::ScopedJavaLocalRef
;
24 void AddTabToList(JNIEnv
* env
,
25 sessions::TabRestoreService::Entry
* entry
,
27 const sessions::TabRestoreService::Tab
* tab
=
28 static_cast<sessions::TabRestoreService::Tab
*>(entry
);
29 const sessions::SerializedNavigationEntry
& current_navigation
=
30 tab
->navigations
.at(tab
->current_navigation_index
);
31 Java_RecentlyClosedBridge_pushTab(
32 env
, jtabs_list
, entry
->id
,
33 ConvertUTF16ToJavaString(env
, current_navigation
.title()).obj(),
34 ConvertUTF8ToJavaString(env
, current_navigation
.virtual_url().spec())
38 void AddTabsToList(JNIEnv
* env
,
39 const sessions::TabRestoreService::Entries
& entries
,
43 for (sessions::TabRestoreService::Entries::const_iterator it
=
45 it
!= entries
.end() && added_count
< max_tab_count
; ++it
) {
46 sessions::TabRestoreService::Entry
* entry
= *it
;
47 DCHECK_EQ(entry
->type
, sessions::TabRestoreService::TAB
);
48 if (entry
->type
== sessions::TabRestoreService::TAB
) {
49 AddTabToList(env
, entry
, jtabs_list
);
57 RecentlyClosedTabsBridge::RecentlyClosedTabsBridge(Profile
* profile
)
59 tab_restore_service_(NULL
) {
62 RecentlyClosedTabsBridge::~RecentlyClosedTabsBridge() {
63 if (tab_restore_service_
)
64 tab_restore_service_
->RemoveObserver(this);
67 void RecentlyClosedTabsBridge::Destroy(JNIEnv
* env
, jobject obj
) {
71 void RecentlyClosedTabsBridge::SetRecentlyClosedCallback(JNIEnv
* env
,
74 callback_
.Reset(env
, jcallback
);
77 jboolean
RecentlyClosedTabsBridge::GetRecentlyClosedTabs(JNIEnv
* env
,
81 EnsureTabRestoreService();
82 if (!tab_restore_service_
)
85 AddTabsToList(env
, tab_restore_service_
->entries(), jtabs_list
,
90 jboolean
RecentlyClosedTabsBridge::OpenRecentlyClosedTab(JNIEnv
* env
,
95 if (!tab_restore_service_
)
98 // Find and remove the corresponding tab entry from TabRestoreService.
99 // We take ownership of the returned tab.
100 scoped_ptr
<sessions::TabRestoreService::Tab
> tab_entry(
101 tab_restore_service_
->RemoveTabEntryById(recent_tab_id
));
105 TabAndroid
* tab_android
= TabAndroid::GetNativeTab(env
, jtab
);
108 content::WebContents
* web_contents
= tab_android
->web_contents();
112 // RestoreForeignSessionTab needs a SessionTab.
113 sessions::SessionTab session_tab
;
114 session_tab
.current_navigation_index
= tab_entry
->current_navigation_index
;
115 session_tab
.navigations
= tab_entry
->navigations
;
117 WindowOpenDisposition disposition
=
118 static_cast<WindowOpenDisposition
>(j_disposition
);
119 SessionRestore::RestoreForeignSessionTab(web_contents
,
125 void RecentlyClosedTabsBridge::ClearRecentlyClosedTabs(JNIEnv
* env
,
127 EnsureTabRestoreService();
128 if (tab_restore_service_
)
129 tab_restore_service_
->ClearEntries();
132 void RecentlyClosedTabsBridge::TabRestoreServiceChanged(
133 sessions::TabRestoreService
* service
) {
134 if (callback_
.is_null())
136 JNIEnv
* env
= AttachCurrentThread();
137 Java_RecentlyClosedCallback_onUpdated(env
, callback_
.obj());
140 void RecentlyClosedTabsBridge::TabRestoreServiceDestroyed(
141 sessions::TabRestoreService
* service
) {
142 tab_restore_service_
= NULL
;
145 void RecentlyClosedTabsBridge::EnsureTabRestoreService() {
146 if (tab_restore_service_
)
149 tab_restore_service_
= TabRestoreServiceFactory::GetForProfile(profile_
);
151 // TabRestoreServiceFactory::GetForProfile() can return NULL (e.g. in
153 if (tab_restore_service_
) {
154 // This does nothing if the tabs have already been loaded or they
155 // shouldn't be loaded.
156 tab_restore_service_
->LoadTabsFromLastSession();
157 tab_restore_service_
->AddObserver(this);
161 static jlong
Init(JNIEnv
* env
,
162 const JavaParamRef
<jobject
>& obj
,
163 const JavaParamRef
<jobject
>& jprofile
) {
164 RecentlyClosedTabsBridge
* bridge
= new RecentlyClosedTabsBridge(
165 ProfileAndroid::FromProfileAndroid(jprofile
));
166 return reinterpret_cast<intptr_t>(bridge
);
170 bool RecentlyClosedTabsBridge::Register(JNIEnv
* env
) {
171 return RegisterNativesImpl(env
);