1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
// Copyright 2014 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/extensions/extension_install_prompt_show_params.h"
#include <memory>
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/web_contents.h"
#if !BUILDFLAG(IS_ANDROID)
#include "ui/views/native_window_tracker.h"
#endif
#if defined(USE_AURA)
#include "ui/aura/window.h"
#endif
namespace {
#if defined(USE_AURA)
bool g_root_checking_enabled = true;
#endif
bool RootCheck(gfx::NativeWindow window) {
#if defined(USE_AURA)
// If the window is not contained in a root window, then it's not connected
// to a display and can't be used as the context. To do otherwise results in
// checks later on assuming context has a root.
return !g_root_checking_enabled || (window->GetRootWindow() != nullptr);
#else
return true;
#endif
}
} // namespace
ExtensionInstallPromptShowParams::ExtensionInstallPromptShowParams(
content::WebContents* contents)
: profile_(Profile::FromBrowserContext(contents->GetBrowserContext())),
parent_web_contents_(contents->GetWeakPtr()) {
DCHECK(profile_);
DCHECK(parent_web_contents_);
if (!parent_web_contents_->GetTopLevelNativeWindow()) {
// WebContents were created without a top-level window. This can happen when
// the callers pass a dummy WebContents, or in some tests. There is no
// window to track in this case. Reset the WebContents pointer and just keep
// the profile. If we keep web contents in this case, WasParentDestroyed()
// will always return true, even though there is no real window to check.
parent_web_contents_.reset();
}
}
ExtensionInstallPromptShowParams::ExtensionInstallPromptShowParams(
Profile* profile,
gfx::NativeWindow parent_window)
: profile_(profile),
parent_web_contents_(nullptr),
parent_window_(parent_window) {
DCHECK(profile);
#if BUILDFLAG(IS_ANDROID)
DCHECK(!parent_window) << "Android does not support a parent window.";
#else
if (parent_window_) {
native_window_tracker_ = views::NativeWindowTracker::Create(parent_window_);
}
#endif
}
ExtensionInstallPromptShowParams::~ExtensionInstallPromptShowParams() = default;
content::WebContents* ExtensionInstallPromptShowParams::GetParentWebContents() {
return parent_web_contents_.get();
}
gfx::NativeWindow ExtensionInstallPromptShowParams::GetParentWindow() {
if (WasParentDestroyed()) {
return gfx::NativeWindow();
}
if (WasConfiguredForWebContents()) {
return parent_web_contents_->GetTopLevelNativeWindow();
}
return parent_window_;
}
bool ExtensionInstallPromptShowParams::WasParentDestroyed() {
if (profile_->ShutdownStarted()) {
return true;
}
if (WasConfiguredForWebContents()) {
return !parent_web_contents_ || parent_web_contents_->IsBeingDestroyed() ||
!parent_web_contents_->GetTopLevelNativeWindow() ||
!RootCheck(parent_web_contents_->GetTopLevelNativeWindow());
}
#if !BUILDFLAG(IS_ANDROID)
if (native_window_tracker_) {
return native_window_tracker_->WasNativeWindowDestroyed() ||
!RootCheck(parent_window_);
}
#endif
return false;
}
bool ExtensionInstallPromptShowParams::WasConfiguredForWebContents() {
// If we ever had a valid web contents, it means we were configured for it.
return parent_web_contents_ || parent_web_contents_.WasInvalidated();
}
namespace test {
ScopedDisableRootChecking::ScopedDisableRootChecking() {
#if defined(USE_AURA)
// There should be no need to support multiple ScopedDisableRootCheckings
// at a time.
DCHECK(g_root_checking_enabled);
g_root_checking_enabled = false;
#endif
}
ScopedDisableRootChecking::~ScopedDisableRootChecking() {
#if defined(USE_AURA)
DCHECK(!g_root_checking_enabled);
g_root_checking_enabled = true;
#endif
}
} // namespace test
|