1 // Copyright (c) 2012 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 "chrome/browser/profiles/profile_destroyer.h"
6 
7 #include "base/macros.h"
8 #include "base/run_loop.h"
9 #include "chrome/test/base/browser_with_test_window_test.h"
10 #include "chrome/test/base/testing_profile.h"
11 #include "content/public/browser/render_process_host.h"
12 #include "content/public/browser/site_instance.h"
13 
14 class ProfileDestroyerTest : public BrowserWithTestWindowTest {
15  public:
16   ProfileDestroyerTest() = default;
17 
SetUp()18   void SetUp() override {
19     BrowserWithTestWindowTest::SetUp();
20     GetOriginalProfile()->SetProfileDestructionObserver(
21         base::BindOnce(&ProfileDestroyerTest::SetOriginalProfileDestroyed,
22                        base::Unretained(this)));
23   }
24 
GetOriginalProfile()25   TestingProfile* GetOriginalProfile() { return GetProfile(); }
26 
GetIncognitoProfile()27   TestingProfile* GetIncognitoProfile() {
28     if (!incognito_profile_) {
29       TestingProfile::Builder builder;
30       incognito_profile_ = builder.BuildIncognito(GetOriginalProfile());
31       incognito_profile_->SetProfileDestructionObserver(
32           base::BindOnce(&ProfileDestroyerTest::SetIncognitoProfileDestroyed,
33                          base::Unretained(this)));
34     }
35     return incognito_profile_;
36   }
37 
SetOriginalProfileDestroyed()38   void SetOriginalProfileDestroyed() { original_profile_destroyed_ = true; }
SetIncognitoProfileDestroyed()39   void SetIncognitoProfileDestroyed() { incognito_profile_destroyed_ = true; }
40 
IsOriginalProfileDestroyed()41   bool IsOriginalProfileDestroyed() { return original_profile_destroyed_; }
IsIncognitoProfileDestroyed()42   bool IsIncognitoProfileDestroyed() { return incognito_profile_destroyed_; }
43 
44   // Creates a render process host based on a new site instance given the
45   // |profile| and mark it as used.
CreatedRendererProcessHost(Profile * profile)46   std::unique_ptr<content::RenderProcessHost> CreatedRendererProcessHost(
47       Profile* profile) {
48     site_instances_.emplace_back(content::SiteInstance::Create(profile));
49 
50     std::unique_ptr<content::RenderProcessHost> render_process_host;
51     render_process_host.reset(site_instances_.back()->GetProcess());
52     render_process_host->SetIsUsed();
53     EXPECT_NE(render_process_host.get(), nullptr);
54 
55     return render_process_host;
56   }
57 
58  protected:
59   bool original_profile_destroyed_{false};
60   bool incognito_profile_destroyed_{false};
61   TestingProfile* incognito_profile_{nullptr};
62 
63   std::vector<scoped_refptr<content::SiteInstance>> site_instances_;
64 
65   DISALLOW_COPY_AND_ASSIGN(ProfileDestroyerTest);
66 };
67 
68 // Expect immediate incognito profile destruction when no pending renderer
69 // process host exists.
TEST_F(ProfileDestroyerTest,ImmediateIncognitoProfileDestruction)70 TEST_F(ProfileDestroyerTest, ImmediateIncognitoProfileDestruction) {
71   TestingProfile* incognito_profile = GetIncognitoProfile();
72 
73   // Destroying the regular browser does not result in destruction of regular
74   // profile and hence should not destroy the incognito profile.
75   set_browser(nullptr);
76   EXPECT_FALSE(IsOriginalProfileDestroyed());
77   EXPECT_FALSE(IsIncognitoProfileDestroyed());
78 
79   // Ask for destruction of Incognito profile, and expect immediate destruction.
80   ProfileDestroyer::DestroyProfileWhenAppropriate(incognito_profile);
81   EXPECT_TRUE(IsIncognitoProfileDestroyed());
82 }
83 
84 // Expect pending renderer process hosts delay incognito profile destruction.
TEST_F(ProfileDestroyerTest,DelayedIncognitoProfileDestruction)85 TEST_F(ProfileDestroyerTest, DelayedIncognitoProfileDestruction) {
86   TestingProfile* incognito_profile = GetIncognitoProfile();
87 
88   // Create two render process hosts.
89   std::unique_ptr<content::RenderProcessHost> render_process_host1 =
90       CreatedRendererProcessHost(incognito_profile);
91   std::unique_ptr<content::RenderProcessHost> render_process_host2 =
92       CreatedRendererProcessHost(incognito_profile);
93 
94   // Ask for destruction of Incognito profile, but expect it to be delayed.
95   ProfileDestroyer::DestroyProfileWhenAppropriate(incognito_profile);
96   EXPECT_FALSE(IsIncognitoProfileDestroyed());
97 
98   // Destroy the first pending render process host, and expect it not to destroy
99   // the incognito profile.
100   render_process_host1.release()->Cleanup();
101   base::RunLoop().RunUntilIdle();
102   EXPECT_FALSE(IsIncognitoProfileDestroyed());
103 
104   // Destroy the other renderer process, and expect destruction of incognito
105   // profile.
106   render_process_host2.release()->Cleanup();
107   base::RunLoop().RunUntilIdle();
108   EXPECT_TRUE(IsIncognitoProfileDestroyed());
109 }
110 
111 // TODO(https://crbug.com/1033903): Add tests for non-primary OTRs.
112