Enable extensions in android: allow use with always incognito (#2519 #2511) and fix dangling raw_ptr on destruction

This commit is contained in:
Carmelo Messina
2025-12-11 14:40:17 +01:00
parent 224c227ee0
commit ff33bbeb52
3 changed files with 252 additions and 14 deletions
@@ -3,8 +3,12 @@ Date: Thu, 6 Nov 2025 13:22:24 +0000
Subject: Backport-v144-android-extensions-changes
Enable support for anonymous browsing.
Backport of bugid 7089957 extensions Use BrowserWindowInterface in ExtensionViewHost
Backport of bugid
7089957: extensions Use BrowserWindowInterface in ExtensionViewHost
https://chromium-review.googlesource.com/c/chromium/src/+/7089957
7126008: Destroy ExtensionWindowControllerBridge when its Profile is destroyed
https://chromium-review.googlesource.com/c/chromium/src/+/7126008
---
.../chrome/browser/ChromeTabbedActivity.java | 1 +
.../chrome/browser/app/ChromeActivity.java | 12 ++
@@ -20,13 +24,15 @@ https://chromium-review.googlesource.com/c/chromium/src/+/7089957
chrome/browser/ui/android/extensions/BUILD.gn | 1 +
.../extension_action_popup_contents.cc | 9 +-
.../ExtensionActionPopupContents.java | 14 +-
.../extensions/windowing/internal/BUILD.gn | 1 +
.../ExtensionWindowControllerBridgeImpl.java | 45 ++++++-
chrome/browser/ui/android/toolbar/BUILD.gn | 2 +
.../ExtensionActionListCoordinator.java | 10 +-
.../ExtensionActionListMediator.java | 16 ++-
.../ExtensionActionListMediatorTest.java | 11 +-
.../ExtensionToolbarCoordinator.java | 5 +
.../ExtensionToolbarCoordinatorImpl.java | 4 +
20 files changed, 160 insertions(+), 92 deletions(-)
22 files changed, 201 insertions(+), 97 deletions(-)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -597,6 +603,107 @@ diff --git a/chrome/browser/ui/android/extensions/java/src/org/chromium/chrome/b
/**
* Destroys the native ExtensionActionPopupContents object.
diff --git a/chrome/browser/ui/android/extensions/windowing/internal/BUILD.gn b/chrome/browser/ui/android/extensions/windowing/internal/BUILD.gn
--- a/chrome/browser/ui/android/extensions/windowing/internal/BUILD.gn
+++ b/chrome/browser/ui/android/extensions/windowing/internal/BUILD.gn
@@ -38,6 +38,7 @@ android_library("java") {
]
deps = [
"//build/android:build_java",
+ "//chrome/browser/profiles/android:java",
"//chrome/browser/ui/android/extensions/windowing:java",
"//chrome/browser/ui/browser_window/public/android:java",
"//third_party/androidx:androidx_annotation_annotation_java",
diff --git a/chrome/browser/ui/android/extensions/windowing/internal/java/src/org/chromium/chrome/browser/ui/extensions/windowing/ExtensionWindowControllerBridgeImpl.java b/chrome/browser/ui/android/extensions/windowing/internal/java/src/org/chromium/chrome/browser/ui/extensions/windowing/ExtensionWindowControllerBridgeImpl.java
--- a/chrome/browser/ui/android/extensions/windowing/internal/java/src/org/chromium/chrome/browser/ui/extensions/windowing/ExtensionWindowControllerBridgeImpl.java
+++ b/chrome/browser/ui/android/extensions/windowing/internal/java/src/org/chromium/chrome/browser/ui/extensions/windowing/ExtensionWindowControllerBridgeImpl.java
@@ -11,6 +11,8 @@ import org.jni_zero.CalledByNative;
import org.jni_zero.NativeMethods;
import org.chromium.build.annotations.NullMarked;
+import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.profiles.ProfileManager;
import org.chromium.chrome.browser.ui.browser_window.ChromeAndroidTask;
import java.util.ArrayList;
@@ -19,7 +21,8 @@ import java.util.Map;
/** Implements {@link ExtensionWindowControllerBridge}. */
@NullMarked
-final class ExtensionWindowControllerBridgeImpl implements ExtensionWindowControllerBridge {
+final class ExtensionWindowControllerBridgeImpl
+ implements ExtensionWindowControllerBridge, ProfileManager.Observer {
/**
* Events received by the native singleton {@code WindowControllerListObserverForTesting}.
@@ -82,6 +85,7 @@ final class ExtensionWindowControllerBridgeImpl implements ExtensionWindowContro
assert mNativeExtensionWindowControllerBridge == 0
: "ExtensionWindowControllerBridge is already added to a task.";
+ ProfileManager.addObserver(this);
mNativeExtensionWindowControllerBridge =
ExtensionWindowControllerBridgeImplJni.get()
.create(
@@ -91,10 +95,8 @@ final class ExtensionWindowControllerBridgeImpl implements ExtensionWindowContro
@Override
public void onTaskRemoved() {
- if (mNativeExtensionWindowControllerBridge != 0) {
- ExtensionWindowControllerBridgeImplJni.get()
- .destroy(mNativeExtensionWindowControllerBridge);
- }
+ destroyNativeExtensionWindowControllerBridge();
+ ProfileManager.removeObserver(this);
}
@Override
@@ -113,6 +115,32 @@ final class ExtensionWindowControllerBridgeImpl implements ExtensionWindowContro
}
}
+ @Override
+ public void onProfileAdded(Profile profile) {}
+
+ @Override
+ public void onProfileDestroyed(Profile profile) {
+ // This is a short-term fix for http://crbug.com/450234852.
+ //
+ // The native extension code is cross-platform and depends on BrowserWindowInterface. Per
+ // documentation of BrowserWindowInterface::GetProfile(), cross-platform code assumes
+ // BrowserWindowInterface will always be destroyed *before* its Profile.
+ //
+ // See:
+ // https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/browser_window/public/browser_window_interface.h;l=108;drc=c8dc70b538f1bb0862f1be58237d6e945ee81819
+ //
+ // However, on Android, http://crbug.com/450234852 reveals a case where the Profile is
+ // destroyed before its BrowserWindowInterface, which caused native extension code to
+ // dereference an invalid Profile pointer.
+ //
+ // To avoid this issue, we destroy the native objects for extensions as soon as the native
+ // Profile is about to be destroyed. The long-term fix should be to correct the object
+ // destruction order for the case described in http://crbug.com/450234852.
+ if (profile == mChromeAndroidTask.getProfile()) {
+ destroyNativeExtensionWindowControllerBridge();
+ }
+ }
+
long getNativePtrForTesting() {
return mNativeExtensionWindowControllerBridge;
}
@@ -123,6 +151,13 @@ final class ExtensionWindowControllerBridgeImpl implements ExtensionWindowContro
.getExtensionWindowIdForTesting(mNativeExtensionWindowControllerBridge); // IN-TEST
}
+ private void destroyNativeExtensionWindowControllerBridge() {
+ if (mNativeExtensionWindowControllerBridge != 0) {
+ ExtensionWindowControllerBridgeImplJni.get()
+ .destroy(mNativeExtensionWindowControllerBridge);
+ }
+ }
+
@CalledByNative
private void clearNativePtr() {
mNativeExtensionWindowControllerBridge = 0;
diff --git a/chrome/browser/ui/android/toolbar/BUILD.gn b/chrome/browser/ui/android/toolbar/BUILD.gn
--- a/chrome/browser/ui/android/toolbar/BUILD.gn
+++ b/chrome/browser/ui/android/toolbar/BUILD.gn
@@ -12,22 +12,25 @@ License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html
.../BaseCustomTabRootUiCoordinator.java | 4 +-
.../CustomTabIntentDataProvider.java | 3 +
.../tabbed_mode/TabbedRootUiCoordinator.java | 3 +-
.../browser/tabmodel/TabModelJniBridge.java | 4 +-
.../tabmodel/TabModelSelectorBase.java | 7 ++
.../browser/toolbar/ToolbarManager.java | 4 +-
.../chrome/browser/ui/RootUiCoordinator.java | 6 +-
.../developer_private_functions_shared.cc | 4 +-
.../browser/extensions/extension_tab_util.cc | 2 +-
.../tabmodel/IncognitoTabModelImpl.java | 5 +
.../tabmodel/IncognitoTabModelImpl.java | 10 +-
.../tabmodel/IncognitoTabModelObserver.java | 2 +
.../extensions/extension_actions_bridge.cc | 12 +++
.../extensions/extension_actions_bridge.h | 1 +
.../ui/extensions/ExtensionActionsBridge.java | 6 ++
.../android/tab_model/tab_model_jni_bridge.cc | 4 +
.../ExtensionActionListCoordinator.java | 4 +-
.../ExtensionActionListMediator.java | 16 ++--
.../ExtensionToolbarCoordinator.java | 7 +-
.../ExtensionToolbarCoordinatorImpl.java | 5 +-
.../ChromeAndroidTaskTrackerImpl.java | 93 ++++++++++++++-----
.../ChromeAndroidTaskTracker.java | 6 +-
21 files changed, 201 insertions(+), 51 deletions(-)
24 files changed, 213 insertions(+), 56 deletions(-)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -245,6 +248,22 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/Tab
@NonNull ActivityLifecycleDispatcher activityLifecycleDispatcher,
@NonNull ObservableSupplier<LayoutManagerImpl> layoutManagerSupplier,
@NonNull MenuOrKeyboardActionController menuOrKeyboardActionController,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelJniBridge.java
@@ -129,10 +129,10 @@ public abstract class TabModelJniBridge implements TabModelInternal {
@Override
public void associateWithBrowserWindow(long nativeAndroidBrowserWindow) {
// Ensure this isn't set multiple times.
- assert mNativeAndroidBrowserWindow == 0;
+ if (nativeAndroidBrowserWindow != 0) assert mNativeAndroidBrowserWindow == 0;
mNativeAndroidBrowserWindow = nativeAndroidBrowserWindow;
- assert nativeAndroidBrowserWindow != 0;
+ // assert nativeAndroidBrowserWindow != 0;
TabModelJniBridgeJni.get()
.associateWithBrowserWindow(mNativeTabModelJniBridge, nativeAndroidBrowserWindow);
}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorBase.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorBase.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorBase.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorBase.java
@@ -327,6 +346,20 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordi
@NonNull ActivityLifecycleDispatcher activityLifecycleDispatcher,
@NonNull ObservableSupplier<LayoutManagerImpl> layoutManagerSupplier,
@NonNull MenuOrKeyboardActionController menuOrKeyboardActionController,
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_functions_shared.cc b/chrome/browser/extensions/api/developer_private/developer_private_functions_shared.cc
--- a/chrome/browser/extensions/api/developer_private/developer_private_functions_shared.cc
+++ b/chrome/browser/extensions/api/developer_private/developer_private_functions_shared.cc
@@ -1676,8 +1676,8 @@ DeveloperPrivateDismissSafetyHubExtensionsMenuNotificationFunction::Run() {
}
Profile* profile = Profile::FromBrowserContext(browser_context());
- SafetyHubMenuNotificationServiceFactory::GetForProfile(profile)
- ->DismissActiveNotificationOfModule(
+ if (auto* menu_notification_service_factory = SafetyHubMenuNotificationServiceFactory::GetForProfile(profile))
+ menu_notification_service_factory->DismissActiveNotificationOfModule(
safety_hub::SafetyHubModuleType::EXTENSIONS);
return RespondNow(NoArguments());
}
diff --git a/chrome/browser/extensions/extension_tab_util.cc b/chrome/browser/extensions/extension_tab_util.cc
--- a/chrome/browser/extensions/extension_tab_util.cc
+++ b/chrome/browser/extensions/extension_tab_util.cc
@@ -342,18 +375,31 @@ diff --git a/chrome/browser/extensions/extension_tab_util.cc b/chrome/browser/ex
diff --git a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelImpl.java b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelImpl.java
--- a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelImpl.java
+++ b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelImpl.java
@@ -151,6 +151,11 @@ class IncognitoTabModelImpl implements IncognitoTabModelInternal {
mDelegateModel.destroy();
mCurrentTabSupplier.set(null);
mTabCountSupplier.set(0);
@@ -140,8 +140,12 @@ class IncognitoTabModelImpl implements IncognitoTabModelInternal {
return;
}
+ // Disassociate
+ mDelegateModel.associateWithBrowserWindow(/*nativeAndroidBrowserWindow=*/ 0);
+ mNativeAndroidBrowserWindow = 0;
+
+ for (IncognitoTabModelObserver observer : mIncognitoObservers) {
for (IncognitoTabModelObserver observer : mIncognitoObservers) {
- observer.didBecomeEmpty();
+ observer.didDestroyed();
+ }
}
mDelegateModel
@@ -152,6 +156,10 @@ class IncognitoTabModelImpl implements IncognitoTabModelInternal {
mCurrentTabSupplier.set(null);
mTabCountSupplier.set(0);
+ for (IncognitoTabModelObserver observer : mIncognitoObservers) {
+ observer.didBecomeEmpty();
+ }
+
mDelegateModel = EmptyTabModel.getInstance(true);
for (Callback<TabModelInternal> delegateModelObserver : mDelegateModelObservers) {
delegateModelObserver.onResult(mDelegateModel);
diff --git a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelObserver.java b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelObserver.java
--- a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelObserver.java
+++ b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelObserver.java
@@ -427,6 +473,20 @@ diff --git a/chrome/browser/ui/android/extensions/java/src/org/chromium/chrome/b
HandleKeyEventResult handleKeyDownEvent(
long nativeExtensionActionsBridge,
@JniType("ui::KeyEventAndroid") KeyEvent keyEvent);
diff --git a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc
--- a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc
+++ b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc
@@ -116,6 +116,10 @@ void TabModelJniBridge::AssociateWithBrowserWindow(
// BrowserWindowInterface is available on desktop Android, but not other Android
// builds. For non-desktop Android, this function should be a no-op.
#if BUILDFLAG(IS_DESKTOP_ANDROID_CROMITE)
+ if (native_android_browser_window == 0) {
+ scoped_unowned_user_data_.reset();
+ return;
+ }
BrowserWindowInterface* android_browser_window =
reinterpret_cast<BrowserWindowInterface*>(native_android_browser_window);
CHECK(android_browser_window != nullptr);
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/extensions/ExtensionActionListCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/extensions/ExtensionActionListCoordinator.java
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/extensions/ExtensionActionListCoordinator.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/extensions/ExtensionActionListCoordinator.java
@@ -81,12 +81,13 @@ License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html
chrome/browser/startup_data.h | 6 +-
.../common/task_manager_features.cc | 2 +-
chrome/browser/ui/BUILD.gn | 6 +-
.../browser/ui/android/context_menu_helper.cc | 6 +-
.../browser/ui/android/context_menu_helper.cc | 12 +++-
.../browser/ui/android/context_menu_helper.h | 4 +-
chrome/browser/ui/android/extensions/BUILD.gn | 4 +-
.../extensions/extension_actions_bridge.cc | 23 ++++++
.../extensions/extension_actions_bridge.h | 1 +
.../res/layout/extensions_menu_footer.xml | 3 +-
.../java/res/layout/extensions_menu.xml | 1 +
.../res/layout/extensions_menu_footer.xml | 4 +-
.../extensions/java/res/values/dimens.xml | 1 +
.../ui/extensions/ExtensionActionsBridge.java | 6 ++
.../extensions/windowing/internal/BUILD.gn | 2 +-
@@ -123,6 +124,8 @@ License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html
chrome/common/extensions/api/api_sources.gni | 7 ++
chrome/common/webui_url_constants.cc | 2 +-
chrome/common/webui_url_constants.h | 2 +-
.../sandbox_status_extension_android.cc | 3 +-
.../sandbox_status_extension_android.h | 1 +
chrome/test/BUILD.gn | 14 ++--
chrome/version.gni | 4 +-
.../core/browser/host_content_settings_map.cc | 6 ++
@@ -183,7 +186,7 @@ License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html
ui/webui/resources/cr_elements/BUILD.gn | 2 +-
.../cr_elements/cr_toolbar/cr_toolbar.css | 6 ++
ui/webui/resources/css/BUILD.gn | 2 +-
171 files changed, 561 insertions(+), 288 deletions(-)
174 files changed, 572 insertions(+), 289 deletions(-)
create mode 100644 chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Enable-extensions-Android.grdp
create mode 100644 chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Extensions-Android.grdp
create mode 100644 cromite_flags/chrome/browser/about_flags_cc/Extensions-Android.inc
@@ -1671,6 +1674,24 @@ diff --git a/chrome/browser/ui/android/context_menu_helper.cc b/chrome/browser/u
// Reset any previous menu model, in case a new menu is shown
// before the old one was gracefully closed.
extension_menu_model_.reset();
@@ -82,11 +82,17 @@ void ContextMenuHelper::ShowContextMenu(
}
void ContextMenuHelper::DismissContextMenu() {
+#if BUILDFLAG(ENABLE_DESKTOP_ANDROID_EXTENSIONS_CROMITE)
+ extension_menu_model_.reset();
+#endif // BUILDFLAG(ENABLE_DESKTOP_ANDROID_EXTENSIONS)
JNIEnv* env = base::android::AttachCurrentThread();
Java_ContextMenuHelper_dismissContextMenu(env, java_obj_);
}
void ContextMenuHelper::OnContextMenuClosed(JNIEnv* env) {
+#if BUILDFLAG(ENABLE_DESKTOP_ANDROID_EXTENSIONS_CROMITE)
+ extension_menu_model_.reset();
+#endif // BUILDFLAG(ENABLE_DESKTOP_ANDROID_EXTENSIONS)
GetWebContents().NotifyContextMenuClosed(context_menu_params_.link_followed,
context_menu_params_.impression);
}
diff --git a/chrome/browser/ui/android/context_menu_helper.h b/chrome/browser/ui/android/context_menu_helper.h
--- a/chrome/browser/ui/android/context_menu_helper.h
+++ b/chrome/browser/ui/android/context_menu_helper.h
@@ -1762,6 +1783,17 @@ diff --git a/chrome/browser/ui/android/extensions/extension_actions_bridge.h b/c
jni_zero::ScopedJavaLocalRef<jobject> HandleKeyDownEvent(
JNIEnv* env,
const ui::KeyEventAndroid& key_event);
diff --git a/chrome/browser/ui/android/extensions/java/res/layout/extensions_menu.xml b/chrome/browser/ui/android/extensions/java/res/layout/extensions_menu.xml
--- a/chrome/browser/ui/android/extensions/java/res/layout/extensions_menu.xml
+++ b/chrome/browser/ui/android/extensions/java/res/layout/extensions_menu.xml
@@ -49,6 +49,7 @@ found in the LICENSE file.
<View
android:id="@+id/extensions_menu_footer_divider"
+ android:visibility="gone"
android:layout_width="0dp"
android:layout_height="1dp"
app:layout_constraintTop_toBottomOf="@+id/extensions_menu_items"
diff --git a/chrome/browser/ui/android/extensions/java/res/layout/extensions_menu_footer.xml b/chrome/browser/ui/android/extensions/java/res/layout/extensions_menu_footer.xml
--- a/chrome/browser/ui/android/extensions/java/res/layout/extensions_menu_footer.xml
+++ b/chrome/browser/ui/android/extensions/java/res/layout/extensions_menu_footer.xml
@@ -1773,7 +1805,15 @@ diff --git a/chrome/browser/ui/android/extensions/java/res/layout/extensions_men
style="?android:attr/borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -43,4 +44,4 @@ found in the LICENSE file.
@@ -29,6 +30,7 @@ found in the LICENSE file.
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/extensions_menu_manage_extensions_button"
+ android:visibility="gone"
style="?android:attr/borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -43,4 +45,4 @@ found in the LICENSE file.
android:drawableTint="?android:attr/textColorPrimary"
android:gravity="start|center_vertical"/>
@@ -2512,6 +2552,37 @@ diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_const
inline constexpr char kChromeUIDiscardsHost[] = "discards";
inline constexpr char kChromeUIDiscardsURL[] = "chrome://discards/";
#endif
diff --git a/chrome/renderer/sandbox_status_extension_android.cc b/chrome/renderer/sandbox_status_extension_android.cc
--- a/chrome/renderer/sandbox_status_extension_android.cc
+++ b/chrome/renderer/sandbox_status_extension_android.cc
@@ -34,7 +34,7 @@ SandboxStatusExtension::SandboxStatusExtension(content::RenderFrame* frame)
frame->GetAssociatedInterfaceRegistry()
->AddInterface<chrome::mojom::SandboxStatusExtension>(base::BindRepeating(
&SandboxStatusExtension::OnSandboxStatusExtensionRequest,
- base::RetainedRef(this)));
+ weak_ptr_factory_.GetWeakPtr()));
}
SandboxStatusExtension::~SandboxStatusExtension() = default;
@@ -46,6 +46,7 @@ void SandboxStatusExtension::Create(content::RenderFrame* frame) {
}
void SandboxStatusExtension::OnDestruct() {
+ weak_ptr_factory_.InvalidateWeakPtrs();
// This object is ref-counted, since a callback could still be in-flight.
Release();
}
diff --git a/chrome/renderer/sandbox_status_extension_android.h b/chrome/renderer/sandbox_status_extension_android.h
--- a/chrome/renderer/sandbox_status_extension_android.h
+++ b/chrome/renderer/sandbox_status_extension_android.h
@@ -73,6 +73,7 @@ class SandboxStatusExtension
mojo::AssociatedReceiver<chrome::mojom::SandboxStatusExtension> receiver_{
this};
+ base::WeakPtrFactory<SandboxStatusExtension> weak_ptr_factory_{this};
};
#endif // CHROME_RENDERER_SANDBOX_STATUS_EXTENSION_ANDROID_H_
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn