Commit 16acd1cb authored by Clark DuVall's avatar Clark DuVall Committed by Commit Bot

Fix crash when running NetworkService out of process on Android

SimpleIndex uses an ApplicationStatusListener to know when to write the
cache to disk. This is used in the network service, and when network
service is run out of process, this causes a crash since
ApplicationStatusListener should only be used from the main process.

To fix this, I changed ApplicationStatusListener to have a SetCallback
interface, that can then have an implementation in the network service.
If the cache is being created in the network service, we can pass the
network service implementation of ApplicationStatusListener. The
NetworkServiceClient will then notify network service of status changes
from the main process.

Bug: 881572
Cq-Include-Trybots: luci.chromium.try:linux_mojo
Change-Id: I1824e8e8c13f4294fd3a500545714c13a90db08b
Reviewed-on: https://chromium-review.googlesource.com/1225606Reviewed-by: default avatarMaks Orlovich <morlovich@chromium.org>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Reviewed-by: default avatarTommy Nyquist <nyquist@chromium.org>
Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Commit-Queue: Clark DuVall <cduvall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#593032}
parent 3b19b7fd
...@@ -15,49 +15,72 @@ namespace android { ...@@ -15,49 +15,72 @@ namespace android {
namespace { namespace {
struct LeakyLazyObserverListTraits : class ApplicationStatusListenerImpl;
base::internal::LeakyLazyInstanceTraits<
ObserverListThreadSafe<ApplicationStatusListener> > { struct LeakyLazyObserverListTraits
static ObserverListThreadSafe<ApplicationStatusListener>* : base::internal::LeakyLazyInstanceTraits<
New(void* instance) { ObserverListThreadSafe<ApplicationStatusListenerImpl>> {
ObserverListThreadSafe<ApplicationStatusListener>* ret = static ObserverListThreadSafe<ApplicationStatusListenerImpl>* New(
void* instance) {
ObserverListThreadSafe<ApplicationStatusListenerImpl>* ret =
base::internal::LeakyLazyInstanceTraits<ObserverListThreadSafe< base::internal::LeakyLazyInstanceTraits<ObserverListThreadSafe<
ApplicationStatusListener>>::New(instance); ApplicationStatusListenerImpl>>::New(instance);
// Leaky. // Leaky.
ret->AddRef(); ret->AddRef();
return ret; return ret;
} }
}; };
LazyInstance<ObserverListThreadSafe<ApplicationStatusListener>, LazyInstance<ObserverListThreadSafe<ApplicationStatusListenerImpl>,
LeakyLazyObserverListTraits> g_observers = LeakyLazyObserverListTraits>
LAZY_INSTANCE_INITIALIZER; g_observers = LAZY_INSTANCE_INITIALIZER;
} // namespace class ApplicationStatusListenerImpl : public ApplicationStatusListener {
public:
ApplicationStatusListenerImpl(
const ApplicationStateChangeCallback& callback) {
SetCallback(callback);
g_observers.Get().AddObserver(this);
ApplicationStatusListener::ApplicationStatusListener( Java_ApplicationStatus_registerThreadSafeNativeApplicationStateListener(
const ApplicationStatusListener::ApplicationStateChangeCallback& callback) AttachCurrentThread());
: callback_(callback) { }
DCHECK(!callback_.is_null());
g_observers.Get().AddObserver(this);
Java_ApplicationStatus_registerThreadSafeNativeApplicationStateListener( ~ApplicationStatusListenerImpl() override {
AttachCurrentThread()); g_observers.Get().RemoveObserver(this);
} }
ApplicationStatusListener::~ApplicationStatusListener() { void SetCallback(const ApplicationStateChangeCallback& callback) override {
g_observers.Get().RemoveObserver(this); DCHECK(!callback_);
} DCHECK(callback);
callback_ = callback;
}
void Notify(ApplicationState state) override {
if (callback_)
callback_.Run(state);
}
private:
ApplicationStateChangeCallback callback_;
};
void ApplicationStatusListener::Notify(ApplicationState state) { } // namespace
callback_.Run(state);
ApplicationStatusListener::ApplicationStatusListener() = default;
ApplicationStatusListener::~ApplicationStatusListener() = default;
// static
std::unique_ptr<ApplicationStatusListener> ApplicationStatusListener::New(
const ApplicationStateChangeCallback& callback) {
return std::make_unique<ApplicationStatusListenerImpl>(callback);
} }
// static // static
void ApplicationStatusListener::NotifyApplicationStateChange( void ApplicationStatusListener::NotifyApplicationStateChange(
ApplicationState state) { ApplicationState state) {
TRACE_COUNTER1("browser", "ApplicationState", static_cast<int>(state)); TRACE_COUNTER1("browser", "ApplicationState", static_cast<int>(state));
g_observers.Get().Notify(FROM_HERE, &ApplicationStatusListener::Notify, g_observers.Get().Notify(FROM_HERE, &ApplicationStatusListenerImpl::Notify,
state); state);
} }
......
...@@ -51,22 +51,30 @@ enum ApplicationState { ...@@ -51,22 +51,30 @@ enum ApplicationState {
// } // }
// //
// // Start listening. // // Start listening.
// ApplicationStatusListener* my_listener = // auto my_listener = ApplicationStatusListener::New(
// new ApplicationStatusListener( // base::BindRepeating(&OnApplicationStateChange));
// base::Bind(&OnApplicationStateChange));
// //
// ... // ...
// //
// // Stop listening. // // Stop listening.
// delete my_listener // my_listener.reset();
// //
class BASE_EXPORT ApplicationStatusListener { class BASE_EXPORT ApplicationStatusListener {
public: public:
typedef base::Callback<void(ApplicationState)> ApplicationStateChangeCallback; using ApplicationStateChangeCallback =
base::RepeatingCallback<void(ApplicationState)>;
explicit ApplicationStatusListener( virtual ~ApplicationStatusListener();
// Sets the callback to call when application state changes.
virtual void SetCallback(const ApplicationStateChangeCallback& callback) = 0;
// Notify observers that application state has changed.
virtual void Notify(ApplicationState state) = 0;
// Create a new listener. This object should only be used on a single thread.
static std::unique_ptr<ApplicationStatusListener> New(
const ApplicationStateChangeCallback& callback); const ApplicationStateChangeCallback& callback);
~ApplicationStatusListener();
// Internal use only: must be public to be called from JNI and unit tests. // Internal use only: must be public to be called from JNI and unit tests.
static void NotifyApplicationStateChange(ApplicationState state); static void NotifyApplicationStateChange(ApplicationState state);
...@@ -74,11 +82,10 @@ class BASE_EXPORT ApplicationStatusListener { ...@@ -74,11 +82,10 @@ class BASE_EXPORT ApplicationStatusListener {
// Expose jni call for ApplicationStatus.getStateForApplication. // Expose jni call for ApplicationStatus.getStateForApplication.
static ApplicationState GetState(); static ApplicationState GetState();
private: protected:
void Notify(ApplicationState state); ApplicationStatusListener();
ApplicationStateChangeCallback callback_;
private:
DISALLOW_COPY_AND_ASSIGN(ApplicationStatusListener); DISALLOW_COPY_AND_ASSIGN(ApplicationStatusListener);
}; };
......
...@@ -78,8 +78,8 @@ class MultiThreadedTest { ...@@ -78,8 +78,8 @@ class MultiThreadedTest {
void RegisterThreadForEvents() { void RegisterThreadForEvents() {
ExpectOnThread(); ExpectOnThread();
listener_.reset(new ApplicationStatusListener(base::Bind( listener_ = ApplicationStatusListener::New(base::BindRepeating(
&MultiThreadedTest::StoreStateAndSignal, base::Unretained(this)))); &MultiThreadedTest::StoreStateAndSignal, base::Unretained(this)));
EXPECT_TRUE(listener_.get()); EXPECT_TRUE(listener_.get());
event_.Signal(); event_.Signal();
} }
...@@ -106,7 +106,7 @@ TEST(ApplicationStatusListenerTest, SingleThread) { ...@@ -106,7 +106,7 @@ TEST(ApplicationStatusListenerTest, SingleThread) {
// Create a new listener that stores the new state into |result| on every // Create a new listener that stores the new state into |result| on every
// state change. // state change.
ApplicationStatusListener listener( auto listener = ApplicationStatusListener::New(
base::Bind(&StoreStateTo, base::Unretained(&result))); base::Bind(&StoreStateTo, base::Unretained(&result)));
EXPECT_EQ(kInvalidApplicationState, result); EXPECT_EQ(kInvalidApplicationState, result);
......
...@@ -118,12 +118,13 @@ class ContentSuggestionsNotifierService::NotifyingObserver ...@@ -118,12 +118,13 @@ class ContentSuggestionsNotifierService::NotifyingObserver
: service_(service), : service_(service),
prefs_(prefs), prefs_(prefs),
notifier_(notifier), notifier_(notifier),
app_status_listener_(base::Bind(&NotifyingObserver::AppStatusChanged, app_status_listener_(base::android::ApplicationStatusListener::New(
base::Unretained(this))), base::BindRepeating(&NotifyingObserver::AppStatusChanged,
base::Unretained(this)))),
weak_ptr_factory_(this) {} weak_ptr_factory_(this) {}
void OnNewSuggestions(Category category) override { void OnNewSuggestions(Category category) override {
if (!ShouldNotifyInState(app_status_listener_.GetState())) { if (!ShouldNotifyInState(app_status_listener_->GetState())) {
DVLOG(1) << "Suppressed notification because Chrome is frontmost"; DVLOG(1) << "Suppressed notification because Chrome is frontmost";
return; return;
} else if (!ContentSuggestionsNotifier::ShouldSendNotifications(prefs_)) { } else if (!ContentSuggestionsNotifier::ShouldSendNotifications(prefs_)) {
...@@ -223,7 +224,7 @@ class ContentSuggestionsNotifierService::NotifyingObserver ...@@ -223,7 +224,7 @@ class ContentSuggestionsNotifierService::NotifyingObserver
const base::string16& text, const base::string16& text,
base::Time timeout_at, base::Time timeout_at,
const gfx::Image& image) { const gfx::Image& image) {
if (!ShouldNotifyInState(app_status_listener_.GetState())) { if (!ShouldNotifyInState(app_status_listener_->GetState())) {
return; // Became foreground while we were fetching the image; forget it. return; // Became foreground while we were fetching the image; forget it.
} }
// check if suggestion is still valid. // check if suggestion is still valid.
...@@ -245,7 +246,8 @@ class ContentSuggestionsNotifierService::NotifyingObserver ...@@ -245,7 +246,8 @@ class ContentSuggestionsNotifierService::NotifyingObserver
ContentSuggestionsService* const service_; ContentSuggestionsService* const service_;
PrefService* const prefs_; PrefService* const prefs_;
ContentSuggestionsNotifier* const notifier_; ContentSuggestionsNotifier* const notifier_;
base::android::ApplicationStatusListener app_status_listener_; std::unique_ptr<base::android::ApplicationStatusListener>
app_status_listener_;
base::WeakPtrFactory<NotifyingObserver> weak_ptr_factory_; base::WeakPtrFactory<NotifyingObserver> weak_ptr_factory_;
......
...@@ -40,23 +40,33 @@ void OnApplicationStateChange( ...@@ -40,23 +40,33 @@ void OnApplicationStateChange(
} }
} }
// This wrapper is needed so we can call the ApplicationStatusListener::New
// method which returns a unique_ptr.
class ApplicationStatusListenerWrapper {
public:
ApplicationStatusListenerWrapper()
: listener_(base::android::ApplicationStatusListener::New(
base::BindRepeating(&OnApplicationStateChange))) {}
private:
std::unique_ptr<base::android::ApplicationStatusListener> listener_;
};
struct LeakyApplicationStatusListenerTraits { struct LeakyApplicationStatusListenerTraits {
static const bool kRegisterOnExit = false; static const bool kRegisterOnExit = false;
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
static const bool kAllowedToAccessOnNonjoinableThread = true; static const bool kAllowedToAccessOnNonjoinableThread = true;
#endif #endif
static base::android::ApplicationStatusListener* New(void* instance) { static ApplicationStatusListenerWrapper* New(void* instance) {
ANNOTATE_SCOPED_MEMORY_LEAK; ANNOTATE_SCOPED_MEMORY_LEAK;
return new (instance) base::android::ApplicationStatusListener( return new (instance) ApplicationStatusListenerWrapper();
base::Bind(&OnApplicationStateChange));
} }
static void Delete(base::android::ApplicationStatusListener* instance) { static void Delete(ApplicationStatusListenerWrapper* instance) {}
}
}; };
base::LazyInstance<base::android::ApplicationStatusListener, base::LazyInstance<ApplicationStatusListenerWrapper,
LeakyApplicationStatusListenerTraits> LeakyApplicationStatusListenerTraits>
g_application_status_listener = LAZY_INSTANCE_INITIALIZER; g_application_status_listener = LAZY_INSTANCE_INITIALIZER;
......
...@@ -12,11 +12,11 @@ namespace offline_pages { ...@@ -12,11 +12,11 @@ namespace offline_pages {
LoadTerminationListenerImpl::LoadTerminationListenerImpl() LoadTerminationListenerImpl::LoadTerminationListenerImpl()
: weak_ptr_factory_(this) { : weak_ptr_factory_(this) {
if (base::SysInfo::IsLowEndDevice()) { if (base::SysInfo::IsLowEndDevice())
app_listener_ = std::make_unique<base::android::ApplicationStatusListener>( app_listener_ =
base::Bind(&LoadTerminationListenerImpl::OnApplicationStateChange, base::android::ApplicationStatusListener::New(base::BindRepeating(
weak_ptr_factory_.GetWeakPtr())); &LoadTerminationListenerImpl::OnApplicationStateChange,
} weak_ptr_factory_.GetWeakPtr()));
} }
LoadTerminationListenerImpl::~LoadTerminationListenerImpl() { LoadTerminationListenerImpl::~LoadTerminationListenerImpl() {
......
...@@ -232,10 +232,10 @@ void DataReductionProxyConfigServiceClient::InitializeOnIOThread( ...@@ -232,10 +232,10 @@ void DataReductionProxyConfigServiceClient::InitializeOnIOThread(
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
// It is okay to use Unretained here because |app_status_listener| would be // It is okay to use Unretained here because |app_status_listener| would be
// destroyed before |this|. // destroyed before |this|.
app_status_listener_.reset( app_status_listener_ =
new base::android::ApplicationStatusListener(base::Bind( base::android::ApplicationStatusListener::New(base::BindRepeating(
&DataReductionProxyConfigServiceClient::OnApplicationStateChange, &DataReductionProxyConfigServiceClient::OnApplicationStateChange,
base::Unretained(this)))); base::Unretained(this)));
#endif #endif
url_request_context_getter_ = url_request_context_getter; url_request_context_getter_ = url_request_context_getter;
network_connection_tracker_->AddNetworkConnectionObserver(this); network_connection_tracker_->AddNetworkConnectionObserver(this);
......
...@@ -83,9 +83,9 @@ DataUseMeasurement::DataUseMeasurement( ...@@ -83,9 +83,9 @@ DataUseMeasurement::DataUseMeasurement(
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
, ,
app_state_(base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES), app_state_(base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES),
app_listener_(new base::android::ApplicationStatusListener( app_listener_(base::android::ApplicationStatusListener::New(
base::Bind(&DataUseMeasurement::OnApplicationStateChange, base::BindRepeating(&DataUseMeasurement::OnApplicationStateChange,
base::Unretained(this)))), base::Unretained(this)))),
rx_bytes_os_(0), rx_bytes_os_(0),
tx_bytes_os_(0), tx_bytes_os_(0),
bytes_transferred_since_last_traffic_stats_query_(0), bytes_transferred_since_last_traffic_stats_query_(0),
......
...@@ -88,10 +88,9 @@ MemoryMonitorAndroid::MemoryMonitorAndroid(std::unique_ptr<Delegate> delegate) ...@@ -88,10 +88,9 @@ MemoryMonitorAndroid::MemoryMonitorAndroid(std::unique_ptr<Delegate> delegate)
: delegate_(std::move(delegate)) { : delegate_(std::move(delegate)) {
DCHECK(delegate_.get()); DCHECK(delegate_.get());
RegisterComponentCallbacks(); RegisterComponentCallbacks();
application_state_listener_ = application_state_listener_ = base::android::ApplicationStatusListener::New(
std::make_unique<base::android::ApplicationStatusListener>( base::BindRepeating(&MemoryMonitorAndroid::OnApplicationStateChange,
base::Bind(&MemoryMonitorAndroid::OnApplicationStateChange, base::Unretained(this)));
base::Unretained(this)));
} }
MemoryMonitorAndroid::~MemoryMonitorAndroid() {} MemoryMonitorAndroid::~MemoryMonitorAndroid() {}
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "build/build_config.h" #include "build/build_config.h"
#include "content/browser/storage_partition_impl.h" #include "content/browser/storage_partition_impl.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/url_data_source.h" #include "content/public/browser/url_data_source.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_observer.h"
...@@ -18,11 +19,17 @@ ...@@ -18,11 +19,17 @@
#include "content/public/test/browser_test_utils.h" #include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h" #include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/simple_url_loader_test_helper.h"
#include "content/public/test/test_utils.h" #include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h" #include "content/shell/browser/shell.h"
#include "net/dns/mock_host_resolver.h" #include "net/dns/mock_host_resolver.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/public/cpp/features.h" #include "services/network/public/cpp/features.h"
#if defined(OS_ANDROID)
#include "base/android/application_status_listener.h"
#endif
namespace content { namespace content {
namespace { namespace {
...@@ -110,6 +117,7 @@ class NetworkServiceBrowserTest : public ContentBrowserTest { ...@@ -110,6 +117,7 @@ class NetworkServiceBrowserTest : public ContentBrowserTest {
scoped_feature_list_.InitAndEnableFeature( scoped_feature_list_.InitAndEnableFeature(
network::features::kNetworkService); network::features::kNetworkService);
EXPECT_TRUE(embedded_test_server()->Start()); EXPECT_TRUE(embedded_test_server()->Start());
EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
WebUIControllerFactory::RegisterFactory(&factory_); WebUIControllerFactory::RegisterFactory(&factory_);
} }
...@@ -157,9 +165,32 @@ class NetworkServiceBrowserTest : public ContentBrowserTest { ...@@ -157,9 +165,32 @@ class NetworkServiceBrowserTest : public ContentBrowserTest {
IsolateAllSitesForTesting(command_line); IsolateAllSitesForTesting(command_line);
} }
base::FilePath GetCacheDirectory() { return temp_dir_.GetPath(); }
base::FilePath GetCacheIndexDirectory() {
return GetCacheDirectory().AppendASCII("index-dir");
}
void LoadURL(const GURL& url,
network::mojom::URLLoaderFactory* loader_factory) {
std::unique_ptr<network::ResourceRequest> request =
std::make_unique<network::ResourceRequest>();
request->url = url;
content::SimpleURLLoaderTestHelper simple_loader_helper;
std::unique_ptr<network::SimpleURLLoader> simple_loader =
network::SimpleURLLoader::Create(std::move(request),
TRAFFIC_ANNOTATION_FOR_TESTS);
simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
loader_factory, simple_loader_helper.GetCallback());
simple_loader_helper.WaitForCallback();
ASSERT_TRUE(simple_loader_helper.response_body());
}
private: private:
WebUITestWebUIControllerFactory factory_; WebUITestWebUIControllerFactory factory_;
base::test::ScopedFeatureList scoped_feature_list_; base::test::ScopedFeatureList scoped_feature_list_;
base::ScopedTempDir temp_dir_;
DISALLOW_COPY_AND_ASSIGN(NetworkServiceBrowserTest); DISALLOW_COPY_AND_ASSIGN(NetworkServiceBrowserTest);
}; };
...@@ -195,6 +226,49 @@ IN_PROC_BROWSER_TEST_F(NetworkServiceBrowserTest, ...@@ -195,6 +226,49 @@ IN_PROC_BROWSER_TEST_F(NetworkServiceBrowserTest,
EXPECT_FALSE(FetchResource(file_url)); EXPECT_FALSE(FetchResource(file_url));
} }
#if defined(OS_ANDROID)
IN_PROC_BROWSER_TEST_F(NetworkServiceBrowserTest,
HttpCacheWrittenToDiskOnApplicationStateChange) {
base::ScopedAllowBlockingForTesting allow_blocking;
// Create network context with cache pointing to the temp cache dir.
network::mojom::NetworkContextPtr network_context;
network::mojom::NetworkContextParamsPtr context_params =
network::mojom::NetworkContextParams::New();
context_params->http_cache_path = GetCacheDirectory();
GetNetworkService()->CreateNetworkContext(mojo::MakeRequest(&network_context),
std::move(context_params));
network::mojom::URLLoaderFactoryParamsPtr params =
network::mojom::URLLoaderFactoryParams::New();
params->process_id = network::mojom::kBrowserProcessId;
params->is_corb_enabled = false;
network::mojom::URLLoaderFactoryPtr loader_factory;
network_context->CreateURLLoaderFactory(mojo::MakeRequest(&loader_factory),
std::move(params));
// Load a URL and check the cache index size.
LoadURL(embedded_test_server()->GetURL("/cachetime"), loader_factory.get());
int64_t directory_size = base::ComputeDirectorySize(GetCacheIndexDirectory());
// Load another URL, cache index should not be written to disk yet.
LoadURL(embedded_test_server()->GetURL("/cachetime?foo"),
loader_factory.get());
EXPECT_EQ(directory_size,
base::ComputeDirectorySize(GetCacheIndexDirectory()));
// After application state changes, cache index should be written to disk.
base::android::ApplicationStatusListener::NotifyApplicationStateChange(
base::android::APPLICATION_STATE_HAS_STOPPED_ACTIVITIES);
base::RunLoop().RunUntilIdle();
content::FlushNetworkServiceInstanceForTesting();
disk_cache::FlushCacheThreadForTesting();
EXPECT_GT(base::ComputeDirectorySize(GetCacheIndexDirectory()),
directory_size);
}
#endif
class NetworkServiceInProcessBrowserTest : public ContentBrowserTest { class NetworkServiceInProcessBrowserTest : public ContentBrowserTest {
public: public:
NetworkServiceInProcessBrowserTest() { NetworkServiceInProcessBrowserTest() {
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/global_request_id.h" #include "content/public/browser/global_request_id.h"
#include "content/public/browser/login_delegate.h" #include "content/public/browser/login_delegate.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/resource_request_info.h" #include "content/public/browser/resource_request_info.h"
#include "content/public/common/resource_type.h" #include "content/public/common/resource_type.h"
#include "mojo/public/cpp/bindings/strong_binding.h" #include "mojo/public/cpp/bindings/strong_binding.h"
...@@ -310,7 +311,15 @@ void HandleFileUploadRequest( ...@@ -310,7 +311,15 @@ void HandleFileUploadRequest(
NetworkServiceClient::NetworkServiceClient( NetworkServiceClient::NetworkServiceClient(
network::mojom::NetworkServiceClientRequest network_service_client_request) network::mojom::NetworkServiceClientRequest network_service_client_request)
: binding_(this, std::move(network_service_client_request)) {} : binding_(this, std::move(network_service_client_request))
#if defined(OS_ANDROID)
,
app_status_listener_(base::android::ApplicationStatusListener::New(
base::BindRepeating(&NetworkServiceClient::OnApplicationStateChange,
base::Unretained(this))))
#endif
{
}
NetworkServiceClient::~NetworkServiceClient() = default; NetworkServiceClient::~NetworkServiceClient() = default;
...@@ -474,4 +483,11 @@ void NetworkServiceClient::OnClearSiteData(int process_id, ...@@ -474,4 +483,11 @@ void NetworkServiceClient::OnClearSiteData(int process_id,
std::move(callback)); std::move(callback));
} }
#if defined(OS_ANDROID)
void NetworkServiceClient::OnApplicationStateChange(
base::android::ApplicationState state) {
GetNetworkService()->OnApplicationStateChange(state);
}
#endif
} // namespace content } // namespace content
...@@ -6,11 +6,16 @@ ...@@ -6,11 +6,16 @@
#define CONTENT_BROWSER_NETWORK_SERVICE_IMPL_H_ #define CONTENT_BROWSER_NETWORK_SERVICE_IMPL_H_
#include "base/macros.h" #include "base/macros.h"
#include "build/build_config.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
#include "services/network/public/mojom/network_service.mojom.h" #include "services/network/public/mojom/network_service.mojom.h"
#include "url/gurl.h" #include "url/gurl.h"
#if defined(OS_ANDROID)
#include "base/android/application_status_listener.h"
#endif
namespace content { namespace content {
class CONTENT_EXPORT NetworkServiceClient class CONTENT_EXPORT NetworkServiceClient
...@@ -72,9 +77,18 @@ class CONTENT_EXPORT NetworkServiceClient ...@@ -72,9 +77,18 @@ class CONTENT_EXPORT NetworkServiceClient
int load_flags, int load_flags,
OnClearSiteDataCallback callback) override; OnClearSiteDataCallback callback) override;
#if defined(OS_ANDROID)
void OnApplicationStateChange(base::android::ApplicationState state);
#endif
private: private:
mojo::Binding<network::mojom::NetworkServiceClient> binding_; mojo::Binding<network::mojom::NetworkServiceClient> binding_;
#if defined(OS_ANDROID)
std::unique_ptr<base::android::ApplicationStatusListener>
app_status_listener_;
#endif
DISALLOW_COPY_AND_ASSIGN(NetworkServiceClient); DISALLOW_COPY_AND_ASSIGN(NetworkServiceClient);
}; };
......
...@@ -217,9 +217,10 @@ class CompositorDependencies { ...@@ -217,9 +217,10 @@ class CompositorDependencies {
CompositorDependencies() CompositorDependencies()
: frame_sink_id_allocator(kDefaultClientId), : frame_sink_id_allocator(kDefaultClientId),
app_listener_(base::BindRepeating( app_listener_(
&CompositorDependencies::OnApplicationStateChange, base::android::ApplicationStatusListener::New(base::BindRepeating(
base::Unretained(this))) { &CompositorDependencies::OnApplicationStateChange,
base::Unretained(this)))) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
bool enable_viz = bool enable_viz =
...@@ -330,7 +331,7 @@ class CompositorDependencies { ...@@ -330,7 +331,7 @@ class CompositorDependencies {
base::CancelableOnceClosure low_end_background_cleanup_task_; base::CancelableOnceClosure low_end_background_cleanup_task_;
// An instance of Android AppListener. // An instance of Android AppListener.
base::android::ApplicationStatusListener app_listener_; std::unique_ptr<base::android::ApplicationStatusListener> app_listener_;
}; };
const unsigned int kMaxDisplaySwapBuffers = 1U; const unsigned int kMaxDisplaySwapBuffers = 1U;
......
...@@ -114,9 +114,9 @@ void VideoCaptureManager::RegisterListener( ...@@ -114,9 +114,9 @@ void VideoCaptureManager::RegisterListener(
listeners_.AddObserver(listener); listeners_.AddObserver(listener);
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
application_state_has_running_activities_ = true; application_state_has_running_activities_ = true;
app_status_listener_.reset(new base::android::ApplicationStatusListener( app_status_listener_ = base::android::ApplicationStatusListener::New(
base::Bind(&VideoCaptureManager::OnApplicationStateChange, base::BindRepeating(&VideoCaptureManager::OnApplicationStateChange,
base::Unretained(this)))); base::Unretained(this)));
#endif #endif
} }
......
...@@ -32,6 +32,9 @@ class CacheCreator { ...@@ -32,6 +32,9 @@ class CacheCreator {
net::CacheType type, net::CacheType type,
net::BackendType backend_type, net::BackendType backend_type,
uint32_t flags, uint32_t flags,
#if defined(OS_ANDROID)
base::android::ApplicationStatusListener* app_status_listener,
#endif
net::NetLog* net_log, net::NetLog* net_log,
std::unique_ptr<disk_cache::Backend>* backend, std::unique_ptr<disk_cache::Backend>* backend,
base::OnceClosure post_cleanup_callback, base::OnceClosure post_cleanup_callback,
...@@ -58,6 +61,8 @@ class CacheCreator { ...@@ -58,6 +61,8 @@ class CacheCreator {
net::BackendType backend_type_; net::BackendType backend_type_;
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
uint32_t flags_; uint32_t flags_;
#else
base::android::ApplicationStatusListener* app_status_listener_;
#endif #endif
std::unique_ptr<disk_cache::Backend>* backend_; std::unique_ptr<disk_cache::Backend>* backend_;
base::OnceClosure post_cleanup_callback_; base::OnceClosure post_cleanup_callback_;
...@@ -69,16 +74,20 @@ class CacheCreator { ...@@ -69,16 +74,20 @@ class CacheCreator {
DISALLOW_COPY_AND_ASSIGN(CacheCreator); DISALLOW_COPY_AND_ASSIGN(CacheCreator);
}; };
CacheCreator::CacheCreator(const base::FilePath& path, CacheCreator::CacheCreator(
bool force, const base::FilePath& path,
int64_t max_bytes, bool force,
net::CacheType type, int64_t max_bytes,
net::BackendType backend_type, net::CacheType type,
uint32_t flags, net::BackendType backend_type,
net::NetLog* net_log, uint32_t flags,
std::unique_ptr<disk_cache::Backend>* backend, #if defined(OS_ANDROID)
base::OnceClosure post_cleanup_callback, base::android::ApplicationStatusListener* app_status_listener,
net::CompletionOnceCallback callback) #endif
net::NetLog* net_log,
std::unique_ptr<disk_cache::Backend>* backend,
base::OnceClosure post_cleanup_callback,
net::CompletionOnceCallback callback)
: path_(path), : path_(path),
force_(force), force_(force),
retry_(false), retry_(false),
...@@ -87,6 +96,8 @@ CacheCreator::CacheCreator(const base::FilePath& path, ...@@ -87,6 +96,8 @@ CacheCreator::CacheCreator(const base::FilePath& path,
backend_type_(backend_type), backend_type_(backend_type),
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
flags_(flags), flags_(flags),
#else
app_status_listener_(app_status_listener),
#endif #endif
backend_(backend), backend_(backend),
post_cleanup_callback_(std::move(post_cleanup_callback)), post_cleanup_callback_(std::move(post_cleanup_callback)),
...@@ -110,6 +121,10 @@ int CacheCreator::Run() { ...@@ -110,6 +121,10 @@ int CacheCreator::Run() {
/* file_tracker = */ nullptr, /* file_tracker = */ nullptr,
max_bytes_, type_, net_log_); max_bytes_, type_, net_log_);
created_cache_.reset(simple_cache); created_cache_.reset(simple_cache);
#if defined(OS_ANDROID)
if (app_status_listener_)
simple_cache->set_app_status_listener(app_status_listener_);
#endif
return simple_cache->Init( return simple_cache->Init(
base::Bind(&CacheCreator::OnIOComplete, base::Unretained(this))); base::Bind(&CacheCreator::OnIOComplete, base::Unretained(this)));
} }
...@@ -196,15 +211,19 @@ void CacheCreator::OnIOComplete(int result) { ...@@ -196,15 +211,19 @@ void CacheCreator::OnIOComplete(int result) {
namespace disk_cache { namespace disk_cache {
int CreateCacheBackendImpl(net::CacheType type, int CreateCacheBackendImpl(
net::BackendType backend_type, net::CacheType type,
const base::FilePath& path, net::BackendType backend_type,
int64_t max_bytes, const base::FilePath& path,
bool force, int64_t max_bytes,
net::NetLog* net_log, bool force,
std::unique_ptr<Backend>* backend, #if defined(OS_ANDROID)
base::OnceClosure post_cleanup_callback, base::android::ApplicationStatusListener* app_status_listener,
net::CompletionOnceCallback callback) { #endif
net::NetLog* net_log,
std::unique_ptr<Backend>* backend,
base::OnceClosure post_cleanup_callback,
net::CompletionOnceCallback callback) {
DCHECK(!callback.is_null()); DCHECK(!callback.is_null());
if (type == net::MEMORY_CACHE) { if (type == net::MEMORY_CACHE) {
...@@ -225,8 +244,11 @@ int CreateCacheBackendImpl(net::CacheType type, ...@@ -225,8 +244,11 @@ int CreateCacheBackendImpl(net::CacheType type,
bool had_post_cleanup_callback = !post_cleanup_callback.is_null(); bool had_post_cleanup_callback = !post_cleanup_callback.is_null();
CacheCreator* creator = new CacheCreator( CacheCreator* creator = new CacheCreator(
path, force, max_bytes, type, backend_type, kNone, net_log, backend, path, force, max_bytes, type, backend_type, kNone,
std::move(post_cleanup_callback), std::move(callback)); #if defined(OS_ANDROID)
std::move(app_status_listener),
#endif
net_log, backend, std::move(post_cleanup_callback), std::move(callback));
if (type == net::DISK_CACHE || type == net::MEDIA_CACHE) { if (type == net::DISK_CACHE || type == net::MEDIA_CACHE) {
DCHECK(!had_post_cleanup_callback); DCHECK(!had_post_cleanup_callback);
return creator->Run(); return creator->Run();
...@@ -244,10 +266,31 @@ int CreateCacheBackend(net::CacheType type, ...@@ -244,10 +266,31 @@ int CreateCacheBackend(net::CacheType type,
std::unique_ptr<Backend>* backend, std::unique_ptr<Backend>* backend,
net::CompletionOnceCallback callback) { net::CompletionOnceCallback callback) {
return CreateCacheBackendImpl(type, backend_type, path, max_bytes, force, return CreateCacheBackendImpl(type, backend_type, path, max_bytes, force,
#if defined(OS_ANDROID)
nullptr,
#endif
net_log, backend, base::OnceClosure(), net_log, backend, base::OnceClosure(),
std::move(callback)); std::move(callback));
} }
#if defined(OS_ANDROID)
NET_EXPORT int CreateCacheBackend(
net::CacheType type,
net::BackendType backend_type,
const base::FilePath& path,
int64_t max_bytes,
bool force,
net::NetLog* net_log,
std::unique_ptr<Backend>* backend,
net::CompletionOnceCallback callback,
base::android::ApplicationStatusListener* app_status_listener) {
return CreateCacheBackendImpl(type, backend_type, path, max_bytes, force,
std::move(app_status_listener), net_log,
backend, base::OnceClosure(),
std::move(callback));
}
#endif
int CreateCacheBackend(net::CacheType type, int CreateCacheBackend(net::CacheType type,
net::BackendType backend_type, net::BackendType backend_type,
const base::FilePath& path, const base::FilePath& path,
...@@ -258,8 +301,11 @@ int CreateCacheBackend(net::CacheType type, ...@@ -258,8 +301,11 @@ int CreateCacheBackend(net::CacheType type,
base::OnceClosure post_cleanup_callback, base::OnceClosure post_cleanup_callback,
net::CompletionOnceCallback callback) { net::CompletionOnceCallback callback) {
return CreateCacheBackendImpl( return CreateCacheBackendImpl(
type, backend_type, path, max_bytes, force, net_log, backend, type, backend_type, path, max_bytes, force,
std::move(post_cleanup_callback), std::move(callback)); #if defined(OS_ANDROID)
nullptr,
#endif
net_log, backend, std::move(post_cleanup_callback), std::move(callback));
} }
void FlushCacheThreadForTesting() { void FlushCacheThreadForTesting() {
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/strings/string_split.h" #include "base/strings/string_split.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "build/build_config.h"
#include "net/base/cache_type.h" #include "net/base/cache_type.h"
#include "net/base/completion_once_callback.h" #include "net/base/completion_once_callback.h"
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
...@@ -30,6 +31,10 @@ namespace trace_event { ...@@ -30,6 +31,10 @@ namespace trace_event {
class ProcessMemoryDump; class ProcessMemoryDump;
} }
namespace android {
class ApplicationStatusListener;
} // namespace android
} // namespace base } // namespace base
namespace net { namespace net {
...@@ -68,6 +73,22 @@ NET_EXPORT int CreateCacheBackend(net::CacheType type, ...@@ -68,6 +73,22 @@ NET_EXPORT int CreateCacheBackend(net::CacheType type,
std::unique_ptr<Backend>* backend, std::unique_ptr<Backend>* backend,
net::CompletionOnceCallback callback); net::CompletionOnceCallback callback);
#if defined(OS_ANDROID)
// Similar to the function above, but takes an |app_status_listener| which is
// used to listen for when the Android application status changes, so we can
// flush the cache to disk when the app goes to the background.
NET_EXPORT int CreateCacheBackend(
net::CacheType type,
net::BackendType backend_type,
const base::FilePath& path,
int64_t max_bytes,
bool force,
net::NetLog* net_log,
std::unique_ptr<Backend>* backend,
net::CompletionOnceCallback callback,
base::android::ApplicationStatusListener* app_status_listener);
#endif
// Variant of the above that calls |post_cleanup_callback| once all the I/O // Variant of the above that calls |post_cleanup_callback| once all the I/O
// that was in flight has completed post-destruction. |post_cleanup_callback| // that was in flight has completed post-destruction. |post_cleanup_callback|
// will get invoked even if the creation fails. The invocation will always be // will get invoked even if the creation fails. The invocation will always be
......
...@@ -663,6 +663,10 @@ void SimpleBackendImpl::InitializeIndex(CompletionOnceCallback callback, ...@@ -663,6 +663,10 @@ void SimpleBackendImpl::InitializeIndex(CompletionOnceCallback callback,
const DiskStatResult& result) { const DiskStatResult& result) {
if (result.net_error == net::OK) { if (result.net_error == net::OK) {
index_->SetMaxSize(result.max_size); index_->SetMaxSize(result.max_size);
#if defined(OS_ANDROID)
if (app_status_listener_)
index_->set_app_status_listener(app_status_listener_);
#endif
index_->Initialize(result.cache_dir_mtime); index_->Initialize(result.cache_dir_mtime);
} }
std::move(callback).Run(result.net_error); std::move(callback).Run(result.net_error);
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "base/strings/string_split.h" #include "base/strings/string_split.h"
#include "base/task_runner.h" #include "base/task_runner.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "build/build_config.h"
#include "net/base/cache_type.h" #include "net/base/cache_type.h"
#include "net/base/net_export.h" #include "net/base/net_export.h"
#include "net/disk_cache/disk_cache.h" #include "net/disk_cache/disk_cache.h"
...@@ -141,6 +142,13 @@ class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend, ...@@ -141,6 +142,13 @@ class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend,
return prioritized_task_runner_.get(); return prioritized_task_runner_.get();
} }
#if defined(OS_ANDROID)
void set_app_status_listener(
base::android::ApplicationStatusListener* app_status_listener) {
app_status_listener_ = app_status_listener;
}
#endif
private: private:
class SimpleIterator; class SimpleIterator;
friend class SimpleIterator; friend class SimpleIterator;
...@@ -282,6 +290,10 @@ class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend, ...@@ -282,6 +290,10 @@ class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend,
net::NetLog* const net_log_; net::NetLog* const net_log_;
uint32_t entry_count_ = 0; uint32_t entry_count_ = 0;
#if defined(OS_ANDROID)
base::android::ApplicationStatusListener* app_status_listener_ = nullptr;
#endif
}; };
} // namespace disk_cache } // namespace disk_cache
......
...@@ -178,9 +178,14 @@ void SimpleIndex::Initialize(base::Time cache_mtime) { ...@@ -178,9 +178,14 @@ void SimpleIndex::Initialize(base::Time cache_mtime) {
DCHECK(io_thread_checker_.CalledOnValidThread()); DCHECK(io_thread_checker_.CalledOnValidThread());
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
if (base::android::IsVMInitialized()) { if (app_status_listener_) {
app_status_listener_.reset(new base::android::ApplicationStatusListener( app_status_listener_->SetCallback(base::BindRepeating(
base::Bind(&SimpleIndex::OnApplicationStateChange, AsWeakPtr()))); &SimpleIndex::OnApplicationStateChange, AsWeakPtr()));
} else if (base::android::IsVMInitialized()) {
owned_app_status_listener_ =
base::android::ApplicationStatusListener::New(base::BindRepeating(
&SimpleIndex::OnApplicationStateChange, AsWeakPtr()));
app_status_listener_ = owned_app_status_listener_.get();
} }
#endif #endif
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "base/threading/thread_checker.h" #include "base/threading/thread_checker.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "build/build_config.h"
#include "net/base/cache_type.h" #include "net/base/cache_type.h"
#include "net/base/completion_once_callback.h" #include "net/base/completion_once_callback.h"
#include "net/base/net_export.h" #include "net/base/net_export.h"
...@@ -194,6 +195,13 @@ class NET_EXPORT_PRIVATE SimpleIndex ...@@ -194,6 +195,13 @@ class NET_EXPORT_PRIVATE SimpleIndex
void SetLastUsedTimeForTest(uint64_t entry_hash, const base::Time last_used); void SetLastUsedTimeForTest(uint64_t entry_hash, const base::Time last_used);
#if defined(OS_ANDROID)
void set_app_status_listener(
base::android::ApplicationStatusListener* app_status_listener) {
app_status_listener_ = app_status_listener;
}
#endif
private: private:
friend class SimpleIndexTest; friend class SimpleIndexTest;
FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest, IndexSizeCorrectOnMerge); FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest, IndexSizeCorrectOnMerge);
...@@ -216,7 +224,8 @@ class NET_EXPORT_PRIVATE SimpleIndex ...@@ -216,7 +224,8 @@ class NET_EXPORT_PRIVATE SimpleIndex
void OnApplicationStateChange(base::android::ApplicationState state); void OnApplicationStateChange(base::android::ApplicationState state);
std::unique_ptr<base::android::ApplicationStatusListener> std::unique_ptr<base::android::ApplicationStatusListener>
app_status_listener_; owned_app_status_listener_;
base::android::ApplicationStatusListener* app_status_listener_ = nullptr;
#endif #endif
scoped_refptr<BackendCleanupTracker> cleanup_tracker_; scoped_refptr<BackendCleanupTracker> cleanup_tracker_;
......
...@@ -77,11 +77,25 @@ int HttpCache::DefaultBackend::CreateBackend( ...@@ -77,11 +77,25 @@ int HttpCache::DefaultBackend::CreateBackend(
std::unique_ptr<disk_cache::Backend>* backend, std::unique_ptr<disk_cache::Backend>* backend,
CompletionOnceCallback callback) { CompletionOnceCallback callback) {
DCHECK_GE(max_bytes_, 0); DCHECK_GE(max_bytes_, 0);
#if defined(OS_ANDROID)
if (app_status_listener_) {
return disk_cache::CreateCacheBackend(
type_, backend_type_, path_, max_bytes_, true, net_log, backend,
std::move(callback), app_status_listener_);
}
#endif
return disk_cache::CreateCacheBackend(type_, backend_type_, path_, max_bytes_, return disk_cache::CreateCacheBackend(type_, backend_type_, path_, max_bytes_,
true, net_log, backend, true, net_log, backend,
std::move(callback)); std::move(callback));
} }
#if defined(OS_ANDROID)
void HttpCache::DefaultBackend::SetAppStatusListener(
base::android::ApplicationStatusListener* app_status_listener) {
app_status_listener_ = app_status_listener;
}
#endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
HttpCache::ActiveEntry::ActiveEntry(disk_cache::Entry* entry) HttpCache::ActiveEntry::ActiveEntry(disk_cache::Entry* entry)
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "base/threading/thread_checker.h" #include "base/threading/thread_checker.h"
#include "base/time/clock.h" #include "base/time/clock.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "build/build_config.h"
#include "net/base/cache_type.h" #include "net/base/cache_type.h"
#include "net/base/completion_once_callback.h" #include "net/base/completion_once_callback.h"
#include "net/base/load_states.h" #include "net/base/load_states.h"
...@@ -40,6 +41,10 @@ namespace base { ...@@ -40,6 +41,10 @@ namespace base {
namespace trace_event { namespace trace_event {
class ProcessMemoryDump; class ProcessMemoryDump;
} }
namespace android {
class ApplicationStatusListener;
} // namespace android
} // namespace base } // namespace base
namespace disk_cache { namespace disk_cache {
...@@ -81,6 +86,11 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory { ...@@ -81,6 +86,11 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory {
virtual int CreateBackend(NetLog* net_log, virtual int CreateBackend(NetLog* net_log,
std::unique_ptr<disk_cache::Backend>* backend, std::unique_ptr<disk_cache::Backend>* backend,
CompletionOnceCallback callback) = 0; CompletionOnceCallback callback) = 0;
#if defined(OS_ANDROID)
virtual void SetAppStatusListener(
base::android::ApplicationStatusListener* app_status_listener){};
#endif
}; };
// A default backend factory for the common use cases. // A default backend factory for the common use cases.
...@@ -102,11 +112,19 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory { ...@@ -102,11 +112,19 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory {
std::unique_ptr<disk_cache::Backend>* backend, std::unique_ptr<disk_cache::Backend>* backend,
CompletionOnceCallback callback) override; CompletionOnceCallback callback) override;
#if defined(OS_ANDROID)
void SetAppStatusListener(
base::android::ApplicationStatusListener* app_status_listener) override;
#endif
private: private:
CacheType type_; CacheType type_;
BackendType backend_type_; BackendType backend_type_;
const base::FilePath path_; const base::FilePath path_;
int max_bytes_; int max_bytes_;
#if defined(OS_ANDROID)
base::android::ApplicationStatusListener* app_status_listener_ = nullptr;
#endif
}; };
// Whether a transaction can join parallel writing or not is a function of the // Whether a transaction can join parallel writing or not is a function of the
......
...@@ -600,6 +600,10 @@ std::unique_ptr<URLRequestContext> URLRequestContextBuilder::Build() { ...@@ -600,6 +600,10 @@ std::unique_ptr<URLRequestContext> URLRequestContextBuilder::Build() {
http_cache_backend = http_cache_backend =
HttpCache::DefaultBackend::InMemory(http_cache_params_.max_size); HttpCache::DefaultBackend::InMemory(http_cache_params_.max_size);
} }
#if defined(OS_ANDROID)
http_cache_backend->SetAppStatusListener(
http_cache_params_.app_status_listener);
#endif
http_transaction_factory.reset( http_transaction_factory.reset(
new HttpCache(std::move(http_transaction_factory), new HttpCache(std::move(http_transaction_factory),
......
...@@ -42,6 +42,12 @@ ...@@ -42,6 +42,12 @@
#include "net/third_party/quic/core/quic_packets.h" #include "net/third_party/quic/core/quic_packets.h"
#include "net/url_request/url_request_job_factory.h" #include "net/url_request/url_request_job_factory.h"
namespace base {
namespace android {
class ApplicationStatusListener;
}
} // namespace base
namespace net { namespace net {
class CertVerifier; class CertVerifier;
...@@ -119,6 +125,12 @@ class NET_EXPORT URLRequestContextBuilder { ...@@ -119,6 +125,12 @@ class NET_EXPORT URLRequestContextBuilder {
// The cache path (when type is DISK). // The cache path (when type is DISK).
base::FilePath path; base::FilePath path;
#if defined(OS_ANDROID)
// If this is set, will override the default ApplicationStatusListener. This
// is useful if the cache will not be in the main process.
base::android::ApplicationStatusListener* app_status_listener = nullptr;
#endif
}; };
URLRequestContextBuilder(); URLRequestContextBuilder();
......
...@@ -113,6 +113,10 @@ ...@@ -113,6 +113,10 @@
#include "net/cert_net/cert_net_fetcher_impl.h" #include "net/cert_net/cert_net_fetcher_impl.h"
#endif #endif
#if defined(OS_ANDROID)
#include "base/android/application_status_listener.h"
#endif
namespace network { namespace network {
namespace { namespace {
...@@ -225,6 +229,27 @@ void OnClearedChannelIds(net::SSLConfigService* ssl_config_service, ...@@ -225,6 +229,27 @@ void OnClearedChannelIds(net::SSLConfigService* ssl_config_service,
std::move(callback).Run(); std::move(callback).Run();
} }
#if defined(OS_ANDROID)
class NetworkContextApplicationStatusListener
: public base::android::ApplicationStatusListener {
public:
// base::android::ApplicationStatusListener implementation:
void SetCallback(const ApplicationStateChangeCallback& callback) override {
DCHECK(!callback_);
DCHECK(callback);
callback_ = callback;
}
void Notify(base::android::ApplicationState state) override {
if (callback_)
callback_.Run(state);
}
private:
ApplicationStateChangeCallback callback_;
};
#endif
} // namespace } // namespace
constexpr bool NetworkContext::enable_resource_scheduler_; constexpr bool NetworkContext::enable_resource_scheduler_;
...@@ -395,6 +420,10 @@ NetworkContext::NetworkContext( ...@@ -395,6 +420,10 @@ NetworkContext::NetworkContext(
: network_service_(network_service), : network_service_(network_service),
params_(std::move(params)), params_(std::move(params)),
on_connection_close_callback_(std::move(on_connection_close_callback)), on_connection_close_callback_(std::move(on_connection_close_callback)),
#if defined(OS_ANDROID)
app_status_listener_(
std::make_unique<NetworkContextApplicationStatusListener>()),
#endif
binding_(this, std::move(request)) { binding_(this, std::move(request)) {
url_request_context_owner_ = MakeURLRequestContext(); url_request_context_owner_ = MakeURLRequestContext();
url_request_context_ = url_request_context_owner_.url_request_context.get(); url_request_context_ = url_request_context_owner_.url_request_context.get();
...@@ -424,6 +453,10 @@ NetworkContext::NetworkContext( ...@@ -424,6 +453,10 @@ NetworkContext::NetworkContext(
std::unique_ptr<URLRequestContextBuilderMojo> builder) std::unique_ptr<URLRequestContextBuilderMojo> builder)
: network_service_(network_service), : network_service_(network_service),
params_(std::move(params)), params_(std::move(params)),
#if defined(OS_ANDROID)
app_status_listener_(
std::make_unique<NetworkContextApplicationStatusListener>()),
#endif
binding_(this, std::move(request)) { binding_(this, std::move(request)) {
url_request_context_owner_ = ApplyContextParamsToBuilder(builder.get()); url_request_context_owner_ = ApplyContextParamsToBuilder(builder.get());
url_request_context_ = url_request_context_owner_.url_request_context.get(); url_request_context_ = url_request_context_owner_.url_request_context.get();
...@@ -440,6 +473,10 @@ NetworkContext::NetworkContext(NetworkService* network_service, ...@@ -440,6 +473,10 @@ NetworkContext::NetworkContext(NetworkService* network_service,
net::URLRequestContext* url_request_context) net::URLRequestContext* url_request_context)
: network_service_(network_service), : network_service_(network_service),
url_request_context_(url_request_context), url_request_context_(url_request_context),
#if defined(OS_ANDROID)
app_status_listener_(
std::make_unique<NetworkContextApplicationStatusListener>()),
#endif
binding_(this, std::move(request)), binding_(this, std::move(request)),
cookie_manager_( cookie_manager_(
std::make_unique<CookieManager>(url_request_context->cookie_store(), std::make_unique<CookieManager>(url_request_context->cookie_store(),
...@@ -1139,6 +1176,9 @@ URLRequestContextOwner NetworkContext::ApplyContextParamsToBuilder( ...@@ -1139,6 +1176,9 @@ URLRequestContextOwner NetworkContext::ApplyContextParamsToBuilder(
*base::CommandLine::ForCurrentProcess()); *base::CommandLine::ForCurrentProcess());
} }
#if defined(OS_ANDROID)
cache_params.app_status_listener = app_status_listener();
#endif
builder->EnableHttpCache(cache_params); builder->EnableHttpCache(cache_params);
} }
......
...@@ -134,6 +134,12 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext ...@@ -134,6 +134,12 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
CookieManager* cookie_manager() { return cookie_manager_.get(); } CookieManager* cookie_manager() { return cookie_manager_.get(); }
#if defined(OS_ANDROID)
base::android::ApplicationStatusListener* app_status_listener() const {
return app_status_listener_.get();
}
#endif
// Creates a URLLoaderFactory with a ResourceSchedulerClient specified. This // Creates a URLLoaderFactory with a ResourceSchedulerClient specified. This
// is used to reuse the existing ResourceSchedulerClient for cloned // is used to reuse the existing ResourceSchedulerClient for cloned
// URLLoaderFactory. // URLLoaderFactory.
...@@ -320,6 +326,11 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext ...@@ -320,6 +326,11 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
// If non-null, called when the mojo pipe for the NetworkContext is closed. // If non-null, called when the mojo pipe for the NetworkContext is closed.
OnConnectionCloseCallback on_connection_close_callback_; OnConnectionCloseCallback on_connection_close_callback_;
#if defined(OS_ANDROID)
std::unique_ptr<base::android::ApplicationStatusListener>
app_status_listener_;
#endif
mojo::Binding<mojom::NetworkContext> binding_; mojo::Binding<mojom::NetworkContext> binding_;
std::unique_ptr<CookieManager> cookie_manager_; std::unique_ptr<CookieManager> cookie_manager_;
......
...@@ -52,6 +52,10 @@ ...@@ -52,6 +52,10 @@
#include "components/os_crypt/key_storage_config_linux.h" #include "components/os_crypt/key_storage_config_linux.h"
#endif #endif
#if defined(OS_ANDROID)
#include "base/android/application_status_listener.h"
#endif
namespace network { namespace network {
namespace { namespace {
...@@ -458,6 +462,14 @@ void NetworkService::RemoveCorbExceptionForPlugin(uint32_t process_id) { ...@@ -458,6 +462,14 @@ void NetworkService::RemoveCorbExceptionForPlugin(uint32_t process_id) {
CrossOriginReadBlocking::RemoveExceptionForPlugin(process_id); CrossOriginReadBlocking::RemoveExceptionForPlugin(process_id);
} }
#if defined(OS_ANDROID)
void NetworkService::OnApplicationStateChange(
base::android::ApplicationState state) {
for (auto* network_context : network_contexts_)
network_context->app_status_listener()->Notify(state);
}
#endif
net::HttpAuthHandlerFactory* NetworkService::GetHttpAuthHandlerFactory() { net::HttpAuthHandlerFactory* NetworkService::GetHttpAuthHandlerFactory() {
if (!http_auth_handler_factory_) { if (!http_auth_handler_factory_) {
http_auth_handler_factory_ = net::HttpAuthHandlerFactory::CreateDefault( http_auth_handler_factory_ = net::HttpAuthHandlerFactory::CreateDefault(
......
...@@ -151,6 +151,9 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkService ...@@ -151,6 +151,9 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkService
#endif #endif
void AddCorbExceptionForPlugin(uint32_t process_id) override; void AddCorbExceptionForPlugin(uint32_t process_id) override;
void RemoveCorbExceptionForPlugin(uint32_t process_id) override; void RemoveCorbExceptionForPlugin(uint32_t process_id) override;
#if defined(OS_ANDROID)
void OnApplicationStateChange(base::android::ApplicationState state) override;
#endif
// Returns the shared HttpAuthHandlerFactory for the NetworkService, creating // Returns the shared HttpAuthHandlerFactory for the NetworkService, creating
// one if needed. // one if needed.
......
# Copyright 2018 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.
mojom = "//services/network/public/mojom/network_param.mojom"
os_whitelist = [ "android" ]
public_headers = [ "//base/android/application_status_listener.h" ]
traits_headers =
[ "//services/network/public/cpp/network_param_mojom_traits.h" ]
deps = [
"//base",
]
type_mappings =
[ "network.mojom.ApplicationState=base::android::ApplicationState" ]
...@@ -13,4 +13,53 @@ bool StructTraits<network::mojom::HttpVersionDataView, net::HttpVersion>::Read( ...@@ -13,4 +13,53 @@ bool StructTraits<network::mojom::HttpVersionDataView, net::HttpVersion>::Read(
return true; return true;
} }
#if defined(OS_ANDROID)
network::mojom::ApplicationState
EnumTraits<network::mojom::ApplicationState, base::android::ApplicationState>::
ToMojom(base::android::ApplicationState input) {
switch (input) {
case base::android::APPLICATION_STATE_UNKNOWN:
return network::mojom::ApplicationState::UNKNOWN;
case base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES:
return network::mojom::ApplicationState::HAS_RUNNING_ACTIVITIES;
case base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES:
return network::mojom::ApplicationState::HAS_PAUSED_ACTIVITIES;
case base::android::APPLICATION_STATE_HAS_STOPPED_ACTIVITIES:
return network::mojom::ApplicationState::HAS_STOPPED_ACTIVITIES;
case base::android::APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES:
return network::mojom::ApplicationState::HAS_DESTROYED_ACTIVITIES;
}
NOTREACHED();
return static_cast<network::mojom::ApplicationState>(input);
}
bool EnumTraits<network::mojom::ApplicationState,
base::android::ApplicationState>::
FromMojom(network::mojom::ApplicationState input,
base::android::ApplicationState* output) {
switch (input) {
case network::mojom::ApplicationState::UNKNOWN:
*output = base::android::ApplicationState::APPLICATION_STATE_UNKNOWN;
return true;
case network::mojom::ApplicationState::HAS_RUNNING_ACTIVITIES:
*output = base::android::ApplicationState::
APPLICATION_STATE_HAS_RUNNING_ACTIVITIES;
return true;
case network::mojom::ApplicationState::HAS_PAUSED_ACTIVITIES:
*output = base::android::ApplicationState::
APPLICATION_STATE_HAS_PAUSED_ACTIVITIES;
return true;
case network::mojom::ApplicationState::HAS_STOPPED_ACTIVITIES:
*output = base::android::ApplicationState::
APPLICATION_STATE_HAS_STOPPED_ACTIVITIES;
return true;
case network::mojom::ApplicationState::HAS_DESTROYED_ACTIVITIES:
*output = base::android::ApplicationState::
APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES;
return true;
}
return false;
}
#endif
} // namespace mojo } // namespace mojo
...@@ -5,10 +5,15 @@ ...@@ -5,10 +5,15 @@
#ifndef SERVICES_NETWORK_PUBLIC_CPP_NETWORK_PARAM_MOJOM_TRAITS_H_ #ifndef SERVICES_NETWORK_PUBLIC_CPP_NETWORK_PARAM_MOJOM_TRAITS_H_
#define SERVICES_NETWORK_PUBLIC_CPP_NETWORK_PARAM_MOJOM_TRAITS_H_ #define SERVICES_NETWORK_PUBLIC_CPP_NETWORK_PARAM_MOJOM_TRAITS_H_
#include "build/build_config.h"
#include "mojo/public/cpp/bindings/struct_traits.h" #include "mojo/public/cpp/bindings/struct_traits.h"
#include "net/http/http_version.h" #include "net/http/http_version.h"
#include "services/network/public/mojom/network_param.mojom.h" #include "services/network/public/mojom/network_param.mojom.h"
#if defined(OS_ANDROID)
#include "base/android/application_status_listener.h"
#endif
namespace mojo { namespace mojo {
template <> template <>
...@@ -25,6 +30,17 @@ class StructTraits<network::mojom::HttpVersionDataView, net::HttpVersion> { ...@@ -25,6 +30,17 @@ class StructTraits<network::mojom::HttpVersionDataView, net::HttpVersion> {
net::HttpVersion* out); net::HttpVersion* out);
}; };
#if defined(OS_ANDROID)
template <>
struct EnumTraits<network::mojom::ApplicationState,
base::android::ApplicationState> {
static network::mojom::ApplicationState ToMojom(
base::android::ApplicationState input);
static bool FromMojom(network::mojom::ApplicationState input,
base::android::ApplicationState* output);
};
#endif
} // namespace mojo } // namespace mojo
#endif // SERVICES_NETWORK_PUBLIC_CPP_NETWORK_PARAM_MOJOM_TRAITS_H_ #endif // SERVICES_NETWORK_PUBLIC_CPP_NETWORK_PARAM_MOJOM_TRAITS_H_
...@@ -11,6 +11,7 @@ typemaps = [ ...@@ -11,6 +11,7 @@ typemaps = [
"//services/network/public/cpp/mutable_network_traffic_annotation_tag.typemap", "//services/network/public/cpp/mutable_network_traffic_annotation_tag.typemap",
"//services/network/public/cpp/mutable_partial_network_traffic_annotation_tag.typemap", "//services/network/public/cpp/mutable_partial_network_traffic_annotation_tag.typemap",
"//services/network/public/cpp/network_param.typemap", "//services/network/public/cpp/network_param.typemap",
"//services/network/public/cpp/network_param_android.typemap",
"//services/network/public/cpp/network_types.typemap", "//services/network/public/cpp/network_types.typemap",
"//services/network/public/cpp/p2p.typemap", "//services/network/public/cpp/p2p.typemap",
"//services/network/public/cpp/proxy_config.typemap", "//services/network/public/cpp/proxy_config.typemap",
......
...@@ -4,6 +4,16 @@ ...@@ -4,6 +4,16 @@
module network.mojom; module network.mojom;
// Mirror of base::android::ApplicationState.
[EnableIf=is_android]
enum ApplicationState {
UNKNOWN,
HAS_RUNNING_ACTIVITIES,
HAS_PAUSED_ACTIVITIES,
HAS_STOPPED_ACTIVITIES,
HAS_DESTROYED_ACTIVITIES,
};
[Native] [Native]
struct AuthChallengeInfo; struct AuthChallengeInfo;
......
...@@ -316,4 +316,8 @@ interface NetworkService { ...@@ -316,4 +316,8 @@ interface NetworkService {
// Reverts AddCorbExceptionForPlugin. // Reverts AddCorbExceptionForPlugin.
RemoveCorbExceptionForPlugin(uint32 process_id); RemoveCorbExceptionForPlugin(uint32 process_id);
// Called on state changes of the Android application.
[EnableIf=is_android]
OnApplicationStateChange(ApplicationState state);
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment