Commit bb18129f authored by Tim Volodine's avatar Tim Volodine Committed by Commit Bot

[WebLayer] Implement Safe Browsing opt-in/opt-out API

Implement WebLayer API and the corresponding internal Safe Browsing
bits to make Safe Browsing user opt-in/opt-out possible.

Using this API the embedder can disable/enable the Safe Browsing
functionality (which checks whether the loaded URLs and resources
are safe) and obtain its current state. This can be done using
two methods introduced in this patch which are defined on the
WebLayer's Profile class:
 - setBooleanSetting(SettingType, boolean)
 - getBooleanSetting(SettingType)

For example, to opt-out of Safe Browsing the embedder can call
getProfile().setBooleanSetting(SettingType.BASIC_SAFE_BROWSING_ENABLED,
false) on its browser instance.

Safe Browsing in weblayer is enabled by default, so the current
semantics is that this is an opt-out option. When toggling the state
(e.g. opting out) the settings take effect on next load. The setting
applies to both the browser and renderer initiated loads.

In this patch:
- Implement internal bits to disable/enable Safe Browsing checks.
- Make sure to apply the setting via Profile for both browser and
  renderer initiated loads.
- Implement getter/setter WebLayer API for the embedder to set user
  opt-in/opt-out via Profile.
- Add SettingType interfaces (with the BASIC_SAFE_BROWSING_ENABLED
  setting) and the corresponding {Get,Set}BooleanSetting() methods.
- Add the necessary plumbing to the aidl and jni parts of the
  profile classes.

BUG=1083376


Change-Id: I3e3b9e314404d262bef57da26e070909feefb095
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2225756
Commit-Queue: Tim Volodine <timvolodine@chromium.org>
Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#776360}
parent be6657ec
......@@ -285,6 +285,7 @@ android_library("interfaces_java") {
"org/chromium/weblayer_private/interfaces/NavigationState.java",
"org/chromium/weblayer_private/interfaces/NewTabType.java",
"org/chromium/weblayer_private/interfaces/ObjectWrapper.java",
"org/chromium/weblayer_private/interfaces/SettingType.java",
"org/chromium/weblayer_private/interfaces/SiteSettingsFragmentArgs.java",
"org/chromium/weblayer_private/interfaces/SiteSettingsIntentHelper.java",
"org/chromium/weblayer_private/interfaces/StrictModeWorkaround.java",
......
......@@ -21,6 +21,7 @@ import org.chromium.weblayer_private.interfaces.IDownloadCallbackClient;
import org.chromium.weblayer_private.interfaces.IObjectWrapper;
import org.chromium.weblayer_private.interfaces.IProfile;
import org.chromium.weblayer_private.interfaces.ObjectWrapper;
import org.chromium.weblayer_private.interfaces.SettingType;
import org.chromium.weblayer_private.interfaces.StrictModeWorkaround;
import java.util.ArrayList;
......@@ -206,6 +207,16 @@ public final class ProfileImpl extends IProfile.Stub implements BrowserContextHa
mDownloadNotificationIntents.clear();
}
@Override
public void setBooleanSetting(@SettingType int type, boolean value) {
ProfileImplJni.get().setBooleanSetting(mNativeProfile, type, value);
}
@Override
public boolean getBooleanSetting(@SettingType int type) {
return ProfileImplJni.get().getBooleanSetting(mNativeProfile, type);
}
@NativeMethods
interface Natives {
void enumerateAllProfileNames(Callback<String[]> callback);
......@@ -219,5 +230,7 @@ public final class ProfileImpl extends IProfile.Stub implements BrowserContextHa
void setDownloadDirectory(long nativeProfileImpl, String directory);
long getCookieManager(long nativeProfileImpl);
void ensureBrowserContextInitialized(long nativeProfileImpl);
void setBooleanSetting(long nativeProfileImpl, int type, boolean value);
boolean getBooleanSetting(long nativeProfileImpl, int type);
}
}
......@@ -26,4 +26,8 @@ interface IProfile {
// Added in Version 83.
ICookieManager getCookieManager() = 6;
// Added in Version 84.
void setBooleanSetting(int type, boolean value) = 7;
boolean getBooleanSetting(int type) = 8;
}
// Copyright 2020 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.interfaces;
import androidx.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@IntDef({SettingType.BASIC_SAFE_BROWSING_ENABLED})
@Retention(RetentionPolicy.SOURCE)
public @interface SettingType {
int BASIC_SAFE_BROWSING_ENABLED = 0;
}
......@@ -33,7 +33,10 @@
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "weblayer/browser/browser_process.h"
#include "weblayer/browser/java/jni/ProfileImpl_jni.h"
#include "weblayer/browser/safe_browsing/safe_browsing_service.h"
#include "weblayer/browser/user_agent.h"
#endif
#if defined(OS_POSIX)
......@@ -382,6 +385,17 @@ jlong ProfileImpl::GetCookieManager(JNIEnv* env) {
void ProfileImpl::EnsureBrowserContextInitialized(JNIEnv* env) {
content::BrowserContext::GetDownloadManager(GetBrowserContext());
}
void ProfileImpl::SetBooleanSetting(JNIEnv* env,
jint j_type,
jboolean j_value) {
SetBooleanSetting(static_cast<SettingType>(j_type), j_value);
}
jboolean ProfileImpl::GetBooleanSetting(JNIEnv* env, jint j_type) {
return GetBooleanSetting(static_cast<SettingType>(j_type));
}
#endif // OS_ANDROID
void ProfileImpl::IncrementBrowserImplCount() {
......@@ -397,4 +411,24 @@ base::FilePath ProfileImpl::GetBrowserPersisterDataBaseDir() const {
return ComputeBrowserPersisterDataBaseDir(info_);
}
void ProfileImpl::SetBooleanSetting(SettingType type, bool value) {
switch (type) {
case SettingType::BASIC_SAFE_BROWSING_ENABLED:
basic_safe_browsing_enabled_ = value;
#if defined(OS_ANDROID)
BrowserProcess::GetInstance()
->GetSafeBrowsingService(weblayer::GetUserAgent())
->SetSafeBrowsingDisabled(!basic_safe_browsing_enabled_);
#endif
}
}
bool ProfileImpl::GetBooleanSetting(SettingType type) {
switch (type) {
case SettingType::BASIC_SAFE_BROWSING_ENABLED:
return basic_safe_browsing_enabled_;
}
NOTREACHED();
}
} // namespace weblayer
......@@ -65,6 +65,8 @@ class ProfileImpl : public Profile {
void SetDownloadDirectory(const base::FilePath& directory) override;
void SetDownloadDelegate(DownloadDelegate* delegate) override;
CookieManager* GetCookieManager() override;
void SetBooleanSetting(SettingType type, bool value) override;
bool GetBooleanSetting(SettingType type) override;
#if defined(OS_ANDROID)
ProfileImpl(JNIEnv* env,
......@@ -87,6 +89,8 @@ class ProfileImpl : public Profile {
const base::android::JavaParamRef<jstring>& directory);
jlong GetCookieManager(JNIEnv* env);
void EnsureBrowserContextInitialized(JNIEnv* env);
void SetBooleanSetting(JNIEnv* env, jint j_type, jboolean j_value);
jboolean GetBooleanSetting(JNIEnv* env, jint j_type);
#endif
void IncrementBrowserImplCount();
......@@ -125,6 +129,8 @@ class ProfileImpl : public Profile {
size_t num_browser_impl_ = 0u;
bool basic_safe_browsing_enabled_ = true;
#if defined(OS_ANDROID)
base::android::ScopedJavaGlobalRef<jobject> java_profile_;
#endif
......
......@@ -62,7 +62,7 @@ void MaybeCreateSafeBrowsing(
} // namespace
SafeBrowsingService::SafeBrowsingService(const std::string& user_agent)
: user_agent_(user_agent) {}
: user_agent_(user_agent), safe_browsing_disabled_(false) {}
SafeBrowsingService::~SafeBrowsingService() = default;
......@@ -125,7 +125,8 @@ SafeBrowsingService::GetSafeBrowsingUrlCheckerDelegate() {
if (!safe_browsing_url_checker_delegate_) {
safe_browsing_url_checker_delegate_ = new UrlCheckerDelegateImpl(
GetSafeBrowsingDBManager(), GetSafeBrowsingUIManager());
GetSafeBrowsingDBManager(), GetSafeBrowsingUIManager(),
safe_browsing_disabled_);
}
return safe_browsing_url_checker_delegate_;
......@@ -217,4 +218,15 @@ void SafeBrowsingService::StopDBManagerOnIOThread() {
}
}
void SafeBrowsingService::SetSafeBrowsingDisabled(bool disabled) {
if (safe_browsing_disabled_ != disabled) {
safe_browsing_disabled_ = disabled;
// If there is no safe_browsing_url_checker_delegate_ yet the opt_out
// setting will be set later during its creation.
if (safe_browsing_url_checker_delegate_) {
safe_browsing_url_checker_delegate_->SetSafeBrowsingDisabled(disabled);
}
}
}
} // namespace weblayer
......@@ -35,6 +35,7 @@ class SafeBrowsingNetworkContext;
} // namespace safe_browsing
namespace weblayer {
class UrlCheckerDelegateImpl;
// Class for managing safebrowsing related functionality. In particular this
// class owns both the safebrowsing database and UI managers and provides
......@@ -54,6 +55,7 @@ class SafeBrowsingService {
void AddInterface(service_manager::BinderRegistry* registry,
content::RenderProcessHost* render_process_host);
void StopDBManager();
void SetSafeBrowsingDisabled(bool disabled);
private:
SafeBrowsingUIManager* GetSafeBrowsingUIManager();
......@@ -88,14 +90,15 @@ class SafeBrowsingService {
scoped_refptr<network::WeakWrapperSharedURLLoaderFactory>
shared_url_loader_factory_on_io_;
scoped_refptr<safe_browsing::UrlCheckerDelegate>
safe_browsing_url_checker_delegate_;
scoped_refptr<UrlCheckerDelegateImpl> safe_browsing_url_checker_delegate_;
std::unique_ptr<safe_browsing::SafeBrowsingApiHandler>
safe_browsing_api_handler_;
std::string user_agent_;
bool safe_browsing_disabled_;
DISALLOW_COPY_AND_ASSIGN(SafeBrowsingService);
};
......
......@@ -15,9 +15,11 @@ namespace weblayer {
UrlCheckerDelegateImpl::UrlCheckerDelegateImpl(
scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager,
scoped_refptr<SafeBrowsingUIManager> ui_manager)
scoped_refptr<SafeBrowsingUIManager> ui_manager,
bool disabled)
: database_manager_(std::move(database_manager)),
ui_manager_(std::move(ui_manager)),
safe_browsing_disabled_(disabled),
threat_types_(safe_browsing::CreateSBThreatTypeSet(
{safe_browsing::SB_THREAT_TYPE_URL_MALWARE,
safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
......@@ -68,16 +70,17 @@ bool UrlCheckerDelegateImpl::IsUrlWhitelisted(const GURL& url) {
return false;
}
void UrlCheckerDelegateImpl::SetSafeBrowsingDisabled(bool disabled) {
safe_browsing_disabled_ = disabled;
}
bool UrlCheckerDelegateImpl::ShouldSkipRequestCheck(
const GURL& original_url,
int frame_tree_node_id,
int render_process_id,
int render_frame_id,
bool originated_from_service_worker) {
// TODO(timvolodine): this is needed when safebrowsing is not enabled.
// For now in the context of weblayer we consider safebrowsing as always
// enabled. This may change in the future.
return false;
return safe_browsing_disabled_ ? true : false;
}
void UrlCheckerDelegateImpl::NotifySuspiciousSiteDetected(
......
......@@ -23,7 +23,10 @@ class UrlCheckerDelegateImpl : public safe_browsing::UrlCheckerDelegate {
UrlCheckerDelegateImpl(
scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
database_manager,
scoped_refptr<SafeBrowsingUIManager> ui_manager);
scoped_refptr<SafeBrowsingUIManager> ui_manager,
bool disabled);
void SetSafeBrowsingDisabled(bool disabled);
private:
~UrlCheckerDelegateImpl() override;
......@@ -58,6 +61,7 @@ class UrlCheckerDelegateImpl : public safe_browsing::UrlCheckerDelegate {
scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager_;
scoped_refptr<SafeBrowsingUIManager> ui_manager_;
bool safe_browsing_disabled_;
safe_browsing::SBThreatTypeSet threat_types_;
DISALLOW_COPY_AND_ASSIGN(UrlCheckerDelegateImpl);
......
......@@ -68,6 +68,7 @@ android_library("java") {
"org/chromium/weblayer/ObserverList.java",
"org/chromium/weblayer/Profile.java",
"org/chromium/weblayer/RemoteFragment.java",
"org/chromium/weblayer/SettingType.java",
"org/chromium/weblayer/SiteSettingsActivity.java",
"org/chromium/weblayer/SiteSettingsFragment.java",
"org/chromium/weblayer/Tab.java",
......
......@@ -213,6 +213,37 @@ public class Profile {
return mCookieManager;
}
/**
* Allows the embedder to set a boolean value for a specific setting, see {@link SettingType}
* for more details and the possible options.
*
* @param type See {@link SettingType}.
* @param value The value to set for the setting.
*
* @since 84
*/
public void setBooleanSetting(@SettingType int type, boolean value) {
try {
mImpl.setBooleanSetting(type, value);
} catch (RemoteException e) {
throw new APICallException(e);
}
}
/**
* Returns the current value for the given setting type, see {@link SettingType} for more
* details and the possible options.
*
* @since 84
*/
public boolean getBooleanSetting(@SettingType int type) {
try {
return mImpl.getBooleanSetting(type);
} catch (RemoteException e) {
throw new APICallException(e);
}
}
static final class DownloadCallbackClientImpl extends IDownloadCallbackClient.Stub {
private final DownloadCallback mCallback;
......
// Copyright 2020 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;
/**
* @hide
*/
@IntDef({SettingType.BASIC_SAFE_BROWSING_ENABLED})
@Retention(RetentionPolicy.SOURCE)
public @interface SettingType {
/**
* Allows the embedder to set whether it wants to disable/enable the Safe Browsing functionality
* (which checks that the loaded URLs are safe). Safe Browsing is enabled by default.
*/
int BASIC_SAFE_BROWSING_ENABLED =
org.chromium.weblayer_private.interfaces.SettingType.BASIC_SAFE_BROWSING_ENABLED;
}
......@@ -23,6 +23,10 @@ enum class BrowsingDataType {
CACHE = 1,
};
enum class SettingType {
BASIC_SAFE_BROWSING_ENABLED = 0,
};
class Profile {
public:
// Pass an empty |name| for an in-memory profile.
......@@ -56,6 +60,12 @@ class Profile {
// Gets the cookie manager for this profile.
virtual CookieManager* GetCookieManager() = 0;
// Set the boolean value of the given setting type.
virtual void SetBooleanSetting(SettingType type, bool value) = 0;
// Get the boolean value of the given setting type.
virtual bool GetBooleanSetting(SettingType type) = 0;
};
} // namespace weblayer
......
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