blob: 11cdb81c1b5d32f7d88d6fdd4bcb03c29c450ecc [file] [log] [blame]
Scott Violet009c09c2020-01-18 00:57:181// Copyright 2020 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 "weblayer/browser/browser_impl.h"
6
7#include <algorithm>
8
Mugdha Lakhani5f8de7cc2020-03-10 20:43:369#include "base/callback_forward.h"
Scott Violetbb6c84552020-01-29 23:35:2410#include "base/containers/unique_ptr_adapters.h"
Gabriel Charette9f60dd12020-03-06 20:48:0411#include "base/memory/ptr_util.h"
Scott Violet87450ce2020-01-23 01:56:2512#include "base/path_service.h"
Scott Violet95a6d682020-06-11 23:28:3213#include "base/stl_util.h"
Scott Violet87450ce2020-01-23 01:56:2514#include "components/base32/base32.h"
Bo Liuf6389812020-07-13 16:24:1315#include "content/public/browser/web_contents.h"
Gyuyoung Kim1ac4ca782020-09-11 03:32:5116#include "third_party/blink/public/common/web_preferences/web_preferences.h"
John Abd-El-Malek6ecfbd32020-07-22 18:11:3117#include "weblayer/browser/browser_context_impl.h"
Scott Violet7e39f86c2020-06-24 22:33:4618#include "weblayer/browser/browser_list.h"
Scott Violet1e3e0b42020-04-02 14:43:2219#include "weblayer/browser/feature_list_creator.h"
Scott Violet9843d0a2020-02-11 22:38:0720#include "weblayer/browser/persistence/browser_persister.h"
Scott Violet95a6d682020-06-11 23:28:3221#include "weblayer/browser/persistence/browser_persister_file_utils.h"
Scott Violet343f4ec2020-01-30 02:58:0822#include "weblayer/browser/persistence/minimal_browser_persister.h"
Scott Violet009c09c2020-01-18 00:57:1823#include "weblayer/browser/profile_impl.h"
24#include "weblayer/browser/tab_impl.h"
Scott Violet87450ce2020-01-23 01:56:2525#include "weblayer/common/weblayer_paths.h"
Scott Violet009c09c2020-01-18 00:57:1826#include "weblayer/public/browser_observer.h"
Scott Violetf251a022020-10-07 16:54:4327#include "weblayer/public/browser_restore_observer.h"
Scott Violet009c09c2020-01-18 00:57:1828
29#if defined(OS_ANDROID)
30#include "base/android/callback_android.h"
Scott Violetbf8b8aa72020-01-28 19:37:3231#include "base/android/jni_array.h"
Scott Violet009c09c2020-01-18 00:57:1832#include "base/android/jni_string.h"
33#include "base/json/json_writer.h"
John Abd-El-Malek6dd19662020-06-19 05:49:3434#include "components/metrics/metrics_service.h"
35#include "components/ukm/ukm_service.h"
36#include "weblayer/browser/android/metrics/weblayer_metrics_service_client.h"
Tim Volodine9839f182020-04-23 17:51:2537#include "weblayer/browser/browser_process.h"
Scott Violet009c09c2020-01-18 00:57:1838#include "weblayer/browser/java/jni/BrowserImpl_jni.h"
39#endif
40
Scott Violet90564152020-01-31 18:31:3041#if defined(OS_ANDROID)
42using base::android::AttachCurrentThread;
43using base::android::JavaParamRef;
44using base::android::ScopedJavaLocalRef;
45#endif
46
Scott Violet009c09c2020-01-18 00:57:1847namespace weblayer {
48
Scott Violet95a6d682020-06-11 23:28:3249namespace {
50
John Abd-El-Malek6dd19662020-06-19 05:49:3451#if defined(OS_ANDROID)
52void UpdateMetricsService() {
53 static bool s_foreground = false;
Scott Violet7e39f86c2020-06-24 22:33:4654 // TODO(sky): convert this to observer.
55 bool foreground = BrowserList::GetInstance()->HasAtLeastOneResumedBrowser();
John Abd-El-Malek6dd19662020-06-19 05:49:3456
57 if (foreground == s_foreground)
58 return;
59
60 s_foreground = foreground;
61
62 auto* metrics_service =
63 WebLayerMetricsServiceClient::GetInstance()->GetMetricsService();
64 if (metrics_service) {
65 if (foreground)
66 metrics_service->OnAppEnterForeground();
67 else
68 metrics_service->OnAppEnterBackground();
69 }
70
71 auto* ukm_service =
72 WebLayerMetricsServiceClient::GetInstance()->GetUkmService();
73 if (ukm_service) {
74 if (foreground)
75 ukm_service->OnAppEnterForeground();
76 else
77 ukm_service->OnAppEnterBackground();
78 }
79}
80#endif // defined(OS_ANDROID)
81
Scott Violet95a6d682020-06-11 23:28:3282} // namespace
83
84// static
85constexpr char BrowserImpl::kPersistenceFilePrefix[];
Tim Volodine9839f182020-04-23 17:51:2586
Scott Violetbf8b8aa72020-01-28 19:37:3287std::unique_ptr<Browser> Browser::Create(
88 Profile* profile,
89 const PersistenceInfo* persistence_info) {
Scott Violetb7df9d62020-01-31 16:18:4990 // BrowserImpl's constructor is private.
91 auto browser =
92 base::WrapUnique(new BrowserImpl(static_cast<ProfileImpl*>(profile)));
Scott Violetbf8b8aa72020-01-28 19:37:3293 if (persistence_info)
Scott Violetb7df9d62020-01-31 16:18:4994 browser->RestoreStateIfNecessary(*persistence_info);
95 return browser;
Scott Violet87450ce2020-01-23 01:56:2596}
Scott Violet009c09c2020-01-18 00:57:1897
98BrowserImpl::~BrowserImpl() {
Scott Violetbb6c84552020-01-29 23:35:2499#if defined(OS_ANDROID)
100 // Android side should always remove tabs first (because the Java Tab class
101 // owns the C++ Tab). See BrowserImpl.destroy() (in the Java BrowserImpl
102 // class).
103 DCHECK(tabs_.empty());
104#else
105 while (!tabs_.empty())
Clark DuVallb9658c12020-06-12 02:25:08106 DestroyTab(tabs_.back().get());
Scott Violetbb6c84552020-01-29 23:35:24107#endif
Scott Violet7e39f86c2020-06-24 22:33:46108 BrowserList::GetInstance()->RemoveBrowser(this);
Tim Volodine9839f182020-04-23 17:51:25109
110#if defined(OS_ANDROID)
Scott Violet7e39f86c2020-06-24 22:33:46111 if (BrowserList::GetInstance()->browsers().empty())
Clark DuVall96b01ef2020-05-07 21:11:19112 BrowserProcess::GetInstance()->StopSafeBrowsingService();
Tim Volodine9839f182020-04-23 17:51:25113#endif
Scott Violet009c09c2020-01-18 00:57:18114}
115
Scott Violet58ad5a32020-01-23 22:07:27116TabImpl* BrowserImpl::CreateTabForSessionRestore(
Scott Violetb2e0cf12020-03-09 18:46:43117 std::unique_ptr<content::WebContents> web_contents,
118 const std::string& guid) {
Bo Liuf6389812020-07-13 16:24:13119 if (!web_contents) {
120 content::WebContents::CreateParams create_params(
121 profile_->GetBrowserContext());
122 web_contents = content::WebContents::Create(create_params);
123 }
Scott Violetbb6c84552020-01-29 23:35:24124 std::unique_ptr<TabImpl> tab =
Scott Violetb2e0cf12020-03-09 18:46:43125 std::make_unique<TabImpl>(profile_, std::move(web_contents), guid);
Scott Violet58ad5a32020-01-23 22:07:27126#if defined(OS_ANDROID)
Clark DuVallb9658c12020-06-12 02:25:08127 Java_BrowserImpl_createJavaTabForNativeTab(
Scott Violet90564152020-01-31 18:31:30128 AttachCurrentThread(), java_impl_, reinterpret_cast<jlong>(tab.get()));
Scott Violet58ad5a32020-01-23 22:07:27129#endif
Clark DuVallb9658c12020-06-12 02:25:08130 return AddTab(std::move(tab));
131}
132
133TabImpl* BrowserImpl::CreateTab(
134 std::unique_ptr<content::WebContents> web_contents) {
135 return CreateTabForSessionRestore(std::move(web_contents), std::string());
Scott Violet58ad5a32020-01-23 22:07:27136}
137
Scott Violet009c09c2020-01-18 00:57:18138#if defined(OS_ANDROID)
Bo Liu7f0b7ee2020-05-01 02:43:07139bool BrowserImpl::CompositorHasSurface() {
140 return Java_BrowserImpl_compositorHasSurface(AttachCurrentThread(),
141 java_impl_);
142}
143
Scott Violet009c09c2020-01-18 00:57:18144void BrowserImpl::AddTab(JNIEnv* env,
Scott Violet009c09c2020-01-18 00:57:18145 long native_tab) {
Clark DuVallb9658c12020-06-12 02:25:08146 AddTab(reinterpret_cast<TabImpl*>(native_tab));
Scott Violet009c09c2020-01-18 00:57:18147}
148
Scott Violet0ccd63292020-05-03 02:32:45149ScopedJavaLocalRef<jobjectArray> BrowserImpl::GetTabs(JNIEnv* env) {
Scott Violet90564152020-01-31 18:31:30150 ScopedJavaLocalRef<jclass> clazz =
Scott Violet009c09c2020-01-18 00:57:18151 base::android::GetClass(env, "org/chromium/weblayer_private/TabImpl");
152 jobjectArray tabs = env->NewObjectArray(tabs_.size(), clazz.obj(),
153 nullptr /* initialElement */);
154 base::android::CheckException(env);
155
156 for (size_t i = 0; i < tabs_.size(); ++i) {
Scott Violetbb6c84552020-01-29 23:35:24157 TabImpl* tab = static_cast<TabImpl*>(tabs_[i].get());
Scott Violet009c09c2020-01-18 00:57:18158 env->SetObjectArrayElement(tabs, i, tab->GetJavaTab().obj());
159 }
Scott Violet90564152020-01-31 18:31:30160 return ScopedJavaLocalRef<jobjectArray>(env, tabs);
Scott Violet009c09c2020-01-18 00:57:18161}
162
Scott Violet90564152020-01-31 18:31:30163void BrowserImpl::SetActiveTab(JNIEnv* env,
Scott Violet90564152020-01-31 18:31:30164 long native_tab) {
Scott Violet009c09c2020-01-18 00:57:18165 SetActiveTab(reinterpret_cast<TabImpl*>(native_tab));
166}
167
Scott Violet0ccd63292020-05-03 02:32:45168ScopedJavaLocalRef<jobject> BrowserImpl::GetActiveTab(JNIEnv* env) {
Scott Violet009c09c2020-01-18 00:57:18169 if (!active_tab_)
170 return nullptr;
Scott Violet90564152020-01-31 18:31:30171 return ScopedJavaLocalRef<jobject>(active_tab_->GetJavaTab());
Scott Violet009c09c2020-01-18 00:57:18172}
Scott Violet58ad5a32020-01-23 22:07:27173
Scott Violet0ccd63292020-05-03 02:32:45174void BrowserImpl::PrepareForShutdown(JNIEnv* env) {
Scott Violet58ad5a32020-01-23 22:07:27175 PrepareForShutdown();
176}
177
Scott Violet0ccd63292020-05-03 02:32:45178ScopedJavaLocalRef<jstring> BrowserImpl::GetPersistenceId(JNIEnv* env) {
Scott Violet90564152020-01-31 18:31:30179 return ScopedJavaLocalRef<jstring>(
Scott Violetbf8b8aa72020-01-28 19:37:32180 base::android::ConvertUTF8ToJavaString(env, GetPersistenceId()));
181}
182
Scott Violet0ccd63292020-05-03 02:32:45183void BrowserImpl::SaveBrowserPersisterIfNecessary(JNIEnv* env) {
Scott Violet9843d0a2020-02-11 22:38:07184 browser_persister_->SaveIfNecessary();
Scott Violetbf8b8aa72020-01-28 19:37:32185}
186
Scott Violet9843d0a2020-02-11 22:38:07187ScopedJavaLocalRef<jbyteArray> BrowserImpl::GetBrowserPersisterCryptoKey(
Scott Violet0ccd63292020-05-03 02:32:45188 JNIEnv* env) {
Scott Violetbf8b8aa72020-01-28 19:37:32189 std::vector<uint8_t> key;
Scott Violet9843d0a2020-02-11 22:38:07190 if (browser_persister_)
191 key = browser_persister_->GetCryptoKey();
Scott Violetbf8b8aa72020-01-28 19:37:32192 return base::android::ToJavaByteArray(env, key);
Scott Violet58ad5a32020-01-23 22:07:27193}
194
Scott Violet90564152020-01-31 18:31:30195ScopedJavaLocalRef<jbyteArray> BrowserImpl::GetMinimalPersistenceState(
Scott Violet0ccd63292020-05-03 02:32:45196 JNIEnv* env) {
Clark DuVallb7c09942020-05-20 04:12:51197 return base::android::ToJavaByteArray(env, GetMinimalPersistenceState());
Scott Violet343f4ec2020-01-30 02:58:08198}
199
Scott Violetb7df9d62020-01-31 16:18:49200void BrowserImpl::RestoreStateIfNecessary(
201 JNIEnv* env,
Scott Violet90564152020-01-31 18:31:30202 const JavaParamRef<jstring>& j_persistence_id,
203 const JavaParamRef<jbyteArray>& j_persistence_crypto_key,
204 const JavaParamRef<jbyteArray>& j_minimal_persistence_state) {
Scott Violetb7df9d62020-01-31 16:18:49205 Browser::PersistenceInfo persistence_info;
206 Browser::PersistenceInfo* persistence_info_ptr = nullptr;
207
208 if (j_persistence_id.obj()) {
209 const std::string persistence_id =
210 base::android::ConvertJavaStringToUTF8(j_persistence_id);
211 if (!persistence_id.empty()) {
212 persistence_info.id = persistence_id;
213 if (j_persistence_crypto_key.obj()) {
214 base::android::JavaByteArrayToByteVector(
215 env, j_persistence_crypto_key, &(persistence_info.last_crypto_key));
216 }
217 persistence_info_ptr = &persistence_info;
218 }
219 } else if (j_minimal_persistence_state.obj()) {
220 base::android::JavaByteArrayToByteVector(env, j_minimal_persistence_state,
221 &(persistence_info.minimal_state));
222 persistence_info_ptr = &persistence_info;
223 }
224 if (persistence_info_ptr)
225 RestoreStateIfNecessary(*persistence_info_ptr);
226}
227
Bo Liu3362d482020-03-31 14:57:33228void BrowserImpl::WebPreferencesChanged(JNIEnv* env) {
229 for (const auto& tab : tabs_) {
230 TabImpl* tab_impl = static_cast<TabImpl*>(tab.get());
231 tab_impl->WebPreferencesChanged();
232 }
233}
Scott Violet1e3e0b42020-04-02 14:43:22234
Scott Violet0ccd63292020-05-03 02:32:45235void BrowserImpl::OnFragmentStart(JNIEnv* env) {
Scott Violet1e3e0b42020-04-02 14:43:22236 // FeatureListCreator is created before any Browsers.
237 DCHECK(FeatureListCreator::GetInstance());
238 FeatureListCreator::GetInstance()->OnBrowserFragmentStarted();
239}
240
John Abd-El-Malek6dd19662020-06-19 05:49:34241void BrowserImpl::OnFragmentResume(JNIEnv* env) {
Scott Violet7e39f86c2020-06-24 22:33:46242 UpdateFragmentResumedState(true);
John Abd-El-Malek6dd19662020-06-19 05:49:34243}
244
245void BrowserImpl::OnFragmentPause(JNIEnv* env) {
Scott Violet7e39f86c2020-06-24 22:33:46246 UpdateFragmentResumedState(false);
John Abd-El-Malek6dd19662020-06-19 05:49:34247}
248
Scott Violet009c09c2020-01-18 00:57:18249#endif
250
Scott Violet343f4ec2020-01-30 02:58:08251std::vector<uint8_t> BrowserImpl::GetMinimalPersistenceState(
252 int max_size_in_bytes) {
253 return PersistMinimalState(this, max_size_in_bytes);
254}
255
Gyuyoung Kim1ac4ca782020-09-11 03:32:51256void BrowserImpl::SetWebPreferences(blink::web_pref::WebPreferences* prefs) {
Bo Liu3362d482020-03-31 14:57:33257#if defined(OS_ANDROID)
Bo Liuabea5dcc2020-04-20 16:06:23258 prefs->password_echo_enabled = Java_BrowserImpl_getPasswordEchoEnabled(
259 AttachCurrentThread(), java_impl_);
260 prefs->preferred_color_scheme =
261 Java_BrowserImpl_getDarkThemeEnabled(AttachCurrentThread(), java_impl_)
262 ? blink::PreferredColorScheme::kDark
263 : blink::PreferredColorScheme::kLight;
Bo Liu0ce3e2e2020-05-07 14:36:31264 prefs->font_scale_factor =
265 Java_BrowserImpl_getFontScale(AttachCurrentThread(), java_impl_);
Bo Liu3362d482020-03-31 14:57:33266#endif
267}
268
Scott Violetf02e62032020-08-28 22:32:22269#if defined(OS_ANDROID)
Scott Violetc3ebff72020-09-15 17:58:47270void BrowserImpl::RemoveTabBeforeDestroyingFromJava(Tab* tab) {
271 // The java side owns the Tab, and is going to delete it shortly. See
272 // JNI_TabImpl_DeleteTab.
273 RemoveTab(tab).release();
Scott Violetf02e62032020-08-28 22:32:22274}
275#endif
276
Clark DuVallb9658c12020-06-12 02:25:08277void BrowserImpl::AddTab(Tab* tab) {
Scott Violet009c09c2020-01-18 00:57:18278 DCHECK(tab);
Clark DuVallb9658c12020-06-12 02:25:08279 TabImpl* tab_impl = static_cast<TabImpl*>(tab);
280 std::unique_ptr<Tab> owned_tab;
281 if (tab_impl->browser())
282 owned_tab = tab_impl->browser()->RemoveTab(tab_impl);
283 else
284 owned_tab.reset(tab_impl);
285 AddTab(std::move(owned_tab));
Clark DuVall9bd21d82020-06-12 00:33:42286}
287
Clark DuVallb9658c12020-06-12 02:25:08288void BrowserImpl::DestroyTab(Tab* tab) {
Scott Violetf02e62032020-08-28 22:32:22289#if defined(OS_ANDROID)
Scott Violetc3ebff72020-09-15 17:58:47290 // Route destruction through the java side.
Scott Violetf02e62032020-08-28 22:32:22291 Java_BrowserImpl_destroyTabImpl(AttachCurrentThread(), java_impl_,
292 static_cast<TabImpl*>(tab)->GetJavaTab());
293#else
Clark DuVallb9658c12020-06-12 02:25:08294 RemoveTab(tab);
Scott Violetf02e62032020-08-28 22:32:22295#endif
Mugdha Lakhani9d858162020-01-31 21:12:04296}
297
Clark DuVall6fc95fb2020-06-12 00:42:10298void BrowserImpl::SetActiveTab(Tab* tab) {
299 if (GetActiveTab() == tab)
300 return;
301 if (active_tab_)
302 active_tab_->OnLosingActive();
303 // TODO: currently the java side sets visibility, this code likely should
304 // too and it should be removed from the java side.
305 active_tab_ = static_cast<TabImpl*>(tab);
306#if defined(OS_ANDROID)
307 Java_BrowserImpl_onActiveTabChanged(
308 AttachCurrentThread(), java_impl_,
309 active_tab_ ? active_tab_->GetJavaTab() : nullptr);
310#endif
311 VisibleSecurityStateOfActiveTabChanged();
312 for (BrowserObserver& obs : browser_observers_)
313 obs.OnActiveTabChanged(active_tab_);
314 if (active_tab_)
315 active_tab_->web_contents()->GetController().LoadIfNecessary();
316}
317
318Tab* BrowserImpl::GetActiveTab() {
319 return active_tab_;
320}
321
322std::vector<Tab*> BrowserImpl::GetTabs() {
323 std::vector<Tab*> tabs(tabs_.size());
324 for (size_t i = 0; i < tabs_.size(); ++i)
325 tabs[i] = tabs_[i].get();
326 return tabs;
327}
328
Clark DuVallb9658c12020-06-12 02:25:08329Tab* BrowserImpl::CreateTab() {
330 return CreateTab(nullptr);
331}
332
Scott Violetf251a022020-10-07 16:54:43333void BrowserImpl::OnRestoreCompleted() {
334 for (BrowserRestoreObserver& obs : browser_restore_observers_)
335 obs.OnRestoreCompleted();
336#if defined(OS_ANDROID)
337 Java_BrowserImpl_onRestoreCompleted(AttachCurrentThread(), java_impl_);
338#endif
339}
340
Clark DuVall6fc95fb2020-06-12 00:42:10341void BrowserImpl::PrepareForShutdown() {
342 browser_persister_.reset();
343}
344
345std::string BrowserImpl::GetPersistenceId() {
346 return persistence_id_;
347}
348
349std::vector<uint8_t> BrowserImpl::GetMinimalPersistenceState() {
350 // 0 means use the default max.
351 return GetMinimalPersistenceState(0);
352}
353
Scott Violetf251a022020-10-07 16:54:43354bool BrowserImpl::IsRestoringPreviousState() {
355 return browser_persister_ && browser_persister_->is_restore_in_progress();
356}
357
Clark DuVall6fc95fb2020-06-12 00:42:10358void BrowserImpl::AddObserver(BrowserObserver* observer) {
359 browser_observers_.AddObserver(observer);
360}
361
362void BrowserImpl::RemoveObserver(BrowserObserver* observer) {
363 browser_observers_.RemoveObserver(observer);
364}
365
Scott Violetf251a022020-10-07 16:54:43366void BrowserImpl::AddBrowserRestoreObserver(BrowserRestoreObserver* observer) {
367 browser_restore_observers_.AddObserver(observer);
368}
369
370void BrowserImpl::RemoveBrowserRestoreObserver(
371 BrowserRestoreObserver* observer) {
372 browser_restore_observers_.RemoveObserver(observer);
373}
374
Clark DuVallb9658c12020-06-12 02:25:08375void BrowserImpl::VisibleSecurityStateOfActiveTabChanged() {
376 if (visible_security_state_changed_callback_for_tests_)
377 std::move(visible_security_state_changed_callback_for_tests_).Run();
378
379#if defined(OS_ANDROID)
380 JNIEnv* env = base::android::AttachCurrentThread();
381 Java_BrowserImpl_onVisibleSecurityStateOfActiveTabChanged(env, java_impl_);
382#endif
383}
384
Clark DuVall6fc95fb2020-06-12 00:42:10385BrowserImpl::BrowserImpl(ProfileImpl* profile) : profile_(profile) {
Scott Violet7e39f86c2020-06-24 22:33:46386 BrowserList::GetInstance()->AddBrowser(this);
Clark DuVall6fc95fb2020-06-12 00:42:10387}
388
389void BrowserImpl::RestoreStateIfNecessary(
390 const PersistenceInfo& persistence_info) {
391 persistence_id_ = persistence_info.id;
392 if (!persistence_id_.empty()) {
393 browser_persister_ = std::make_unique<BrowserPersister>(
394 GetBrowserPersisterDataPath(), this, persistence_info.last_crypto_key);
395 } else if (!persistence_info.minimal_state.empty()) {
396 RestoreMinimalState(this, persistence_info.minimal_state);
397 }
398}
399
Clark DuVallb9658c12020-06-12 02:25:08400TabImpl* BrowserImpl::AddTab(std::unique_ptr<Tab> tab) {
401 TabImpl* tab_impl = static_cast<TabImpl*>(tab.get());
402 DCHECK(!tab_impl->browser());
403 tabs_.push_back(std::move(tab));
404 tab_impl->set_browser(this);
405#if defined(OS_ANDROID)
406 Java_BrowserImpl_onTabAdded(AttachCurrentThread(), java_impl_,
407 tab_impl->GetJavaTab());
408#endif
409 for (BrowserObserver& obs : browser_observers_)
410 obs.OnTabAdded(tab_impl);
411 return tab_impl;
412}
413
414std::unique_ptr<Tab> BrowserImpl::RemoveTab(Tab* tab) {
415 TabImpl* tab_impl = static_cast<TabImpl*>(tab);
416 DCHECK_EQ(this, tab_impl->browser());
417 static_cast<TabImpl*>(tab)->set_browser(nullptr);
418 auto iter =
419 std::find_if(tabs_.begin(), tabs_.end(), base::MatchesUniquePtr(tab));
420 DCHECK(iter != tabs_.end());
421 std::unique_ptr<Tab> owned_tab = std::move(*iter);
422 tabs_.erase(iter);
423 const bool active_tab_changed = active_tab_ == tab;
424 if (active_tab_changed)
425 SetActiveTab(nullptr);
Clark DuVall6fc95fb2020-06-12 00:42:10426
427#if defined(OS_ANDROID)
Clark DuVallb9658c12020-06-12 02:25:08428 Java_BrowserImpl_onTabRemoved(AttachCurrentThread(), java_impl_,
429 tab ? tab_impl->GetJavaTab() : nullptr);
Clark DuVall6fc95fb2020-06-12 00:42:10430#endif
Clark DuVallb9658c12020-06-12 02:25:08431 for (BrowserObserver& obs : browser_observers_)
432 obs.OnTabRemoved(tab, active_tab_changed);
433 return owned_tab;
Clark DuVall6fc95fb2020-06-12 00:42:10434}
435
Scott Violet9843d0a2020-02-11 22:38:07436base::FilePath BrowserImpl::GetBrowserPersisterDataPath() {
Scott Violet95a6d682020-06-11 23:28:32437 return BuildPathForBrowserPersister(
438 profile_->GetBrowserPersisterDataBaseDir(), GetPersistenceId());
Scott Violet87450ce2020-01-23 01:56:25439}
440
Scott Violetb7df9d62020-01-31 16:18:49441#if defined(OS_ANDROID)
Scott Violet7e39f86c2020-06-24 22:33:46442void BrowserImpl::UpdateFragmentResumedState(bool state) {
443 const bool old_has_at_least_one_active_browser =
444 BrowserList::GetInstance()->HasAtLeastOneResumedBrowser();
445 fragment_resumed_ = state;
446 UpdateMetricsService();
447 if (old_has_at_least_one_active_browser !=
448 BrowserList::GetInstance()->HasAtLeastOneResumedBrowser()) {
449 BrowserList::GetInstance()->NotifyHasAtLeastOneResumedBrowserChanged();
450 }
451}
452
Scott Violetb7df9d62020-01-31 16:18:49453// This function is friended. JNI_BrowserImpl_CreateBrowser can not be
454// friended, as it requires browser_impl.h to include BrowserImpl_jni.h, which
455// is problematic (meaning not really supported and generates compile errors).
Scott Violet90564152020-01-31 18:31:30456BrowserImpl* CreateBrowserForAndroid(ProfileImpl* profile,
457 const JavaParamRef<jobject>& java_impl) {
Scott Violetb7df9d62020-01-31 16:18:49458 BrowserImpl* browser = new BrowserImpl(profile);
459 browser->java_impl_ = java_impl;
460 return browser;
Scott Violet87450ce2020-01-23 01:56:25461}
462
Scott Violet009c09c2020-01-18 00:57:18463static jlong JNI_BrowserImpl_CreateBrowser(
464 JNIEnv* env,
465 jlong profile,
Scott Violet90564152020-01-31 18:31:30466 const JavaParamRef<jobject>& java_impl) {
Scott Violetb7df9d62020-01-31 16:18:49467 // The android side does not trigger restore from the constructor as at the
468 // time this is called not enough of WebLayer has been wired up. Specifically,
469 // when this is called BrowserImpl.java hasn't obtained the return value so
470 // that it can't call any functions and further the client side hasn't been
471 // fully created, leading to all sort of assertions if Tabs are created
472 // and/or navigations start (which restore may trigger).
473 return reinterpret_cast<intptr_t>(CreateBrowserForAndroid(
474 reinterpret_cast<ProfileImpl*>(profile), java_impl));
Scott Violet009c09c2020-01-18 00:57:18475}
476
477static void JNI_BrowserImpl_DeleteBrowser(JNIEnv* env, jlong browser) {
478 delete reinterpret_cast<BrowserImpl*>(browser);
479}
480#endif
481
482} // namespace weblayer