Commit c3d14bfd authored by Pavel Shmakov's avatar Pavel Shmakov Committed by Commit Bot

Implement cache clearing API 1/2

Both WebView's and Chrome's cache clearing APIs do the following:
1) Clear the GL shader cache, which corresponds to DATA_TYPE_CACHE in
the language of browser_data_remover.h.
2) Clear the Blink cache of the renderers.

This CL implements the first part in WebLayer.

Change-Id: Ib29edf65bf36bd85c912f02b2e2bce918d7084ec
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1883655
Commit-Queue: Pavel Shmakov <pshmakov@chromium.org>
Reviewed-by: default avatarBo <boliu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#710788}
parent 0d1d1217
...@@ -15,6 +15,12 @@ generate_locale_config_srcjar("weblayer_locale_config") { ...@@ -15,6 +15,12 @@ generate_locale_config_srcjar("weblayer_locale_config") {
java_package = weblayer_locale_config_java_package java_package = weblayer_locale_config_java_package
} }
java_cpp_enum("generated_enums") {
sources = [
"//weblayer/public/profile.h",
]
}
android_library("java") { android_library("java") {
java_files = [ java_files = [
"org/chromium/weblayer_private/BrowserControllerImpl.java", "org/chromium/weblayer_private/BrowserControllerImpl.java",
...@@ -49,7 +55,10 @@ android_library("java") { ...@@ -49,7 +55,10 @@ android_library("java") {
"//third_party/android_deps:com_android_support_support_compat_java", "//third_party/android_deps:com_android_support_support_compat_java",
"//ui/android:ui_java", "//ui/android:ui_java",
] ]
srcjar_deps = [ ":weblayer_locale_config" ] srcjar_deps = [
":weblayer_locale_config",
":generated_enums",
]
jar_excluded_patterns = [ "*/LocaleConfig.class" ] jar_excluded_patterns = [ "*/LocaleConfig.class" ]
annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
...@@ -78,6 +87,11 @@ android_library("client_java") { ...@@ -78,6 +87,11 @@ android_library("client_java") {
"org/chromium/weblayer_private/aidl/WebLayerVersion.java", "org/chromium/weblayer_private/aidl/WebLayerVersion.java",
"org/chromium/weblayer_private/aidl/APICallException.java", "org/chromium/weblayer_private/aidl/APICallException.java",
"org/chromium/weblayer_private/aidl/BrowserFragmentArgs.java", "org/chromium/weblayer_private/aidl/BrowserFragmentArgs.java",
"org/chromium/weblayer_private/aidl/BrowsingDataType.java",
]
deps = [
"//third_party/android_deps:androidx_annotation_annotation_java",
] ]
srcjar_deps = [ ":aidl" ] srcjar_deps = [ ":aidl" ]
......
...@@ -32,9 +32,7 @@ public class BrowserFragmentControllerImpl extends IBrowserFragmentController.St ...@@ -32,9 +32,7 @@ public class BrowserFragmentControllerImpl extends IBrowserFragmentController.St
} }
public void onFragmentDetached() { public void onFragmentDetached() {
mTabController.destroy(); destroy(); // For now we don't retain anything between detach and attach.
mTabController = null;
mWindowAndroid = null;
} }
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
...@@ -71,5 +69,11 @@ public class BrowserFragmentControllerImpl extends IBrowserFragmentController.St ...@@ -71,5 +69,11 @@ public class BrowserFragmentControllerImpl extends IBrowserFragmentController.St
return mTabController.getView(); return mTabController.getView();
} }
public void destroy() {} public void destroy() {
if (mTabController != null) {
mTabController.destroy();
mTabController = null;
}
mWindowAndroid = null;
}
} }
...@@ -4,9 +4,12 @@ ...@@ -4,9 +4,12 @@
package org.chromium.weblayer_private; package org.chromium.weblayer_private;
import org.chromium.base.annotations.CalledByNative; import androidx.annotation.NonNull;
import org.chromium.base.CollectionUtil;
import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods; import org.chromium.base.annotations.NativeMethods;
import org.chromium.weblayer_private.aidl.BrowsingDataType;
import org.chromium.weblayer_private.aidl.IObjectWrapper; import org.chromium.weblayer_private.aidl.IObjectWrapper;
import org.chromium.weblayer_private.aidl.IProfile; import org.chromium.weblayer_private.aidl.IProfile;
import org.chromium.weblayer_private.aidl.ObjectWrapper; import org.chromium.weblayer_private.aidl.ObjectWrapper;
...@@ -16,13 +19,11 @@ import java.util.List; ...@@ -16,13 +19,11 @@ import java.util.List;
@JNINamespace("weblayer") @JNINamespace("weblayer")
public final class ProfileImpl extends IProfile.Stub { public final class ProfileImpl extends IProfile.Stub {
private final List<Runnable> mCurrentClearDataCallbacks = new ArrayList<>();
private final List<Runnable> mPendingClearDataCallbacks = new ArrayList<>();
private long mNativeProfile; private long mNativeProfile;
private Runnable mOnDestroyCallback; private Runnable mOnDestroyCallback;
ProfileImpl(String path, Runnable onDestroyCallback) { ProfileImpl(String path, Runnable onDestroyCallback) {
mNativeProfile = ProfileImplJni.get().createProfile(this, path); mNativeProfile = ProfileImplJni.get().createProfile(path);
mOnDestroyCallback = onDestroyCallback; mOnDestroyCallback = onDestroyCallback;
} }
...@@ -35,29 +36,31 @@ public final class ProfileImpl extends IProfile.Stub { ...@@ -35,29 +36,31 @@ public final class ProfileImpl extends IProfile.Stub {
} }
@Override @Override
public void clearBrowsingData(IObjectWrapper completionCallback) { public void clearBrowsingData(@NonNull @BrowsingDataType int[] dataTypes,
@NonNull IObjectWrapper completionCallback) {
Runnable callback = ObjectWrapper.unwrap(completionCallback, Runnable.class); Runnable callback = ObjectWrapper.unwrap(completionCallback, Runnable.class);
if (!mCurrentClearDataCallbacks.isEmpty()) { ProfileImplJni.get().clearBrowsingData(mNativeProfile, mapBrowsingDataTypes(dataTypes),
// Already running a clear data job. Will have to re-run the job once it's completed, callback);
// because new data may have been stored.
mPendingClearDataCallbacks.add(callback);
return;
}
mCurrentClearDataCallbacks.add(callback);
ProfileImplJni.get().clearBrowsingData(mNativeProfile);
} }
@CalledByNative private static @ImplBrowsingDataType int[] mapBrowsingDataTypes(
private void onBrowsingDataCleared() { @NonNull @BrowsingDataType int[] dataTypes) {
for (Runnable callback : mCurrentClearDataCallbacks) { // Convert data types coming from aidl to the ones accepted by C++ (ImplBrowsingDataType is
callback.run(); // generated from a C++ enum).
} List<Integer> convertedTypes = new ArrayList<>();
mCurrentClearDataCallbacks.clear(); for (int aidlType : dataTypes) {
if (!mPendingClearDataCallbacks.isEmpty()) { switch (aidlType) {
mCurrentClearDataCallbacks.addAll(mPendingClearDataCallbacks); case BrowsingDataType.COOKIES_AND_SITE_DATA:
mPendingClearDataCallbacks.clear(); convertedTypes.add(ImplBrowsingDataType.COOKIES_AND_SITE_DATA);
ProfileImplJni.get().clearBrowsingData(mNativeProfile); break;
case BrowsingDataType.CACHE:
convertedTypes.add(ImplBrowsingDataType.CACHE);
break;
default:
break; // Skip unrecognized values for forward compatibility.
}
} }
return CollectionUtil.integerListToIntArray(convertedTypes);
} }
long getNativeProfile() { long getNativeProfile() {
...@@ -66,8 +69,9 @@ public final class ProfileImpl extends IProfile.Stub { ...@@ -66,8 +69,9 @@ public final class ProfileImpl extends IProfile.Stub {
@NativeMethods @NativeMethods
interface Natives { interface Natives {
long createProfile(ProfileImpl caller, String path); long createProfile(String path);
void deleteProfile(long profile); void deleteProfile(long profile);
void clearBrowsingData(long nativeProfileImpl); void clearBrowsingData(long nativeProfileImpl, @ImplBrowsingDataType int[] dataTypes,
Runnable callback);
} }
} }
// Copyright 2019 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.
package org.chromium.weblayer_private.aidl;
import androidx.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@IntDef({BrowsingDataType.COOKIES_AND_SITE_DATA, BrowsingDataType.CACHE})
@Retention(RetentionPolicy.SOURCE)
public @interface BrowsingDataType {
int COOKIES_AND_SITE_DATA = 0;
int CACHE = 1;
}
...@@ -7,5 +7,5 @@ package org.chromium.weblayer_private.aidl; ...@@ -7,5 +7,5 @@ package org.chromium.weblayer_private.aidl;
interface IProfile { interface IProfile {
void destroy() = 0; void destroy() = 0;
void clearBrowsingData(in IObjectWrapper completionCallback) = 1; void clearBrowsingData(in int[] dataTypes, in IObjectWrapper completionCallback) = 1;
} }
...@@ -5,4 +5,4 @@ ...@@ -5,4 +5,4 @@
package org.chromium.weblayer_private.aidl; package org.chromium.weblayer_private.aidl;
/** Holds the current version number of WebLayer. */ /** Holds the current version number of WebLayer. */
public final class WebLayerVersion { public static int sVersionNumber = 2; } public final class WebLayerVersion { public static int sVersionNumber = 3; }
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "weblayer/browser/profile_impl.h" #include "weblayer/browser/profile_impl.h"
#include "base/callback.h"
#include "base/bind.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "content/public/browser/browsing_data_remover.h" #include "content/public/browser/browsing_data_remover.h"
...@@ -13,7 +15,10 @@ ...@@ -13,7 +15,10 @@
#include "weblayer/public/download_delegate.h" #include "weblayer/public/download_delegate.h"
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
#include "base/android/callback_android.h"
#include "base/android/jni_string.h" #include "base/android/jni_string.h"
#include "base/android/jni_array.h"
#include "base/android/scoped_java_ref.h"
#include "weblayer/browser/java/jni/ProfileImpl_jni.h" #include "weblayer/browser/java/jni/ProfileImpl_jni.h"
#endif #endif
...@@ -155,18 +160,17 @@ class ProfileImpl::BrowserContextImpl : public content::BrowserContext { ...@@ -155,18 +160,17 @@ class ProfileImpl::BrowserContextImpl : public content::BrowserContext {
class ProfileImpl::DataClearer : public content::BrowsingDataRemover::Observer { class ProfileImpl::DataClearer : public content::BrowsingDataRemover::Observer {
public: public:
DataClearer(content::BrowserContext* browser_context, ProfileImpl* profile) DataClearer(content::BrowserContext* browser_context,
base::OnceCallback<void()> callback)
: remover_( : remover_(
content::BrowserContext::GetBrowsingDataRemover(browser_context)), content::BrowserContext::GetBrowsingDataRemover(browser_context)),
profile_(profile) { callback_(std::move(callback)) {
remover_->AddObserver(this); remover_->AddObserver(this);
} }
~DataClearer() override { remover_->RemoveObserver(this); } ~DataClearer() override { remover_->RemoveObserver(this); }
void ClearData() { void ClearData(int mask) {
int mask = content::BrowsingDataRemover::DATA_TYPE_COOKIES |
content::BrowsingDataRemover::DATA_TYPE_MEDIA_LICENSES;
int origin_types = int origin_types =
content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB | content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB |
content::BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB; content::BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB;
...@@ -175,35 +179,52 @@ class ProfileImpl::DataClearer : public content::BrowsingDataRemover::Observer { ...@@ -175,35 +179,52 @@ class ProfileImpl::DataClearer : public content::BrowsingDataRemover::Observer {
} }
void OnBrowsingDataRemoverDone() override { void OnBrowsingDataRemoverDone() override {
profile_->OnBrowsingDataCleared(); std::move(callback_).Run();
delete this;
} }
private: private:
content::BrowsingDataRemover* const remover_; content::BrowsingDataRemover* const remover_;
ProfileImpl* const profile_; base::OnceCallback<void()> callback_;
}; };
ProfileImpl::ProfileImpl(const base::FilePath& path) : path_(path) { ProfileImpl::ProfileImpl(const base::FilePath& path) : path_(path) {
browser_context_ = std::make_unique<BrowserContextImpl>(path_); browser_context_ = std::make_unique<BrowserContextImpl>(path_);
} }
ProfileImpl::~ProfileImpl() = default; ProfileImpl::~ProfileImpl() {
browser_context_->ShutdownStoragePartitions();
}
content::BrowserContext* ProfileImpl::GetBrowserContext() { content::BrowserContext* ProfileImpl::GetBrowserContext() {
return browser_context_.get(); return browser_context_.get();
} }
void ProfileImpl::OnBrowsingDataCleared() { void ProfileImpl::ClearBrowsingData(std::vector<BrowsingDataType> data_types,
#if defined(OS_ANDROID) base::OnceCallback<void()> callback) {
Java_ProfileImpl_onBrowsingDataCleared(AttachCurrentThread(), java_profile_); auto* clearer = new DataClearer(browser_context_.get(), std::move(callback));
#endif // DataClearer will delete itself in OnBrowsingDataRemoverDone().
} // If Profile is destroyed during clearing, it would lead to destroying
// browser_context_ and then BrowsingDataRemover, which in turn would call
void ProfileImpl::ClearBrowsingData() { // OnBrowsingDataRemoverDone(), even though the clearing hasn't been finished.
if (!data_clearer_) {
data_clearer_ = std::make_unique<DataClearer>(browser_context_.get(), this); int remove_mask = 0;
// This follows what Chrome does: see browsing_data_bridge.cc.
for (auto data_type : data_types) {
switch (data_type) {
case BrowsingDataType::COOKIES_AND_SITE_DATA:
remove_mask |= content::BrowsingDataRemover::DATA_TYPE_COOKIES;
remove_mask |= content::BrowsingDataRemover::DATA_TYPE_DOM_STORAGE;
remove_mask |= content::BrowsingDataRemover::DATA_TYPE_MEDIA_LICENSES;
break;
case BrowsingDataType::CACHE:
remove_mask |= content::BrowsingDataRemover::DATA_TYPE_CACHE;
break;
default:
NOTREACHED();
}
} }
data_clearer_->ClearData(); clearer->ClearData(remove_mask);
} }
std::unique_ptr<Profile> Profile::Create(const base::FilePath& path) { std::unique_ptr<Profile> Profile::Create(const base::FilePath& path) {
...@@ -211,25 +232,34 @@ std::unique_ptr<Profile> Profile::Create(const base::FilePath& path) { ...@@ -211,25 +232,34 @@ std::unique_ptr<Profile> Profile::Create(const base::FilePath& path) {
} }
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
ProfileImpl::ProfileImpl( ProfileImpl::ProfileImpl(JNIEnv* env,
JNIEnv* env,
const base::android::JavaParamRef<jobject>& java_profile,
const base::android::JavaParamRef<jstring>& path) const base::android::JavaParamRef<jstring>& path)
: ProfileImpl(base::FilePath(ConvertJavaStringToUTF8(env, path))) { : ProfileImpl(base::FilePath(ConvertJavaStringToUTF8(env, path))) {}
java_profile_.Reset(env, java_profile);
}
static jlong JNI_ProfileImpl_CreateProfile( static jlong JNI_ProfileImpl_CreateProfile(
JNIEnv* env, JNIEnv* env,
const base::android::JavaParamRef<jobject>& java_profile,
const base::android::JavaParamRef<jstring>& path) { const base::android::JavaParamRef<jstring>& path) {
return reinterpret_cast<jlong>( return reinterpret_cast<jlong>(new ProfileImpl(env, path));
new weblayer::ProfileImpl(env, java_profile, path));
} }
static void JNI_ProfileImpl_DeleteProfile(JNIEnv* env, jlong profile) { static void JNI_ProfileImpl_DeleteProfile(JNIEnv* env, jlong profile) {
delete reinterpret_cast<ProfileImpl*>(profile); delete reinterpret_cast<ProfileImpl*>(profile);
} }
void ProfileImpl::ClearBrowsingData(JNIEnv* env,
const base::android::JavaParamRef<jintArray>& j_data_types,
const base::android::JavaRef<jobject>& j_callback) {
std::vector<int> data_type_ints;
base::android::JavaIntArrayToIntVector(env, j_data_types, &data_type_ints);
std::vector<BrowsingDataType> data_types;
data_types.reserve(data_type_ints.size());
for (int type : data_type_ints) {
data_types.push_back(static_cast<BrowsingDataType>(type));
}
ClearBrowsingData(data_types,
base::BindOnce(base::android::RunRunnableAndroid,
base::android::ScopedJavaGlobalRef<jobject>(j_callback)));
}
#endif // OS_ANDROID #endif // OS_ANDROID
} // namespace weblayer } // namespace weblayer
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef WEBLAYER_BROWSER_PROFILE_IMPL_H_ #ifndef WEBLAYER_BROWSER_PROFILE_IMPL_H_
#define WEBLAYER_BROWSER_PROFILE_IMPL_H_ #define WEBLAYER_BROWSER_PROFILE_IMPL_H_
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "weblayer/public/profile.h" #include "weblayer/public/profile.h"
...@@ -27,29 +29,24 @@ class ProfileImpl : public Profile { ...@@ -27,29 +29,24 @@ class ProfileImpl : public Profile {
content::BrowserContext* GetBrowserContext(); content::BrowserContext* GetBrowserContext();
// Profile implementation: // Profile implementation:
void ClearBrowsingData() override; void ClearBrowsingData(std::vector<BrowsingDataType> data_types,
base::OnceCallback<void()> callback) override;
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
ProfileImpl(JNIEnv* env, ProfileImpl(JNIEnv* env,
const base::android::JavaParamRef<jobject>& java_profile,
const base::android::JavaParamRef<jstring>& path); const base::android::JavaParamRef<jstring>& path);
void ClearBrowsingData(JNIEnv* env) { ClearBrowsingData(); } void ClearBrowsingData(JNIEnv* env,
const base::android::JavaParamRef<jintArray>& j_data_types,
const base::android::JavaRef<jobject>& j_callback);
#endif #endif
private: private:
class BrowserContextImpl; class BrowserContextImpl;
class DataClearer; class DataClearer;
void OnBrowsingDataCleared();
base::FilePath path_; base::FilePath path_;
std::unique_ptr<BrowserContextImpl> browser_context_; std::unique_ptr<BrowserContextImpl> browser_context_;
std::unique_ptr<DataClearer> data_clearer_;
#if defined(OS_ANDROID)
base::android::ScopedJavaGlobalRef<jobject> java_profile_;
#endif
}; };
} // namespace weblayer } // namespace weblayer
......
...@@ -25,6 +25,7 @@ android_library("java") { ...@@ -25,6 +25,7 @@ android_library("java") {
"org/chromium/weblayer/BrowserFragmentController.java", "org/chromium/weblayer/BrowserFragmentController.java",
"org/chromium/weblayer/BrowserFragment.java", "org/chromium/weblayer/BrowserFragment.java",
"org/chromium/weblayer/BrowserObserver.java", "org/chromium/weblayer/BrowserObserver.java",
"org/chromium/weblayer/BrowsingDataType.java",
"org/chromium/weblayer/Callback.java", "org/chromium/weblayer/Callback.java",
"org/chromium/weblayer/ChildProcessService.java", "org/chromium/weblayer/ChildProcessService.java",
"org/chromium/weblayer/DownloadDelegate.java", "org/chromium/weblayer/DownloadDelegate.java",
......
// Copyright 2019 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.
package org.chromium.weblayer;
import androidx.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@IntDef({BrowsingDataType.COOKIES_AND_SITE_DATA, BrowsingDataType.CACHE})
@Retention(RetentionPolicy.SOURCE)
public @interface BrowsingDataType {
int COOKIES_AND_SITE_DATA =
org.chromium.weblayer_private.aidl.BrowsingDataType.COOKIES_AND_SITE_DATA;
int CACHE = org.chromium.weblayer_private.aidl.BrowsingDataType.CACHE;
}
...@@ -6,6 +6,8 @@ package org.chromium.weblayer; ...@@ -6,6 +6,8 @@ package org.chromium.weblayer;
import android.os.RemoteException; import android.os.RemoteException;
import androidx.annotation.NonNull;
import org.chromium.weblayer_private.aidl.APICallException; import org.chromium.weblayer_private.aidl.APICallException;
import org.chromium.weblayer_private.aidl.IProfile; import org.chromium.weblayer_private.aidl.IProfile;
import org.chromium.weblayer_private.aidl.ObjectWrapper; import org.chromium.weblayer_private.aidl.ObjectWrapper;
...@@ -29,11 +31,22 @@ public final class Profile { ...@@ -29,11 +31,22 @@ public final class Profile {
// TODO(sky): figure out right assertion here if mImpl is non-null. // TODO(sky): figure out right assertion here if mImpl is non-null.
} }
public ListenableResult<Void> clearBrowsingData() { /**
* Clears the data associated with the Profile.
* The clearing is asynchronous, and new data may be generated during clearing. It is safe to
* call this method repeatedly without waiting for callback.
*
* @param dataTypes See {@link BrowsingDataType}.
* @return {@link ListenableResult} into which a "null" will be supplied when clearing is
* finished.
*/
@NonNull
public ListenableResult<Void> clearBrowsingData(@NonNull @BrowsingDataType int[] dataTypes) {
ThreadCheck.ensureOnUiThread(); ThreadCheck.ensureOnUiThread();
try { try {
ListenableResult<Void> result = new ListenableResult<>(); ListenableResult<Void> result = new ListenableResult<>();
mImpl.clearBrowsingData(ObjectWrapper.wrap((Runnable) () -> result.supplyResult(null))); mImpl.clearBrowsingData(dataTypes,
ObjectWrapper.wrap((Runnable) () -> result.supplyResult(null)));
return result; return result;
} catch (RemoteException e) { } catch (RemoteException e) {
throw new APICallException(e); throw new APICallException(e);
......
...@@ -12,6 +12,13 @@ ...@@ -12,6 +12,13 @@
namespace weblayer { namespace weblayer {
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.weblayer_private
// GENERATED_JAVA_CLASS_NAME_OVERRIDE: ImplBrowsingDataType
enum class BrowsingDataType {
COOKIES_AND_SITE_DATA = 0,
CACHE = 1,
};
class Profile { class Profile {
public: public:
// Pass an empty |path| for an in-memory profile. // Pass an empty |path| for an in-memory profile.
...@@ -19,8 +26,9 @@ class Profile { ...@@ -19,8 +26,9 @@ class Profile {
virtual ~Profile() {} virtual ~Profile() {}
// TODO: add lots of parameters to control what gets deleted and which range. // TODO: add parameters to control which time range gets deleted.
virtual void ClearBrowsingData() = 0; virtual void ClearBrowsingData(std::vector<BrowsingDataType> data_types,
base::OnceCallback<void()> callback) = 0;
}; };
} // namespace weblayer } // namespace weblayer
......
...@@ -7,9 +7,12 @@ package org.chromium.weblayer.test; ...@@ -7,9 +7,12 @@ package org.chromium.weblayer.test;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking;
import static org.chromium.weblayer.BrowsingDataType.CACHE;
import static org.chromium.weblayer.BrowsingDataType.COOKIES_AND_SITE_DATA;
import android.os.Bundle; import android.os.Bundle;
import android.support.test.filters.SmallTest; import android.support.test.filters.SmallTest;
import android.support.v4.app.FragmentManager;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
...@@ -33,16 +36,35 @@ public class DataClearingTest { ...@@ -33,16 +36,35 @@ public class DataClearingTest {
@Test @Test
@SmallTest @SmallTest
public void clearDataWithPersistedProfile_TriggersCallback() throws InterruptedException { public void clearDataWithPersistedProfile_TriggersCallback() throws InterruptedException {
checkTriggersCallbackOnClearData("Profile"); checkTriggersCallbackOnClearData(new int[] {COOKIES_AND_SITE_DATA}, "Profile");
} }
@Test @Test
@SmallTest @SmallTest
public void clearDataWithInMemoryProfile_TriggersCallback() throws InterruptedException { public void clearDataWithInMemoryProfile_TriggersCallback() throws InterruptedException {
checkTriggersCallbackOnClearData(""); checkTriggersCallbackOnClearData(new int[] {COOKIES_AND_SITE_DATA}, "");
}
@Test
@SmallTest
public void clearCache_TriggersCallback() throws InterruptedException {
checkTriggersCallbackOnClearData(new int[] {CACHE}, "Profile");
}
@Test
@SmallTest
public void clearMultipleTypes_TriggersCallback() throws InterruptedException {
checkTriggersCallbackOnClearData(new int[] {COOKIES_AND_SITE_DATA, CACHE}, "Profile");
}
@Test
@SmallTest
public void clearUnknownType_TriggersCallback() throws InterruptedException {
// This is a forward compatibility test: the older versions of Chrome that don't yet
// implement clearing some data type should just ignore it and call the callback.
checkTriggersCallbackOnClearData(new int[] {9999}, "Profile");
} }
// The tests below should rather be unit tests for ProfileImpl.
@Test @Test
@SmallTest @SmallTest
public void twoSuccesiveRequestsTriggerCallbacks() throws InterruptedException { public void twoSuccesiveRequestsTriggerCallbacks() throws InterruptedException {
...@@ -51,8 +73,10 @@ public class DataClearingTest { ...@@ -51,8 +73,10 @@ public class DataClearingTest {
CountDownLatch latch = new CountDownLatch(2); CountDownLatch latch = new CountDownLatch(2);
runOnUiThreadBlocking(() -> { runOnUiThreadBlocking(() -> {
Profile profile = activity.getBrowserFragmentController().getProfile(); Profile profile = activity.getBrowserFragmentController().getProfile();
profile.clearBrowsingData().addCallback((ignored) -> latch.countDown()); profile.clearBrowsingData(new int[] {COOKIES_AND_SITE_DATA}).addCallback(
profile.clearBrowsingData().addCallback((ignored) -> latch.countDown()); (ignored) -> latch.countDown());
profile.clearBrowsingData(new int[] {CACHE}).addCallback(
(ignored) -> latch.countDown());
}); });
assertTrue(latch.await(3, TimeUnit.SECONDS)); assertTrue(latch.await(3, TimeUnit.SECONDS));
} }
...@@ -65,8 +89,9 @@ public class DataClearingTest { ...@@ -65,8 +89,9 @@ public class DataClearingTest {
CountDownLatch latch = new CountDownLatch(1); CountDownLatch latch = new CountDownLatch(1);
runOnUiThreadBlocking(() -> { runOnUiThreadBlocking(() -> {
Profile profile = activity.getBrowserFragmentController().getProfile(); Profile profile = activity.getBrowserFragmentController().getProfile();
profile.clearBrowsingData().addCallback((v1) -> { profile.clearBrowsingData(new int[] {COOKIES_AND_SITE_DATA}).addCallback((v1) -> {
profile.clearBrowsingData().addCallback((v2) -> latch.countDown()); profile.clearBrowsingData(new int[] {CACHE}).addCallback(
(v2) -> latch.countDown());
}); });
}); });
assertTrue(latch.await(3, TimeUnit.SECONDS)); assertTrue(latch.await(3, TimeUnit.SECONDS));
...@@ -74,24 +99,30 @@ public class DataClearingTest { ...@@ -74,24 +99,30 @@ public class DataClearingTest {
@Test @Test
@SmallTest @SmallTest
public void threeSuccesiveRequestsTriggerCallbacks() throws InterruptedException { public void destroyingProfileDuringDataClear_DoesntCrash() throws InterruptedException {
WebLayerShellActivity activity = launchWithProfile("profile"); WebLayerShellActivity activity = launchWithProfile("profile");
CountDownLatch latch = new CountDownLatch(3); CountDownLatch latch = new CountDownLatch(1);
runOnUiThreadBlocking(() -> { runOnUiThreadBlocking(() -> {
Profile profile = activity.getBrowserFragmentController().getProfile(); Profile profile = activity.getBrowserFragmentController().getProfile();
profile.clearBrowsingData().addCallback((ignored) -> latch.countDown()); profile.clearBrowsingData(new int[] {COOKIES_AND_SITE_DATA});
profile.clearBrowsingData().addCallback((ignored) -> latch.countDown());
profile.clearBrowsingData().addCallback((ignored) -> latch.countDown()); // We need to remove the fragment before calling Profile#destroy().
FragmentManager fm = activity.getSupportFragmentManager();
fm.beginTransaction().remove(fm.getFragments().get(0)).commitNow();
profile.destroy();
latch.countDown();
}); });
assertTrue(latch.await(3, TimeUnit.SECONDS)); assertTrue(latch.await(3, TimeUnit.SECONDS));
} }
private void checkTriggersCallbackOnClearData(String profileName) throws InterruptedException { private void checkTriggersCallbackOnClearData(int[] dataTypes, String profileName)
throws InterruptedException {
WebLayerShellActivity activity = launchWithProfile(profileName); WebLayerShellActivity activity = launchWithProfile(profileName);
CountDownLatch latch = new CountDownLatch(1); CountDownLatch latch = new CountDownLatch(1);
runOnUiThreadBlocking(() -> activity.getBrowserFragmentController().getProfile() runOnUiThreadBlocking(() -> activity.getBrowserFragmentController().getProfile()
.clearBrowsingData().addCallback((ignored) -> latch.countDown())); .clearBrowsingData(dataTypes).addCallback((ignored) -> latch.countDown()));
assertTrue(latch.await(3, TimeUnit.SECONDS)); assertTrue(latch.await(3, TimeUnit.SECONDS));
} }
......
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