blob: 14f0413ab8d932dffa4d62931c2966d4c1a3c98c [file] [log] [blame]
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/complex_tasks/task_tab_helper.h"
#include <string>
#include "base/check_op.h"
#include "base/notreached.h"
#include "build/build_config.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "components/search_engines/template_url_service.h"
#include "content/public/browser/navigation_entry.h"
#if BUILDFLAG(IS_ANDROID)
#include "chrome/android/chrome_jni_headers/TaskTabHelper_jni.h"
#include "chrome/browser/android/tab_android.h"
using base::android::JavaParamRef;
#endif // BUILDFLAG(IS_ANDROID)
namespace {
bool DoesTransitionContinueTask(ui::PageTransition transition) {
return ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_LINK) ||
ui::PageTransitionCoreTypeIs(transition,
ui::PAGE_TRANSITION_AUTO_SUBFRAME) ||
ui::PageTransitionCoreTypeIs(transition,
ui::PAGE_TRANSITION_MANUAL_SUBFRAME) ||
ui::PageTransitionCoreTypeIs(transition,
ui::PAGE_TRANSITION_FORM_SUBMIT) ||
transition & ui::PAGE_TRANSITION_IS_REDIRECT_MASK;
}
} // namespace
namespace tasks {
TaskTabHelper::TaskTabHelper(content::WebContents* web_contents)
: content::WebContentsObserver(web_contents),
content::WebContentsUserData<TaskTabHelper>(*web_contents) {}
TaskTabHelper::~TaskTabHelper() = default;
void TaskTabHelper::NavigationEntryCommitted(
const content::LoadCommittedDetails& load_details) {
UpdateAndRecordTaskIds(load_details);
}
sessions::NavigationTaskId* TaskTabHelper::GetCurrentTaskId(
content::WebContents* web_contents) {
if (!web_contents)
return nullptr;
content::NavigationEntry* navigation_entry =
web_contents->GetController().GetLastCommittedEntry();
if (!navigation_entry)
return nullptr;
sessions::NavigationTaskId* navigation_task_id =
sessions::NavigationTaskId::Get(navigation_entry);
if (!navigation_task_id)
return nullptr;
return navigation_task_id;
}
void TaskTabHelper::UpdateAndRecordTaskIds(
const content::LoadCommittedDetails& load_details) {
sessions::NavigationTaskId* navigation_task_id =
sessions::NavigationTaskId::Get(load_details.entry);
// The Task ID is the Global ID of the first navigation. The first
// navigation is detected if the Task ID hasn't been set yet.
if (navigation_task_id->id() == -1) {
navigation_task_id->set_id(
load_details.entry->GetTimestamp().since_origin().InMicroseconds());
}
if (DoesTransitionContinueTask(load_details.entry->GetTransitionType())) {
if (load_details.previous_entry_index != -1) {
content::NavigationEntry* prev_nav_entry =
web_contents()->GetController().GetEntryAtIndex(
load_details.previous_entry_index);
if (prev_nav_entry != nullptr) {
sessions::NavigationTaskId* prev_navigation_task_id =
sessions::NavigationTaskId::Get(prev_nav_entry);
navigation_task_id->set_parent_id(prev_navigation_task_id->id());
navigation_task_id->set_root_id(prev_navigation_task_id->root_id());
}
} else if (GetParentTaskId() != -1) {
// If the previous_entry_index is -1, this is a new tab. Use the parent
// task-id for the case of cross tab navigations (such as window.open).
navigation_task_id->set_parent_id(GetParentTaskId());
navigation_task_id->set_root_id(GetParentRootTaskId());
}
} else {
navigation_task_id->set_root_id(navigation_task_id->id());
}
local_navigation_task_id_map_.emplace(load_details.entry->GetUniqueID(),
*navigation_task_id);
}
int64_t TaskTabHelper::GetParentTaskId() {
#if BUILDFLAG(IS_ANDROID)
TabAndroid* tab_android = TabAndroid::FromWebContents(web_contents());
return tab_android && Java_TaskTabHelper_getParentTaskId(
base::android::AttachCurrentThread(),
tab_android->GetJavaObject());
#else
return -1;
#endif
}
int64_t TaskTabHelper::GetParentRootTaskId() {
#if BUILDFLAG(IS_ANDROID)
TabAndroid* tab_android = TabAndroid::FromWebContents(web_contents());
return tab_android && Java_TaskTabHelper_getParentRootTaskId(
base::android::AttachCurrentThread(),
tab_android->GetJavaObject());
#else
return -1;
#endif
}
#if BUILDFLAG(IS_ANDROID)
jlong JNI_TaskTabHelper_GetTaskId(JNIEnv* env,
const JavaParamRef<jobject>& jweb_contents) {
sessions::NavigationTaskId* navigation_task_id =
TaskTabHelper::GetCurrentTaskId(
content::WebContents::FromJavaWebContents(jweb_contents));
if (navigation_task_id) {
return navigation_task_id->id();
}
return -1;
}
jlong JNI_TaskTabHelper_GetRootTaskId(
JNIEnv* env,
const JavaParamRef<jobject>& jweb_contents) {
sessions::NavigationTaskId* navigation_task_id =
TaskTabHelper::GetCurrentTaskId(
content::WebContents::FromJavaWebContents(jweb_contents));
if (navigation_task_id) {
return navigation_task_id->root_id();
}
return -1;
}
#endif // BUILDFLAG(IS_ANDROID)
WEB_CONTENTS_USER_DATA_KEY_IMPL(TaskTabHelper);
} // namespace tasks