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

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: some renamings Created 7 years, 5 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::AttachCurrentThread;
30 using base::android::ConvertUTF16ToJavaString;
31 using base::android::ConvertUTF8ToJavaString;
32 using base::android::ConvertJavaStringToUTF8;
33 using browser_sync::SessionModelAssociator;
34 using browser_sync::SyncedSession;
35
36 static jint Init(JNIEnv* env, jclass clazz, jobject profile) {
37 ForeignSessionHelper* foreign_session_helper = new ForeignSessionHelper(
38 ProfileAndroid::FromProfileAndroid(profile));
39 return reinterpret_cast<jint>(foreign_session_helper);
40 }
41
42 ForeignSessionHelper::ForeignSessionHelper(Profile* profile) {
43 profile_ = profile;
Ted C 2013/07/24 23:48:20 can you use an initializer list here instead?
Kibeom Kim (inactive) 2013/07/25 21:18:23 Done.
44 callback_.Reset();
Ted C 2013/07/24 23:48:20 is this necessary?
Kibeom Kim (inactive) 2013/07/25 21:18:23 No :( Done.
45
46 ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()
47 ->GetForProfile(profile);
Ted C 2013/07/24 23:48:20 having the -> on the previous line seems much more
Kibeom Kim (inactive) 2013/07/25 21:18:23 Done.
48
49 registrar_.Add(this, chrome::NOTIFICATION_SYNC_CONFIGURE_DONE,
50 content::Source<ProfileSyncService>(service));
51 registrar_.Add(this, chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED,
52 content::Source<Profile>(profile));
53 registrar_.Add(this, chrome::NOTIFICATION_FOREIGN_SESSION_DISABLED,
54 content::Source<Profile>(profile));
55 }
56
57 void ForeignSessionHelper::Destroy(JNIEnv* env, jobject obj) {
58 delete this;
59 }
60
61 jboolean ForeignSessionHelper::IsTabSyncEnabled(JNIEnv* env, jobject obj) {
62 ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()
63 ->GetForProfile(profile_);
Ted C 2013/07/24 23:48:20 same comment as above
Kibeom Kim (inactive) 2013/07/25 21:18:23 Done.
64 return service && service->GetActiveDataTypes().Has(syncer::PROXY_TABS);
65 }
66
67 void ForeignSessionHelper::SetOnForeignSessionCallback(JNIEnv* env, jobject obj,
Ted C 2013/07/24 23:48:20 I think if all the params don't fit on one line, t
Kibeom Kim (inactive) 2013/07/25 21:18:23 Done.
68 jobject callback) {
69 callback_.Reset(env, callback);
70 }
71
72 void ForeignSessionHelper::Observe(
73 int type, const content::NotificationSource& source,
74 const content::NotificationDetails& details) {
75 if (callback_.is_null())
76 return;
77
78 JNIEnv* env = AttachCurrentThread();
79
80 switch (type) {
81 case chrome::NOTIFICATION_FOREIGN_SESSION_DISABLED:
82 // Tab sync is disabled, so clean up data about collapsed sessions.
83 profile_->GetPrefs()->ClearPref(
84 prefs::kNtpCollapsedForeignSessions);
85 // Purposeful fall through.
86 case chrome::NOTIFICATION_SYNC_CONFIGURE_DONE:
87 case chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED:
88 Java_OnForeignSessionCallback_onUpdated(env, callback_.obj());
89 break;
90 default:
91 NOTREACHED();
92 }
93 }
94
95 jboolean ForeignSessionHelper::GetForeignSessions(JNIEnv* env, jobject obj,
96 jobject result) {
97 SessionModelAssociator* associator = GetSessionModelAssociator();
98 if (associator == NULL)
Ted C 2013/07/24 23:48:20 if (!associator)
Kibeom Kim (inactive) 2013/07/25 21:18:23 Done.
99 return false;
100
101 std::vector<const browser_sync::SyncedSession*> sessions;
102 if (!associator->GetAllForeignSessions(&sessions))
103 return false;
104
105 // Use a pref to keep track of sessions that were collapsed by the user.
106 // To prevent the pref from accumulating stale sessions, clear it each time
107 // and only add back sessions that are still current.
108 DictionaryPrefUpdate pref_update(profile_->GetPrefs(),
109 prefs::kNtpCollapsedForeignSessions);
110 DictionaryValue* current_collapsed_sessions = pref_update.Get();
111 scoped_ptr<DictionaryValue> collapsed_sessions(
112 current_collapsed_sessions->DeepCopy());
113 current_collapsed_sessions->Clear();
114
115 // Note: we don't own the SyncedSessions themselves.
116 for (size_t i = 0; i < sessions.size(); ++i) {
117 const browser_sync::SyncedSession* session = sessions[i];
118
119 const bool is_collapsed = collapsed_sessions->HasKey(session->session_tag);
120
121 if (is_collapsed)
122 current_collapsed_sessions->SetBoolean(session->session_tag, true);
123
124 Java_ForeignSessionHelper_pushSession(
125 env, result,
126 ConvertUTF8ToJavaString(env, session->session_tag).Release(),
127 ConvertUTF8ToJavaString(env, session->session_name).Release(),
128 ConvertUTF8ToJavaString(env, session->DeviceTypeAsString()).Release(),
129 session->modified_time.ToInternalValue());
130
131 for (SyncedSession::SyncedWindowMap::const_iterator it =
132 session->windows.begin(); it != session->windows.end(); ++it) {
133 SessionWindow* window = it->second;
134
135 if (window->tabs.empty()) {
136 NOTREACHED();
137 continue;
138 }
139
140 Java_ForeignSessionHelper_pushWindow(
141 env, result,
142 window->timestamp.ToInternalValue(),
143 window->window_id.id());
144
145 for (std::vector<SessionTab*>::iterator iit = window->tabs.begin();
Ted C 2013/07/24 23:48:20 Might consider having helper methods for the inner
Kibeom Kim (inactive) 2013/07/25 21:18:23 Done.
146 iit != window->tabs.end(); ++iit) {
147 const SessionTab &tab = **iit;
148
149 if (tab.navigations.empty())
150 continue;
151
152 int selected_index = std::min(
153 tab.current_navigation_index,
154 static_cast<int>(tab.navigations.size() - 1));
155 const ::sessions::SerializedNavigationEntry& current_navigation =
156 tab.navigations.at(selected_index);
157
158 GURL tab_url = current_navigation.virtual_url();
159 if (tab_url == GURL(chrome::kChromeUINewTabURL))
160 continue;
161
162 Java_ForeignSessionHelper_pushTab(
163 env, result,
164 ConvertUTF8ToJavaString(env, tab_url.spec()).Release(),
165 ConvertUTF16ToJavaString(env, current_navigation.title()).Release(),
166 tab.timestamp.ToInternalValue(),
167 tab.tab_id.id());
168 }
169 }
170 }
171
172 return true;
173 }
174
175 jboolean ForeignSessionHelper::OpenForeignSessionTab(JNIEnv* env, jobject obj,
176 jstring session_tag,
177 jint tab_id) {
178 content::RecordComputedAction("MobileNTPForeignSession");
179
180 SessionModelAssociator* associator = GetSessionModelAssociator();
181 if (!associator) {
182 LOG(ERROR) << "Null SessionModelAssociator returned.";
183 return false;
184 }
185
186 const SessionTab* tab;
187
188 if (!associator->GetForeignTab(ConvertJavaStringToUTF8(env, session_tag),
189 tab_id, &tab)) {
190 LOG(ERROR) << "Failed to load foreign tab.";
191 return false;
192 }
193
194 if (tab->navigations.empty()) {
195 LOG(ERROR) << "Foreign tab no longer has valid navigations.";
196 return false;
197 }
198
199 TabModel* tab_model = TabModelList::GetTabModelWithProfile(profile_);
200 DCHECK(tab_model);
201 if (!tab_model)
202 return false;
203
204 std::vector<content::NavigationEntry*> entries =
205 sessions::SerializedNavigationEntry::ToNavigationEntries(
206 tab->navigations, profile_);
207 content::WebContents* new_web_contents = content::WebContents::Create(
208 content::WebContents::CreateParams(profile_));
209 int selected_index = tab->normalized_navigation_index();
210 new_web_contents->GetController().Restore(
211 selected_index,
212 content::NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY,
213 &entries);
214 tab_model->CreateTab(new_web_contents);
215
216 return true;
217 }
218
219 void ForeignSessionHelper::SetForeignSessionCollapsed(JNIEnv* env, jobject obj,
220 jstring session_tag,
221 jboolean is_collapsed) {
222 // Store session tags for collapsed sessions in a preference so that the
223 // collapsed state persists.
224 PrefService* prefs = profile_->GetPrefs();
225 DictionaryPrefUpdate update(prefs, prefs::kNtpCollapsedForeignSessions);
226 if (is_collapsed)
227 update.Get()->SetBoolean(ConvertJavaStringToUTF8(env, session_tag), true);
228 else
229 update.Get()->Remove(ConvertJavaStringToUTF8(env, session_tag), NULL);
230 }
231
232 void ForeignSessionHelper::DeleteForeignSession(JNIEnv* env, jobject obj,
233 jstring session_tag) {
234 SessionModelAssociator* associator = GetSessionModelAssociator();
235 if (associator)
236 associator->DeleteForeignSession(ConvertJavaStringToUTF8(env, session_tag));
237 }
238
239 SessionModelAssociator* ForeignSessionHelper::GetSessionModelAssociator() {
240 ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()
241 ->GetForProfile(profile_);
242
243 // Only return the associator if it exists and it is done syncing sessions.
244 if (!service || !service->ShouldPushChanges())
245 return NULL;
246
247 return service->GetSessionModelAssociator();
248 }
249
250 // static
251 bool ForeignSessionHelper::RegisterForeignSessionHelper(JNIEnv* env) {
252 return RegisterNativesImpl(env);
253 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698