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

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: findbug fix (dead code removal) 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
« no previous file with comments | « chrome/browser/android/foreign_session_helper.h ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/prefs/scoped_user_pref_update.h"
12 #include "chrome/browser/profiles/profile_android.h"
13 #include "chrome/browser/sync/glue/session_model_associator.h"
14 #include "chrome/browser/sync/profile_sync_service.h"
15 #include "chrome/browser/sync/profile_sync_service_factory.h"
16 #include "chrome/browser/ui/android/tab_model/tab_model.h"
17 #include "chrome/browser/ui/android/tab_model/tab_model_list.h"
18 #include "chrome/common/pref_names.h"
19 #include "chrome/common/url_constants.h"
20 #include "content/public/browser/notification_source.h"
21 #include "content/public/browser/user_metrics.h"
22 #include "content/public/browser/web_contents.h"
23 #include "jni/ForeignSessionHelper_jni.h"
24
25 using base::android::ScopedJavaGlobalRef;
26 using base::android::ScopedJavaLocalRef;
27 using base::android::AttachCurrentThread;
28 using base::android::ConvertUTF16ToJavaString;
29 using base::android::ConvertUTF8ToJavaString;
30 using base::android::ConvertJavaStringToUTF8;
31 using browser_sync::SessionModelAssociator;
32 using browser_sync::SyncedSession;
33
34 namespace {
35
36 SessionModelAssociator* GetSessionModelAssociator(Profile* profile) {
37 ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()->
38 GetForProfile(profile);
39
40 // Only return the associator if it exists and it is done syncing sessions.
41 if (!service || !service->ShouldPushChanges())
42 return NULL;
43
44 return service->GetSessionModelAssociator();
45 }
46
47 void CopyTabsToJava(
48 JNIEnv* env,
49 const SessionWindow* window,
50 ScopedJavaLocalRef<jobject>& j_window) {
51 for (std::vector<SessionTab*>::const_iterator tab_it = window->tabs.begin();
52 tab_it != window->tabs.end(); ++tab_it) {
53 const SessionTab &tab = **tab_it;
54
55 if (tab.navigations.empty())
56 continue;
57
58 const ::sessions::SerializedNavigationEntry& current_navigation =
59 tab.navigations.at(tab.current_navigation_index);
60
61 GURL tab_url = current_navigation.virtual_url();
62 if (tab_url.SchemeIs(chrome::kChromeNativeScheme) ||
63 (tab_url.SchemeIs(chrome::kChromeUIScheme) &&
64 tab_url.host() == chrome::kChromeUINewTabHost))
65 continue;
66
67 Java_ForeignSessionHelper_pushTab(
68 env, j_window.obj(),
69 ConvertUTF8ToJavaString(env, tab_url.spec()).Release(),
70 ConvertUTF16ToJavaString(env, current_navigation.title()).Release(),
71 tab.timestamp.ToInternalValue(), tab.tab_id.id());
72 }
73 }
74
75 void CopyWindowsToJava(
76 JNIEnv* env,
77 const SyncedSession* session,
78 ScopedJavaLocalRef<jobject>& j_session) {
79 for (SyncedSession::SyncedWindowMap::const_iterator it =
80 session->windows.begin(); it != session->windows.end(); ++it) {
81 const SessionWindow* window = it->second;
82
83 ScopedJavaLocalRef<jobject> last_pushed_window;
84 last_pushed_window.Reset(
85 Java_ForeignSessionHelper_pushWindow(
86 env, j_session.obj(), window->timestamp.ToInternalValue(),
87 window->window_id.id()));
88
89 CopyTabsToJava(env, window, last_pushed_window);
90 }
91 }
92
93 } // namespace
94
95 static jint Init(JNIEnv* env, jclass clazz, jobject profile) {
96 ForeignSessionHelper* foreign_session_helper = new ForeignSessionHelper(
97 ProfileAndroid::FromProfileAndroid(profile));
98 return reinterpret_cast<jint>(foreign_session_helper);
99 }
100
101 ForeignSessionHelper::ForeignSessionHelper(Profile* profile)
102 : profile_(profile) {
103 ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()->
104 GetForProfile(profile);
105
106 registrar_.Add(this, chrome::NOTIFICATION_SYNC_CONFIGURE_DONE,
107 content::Source<ProfileSyncService>(service));
108 registrar_.Add(this, chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED,
109 content::Source<Profile>(profile));
110 registrar_.Add(this, chrome::NOTIFICATION_FOREIGN_SESSION_DISABLED,
111 content::Source<Profile>(profile));
112 }
113
114 ForeignSessionHelper::~ForeignSessionHelper() {
115 }
116
117 void ForeignSessionHelper::Destroy(JNIEnv* env, jobject obj) {
118 delete this;
119 }
120
121 jboolean ForeignSessionHelper::IsTabSyncEnabled(JNIEnv* env, jobject obj) {
122 ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()->
123 GetForProfile(profile_);
124 return service && service->GetActiveDataTypes().Has(syncer::PROXY_TABS);
125 }
126
127 void ForeignSessionHelper::SetOnForeignSessionCallback(JNIEnv* env,
128 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_ForeignSessionCallback_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(profile_);
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* pref_collapsed_sessions = pref_update.Get();
173 scoped_ptr<DictionaryValue> collapsed_sessions(
174 pref_collapsed_sessions->DeepCopy());
175 pref_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 pref_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,
206 jobject obj,
207 jstring session_tag,
208 jint tab_id) {
209 SessionModelAssociator* associator = GetSessionModelAssociator(profile_);
210 if (!associator) {
211 LOG(ERROR) << "Null SessionModelAssociator returned.";
212 return false;
213 }
214
215 const SessionTab* tab;
216
217 if (!associator->GetForeignTab(ConvertJavaStringToUTF8(env, session_tag),
218 tab_id, &tab)) {
219 LOG(ERROR) << "Failed to load foreign tab.";
220 return false;
221 }
222
223 if (tab->navigations.empty()) {
224 LOG(ERROR) << "Foreign tab no longer has valid navigations.";
225 return false;
226 }
227
228 TabModel* tab_model = TabModelList::GetTabModelWithProfile(profile_);
229 DCHECK(tab_model);
230 if (!tab_model)
231 return false;
232
233 std::vector<content::NavigationEntry*> entries =
234 sessions::SerializedNavigationEntry::ToNavigationEntries(
235 tab->navigations, profile_);
236 content::WebContents* new_web_contents = content::WebContents::Create(
237 content::WebContents::CreateParams(profile_));
238 int selected_index = tab->normalized_navigation_index();
239 new_web_contents->GetController().Restore(
240 selected_index,
241 content::NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY,
242 &entries);
243 tab_model->CreateTab(new_web_contents);
244
245 return true;
246 }
247
248 void ForeignSessionHelper::SetForeignSessionCollapsed(JNIEnv* env, jobject obj,
249 jstring session_tag,
250 jboolean is_collapsed) {
251 // Store session tags for collapsed sessions in a preference so that the
252 // collapsed state persists.
253 PrefService* prefs = profile_->GetPrefs();
254 DictionaryPrefUpdate update(prefs, prefs::kNtpCollapsedForeignSessions);
255 if (is_collapsed)
256 update.Get()->SetBoolean(ConvertJavaStringToUTF8(env, session_tag), true);
257 else
258 update.Get()->Remove(ConvertJavaStringToUTF8(env, session_tag), NULL);
259 }
260
261 void ForeignSessionHelper::DeleteForeignSession(JNIEnv* env, jobject obj,
262 jstring session_tag) {
263 SessionModelAssociator* associator = GetSessionModelAssociator(profile_);
264 if (associator)
265 associator->DeleteForeignSession(ConvertJavaStringToUTF8(env, session_tag));
266 }
267
268 // static
269 bool ForeignSessionHelper::RegisterForeignSessionHelper(JNIEnv* env) {
270 return RegisterNativesImpl(env);
271 }
OLDNEW
« no previous file with comments | « chrome/browser/android/foreign_session_helper.h ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698