1 // Copyright 2014 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.
5 #include "chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h"
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/android/jni_weak_ref.h"
10 #include "base/metrics/histogram.h"
11 #include "base/time/time.h"
12 #include "chrome/browser/android/tab_android.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/profiles/profile_android.h"
16 #include "chrome/browser/profiles/profile_manager.h"
17 #include "chrome/browser/tab_contents/tab_util.h"
18 #include "chrome/browser/ui/android/tab_model/tab_model_list.h"
19 #include "content/public/browser/web_contents.h"
20 #include "jni/TabModelJniBridge_jni.h"
22 using base::android::AttachCurrentThread
;
23 using base::android::ConvertUTF8ToJavaString
;
24 using content::WebContents
;
28 static Profile
* FindProfile(jboolean is_incognito
) {
29 if (g_browser_process
== NULL
||
30 g_browser_process
->profile_manager() == NULL
) {
31 LOG(ERROR
) << "Browser process or profile manager not initialized";
34 Profile
* profile
= ProfileManager::GetActiveUserProfile();
36 return profile
->GetOffTheRecordProfile();
42 TabModelJniBridge::TabModelJniBridge(JNIEnv
* env
,
45 : TabModel(FindProfile(is_incognito
)),
46 java_object_(env
, env
->NewWeakGlobalRef(jobj
)) {
47 TabModelList::AddTabModel(this);
50 void TabModelJniBridge::Destroy(JNIEnv
* env
, jobject obj
) {
54 ScopedJavaLocalRef
<jobject
> TabModelJniBridge::GetProfileAndroid(JNIEnv
* env
,
56 ProfileAndroid
* profile_android
= ProfileAndroid::FromProfile(GetProfile());
58 return ScopedJavaLocalRef
<jobject
>();
59 return profile_android
->GetJavaObject();
62 void TabModelJniBridge::TabAddedToModel(JNIEnv
* env
,
65 TabAndroid
* tab
= TabAndroid::GetNativeTab(env
, jtab
);
67 // Tab#initialize() should have been called by now otherwise we can't push
71 tab
->SetWindowSessionID(GetSessionId());
74 int TabModelJniBridge::GetTabCount() const {
75 JNIEnv
* env
= AttachCurrentThread();
76 return Java_TabModelJniBridge_getCount(env
, java_object_
.get(env
).obj());
79 int TabModelJniBridge::GetActiveIndex() const {
80 JNIEnv
* env
= AttachCurrentThread();
81 return Java_TabModelJniBridge_index(env
, java_object_
.get(env
).obj());
84 void TabModelJniBridge::CreateTab(WebContents
* web_contents
,
86 JNIEnv
* env
= AttachCurrentThread();
87 Java_TabModelJniBridge_createTabWithWebContents(
88 env
, java_object_
.get(env
).obj(),
89 web_contents
->GetBrowserContext()->IsOffTheRecord(),
90 web_contents
->GetJavaWebContents().obj(),
94 WebContents
* TabModelJniBridge::GetWebContentsAt(int index
) const {
95 TabAndroid
* tab
= GetTabAt(index
);
96 return tab
== NULL
? NULL
: tab
->web_contents();
99 TabAndroid
* TabModelJniBridge::GetTabAt(int index
) const {
100 JNIEnv
* env
= AttachCurrentThread();
101 ScopedJavaLocalRef
<jobject
> jtab
=
102 Java_TabModelJniBridge_getTabAt(env
,
103 java_object_
.get(env
).obj(),
106 return jtab
.is_null() ?
107 NULL
: TabAndroid::GetNativeTab(env
, jtab
.obj());
110 void TabModelJniBridge::SetActiveIndex(int index
) {
111 JNIEnv
* env
= AttachCurrentThread();
112 Java_TabModelJniBridge_setIndex(env
, java_object_
.get(env
).obj(), index
);
115 void TabModelJniBridge::CloseTabAt(int index
) {
116 JNIEnv
* env
= AttachCurrentThread();
117 Java_TabModelJniBridge_closeTabAt(env
,
118 java_object_
.get(env
).obj(),
122 WebContents
* TabModelJniBridge::CreateNewTabForDevTools(
124 // TODO(dfalcantara): Change the Java side so that it creates and returns the
125 // WebContents, which we can load the URL on and return.
126 JNIEnv
* env
= AttachCurrentThread();
127 ScopedJavaLocalRef
<jstring
> jurl
= ConvertUTF8ToJavaString(env
, url
.spec());
128 ScopedJavaLocalRef
<jobject
> obj
=
129 Java_TabModelJniBridge_createNewTabForDevTools(
131 java_object_
.get(env
).obj(),
134 VLOG(0) << "Failed to create java tab";
137 TabAndroid
* tab
= TabAndroid::GetNativeTab(env
, obj
.obj());
139 VLOG(0) << "Failed to create java tab";
142 return tab
->web_contents();
145 bool TabModelJniBridge::IsSessionRestoreInProgress() const {
146 JNIEnv
* env
= AttachCurrentThread();
147 return Java_TabModelJniBridge_isSessionRestoreInProgress(
148 env
, java_object_
.get(env
).obj());
151 void TabModelJniBridge::BroadcastSessionRestoreComplete(JNIEnv
* env
,
153 TabModel::BroadcastSessionRestoreComplete();
156 inline static base::TimeDelta
GetTimeDelta(jlong ms
) {
157 return base::TimeDelta::FromMilliseconds(static_cast<int64
>(ms
));
160 void LogFromCloseMetric(JNIEnv
* env
,
161 const JavaParamRef
<jclass
>& jcaller
,
163 jboolean perceived
) {
165 UMA_HISTOGRAM_TIMES("Tabs.SwitchFromCloseLatency_Perceived",
168 UMA_HISTOGRAM_TIMES("Tabs.SwitchFromCloseLatency_Actual",
173 void LogFromExitMetric(JNIEnv
* env
,
174 const JavaParamRef
<jclass
>& jcaller
,
176 jboolean perceived
) {
178 UMA_HISTOGRAM_TIMES("Tabs.SwitchFromExitLatency_Perceived",
181 UMA_HISTOGRAM_TIMES("Tabs.SwitchFromExitLatency_Actual",
186 void LogFromNewMetric(JNIEnv
* env
,
187 const JavaParamRef
<jclass
>& jcaller
,
189 jboolean perceived
) {
191 UMA_HISTOGRAM_TIMES("Tabs.SwitchFromNewLatency_Perceived",
194 UMA_HISTOGRAM_TIMES("Tabs.SwitchFromNewLatency_Actual",
199 void LogFromUserMetric(JNIEnv
* env
,
200 const JavaParamRef
<jclass
>& jcaller
,
202 jboolean perceived
) {
204 UMA_HISTOGRAM_TIMES("Tabs.SwitchFromUserLatency_Perceived",
207 UMA_HISTOGRAM_TIMES("Tabs.SwitchFromUserLatency_Actual",
212 TabModelJniBridge::~TabModelJniBridge() {
213 TabModelList::RemoveTabModel(this);
216 bool TabModelJniBridge::Register(JNIEnv
* env
) {
217 return RegisterNativesImpl(env
);
220 static jlong
Init(JNIEnv
* env
,
221 const JavaParamRef
<jobject
>& obj
,
222 jboolean is_incognito
) {
223 TabModel
* tab_model
= new TabModelJniBridge(env
, obj
, is_incognito
);
224 return reinterpret_cast<intptr_t>(tab_model
);