blob: 5c045505a5f95290d3c4740c31427a912bc42d41 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ANDROID_OOM_INTERVENTION_OOM_INTERVENTION_DECIDER_H_
#define CHROME_BROWSER_ANDROID_OOM_INTERVENTION_OOM_INTERVENTION_DECIDER_H_
#include "base/gtest_prod_util.h"
#include "base/supports_user_data.h"
namespace content {
class BrowserContext;
}
namespace user_prefs {
class PrefRegistrySyncable;
}
class OomInterventionDeciderTest;
class PrefService;
// This class contains triggering and opting-out logic for OOM intervention.
// Opt-out logic:
// - If user declined intervention, don't trigger it until OOM is observed on
// the same site.
// - If user declined intervention again even after OOM is observed on the site,
// never trigger intervention on the site.
// - If len(blacklist) > kMaxBlacklistSize, the user is permanently opted out.
//
// An instance of this class is associated with BrowserContext when the
// BrowserContext isn't incognito. You can obtain it via GetForBrowserContext().
// GetForBrowserContext() will return nullptr when in incognito mode.
class OomInterventionDecider : public base::SupportsUserData::Data {
public:
// This delegate is a testing seam.
class Delegate {
public:
virtual ~Delegate() = default;
virtual bool WasLastShutdownClean() = 0;
};
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
static OomInterventionDecider* GetForBrowserContext(
content::BrowserContext* context);
~OomInterventionDecider() override;
bool CanTriggerIntervention(const std::string& host) const;
void OnInterventionDeclined(const std::string& host);
void OnOomDetected(const std::string& host);
void ClearData();
private:
OomInterventionDecider(std::unique_ptr<Delegate> delegate,
PrefService* prefs);
friend class OomInterventionDeciderTest;
FRIEND_TEST_ALL_PREFIXES(OomInterventionDeciderTest, OptOutSingleHost);
FRIEND_TEST_ALL_PREFIXES(OomInterventionDeciderTest, ParmanentlyOptOut);
FRIEND_TEST_ALL_PREFIXES(OomInterventionDeciderTest, WasLastShutdownClean);
// These constants are declared here for testing.
static const size_t kMaxListSize;
static const size_t kMaxBlacklistSize;
// Called when |prefs_| is ready to use. When the last shutdown wasn't clean,
// this method adds the last entry of the declined list to the OOM detected
// list, assuming that the site caused the crash and the crash was due to
// OOM.
void OnPrefInitialized(bool success);
bool IsOptedOut(const std::string& host) const;
bool IsInList(const char* list_name, const std::string& host) const;
void AddToList(const char* list_name, const std::string& host);
std::unique_ptr<Delegate> delegate_;
PrefService* prefs_;
DISALLOW_COPY_AND_ASSIGN(OomInterventionDecider);
};
#endif // CHROME_BROWSER_ANDROID_OOM_INTERVENTION_OOM_INTERVENTION_DECIDER_H_