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.h"
13 #include "chrome/browser/sessions/tab_restore_service_factory.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 TabRestoreService::Entry
* entry
,
27 const TabRestoreService::Tab
* tab
=
28 static_cast<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 TabRestoreService::Entries
& entries
,
43 for (TabRestoreService::Entries::const_iterator it
= entries
.begin();
44 it
!= entries
.end() && added_count
< max_tab_count
; ++it
) {
45 TabRestoreService::Entry
* entry
= *it
;
46 DCHECK_EQ(entry
->type
, TabRestoreService::TAB
);
47 if (entry
->type
== TabRestoreService::TAB
) {
48 AddTabToList(env
, entry
, jtabs_list
);
56 RecentlyClosedTabsBridge::RecentlyClosedTabsBridge(Profile
* profile
)
58 tab_restore_service_(NULL
) {
61 RecentlyClosedTabsBridge::~RecentlyClosedTabsBridge() {
62 if (tab_restore_service_
)
63 tab_restore_service_
->RemoveObserver(this);
66 void RecentlyClosedTabsBridge::Destroy(JNIEnv
* env
, jobject obj
) {
70 void RecentlyClosedTabsBridge::SetRecentlyClosedCallback(JNIEnv
* env
,
73 callback_
.Reset(env
, jcallback
);
76 jboolean
RecentlyClosedTabsBridge::GetRecentlyClosedTabs(JNIEnv
* env
,
80 EnsureTabRestoreService();
81 if (!tab_restore_service_
)
84 AddTabsToList(env
, tab_restore_service_
->entries(), jtabs_list
,
89 jboolean
RecentlyClosedTabsBridge::OpenRecentlyClosedTab(JNIEnv
* env
,
94 if (!tab_restore_service_
)
97 // Find and remove the corresponding tab entry from TabRestoreService.
98 // We take ownership of the returned tab.
99 scoped_ptr
<TabRestoreService::Tab
> tab_entry(
100 tab_restore_service_
->RemoveTabEntryById(recent_tab_id
));
104 TabAndroid
* tab_android
= TabAndroid::GetNativeTab(env
, jtab
);
107 content::WebContents
* web_contents
= tab_android
->web_contents();
111 // RestoreForeignSessionTab needs a SessionTab.
112 sessions::SessionTab session_tab
;
113 session_tab
.current_navigation_index
= tab_entry
->current_navigation_index
;
114 session_tab
.navigations
= tab_entry
->navigations
;
116 WindowOpenDisposition disposition
=
117 static_cast<WindowOpenDisposition
>(j_disposition
);
118 SessionRestore::RestoreForeignSessionTab(web_contents
,
124 void RecentlyClosedTabsBridge::ClearRecentlyClosedTabs(JNIEnv
* env
,
126 EnsureTabRestoreService();
127 if (tab_restore_service_
)
128 tab_restore_service_
->ClearEntries();
131 void RecentlyClosedTabsBridge::TabRestoreServiceChanged(
132 TabRestoreService
* service
) {
133 if (callback_
.is_null())
135 JNIEnv
* env
= AttachCurrentThread();
136 Java_RecentlyClosedCallback_onUpdated(env
, callback_
.obj());
139 void RecentlyClosedTabsBridge::TabRestoreServiceDestroyed(
140 TabRestoreService
* service
) {
141 tab_restore_service_
= NULL
;
144 void RecentlyClosedTabsBridge::EnsureTabRestoreService() {
145 if (tab_restore_service_
)
148 tab_restore_service_
= TabRestoreServiceFactory::GetForProfile(profile_
);
150 // TabRestoreServiceFactory::GetForProfile() can return NULL (e.g. in
152 if (tab_restore_service_
) {
153 // This does nothing if the tabs have already been loaded or they
154 // shouldn't be loaded.
155 tab_restore_service_
->LoadTabsFromLastSession();
156 tab_restore_service_
->AddObserver(this);
160 static jlong
Init(JNIEnv
* env
, jobject obj
, jobject jprofile
) {
161 RecentlyClosedTabsBridge
* bridge
= new RecentlyClosedTabsBridge(
162 ProfileAndroid::FromProfileAndroid(jprofile
));
163 return reinterpret_cast<intptr_t>(bridge
);
167 bool RecentlyClosedTabsBridge::Register(JNIEnv
* env
) {
168 return RegisterNativesImpl(env
);