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

Unified 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, 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/android/foreign_session_helper.cc
diff --git a/chrome/browser/android/foreign_session_helper.cc b/chrome/browser/android/foreign_session_helper.cc
new file mode 100644
index 0000000000000000000000000000000000000000..927dbaea2977c4e0f64433ed40721ebade74d75c
--- /dev/null
+++ b/chrome/browser/android/foreign_session_helper.cc
@@ -0,0 +1,272 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/android/foreign_session_helper.h"
+
+#include <jni.h>
+
+#include "base/android/jni_string.h"
+
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/prefs/scoped_user_pref_update.h"
+#include "chrome/browser/profiles/profile_android.h"
+#include "chrome/browser/sync/glue/session_model_associator.h"
+#include "chrome/browser/sync/profile_sync_service.h"
+#include "chrome/browser/sync/profile_sync_service_factory.h"
+#include "chrome/browser/ui/android/tab_model/tab_model.h"
+#include "chrome/browser/ui/android/tab_model/tab_model_list.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/url_constants.h"
+
+#include "content/public/browser/notification_source.h"
+#include "content/public/browser/user_metrics.h"
+#include "content/public/browser/web_contents.h"
+
+#include "jni/ForeignSessionHelper_jni.h"
+
+using base::android::ScopedJavaGlobalRef;
+using base::android::ScopedJavaLocalRef;
+using base::android::AttachCurrentThread;
+using base::android::ConvertUTF16ToJavaString;
+using base::android::ConvertUTF8ToJavaString;
+using base::android::ConvertJavaStringToUTF8;
+using browser_sync::SessionModelAssociator;
+using browser_sync::SyncedSession;
+
+SessionModelAssociator* ForeignSessionHelper::GetSessionModelAssociator() {
+ ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()
+ ->GetForProfile(profile_);
Ted C 2013/07/26 22:29:47 -> on previous line
Kibeom Kim (inactive) 2013/07/26 23:32:52 Done.
+
+ // Only return the associator if it exists and it is done syncing sessions.
+ if (!service || !service->ShouldPushChanges())
+ return NULL;
+
+ return service->GetSessionModelAssociator();
+}
+
+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.
+ JNIEnv* env,
+ const SessionWindow* window,
+ ScopedJavaLocalRef<jobject>& j_window) {
+ for (std::vector<SessionTab*>::const_iterator iit = window->tabs.begin();
+ iit != window->tabs.end(); ++iit) {
+ const SessionTab &tab = **iit;
+
+ if (tab.navigations.empty())
+ continue;
+
+ int selected_index = std::min(tab.current_navigation_index,
+ static_cast<int>(tab.navigations.size() - 1));
+ 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.
+ .navigations.at(selected_index);
+
+ GURL tab_url = current_navigation.virtual_url();
+ if (tab_url == GURL(chrome::kChromeUINewTabURL))
+ continue;
+
+ Java_ForeignSessionHelper_pushTab(
+ env, j_window.obj(),
+ ConvertUTF8ToJavaString(env, tab_url.spec()).Release(),
+ ConvertUTF16ToJavaString(env, current_navigation.title()).Release(),
+ tab.timestamp.ToInternalValue(), tab.tab_id.id());
+ }
+}
+
+void ForeignSessionHelper::CopyWindowsToJava(
+ JNIEnv* env,
+ const SyncedSession* session,
+ ScopedJavaLocalRef<jobject>& j_session) {
+ for (SyncedSession::SyncedWindowMap::const_iterator it =
+ session->windows.begin(); it != session->windows.end(); ++it) {
+ const SessionWindow* window = it->second;
+
+ if (window->tabs.empty()) {
+ NOTREACHED();
+ continue;
+ }
+
+ ScopedJavaLocalRef<jobject> last_pushed_window;
+ last_pushed_window.Reset(
+ Java_ForeignSessionHelper_pushWindow(
+ env, j_session.obj(), window->timestamp.ToInternalValue(),
+ window->window_id.id()));
+
+ CopyTabsToJava(env, window, last_pushed_window);
+ }
+}
+
+static jint Init(JNIEnv* env, jclass clazz, jobject profile) {
+ ForeignSessionHelper* foreign_session_helper = new ForeignSessionHelper(
+ ProfileAndroid::FromProfileAndroid(profile));
+ return reinterpret_cast<jint>(foreign_session_helper);
+}
+
+ForeignSessionHelper::ForeignSessionHelper(Profile* profile)
+ : profile_(profile) {
+ ProfileSyncService* service =ProfileSyncServiceFactory::GetInstance()->
+ GetForProfile(profile);
+
+ registrar_.Add(this, chrome::NOTIFICATION_SYNC_CONFIGURE_DONE,
+ content::Source<ProfileSyncService>(service));
+ registrar_.Add(this, chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED,
+ content::Source<Profile>(profile));
+ registrar_.Add(this, chrome::NOTIFICATION_FOREIGN_SESSION_DISABLED,
+ content::Source<Profile>(profile));
+}
+
+void ForeignSessionHelper::Destroy(JNIEnv* env, jobject obj) {
+ delete this;
+}
+
+jboolean ForeignSessionHelper::IsTabSyncEnabled(JNIEnv* env, jobject obj) {
+ ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()->
+ GetForProfile(profile_);
+ return service && service->GetActiveDataTypes().Has(syncer::PROXY_TABS);
+}
+
+void ForeignSessionHelper::SetOnForeignSessionCallback(JNIEnv* env, jobject obj,
+ jobject callback) {
+ callback_.Reset(env, callback);
+}
+
+void ForeignSessionHelper::Observe(
+ int type, const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ if (callback_.is_null())
+ return;
+
+ JNIEnv* env = AttachCurrentThread();
+
+ switch (type) {
+ case chrome::NOTIFICATION_FOREIGN_SESSION_DISABLED:
+ // Tab sync is disabled, so clean up data about collapsed sessions.
+ profile_->GetPrefs()->ClearPref(
+ prefs::kNtpCollapsedForeignSessions);
+ // Purposeful fall through.
+ case chrome::NOTIFICATION_SYNC_CONFIGURE_DONE:
+ case chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED:
+ Java_OnForeignSessionCallback_onUpdated(env, callback_.obj());
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+jboolean ForeignSessionHelper::GetForeignSessions(JNIEnv* env,
+ jobject obj,
+ jobject result) {
+ SessionModelAssociator* associator = GetSessionModelAssociator();
+ if (!associator)
+ return false;
+
+ std::vector<const browser_sync::SyncedSession*> sessions;
+ if (!associator->GetAllForeignSessions(&sessions))
+ return false;
+
+ // Use a pref to keep track of sessions that were collapsed by the user.
+ // To prevent the pref from accumulating stale sessions, clear it each time
+ // and only add back sessions that are still current.
+ DictionaryPrefUpdate pref_update(profile_->GetPrefs(),
+ prefs::kNtpCollapsedForeignSessions);
+ DictionaryValue* current_collapsed_sessions = pref_update.Get();
+ scoped_ptr<DictionaryValue> collapsed_sessions(
+ current_collapsed_sessions->DeepCopy());
+ current_collapsed_sessions->Clear();
+
+ ScopedJavaLocalRef<jobject> last_pushed_session;
+ ScopedJavaLocalRef<jobject> last_pushed_window;
+
+ // Note: we don't own the SyncedSessions themselves.
+ for (size_t i = 0; i < sessions.size(); ++i) {
+ const browser_sync::SyncedSession* session = sessions[i];
+
+ const bool is_collapsed = collapsed_sessions->HasKey(session->session_tag);
+
+ if (is_collapsed)
+ current_collapsed_sessions->SetBoolean(session->session_tag, true);
+
+ last_pushed_session.Reset(
+ Java_ForeignSessionHelper_pushSession(
+ env,
+ result,
+ ConvertUTF8ToJavaString(env, session->session_tag).Release(),
+ ConvertUTF8ToJavaString(env, session->session_name).Release(),
+ ConvertUTF8ToJavaString(env,
+ session->DeviceTypeAsString()).Release(),
+ session->modified_time.ToInternalValue()));
+
+ CopyWindowsToJava(env, session, last_pushed_session);
+ }
+
+ return true;
+}
+
+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.
+ jstring session_tag,
+ jint tab_id) {
+ content::RecordComputedAction("MobileNTPForeignSession");
+
+ SessionModelAssociator* associator = GetSessionModelAssociator();
+ if (!associator) {
+ LOG(ERROR) << "Null SessionModelAssociator returned.";
+ return false;
+ }
+
+ const SessionTab* tab;
+
+ if (!associator->GetForeignTab(ConvertJavaStringToUTF8(env, session_tag),
+ tab_id, &tab)) {
+ LOG(ERROR) << "Failed to load foreign tab.";
+ return false;
+ }
+
+ if (tab->navigations.empty()) {
+ LOG(ERROR) << "Foreign tab no longer has valid navigations.";
+ return false;
+ }
+
+ TabModel* tab_model = TabModelList::GetTabModelWithProfile(profile_);
+ DCHECK(tab_model);
+ if (!tab_model)
+ return false;
+
+ std::vector<content::NavigationEntry*> entries =
+ sessions::SerializedNavigationEntry::ToNavigationEntries(
+ tab->navigations, profile_);
+ content::WebContents* new_web_contents = content::WebContents::Create(
+ content::WebContents::CreateParams(profile_));
+ int selected_index = tab->normalized_navigation_index();
+ new_web_contents->GetController().Restore(
+ selected_index,
+ content::NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY,
+ &entries);
+ tab_model->CreateTab(new_web_contents);
+
+ return true;
+}
+
+void ForeignSessionHelper::SetForeignSessionCollapsed(JNIEnv* env, jobject obj,
+ jstring session_tag,
+ jboolean is_collapsed) {
+ // Store session tags for collapsed sessions in a preference so that the
+ // collapsed state persists.
+ PrefService* prefs = profile_->GetPrefs();
+ DictionaryPrefUpdate update(prefs, prefs::kNtpCollapsedForeignSessions);
+ if (is_collapsed)
+ update.Get()->SetBoolean(ConvertJavaStringToUTF8(env, session_tag), true);
+ else
+ update.Get()->Remove(ConvertJavaStringToUTF8(env, session_tag), NULL);
+}
+
+void ForeignSessionHelper::DeleteForeignSession(JNIEnv* env, jobject obj,
+ jstring session_tag) {
+ SessionModelAssociator* associator = GetSessionModelAssociator();
+ if (associator)
+ associator->DeleteForeignSession(ConvertJavaStringToUTF8(env, session_tag));
+}
+
+// static
+bool ForeignSessionHelper::RegisterForeignSessionHelper(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}

Powered by Google App Engine
This is Rietveld 408576698