Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(297)

Side by Side Diff: chrome/browser/android/foreign_session_helper.cc

Issue 19874002: [Android] Expose foreign session sync related funtionalities through JNI. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fixed patchest 1 comments Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "chrome/browser/android/foreign_session_helper.h"
6
7 #include <jni.h>
8
9 #include "base/android/jni_string.h"
10
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/prefs/scoped_user_pref_update.h"
13 #include "chrome/browser/profiles/profile_android.h"
14 #include "chrome/browser/sync/glue/session_model_associator.h"
15 #include "chrome/browser/sync/profile_sync_service.h"
16 #include "chrome/browser/sync/profile_sync_service_factory.h"
17 #include "chrome/browser/ui/android/tab_model/tab_model.h"
18 #include "chrome/browser/ui/android/tab_model/tab_model_list.h"
19 #include "chrome/common/pref_names.h"
20 #include "chrome/common/url_constants.h"
21
22 #include "content/public/browser/notification_source.h"
23 #include "content/public/browser/user_metrics.h"
24 #include "content/public/browser/web_contents.h"
25
26 #include "jni/ForeignSessionHelper_jni.h"
27
28 using base::android::ScopedJavaGlobalRef;
29 using base::android::ScopedJavaLocalRef;
30 using base::android::AttachCurrentThread;
31 using base::android::ConvertUTF16ToJavaString;
32 using base::android::ConvertUTF8ToJavaString;
33 using base::android::ConvertJavaStringToUTF8;
34 using browser_sync::SessionModelAssociator;
35 using browser_sync::SyncedSession;
36
37 SessionModelAssociator* ForeignSessionHelper::GetSessionModelAssociator() {
38 ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()
39 ->GetForProfile(profile_);
Ted C 2013/07/26 22:29:47 -> on previous line
Kibeom Kim (inactive) 2013/07/26 23:32:52 Done.
40
41 // Only return the associator if it exists and it is done syncing sessions.
42 if (!service || !service->ShouldPushChanges())
43 return NULL;
44
45 return service->GetSessionModelAssociator();
46 }
47
48 void ForeignSessionHelper::CopyTabsToJava(
Ted C 2013/07/26 22:29:47 can these be helper methods in an empty namespace
Kibeom Kim (inactive) 2013/07/26 23:32:52 Done.
49 JNIEnv* env,
50 const SessionWindow* window,
51 ScopedJavaLocalRef<jobject>& j_window) {
52 for (std::vector<SessionTab*>::const_iterator iit = window->tabs.begin();
53 iit != window->tabs.end(); ++iit) {
54 const SessionTab &tab = **iit;
55
56 if (tab.navigations.empty())
57 continue;
58
59 int selected_index = std::min(tab.current_navigation_index,
60 static_cast<int>(tab.navigations.size() - 1));
61 const ::sessions::SerializedNavigationEntry& current_navigation = tab
Ted C 2013/07/26 22:29:47 I would put tab on the following line.
Kibeom Kim (inactive) 2013/07/26 23:32:52 Done.
62 .navigations.at(selected_index);
63
64 GURL tab_url = current_navigation.virtual_url();
65 if (tab_url == GURL(chrome::kChromeUINewTabURL))
66 continue;
67
68 Java_ForeignSessionHelper_pushTab(
69 env, j_window.obj(),
70 ConvertUTF8ToJavaString(env, tab_url.spec()).Release(),
71 ConvertUTF16ToJavaString(env, current_navigation.title()).Release(),
72 tab.timestamp.ToInternalValue(), tab.tab_id.id());
73 }
74 }
75
76 void ForeignSessionHelper::CopyWindowsToJava(
77 JNIEnv* env,
78 const SyncedSession* session,
79 ScopedJavaLocalRef<jobject>& j_session) {
80 for (SyncedSession::SyncedWindowMap::const_iterator it =
81 session->windows.begin(); it != session->windows.end(); ++it) {
82 const SessionWindow* window = it->second;
83
84 if (window->tabs.empty()) {
85 NOTREACHED();
86 continue;
87 }
88
89 ScopedJavaLocalRef<jobject> last_pushed_window;
90 last_pushed_window.Reset(
91 Java_ForeignSessionHelper_pushWindow(
92 env, j_session.obj(), window->timestamp.ToInternalValue(),
93 window->window_id.id()));
94
95 CopyTabsToJava(env, window, last_pushed_window);
96 }
97 }
98
99 static jint Init(JNIEnv* env, jclass clazz, jobject profile) {
100 ForeignSessionHelper* foreign_session_helper = new ForeignSessionHelper(
101 ProfileAndroid::FromProfileAndroid(profile));
102 return reinterpret_cast<jint>(foreign_session_helper);
103 }
104
105 ForeignSessionHelper::ForeignSessionHelper(Profile* profile)
106 : profile_(profile) {
107 ProfileSyncService* service =ProfileSyncServiceFactory::GetInstance()->
108 GetForProfile(profile);
109
110 registrar_.Add(this, chrome::NOTIFICATION_SYNC_CONFIGURE_DONE,
111 content::Source<ProfileSyncService>(service));
112 registrar_.Add(this, chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED,
113 content::Source<Profile>(profile));
114 registrar_.Add(this, chrome::NOTIFICATION_FOREIGN_SESSION_DISABLED,
115 content::Source<Profile>(profile));
116 }
117
118 void ForeignSessionHelper::Destroy(JNIEnv* env, jobject obj) {
119 delete this;
120 }
121
122 jboolean ForeignSessionHelper::IsTabSyncEnabled(JNIEnv* env, jobject obj) {
123 ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()->
124 GetForProfile(profile_);
125 return service && service->GetActiveDataTypes().Has(syncer::PROXY_TABS);
126 }
127
128 void ForeignSessionHelper::SetOnForeignSessionCallback(JNIEnv* env, jobject obj,
129 jobject callback) {
130 callback_.Reset(env, callback);
131 }
132
133 void ForeignSessionHelper::Observe(
134 int type, const content::NotificationSource& source,
135 const content::NotificationDetails& details) {
136 if (callback_.is_null())
137 return;
138
139 JNIEnv* env = AttachCurrentThread();
140
141 switch (type) {
142 case chrome::NOTIFICATION_FOREIGN_SESSION_DISABLED:
143 // Tab sync is disabled, so clean up data about collapsed sessions.
144 profile_->GetPrefs()->ClearPref(
145 prefs::kNtpCollapsedForeignSessions);
146 // Purposeful fall through.
147 case chrome::NOTIFICATION_SYNC_CONFIGURE_DONE:
148 case chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED:
149 Java_OnForeignSessionCallback_onUpdated(env, callback_.obj());
150 break;
151 default:
152 NOTREACHED();
153 }
154 }
155
156 jboolean ForeignSessionHelper::GetForeignSessions(JNIEnv* env,
157 jobject obj,
158 jobject result) {
159 SessionModelAssociator* associator = GetSessionModelAssociator();
160 if (!associator)
161 return false;
162
163 std::vector<const browser_sync::SyncedSession*> sessions;
164 if (!associator->GetAllForeignSessions(&sessions))
165 return false;
166
167 // Use a pref to keep track of sessions that were collapsed by the user.
168 // To prevent the pref from accumulating stale sessions, clear it each time
169 // and only add back sessions that are still current.
170 DictionaryPrefUpdate pref_update(profile_->GetPrefs(),
171 prefs::kNtpCollapsedForeignSessions);
172 DictionaryValue* current_collapsed_sessions = pref_update.Get();
173 scoped_ptr<DictionaryValue> collapsed_sessions(
174 current_collapsed_sessions->DeepCopy());
175 current_collapsed_sessions->Clear();
176
177 ScopedJavaLocalRef<jobject> last_pushed_session;
178 ScopedJavaLocalRef<jobject> last_pushed_window;
179
180 // Note: we don't own the SyncedSessions themselves.
181 for (size_t i = 0; i < sessions.size(); ++i) {
182 const browser_sync::SyncedSession* session = sessions[i];
183
184 const bool is_collapsed = collapsed_sessions->HasKey(session->session_tag);
185
186 if (is_collapsed)
187 current_collapsed_sessions->SetBoolean(session->session_tag, true);
188
189 last_pushed_session.Reset(
190 Java_ForeignSessionHelper_pushSession(
191 env,
192 result,
193 ConvertUTF8ToJavaString(env, session->session_tag).Release(),
194 ConvertUTF8ToJavaString(env, session->session_name).Release(),
195 ConvertUTF8ToJavaString(env,
196 session->DeviceTypeAsString()).Release(),
197 session->modified_time.ToInternalValue()));
198
199 CopyWindowsToJava(env, session, last_pushed_session);
200 }
201
202 return true;
203 }
204
205 jboolean ForeignSessionHelper::OpenForeignSessionTab(JNIEnv* env, jobject obj,
Ted C 2013/07/26 22:29:47 same comment about params on their own lines
Kibeom Kim (inactive) 2013/07/26 23:32:52 Done.
206 jstring session_tag,
207 jint tab_id) {
208 content::RecordComputedAction("MobileNTPForeignSession");
209
210 SessionModelAssociator* associator = GetSessionModelAssociator();
211 if (!associator) {
212 LOG(ERROR) << "Null SessionModelAssociator returned.";
213 return false;
214 }
215
216 const SessionTab* tab;
217
218 if (!associator->GetForeignTab(ConvertJavaStringToUTF8(env, session_tag),
219 tab_id, &tab)) {
220 LOG(ERROR) << "Failed to load foreign tab.";
221 return false;
222 }
223
224 if (tab->navigations.empty()) {
225 LOG(ERROR) << "Foreign tab no longer has valid navigations.";
226 return false;
227 }
228
229 TabModel* tab_model = TabModelList::GetTabModelWithProfile(profile_);
230 DCHECK(tab_model);
231 if (!tab_model)
232 return false;
233
234 std::vector<content::NavigationEntry*> entries =
235 sessions::SerializedNavigationEntry::ToNavigationEntries(
236 tab->navigations, profile_);
237 content::WebContents* new_web_contents = content::WebContents::Create(
238 content::WebContents::CreateParams(profile_));
239 int selected_index = tab->normalized_navigation_index();
240 new_web_contents->GetController().Restore(
241 selected_index,
242 content::NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY,
243 &entries);
244 tab_model->CreateTab(new_web_contents);
245
246 return true;
247 }
248
249 void ForeignSessionHelper::SetForeignSessionCollapsed(JNIEnv* env, jobject obj,
250 jstring session_tag,
251 jboolean is_collapsed) {
252 // Store session tags for collapsed sessions in a preference so that the
253 // collapsed state persists.
254 PrefService* prefs = profile_->GetPrefs();
255 DictionaryPrefUpdate update(prefs, prefs::kNtpCollapsedForeignSessions);
256 if (is_collapsed)
257 update.Get()->SetBoolean(ConvertJavaStringToUTF8(env, session_tag), true);
258 else
259 update.Get()->Remove(ConvertJavaStringToUTF8(env, session_tag), NULL);
260 }
261
262 void ForeignSessionHelper::DeleteForeignSession(JNIEnv* env, jobject obj,
263 jstring session_tag) {
264 SessionModelAssociator* associator = GetSessionModelAssociator();
265 if (associator)
266 associator->DeleteForeignSession(ConvertJavaStringToUTF8(env, session_tag));
267 }
268
269 // static
270 bool ForeignSessionHelper::RegisterForeignSessionHelper(JNIEnv* env) {
271 return RegisterNativesImpl(env);
272 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698