diff --git a/android/BUILD.gn b/android/BUILD.gn
index a6822278f4b..b000cb41d80 100644
--- a/android/BUILD.gn
+++ b/android/BUILD.gn
@@ -294,6 +294,7 @@ android_resources("java_resources") {
"java/brave-res/drawable/ic_brave.xml",
"java/brave-res/drawable/ic_brave_36.xml",
"java/brave-res/drawable/ic_brave_ai.xml",
+ "java/brave-res/drawable/ic_brave_auto_shred.xml",
"java/brave-res/drawable/ic_brave_battery.xml",
"java/brave-res/drawable/ic_brave_logo.xml",
"java/brave-res/drawable/ic_brave_mobiledata.xml",
@@ -591,6 +592,7 @@ android_resources("java_resources") {
"java/brave-res/layout/brave_shields_main_layout.xml",
"java/brave-res/layout/brave_shields_option_layout.xml",
"java/brave-res/layout/brave_shields_secondary_layout.xml",
+ "java/brave-res/layout/brave_shields_shred_site_data_layout.xml",
"java/brave-res/layout/brave_shields_stats_row.xml",
"java/brave-res/layout/brave_shields_switcher.xml",
"java/brave-res/layout/brave_shields_thank_you_layout.xml",
diff --git a/android/java/brave-res/drawable/ic_brave_auto_shred.xml b/android/java/brave-res/drawable/ic_brave_auto_shred.xml
new file mode 100644
index 00000000000..ce6ad7ebc2e
--- /dev/null
+++ b/android/java/brave-res/drawable/ic_brave_auto_shred.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
diff --git a/android/java/brave-res/layout/brave_shields_main_layout.xml b/android/java/brave-res/layout/brave_shields_main_layout.xml
index fe3549931b1..ccba3e4429d 100644
--- a/android/java/brave-res/layout/brave_shields_main_layout.xml
+++ b/android/java/brave-res/layout/brave_shields_main_layout.xml
@@ -158,6 +158,14 @@
android:id="@+id/brave_shields_block_fingerprinting_layout_id"
layout="@layout/brave_shields_option_layout"/>
+
+
+
+
diff --git a/android/java/brave-res/layout/brave_shields_option_layout.xml b/android/java/brave-res/layout/brave_shields_option_layout.xml
index 13a2a3f4437..09a09758b45 100644
--- a/android/java/brave-res/layout/brave_shields_option_layout.xml
+++ b/android/java/brave-res/layout/brave_shields_option_layout.xml
@@ -26,7 +26,7 @@
android:gravity="start|center_vertical"
android:padding="16dp"
app:srcCompat="@drawable/ic_back"
- app:tint="@color/shield_back_button_tint"/>
+ app:tint="@color/schemes_on_surface_variant"/>
+ android:textColor="@color/schemes_on_surface"/>
@@ -70,7 +70,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
- android:layout_marginEnd="16dp">
+ android:layout_marginEnd="16dp"
+ android:layout_marginBottom="16dp">
+ android:textColor="@color/shield_text_color"
+ android:layoutDirection="rtl"
+ app:buttonTint="@color/schemes_primary"/>
-
+ android:textColor="@color/shield_text_color"
+ android:layoutDirection="rtl"
+ app:buttonTint="@color/schemes_primary"/>
+ android:textColor="@color/shield_text_color"
+ android:layoutDirection="rtl"
+ app:buttonTint="@color/schemes_primary"/>
-
-
-
\ No newline at end of file
+
diff --git a/android/java/brave-res/layout/brave_shields_secondary_layout.xml b/android/java/brave-res/layout/brave_shields_secondary_layout.xml
index e8289273da6..c9cf759b9ae 100644
--- a/android/java/brave-res/layout/brave_shields_secondary_layout.xml
+++ b/android/java/brave-res/layout/brave_shields_secondary_layout.xml
@@ -43,6 +43,11 @@
android:id="@+id/brave_shields_forget_first_party_storage_id"
layout="@layout/brave_shields_switcher"/>
+
+
+
diff --git a/android/java/brave-res/layout/brave_shields_shred_site_data_layout.xml b/android/java/brave-res/layout/brave_shields_shred_site_data_layout.xml
new file mode 100644
index 00000000000..6be097d9a70
--- /dev/null
+++ b/android/java/brave-res/layout/brave_shields_shred_site_data_layout.xml
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/java/brave-res/layout/brave_shields_toggle_layout.xml b/android/java/brave-res/layout/brave_shields_toggle_layout.xml
index 2421e207caa..a96336ea1e7 100644
--- a/android/java/brave-res/layout/brave_shields_toggle_layout.xml
+++ b/android/java/brave-res/layout/brave_shields_toggle_layout.xml
@@ -13,6 +13,7 @@
android:background="@color/shield_toggle_bg_color">
-
+
+
+ android:orientation="vertical">
+
+
+
+
+
+
-
\ No newline at end of file
+
diff --git a/android/java/org/chromium/chrome/browser/app/BraveActivity.java b/android/java/org/chromium/chrome/browser/app/BraveActivity.java
index aac8034e03e..fb7a19e56ac 100644
--- a/android/java/org/chromium/chrome/browser/app/BraveActivity.java
+++ b/android/java/org/chromium/chrome/browser/app/BraveActivity.java
@@ -1081,6 +1081,12 @@ public abstract class BraveActivity extends ChromeActivity
ApplicationStatus.registerApplicationStateListener(mApplicationStateListener);
}
+ Profile profile = getCurrentProfile();
+ if (profile != null) {
+ // Triggers notification of current app state on Android.
+ BraveFirstPartyStorageCleanerUtils.triggerCurrentAppStateNotification(profile);
+ }
+
super.onStartWithNative();
}
diff --git a/android/java/org/chromium/chrome/browser/preferences/website/BraveShieldsContentSettings.java b/android/java/org/chromium/chrome/browser/preferences/website/BraveShieldsContentSettings.java
index 23fcb329769..3d713e55aef 100644
--- a/android/java/org/chromium/chrome/browser/preferences/website/BraveShieldsContentSettings.java
+++ b/android/java/org/chromium/chrome/browser/preferences/website/BraveShieldsContentSettings.java
@@ -28,6 +28,7 @@ public class BraveShieldsContentSettings {
public static final String RESOURCE_IDENTIFIER_HTTPS_UPGRADE = "httpsUpgrade";
public static final String RESOURCE_IDENTIFIER_FORGET_FIRST_PARTY_STORAGE =
"forgetFirstPartyStorage";
+ public static final String RESOURCE_IDENTIFIER_SHRED_SITE_DATA = "shredSiteData";
public static final String RESOURCE_IDENTIFIER_ALLOW_ELEMENT_BLOCKER_IN_PRIVATE =
"allowElementBlockerInPrivate";
@@ -37,6 +38,11 @@ public class BraveShieldsContentSettings {
public static final String ALLOW_RESOURCE = "allow";
public static final String AGGRESSIVE = "aggressive";
+ // Auto Shred Modes, must be consistent with brave_shields::mojom::AutoShredMode
+ public static final String AUTO_SHRED_MODE_NEVER = "0";
+ public static final String AUTO_SHRED_MODE_LAST_TAB_CLOSED = "1";
+ public static final String AUTO_SHRED_MODE_APP_EXIT = "2";
+
public static final int ALWAYS = 0;
public static final int ASK = 1;
public static final int NEVER = 2;
@@ -129,12 +135,23 @@ public class BraveShieldsContentSettings {
} else if (resourceIndentifier.equals(RESOURCE_IDENTIFIER_COOKIES)) {
BraveShieldsContentSettingsJni.get().setCookieControlType(settingOption, host, profile);
} else if (resourceIndentifier.equals(RESOURCE_IDENTIFIER_TRACKERS)) {
- BraveShieldsContentSettingsJni.get().setCosmeticFilteringControlType(
- DEFAULT.equals(settingOption) ? BLOCK_THIRDPARTY_RESOURCE : settingOption, host,
- profile);
- BraveShieldsContentSettingsJni.get().setAdControlType(
- BLOCK_THIRDPARTY_RESOURCE.equals(settingOption) ? DEFAULT : settingOption, host,
- profile);
+ BraveShieldsContentSettingsJni.get()
+ .setCosmeticFilteringControlType(
+ DEFAULT.equals(settingOption)
+ ? BLOCK_THIRDPARTY_RESOURCE
+ : settingOption,
+ host,
+ profile);
+ BraveShieldsContentSettingsJni.get()
+ .setAdControlType(
+ BLOCK_THIRDPARTY_RESOURCE.equals(settingOption)
+ ? DEFAULT
+ : settingOption,
+ host,
+ profile);
+ } else if (resourceIndentifier.equals(RESOURCE_IDENTIFIER_SHRED_SITE_DATA)) {
+ BraveShieldsContentSettingsJni.get()
+ .setAutoShredMode(Integer.parseInt(settingOption), host, profile);
}
}
@@ -172,6 +189,9 @@ public class BraveShieldsContentSettings {
if (settings.equals(BLOCK_THIRDPARTY_RESOURCE)) {
settings = DEFAULT;
}
+ } else if (resourceIndentifier.equals(RESOURCE_IDENTIFIER_SHRED_SITE_DATA)) {
+ int mode = BraveShieldsContentSettingsJni.get().getAutoShredMode(host, profile);
+ settings = Integer.toString(mode);
}
return settings;
}
@@ -332,5 +352,9 @@ public class BraveShieldsContentSettings {
boolean getAllowElementBlockerInPrivateModeEnabled();
void setAllowElementBlockerInPrivateModeEnabled(boolean enabled);
+
+ void setAutoShredMode(int mode, String url, Profile profile);
+
+ int getAutoShredMode(String url, Profile profile);
}
}
diff --git a/android/java/org/chromium/chrome/browser/privacy/settings/BravePrivacySettings.java b/android/java/org/chromium/chrome/browser/privacy/settings/BravePrivacySettings.java
index 86eb0ac5a44..c5e96fd8fd8 100644
--- a/android/java/org/chromium/chrome/browser/privacy/settings/BravePrivacySettings.java
+++ b/android/java/org/chromium/chrome/browser/privacy/settings/BravePrivacySettings.java
@@ -355,7 +355,8 @@ public class BravePrivacySettings extends PrivacySettings {
(ChromeSwitchPreference) findPreference(PREF_FORGET_FIRST_PARTY_STORAGE);
mForgetFirstPartyStoragePref.setOnPreferenceChangeListener(this);
boolean forgetFirstPartyStorageIsEnabled =
- ChromeFeatureList.isEnabled(BraveFeatureList.BRAVE_FORGET_FIRST_PARTY_STORAGE);
+ ChromeFeatureList.isEnabled(BraveFeatureList.BRAVE_FORGET_FIRST_PARTY_STORAGE)
+ && !ChromeFeatureList.isEnabled(BraveFeatureList.BRAVE_SHRED);
mForgetFirstPartyStoragePref.setVisible(forgetFirstPartyStorageIsEnabled);
if (ChromeFeatureList.isEnabled(BraveFeatureList.BRAVE_SHIELDS_ELEMENT_PICKER)) {
diff --git a/android/java/org/chromium/chrome/browser/shields/BraveShieldsHandler.java b/android/java/org/chromium/chrome/browser/shields/BraveShieldsHandler.java
index e0ad913e0cf..f2e6f301755 100644
--- a/android/java/org/chromium/chrome/browser/shields/BraveShieldsHandler.java
+++ b/android/java/org/chromium/chrome/browser/shields/BraveShieldsHandler.java
@@ -171,6 +171,8 @@ public class BraveShieldsHandler implements BraveRewardsHelper.LargeIconReadyCal
private TextView mSiteBlockCounterText;
private View mBottomDivider;
private ImageView mToggleIcon;
+ private LinearLayout mShredSiteDataLayout;
+ private LinearLayout mAutoShredOptionsLayout;
private BraveRewardsNativeWorker mBraveRewardsNativeWorker;
private BraveRewardsHelper mIconFetcher;
@@ -391,7 +393,23 @@ public class BraveShieldsHandler implements BraveRewardsHelper.LargeIconReadyCal
});
} else {
popupWindow.setAnimationStyle(R.style.AnchoredPopupAnimEndTop);
- popupWindow.showAsDropDown(mAnchorView);
+
+ // Add 8dp margin from right edge for showAsDropDown case
+ int marginRightDp = 8;
+ int marginRightPx =
+ (int) (marginRightDp * mContext.getResources().getDisplayMetrics().density);
+ int screenWidth = mContext.getResources().getDisplayMetrics().widthPixels;
+ int[] anchorLocation = new int[2];
+ mAnchorView.getLocationOnScreen(anchorLocation);
+ int anchorX = anchorLocation[0];
+
+ if (anchorX + width > screenWidth - marginRightPx) {
+ // Calculate offset to keep popup within bounds
+ int xOffset = screenWidth - width - marginRightPx - anchorX;
+ popupWindow.showAsDropDown(mAnchorView, xOffset, 0);
+ } else {
+ popupWindow.showAsDropDown(mAnchorView);
+ }
}
return popupWindow;
@@ -502,6 +520,10 @@ public class BraveShieldsHandler implements BraveRewardsHelper.LargeIconReadyCal
mBottomDivider = mToggleLayout.findViewById(R.id.bottom_divider);
mToggleIcon = mToggleLayout.findViewById(R.id.toggle_favicon);
+ mShredSiteDataLayout =
+ mPopupView.findViewById(R.id.brave_shields_shred_site_data_layout_id);
+ mAutoShredOptionsLayout =
+ mPopupView.findViewById(R.id.brave_shields_auto_shred_options_layout_id);
}
private void setUpMainLayout() {
@@ -610,6 +632,8 @@ public class BraveShieldsHandler implements BraveRewardsHelper.LargeIconReadyCal
setUpSwitchLayouts();
setupDetailsLayouts();
+
+ setupShredSiteDataLayout();
}
private void setupDetailsLayouts() {
@@ -692,8 +716,6 @@ public class BraveShieldsHandler implements BraveRewardsHelper.LargeIconReadyCal
mBlockShieldsOption2.setText(option2StringId);
RadioButton mBlockShieldsOption3 = mBlockShieldsLayout.findViewById(R.id.option3);
mBlockShieldsOption3.setText(option3StringId);
- Button mBlockShieldsDoneButton = mBlockShieldsLayout.findViewById(R.id.done_button);
- mBlockShieldsDoneButton.setOnClickListener(mDoneClickListener);
ImageView mBlockShieldsBackButton = mBlockShieldsLayout.findViewById(R.id.back_button);
mBlockShieldsBackButton.setOnClickListener(new View.OnClickListener() {
@Override
@@ -784,6 +806,238 @@ public class BraveShieldsHandler implements BraveRewardsHelper.LargeIconReadyCal
}
}
+ private void updateSecondaryShredSiteDataText(String text) {
+ LinearLayout secondaryShredSiteDataLayout =
+ mSecondaryLayout.findViewById(
+ R.id.brave_shields_secondary_shred_site_data_layout_id);
+ TextView secondaryShredSiteDataText =
+ secondaryShredSiteDataLayout.findViewById(R.id.toggle_text_sub_text);
+
+ secondaryShredSiteDataText.setText(
+ mContext.getResources()
+ .getString(R.string.brave_shields_shred_sites_data_sub_text, text));
+ secondaryShredSiteDataText.setVisibility(text == null ? View.GONE : View.VISIBLE);
+ }
+
+ private void updateBraveShieldsAutoShredSiteDataSubText(String autoShredSettingOption) {
+ LinearLayout braveShieldsAutoShredItemLayout =
+ mShredSiteDataLayout.findViewById(
+ R.id.brave_shields_auto_shred_site_data_layout_id);
+ TextView braveShieldsAutoShredSiteDataSubText =
+ braveShieldsAutoShredItemLayout.findViewById(R.id.toggle_text_sub_text);
+
+ if (autoShredSettingOption.equals(BraveShieldsContentSettings.AUTO_SHRED_MODE_NEVER)) {
+ braveShieldsAutoShredSiteDataSubText.setText(
+ R.string.brave_shields_auto_shred_never_mode_text);
+ braveShieldsAutoShredSiteDataSubText.setVisibility(View.VISIBLE);
+ updateSecondaryShredSiteDataText(null);
+ } else if (autoShredSettingOption.equals(
+ BraveShieldsContentSettings.AUTO_SHRED_MODE_LAST_TAB_CLOSED)) {
+ braveShieldsAutoShredSiteDataSubText.setText(
+ R.string.brave_shields_auto_shred_site_tab_closed_mode_text);
+ braveShieldsAutoShredSiteDataSubText.setVisibility(View.VISIBLE);
+
+ updateSecondaryShredSiteDataText(
+ mContext.getResources()
+ .getString(
+ R.string.brave_shields_auto_shred_site_tab_closed_mode_text));
+ } else if (autoShredSettingOption.equals(
+ BraveShieldsContentSettings.AUTO_SHRED_MODE_APP_EXIT)) {
+ braveShieldsAutoShredSiteDataSubText.setText(
+ R.string.brave_shields_auto_shred_app_close_mode_text);
+ braveShieldsAutoShredSiteDataSubText.setVisibility(View.VISIBLE);
+ updateSecondaryShredSiteDataText(
+ mContext.getResources()
+ .getString(R.string.brave_shields_auto_shred_app_close_mode_text));
+ } else {
+ braveShieldsAutoShredSiteDataSubText.setVisibility(View.GONE);
+ updateSecondaryShredSiteDataText(null);
+ }
+ }
+
+ private void setupShredSiteDataLayout() {
+ LinearLayout secondaryShredSiteDataLayout =
+ mSecondaryLayout.findViewById(
+ R.id.brave_shields_secondary_shred_site_data_layout_id);
+ if (!ChromeFeatureList.isEnabled(BraveFeatureList.BRAVE_SHRED)) {
+ secondaryShredSiteDataLayout.setVisibility(View.GONE);
+ return;
+ }
+ secondaryShredSiteDataLayout.setVisibility(View.VISIBLE);
+
+ secondaryShredSiteDataLayout.setBackground(null);
+
+ ImageView secondaryShredSiteDataShieldsIcon =
+ secondaryShredSiteDataLayout.findViewById(R.id.toggle_favicon);
+ secondaryShredSiteDataShieldsIcon.setImageResource(R.drawable.ic_chevron_right);
+ secondaryShredSiteDataShieldsIcon.setColorFilter(
+ mContext.getColor(R.color.default_icon_color_baseline));
+ TextView secondaryShredSiteDataText =
+ secondaryShredSiteDataLayout.findViewById(R.id.toggle_text);
+ secondaryShredSiteDataText.setText(R.string.brave_shields_shred_sites_data_text);
+
+ secondaryShredSiteDataLayout.setOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ mMainLayout.setVisibility(View.GONE);
+ mShredSiteDataLayout.setVisibility(View.VISIBLE);
+ }
+ });
+ ImageView shredSiteDataBackButton =
+ mShredSiteDataLayout.findViewById(R.id.shred_site_data_back_button);
+ shredSiteDataBackButton.setOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ mShredSiteDataLayout.setVisibility(View.GONE);
+ mMainLayout.setVisibility(View.VISIBLE);
+ }
+ });
+
+ // Manual shred layout
+ LinearLayout braveShieldsManualShredItemLayout =
+ mShredSiteDataLayout.findViewById(
+ R.id.brave_shields_manual_shred_site_data_layout_id);
+ braveShieldsManualShredItemLayout.setOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ hideBraveShieldsMenu();
+ try {
+ BraveActivity.getBraveActivity().shredSiteData();
+ } catch (BraveActivity.BraveActivityNotFoundException e) {
+ Log.e(TAG, "setupShredSiteDataLayout manual shred click " + e);
+ }
+ }
+ });
+
+ String autoShredSettingOption =
+ BraveShieldsContentSettings.getShieldsValue(
+ mProfile,
+ mUrlSpec,
+ BraveShieldsContentSettings.RESOURCE_IDENTIFIER_SHRED_SITE_DATA);
+
+ // Autoshred layout
+ LinearLayout braveShieldsAutoShredItemLayout =
+ mShredSiteDataLayout.findViewById(
+ R.id.brave_shields_auto_shred_site_data_layout_id);
+
+ braveShieldsAutoShredItemLayout.setBackground(null);
+ braveShieldsAutoShredItemLayout.setOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ mShredSiteDataLayout.setVisibility(View.GONE);
+ mAutoShredOptionsLayout.setVisibility(View.VISIBLE);
+ }
+ });
+
+ // Autoshred menu item's icon
+ View braveShieldsAutoShredToggleDivider =
+ braveShieldsAutoShredItemLayout.findViewById(R.id.toggle_top_divider);
+ braveShieldsAutoShredToggleDivider.setVisibility(View.GONE);
+ ImageView braveShieldsAutoShredButtonIcon =
+ braveShieldsAutoShredItemLayout.findViewById(R.id.toggle_button_icon);
+ braveShieldsAutoShredButtonIcon.setVisibility(View.VISIBLE);
+ braveShieldsAutoShredButtonIcon.setImageResource(R.drawable.ic_brave_auto_shred);
+ braveShieldsAutoShredButtonIcon.setColorFilter(
+ mContext.getColor(R.color.default_icon_color_baseline));
+
+ // Autoshred menu item's text
+ TextView braveShieldsAutoShredSiteDataText =
+ braveShieldsAutoShredItemLayout.findViewById(R.id.toggle_text);
+ braveShieldsAutoShredSiteDataText.setText(
+ R.string.brave_shields_auto_shred_sites_data_text);
+ updateBraveShieldsAutoShredSiteDataSubText(autoShredSettingOption);
+
+ ImageView braveShieldsAutoShredSiteDataShieldsIcon =
+ braveShieldsAutoShredItemLayout.findViewById(R.id.toggle_favicon);
+ braveShieldsAutoShredSiteDataShieldsIcon.setImageResource(R.drawable.ic_chevron_right);
+ braveShieldsAutoShredSiteDataShieldsIcon.setColorFilter(
+ mContext.getColor(R.color.default_icon_color_baseline));
+
+ // Auto shred options layout
+ TextView autoShredOptionTitle = mAutoShredOptionsLayout.findViewById(R.id.option_title);
+ autoShredOptionTitle.setText(R.string.brave_shields_auto_shred_sites_data_text);
+ TextView autoShredOptionText = mAutoShredOptionsLayout.findViewById(R.id.option_text);
+ autoShredOptionText.setVisibility(View.GONE);
+ ImageView mAutoShredOptionsBackButton =
+ mAutoShredOptionsLayout.findViewById(R.id.back_button);
+ mAutoShredOptionsBackButton.setOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ mAutoShredOptionsLayout.setVisibility(View.GONE);
+ mShredSiteDataLayout.setVisibility(View.VISIBLE);
+ }
+ });
+ RadioButton autoShredOption1 = mAutoShredOptionsLayout.findViewById(R.id.option1);
+ autoShredOption1.setText(R.string.brave_shields_auto_shred_never_mode_text);
+ autoShredOption1.setChecked(
+ autoShredSettingOption.equals(BraveShieldsContentSettings.AUTO_SHRED_MODE_NEVER));
+ RadioButton autoShredOption2 = mAutoShredOptionsLayout.findViewById(R.id.option2);
+ autoShredOption2.setText(R.string.brave_shields_auto_shred_site_tab_closed_mode_text);
+ autoShredOption2.setChecked(
+ autoShredSettingOption.equals(
+ BraveShieldsContentSettings.AUTO_SHRED_MODE_LAST_TAB_CLOSED));
+ RadioButton autoShredOption3 = mAutoShredOptionsLayout.findViewById(R.id.option3);
+ autoShredOption3.setText(R.string.brave_shields_auto_shred_app_close_mode_text);
+ autoShredOption3.setChecked(
+ autoShredSettingOption.equals(
+ BraveShieldsContentSettings.AUTO_SHRED_MODE_APP_EXIT));
+
+ // Handle Auto shred options selection
+ RadioGroup autoShredOptionGroup =
+ mAutoShredOptionsLayout.findViewById(R.id.options_radio_group);
+ autoShredOptionGroup.setOnCheckedChangeListener(
+ new RadioGroup.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(RadioGroup group, int checkedId) {
+ RadioButton checkedRadioButton =
+ (RadioButton) group.findViewById(checkedId);
+ boolean isChecked = checkedRadioButton.isChecked();
+ if (isChecked) {
+ if (checkedId == R.id.option1) {
+ BraveShieldsContentSettings.setShieldsValue(
+ mProfile,
+ mUrlSpec,
+ BraveShieldsContentSettings
+ .RESOURCE_IDENTIFIER_SHRED_SITE_DATA,
+ BraveShieldsContentSettings.AUTO_SHRED_MODE_NEVER,
+ false);
+ updateBraveShieldsAutoShredSiteDataSubText(
+ BraveShieldsContentSettings.AUTO_SHRED_MODE_NEVER);
+ } else if (checkedId == R.id.option2) {
+ BraveShieldsContentSettings.setShieldsValue(
+ mProfile,
+ mUrlSpec,
+ BraveShieldsContentSettings
+ .RESOURCE_IDENTIFIER_SHRED_SITE_DATA,
+ BraveShieldsContentSettings.AUTO_SHRED_MODE_LAST_TAB_CLOSED,
+ false);
+ updateBraveShieldsAutoShredSiteDataSubText(
+ BraveShieldsContentSettings
+ .AUTO_SHRED_MODE_LAST_TAB_CLOSED);
+ } else if (checkedId == R.id.option3) {
+ BraveShieldsContentSettings.setShieldsValue(
+ mProfile,
+ mUrlSpec,
+ BraveShieldsContentSettings
+ .RESOURCE_IDENTIFIER_SHRED_SITE_DATA,
+ BraveShieldsContentSettings.AUTO_SHRED_MODE_APP_EXIT,
+ false);
+ updateBraveShieldsAutoShredSiteDataSubText(
+ BraveShieldsContentSettings.AUTO_SHRED_MODE_APP_EXIT);
+ }
+ if (null != mMenuObserver) {
+ mMenuObserver.onMenuTopShieldsChanged(isChecked, false);
+ }
+ }
+ }
+ });
+ }
+
private void setUpSwitchLayouts() {
LinearLayout upgradeHttpsLayout =
mSecondaryLayout.findViewById(R.id.brave_shields_upgrade_https_id);
@@ -799,7 +1053,8 @@ public class BraveShieldsHandler implements BraveRewardsHelper.LargeIconReadyCal
LinearLayout forgetFirstPartyStorageLayout =
mSecondaryLayout.findViewById(R.id.brave_shields_forget_first_party_storage_id);
- if (ChromeFeatureList.isEnabled(BraveFeatureList.BRAVE_FORGET_FIRST_PARTY_STORAGE)) {
+ if (ChromeFeatureList.isEnabled(BraveFeatureList.BRAVE_FORGET_FIRST_PARTY_STORAGE)
+ && !ChromeFeatureList.isEnabled(BraveFeatureList.BRAVE_SHRED)) {
TextView forgetFirstPartyStorageText =
forgetFirstPartyStorageLayout.findViewById(R.id.brave_shields_switch_text);
forgetFirstPartyStorageText.setText(R.string.brave_forget_first_party_storage_switch);
@@ -857,8 +1112,6 @@ public class BraveShieldsHandler implements BraveRewardsHelper.LargeIconReadyCal
mOptionText.setVisibility(View.GONE);
RadioGroup mOptionGroup = mAboutLayout.findViewById(R.id.options_radio_group);
mOptionGroup.setVisibility(View.GONE);
- Button mDoneButton = mAboutLayout.findViewById(R.id.done_button);
- mDoneButton.setOnClickListener(mDoneClickListener);
ImageView mBackButton = mAboutLayout.findViewById(R.id.back_button);
mBackButton.setOnClickListener(new View.OnClickListener() {
@Override
@@ -1408,22 +1661,19 @@ public class BraveShieldsHandler implements BraveRewardsHelper.LargeIconReadyCal
private void setFavIcon(Bitmap bmp) {
if (bmp != null && mContext != null) {
- ((Activity)mContext).runOnUiThread(
- new Runnable() {
- @Override
- public void run() {
- ImageView iv = (ImageView) mPopupView.findViewById(R.id.site_favicon);
- if (iv != null) iv.setImageBitmap(BraveRewardsHelper.getCircularBitmap(bmp));
- }
- });
+ ((Activity) mContext)
+ .runOnUiThread(
+ new Runnable() {
+ @Override
+ public void run() {
+ ImageView iv =
+ (ImageView) mPopupView.findViewById(R.id.site_favicon);
+ if (iv != null) {
+ iv.setImageBitmap(
+ BraveRewardsHelper.getCircularBitmap(bmp));
+ }
+ }
+ });
}
}
-
- private final View.OnClickListener mDoneClickListener =
- new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- hideBraveShieldsMenu();
- }
- };
}
diff --git a/browser/android/BUILD.gn b/browser/android/BUILD.gn
index bf5c521619c..2690fa1be20 100644
--- a/browser/android/BUILD.gn
+++ b/browser/android/BUILD.gn
@@ -30,6 +30,7 @@ source_set("android_browser_process") {
"//brave/components/brave_ads/browser",
"//brave/components/brave_shields/content/browser",
"//brave/components/brave_shields/core/browser",
+ "//brave/components/brave_shields/core/common",
"//brave/components/brave_sync",
"//brave/components/brave_sync:crypto",
"//brave/components/brave_sync:prefs",
diff --git a/browser/android/brave_shields_content_settings.cc b/browser/android/brave_shields_content_settings.cc
index 66d042093b8..b7e558ae40d 100644
--- a/browser/android/brave_shields_content_settings.cc
+++ b/browser/android/brave_shields_content_settings.cc
@@ -15,6 +15,7 @@
#include "brave/components/brave_shields/content/browser/ad_block_service.h"
#include "brave/components/brave_shields/core/browser/brave_shields_settings_service.h"
#include "brave/components/brave_shields/core/browser/brave_shields_utils.h"
+#include "brave/components/brave_shields/core/common/brave_shields_settings_values.h"
#include "chrome/android/chrome_jni_headers/BraveShieldsContentSettings_jni.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/cookie_settings_factory.h"
@@ -330,5 +331,37 @@ void JNI_BraveShieldsContentSettings_SetAllowElementBlockerInPrivateModeEnabled(
g_browser_process->local_state(), enabled);
}
+void JNI_BraveShieldsContentSettings_SetAutoShredMode(
+ JNIEnv* env,
+ jint mode,
+ const base::android::JavaParamRef& url,
+ const base::android::JavaParamRef& j_profile) {
+ std::optional maybe_mode =
+ brave_shields::traits::SettingTraits<
+ brave_shields::mojom::AutoShredMode>::From(mode);
+ CHECK(maybe_mode.has_value());
+
+ auto* brave_shields_settings =
+ BraveShieldsSettingsServiceFactory::GetForProfile(
+ Profile::FromJavaObject(j_profile));
+ brave_shields_settings->SetAutoShredMode(
+ maybe_mode.value(),
+ GURL(base::android::ConvertJavaStringToUTF8(env, url)));
+}
+
+jint JNI_BraveShieldsContentSettings_GetAutoShredMode(
+ JNIEnv* env,
+ const base::android::JavaParamRef& url,
+ const base::android::JavaParamRef& j_profile) {
+ auto* brave_shields_settings =
+ BraveShieldsSettingsServiceFactory::GetForProfile(
+ Profile::FromJavaObject(j_profile));
+ const auto mode = brave_shields_settings->GetAutoShredMode(
+ GURL(base::android::ConvertJavaStringToUTF8(env, url)));
+
+ return brave_shields::traits::SettingTraits<
+ brave_shields::mojom::AutoShredMode>::To(mode);
+}
+
} // namespace android
} // namespace chrome
diff --git a/browser/brave_shields/android/BUILD.gn b/browser/brave_shields/android/BUILD.gn
index 0cb4745e8cf..855edacfd31 100644
--- a/browser/brave_shields/android/BUILD.gn
+++ b/browser/brave_shields/android/BUILD.gn
@@ -19,6 +19,7 @@ android_library("java") {
deps = [
":java_resources",
"//base:base_java",
+ "//chrome/browser/profiles/android:java",
"//chrome/browser/tab:java",
"//third_party/android_deps:com_airbnb_android_lottie_java",
"//third_party/androidx:androidx_fragment_fragment_java",
diff --git a/browser/brave_shields/android/brave_first_party_storage_cleaner_utils.cc b/browser/brave_shields/android/brave_first_party_storage_cleaner_utils.cc
index 34de074f06f..5adb24fc4e4 100644
--- a/browser/brave_shields/android/brave_first_party_storage_cleaner_utils.cc
+++ b/browser/brave_shields/android/brave_first_party_storage_cleaner_utils.cc
@@ -6,10 +6,13 @@
#include
#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
#include "brave/browser/brave_shields/android/jni_headers/BraveFirstPartyStorageCleanerUtils_jni.h"
#include "brave/browser/brave_shields/brave_shields_tab_helper.h"
+#include "brave/browser/ephemeral_storage/ephemeral_storage_service_factory.h"
#include "brave/browser/ephemeral_storage/ephemeral_storage_tab_helper.h"
#include "chrome/browser/android/tab_android.h"
+#include "chrome/browser/profiles/profile.h"
namespace brave_shields {
@@ -39,4 +42,29 @@ static void JNI_BraveFirstPartyStorageCleanerUtils_CleanupTLDFirstPartyStorage(
brave_shields_tab_helper->EnforceSiteDataCleanup();
}
+static void
+JNI_BraveFirstPartyStorageCleanerUtils_TriggerCurrentAppStateNotification(
+ JNIEnv* env,
+ const base::android::JavaParamRef& j_profile) {
+ CHECK(env);
+ Profile* profile = Profile::FromJavaObject(j_profile);
+ if (!profile) {
+ return;
+ }
+
+ auto* ephemeral_storage_service =
+ EphemeralStorageServiceFactory::GetForContext(
+ static_cast(profile));
+ if (!ephemeral_storage_service) {
+ return;
+ }
+
+ ephemeral_storage_service->TriggerCurrentAppStateNotification();
+}
+
+bool IsAppInTaskStack() {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ return Java_BraveFirstPartyStorageCleanerUtils_isAppInTaskStack(env);
+}
+
} // namespace brave_shields
diff --git a/browser/brave_shields/android/brave_first_party_storage_cleaner_utils.h b/browser/brave_shields/android/brave_first_party_storage_cleaner_utils.h
new file mode 100644
index 00000000000..c1ca5f32fa2
--- /dev/null
+++ b/browser/brave_shields/android/brave_first_party_storage_cleaner_utils.h
@@ -0,0 +1,15 @@
+/* Copyright (c) 2026 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+#ifndef BRAVE_BROWSER_BRAVE_SHIELDS_ANDROID_BRAVE_FIRST_PARTY_STORAGE_CLEANER_UTILS_H_
+#define BRAVE_BROWSER_BRAVE_SHIELDS_ANDROID_BRAVE_FIRST_PARTY_STORAGE_CLEANER_UTILS_H_
+
+namespace brave_shields {
+
+bool IsAppInTaskStack();
+
+} // namespace brave_shields
+
+#endif // BRAVE_BROWSER_BRAVE_SHIELDS_ANDROID_BRAVE_FIRST_PARTY_STORAGE_CLEANER_UTILS_H_
diff --git a/browser/brave_shields/android/java/src/org/chromium/chrome/browser/brave_shields/BraveFirstPartyStorageCleanerUtils.java b/browser/brave_shields/android/java/src/org/chromium/chrome/browser/brave_shields/BraveFirstPartyStorageCleanerUtils.java
index 3f9300d3ed9..c1cddc96985 100644
--- a/browser/brave_shields/android/java/src/org/chromium/chrome/browser/brave_shields/BraveFirstPartyStorageCleanerUtils.java
+++ b/browser/brave_shields/android/java/src/org/chromium/chrome/browser/brave_shields/BraveFirstPartyStorageCleanerUtils.java
@@ -5,23 +5,57 @@
package org.chromium.chrome.browser.brave_shields;
+import android.app.ActivityManager;
+import android.content.Context;
+
+import org.jni_zero.CalledByNative;
import org.jni_zero.JNINamespace;
import org.jni_zero.NativeMethods;
+import org.chromium.base.ContextUtils;
+import org.chromium.base.Log;
import org.chromium.build.annotations.NullMarked;
+import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.tab.Tab;
+import java.util.List;
+
@JNINamespace("brave_shields")
@NullMarked
public class BraveFirstPartyStorageCleanerUtils {
- private static final String TAG = "FirstPartyStorageCleanerUtils";
+ private static final String TAG = "FPSCleanerUtils";
public static void cleanupTLDFirstPartyStorage(Tab tab) {
BraveFirstPartyStorageCleanerUtilsJni.get().cleanupTLDFirstPartyStorage(tab);
}
+ public static void triggerCurrentAppStateNotification(Profile profile) {
+ BraveFirstPartyStorageCleanerUtilsJni.get().triggerCurrentAppStateNotification(profile);
+ }
+
+ @CalledByNative
+ public static boolean isAppInTaskStack() {
+ try {
+ ActivityManager am =
+ (ActivityManager)
+ ContextUtils.getApplicationContext()
+ .getSystemService(Context.ACTIVITY_SERVICE);
+ if (am == null) {
+ return false;
+ }
+
+ List appTasks = am.getAppTasks();
+ return !appTasks.isEmpty();
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to check task stack", e);
+ return false;
+ }
+ }
+
@NativeMethods
interface Natives {
void cleanupTLDFirstPartyStorage(Tab tab);
+
+ void triggerCurrentAppStateNotification(Profile profile);
}
}
diff --git a/browser/brave_shields/sources.gni b/browser/brave_shields/sources.gni
index a697c187c02..d67a1af6bc4 100644
--- a/browser/brave_shields/sources.gni
+++ b/browser/brave_shields/sources.gni
@@ -44,6 +44,7 @@ brave_browser_brave_shields_deps = [
if (is_android) {
brave_browser_brave_shields_sources += [
"//brave/browser/brave_shields/android/brave_first_party_storage_cleaner_utils.cc",
+ "//brave/browser/brave_shields/android/brave_first_party_storage_cleaner_utils.h",
"//brave/browser/brave_shields/android/filter_list_service_factory_android.cc",
"//brave/browser/brave_shields/brave_shields_web_contents_observer_android.cc",
]
diff --git a/browser/ephemeral_storage/application_state_observer.cc b/browser/ephemeral_storage/application_state_observer.cc
index cb5fffcb02a..18ec57ef309 100644
--- a/browser/ephemeral_storage/application_state_observer.cc
+++ b/browser/ephemeral_storage/application_state_observer.cc
@@ -13,6 +13,8 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
+#else
+#include "brave/browser/brave_shields/android/brave_first_party_storage_cleaner_utils.h"
#endif
namespace ephemeral_storage {
@@ -59,12 +61,13 @@ void ApplicationStateObserver::TriggerCurrentAppStateNotification() {
void ApplicationStateObserver::OnApplicationStateChange(
base::android::ApplicationState new_state) {
+ auto app_in_stack = brave_shields::IsAppInTaskStack();
if (new_state == base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) {
if (!has_notified_active_) {
NotifyApplicationBecameActive();
has_notified_active_ = true;
}
- } else if (current_state_ != new_state &&
+ } else if (!app_in_stack && current_state_ != new_state &&
current_state_ ==
base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) {
NotifyApplicationBecameInactive();
diff --git a/browser/ephemeral_storage/ephemeral_storage_service_unittest.cc b/browser/ephemeral_storage/ephemeral_storage_service_unittest.cc
index 1dcf20ccea5..97c084dd7a2 100644
--- a/browser/ephemeral_storage/ephemeral_storage_service_unittest.cc
+++ b/browser/ephemeral_storage/ephemeral_storage_service_unittest.cc
@@ -181,9 +181,8 @@ TEST_F(EphemeralStorageServiceTest, EphemeralCleanup) {
const std::string ephemeral_domain = url.GetHost();
const auto storage_partition_config =
content::StoragePartitionConfig::CreateDefault(&profile_);
-#if BUILDFLAG(IS_ANDROID)
- EXPECT_CALL(*mock_delegate_, TriggerCurrentAppStateNotification());
-#endif
+ EXPECT_CALL(*mock_delegate_, GetAutoShredMode(url))
+ .WillOnce(testing::Return(std::nullopt));
// Create tld ephemeral lifetime.
service_->TLDEphemeralLifetimeCreated(ephemeral_domain,
storage_partition_config);
@@ -199,9 +198,8 @@ TEST_F(EphemeralStorageServiceTest, EphemeralCleanup) {
task_environment_.FastForwardBy(base::Seconds(10));
}
-#if BUILDFLAG(IS_ANDROID)
- EXPECT_CALL(*mock_delegate_, TriggerCurrentAppStateNotification());
-#endif
+ EXPECT_CALL(*mock_delegate_, GetAutoShredMode(url))
+ .WillOnce(testing::Return(std::nullopt));
// Reopen tld ephemeral lifetime while the keepalive is active.
service_->TLDEphemeralLifetimeCreated(ephemeral_domain,
storage_partition_config);
@@ -238,12 +236,13 @@ TEST_F(EphemeralStorageServiceTest,
const auto second_storage_partition_config =
content::StoragePartitionConfig::Create(&profile_, "partition_domain",
"partition_name", false);
-#if BUILDFLAG(IS_ANDROID)
- EXPECT_CALL(*mock_delegate_, TriggerCurrentAppStateNotification()).Times(2);
-#endif
+ EXPECT_CALL(*mock_delegate_, GetAutoShredMode(url))
+ .WillOnce(testing::Return(std::nullopt));
// Create tld ephemeral lifetime.
service_->TLDEphemeralLifetimeCreated(ephemeral_domain,
storage_partition_config);
+ EXPECT_CALL(*mock_delegate_, GetAutoShredMode(url))
+ .WillOnce(testing::Return(std::nullopt));
// Create tld ephemeral lifetime in a different storage partition.
service_->TLDEphemeralLifetimeCreated(ephemeral_domain,
second_storage_partition_config);
@@ -297,9 +296,8 @@ TEST_F(EphemeralStorageServiceNoKeepAliveTest, ImmediateCleanup) {
const std::string ephemeral_domain = url.GetHost();
const auto storage_partition_config =
content::StoragePartitionConfig::CreateDefault(&profile_);
-#if BUILDFLAG(IS_ANDROID)
- EXPECT_CALL(*mock_delegate_, TriggerCurrentAppStateNotification());
-#endif
+ EXPECT_CALL(*mock_delegate_, GetAutoShredMode(url))
+ .WillOnce(testing::Return(std::nullopt));
// Create tld ephemeral lifetime.
service_->TLDEphemeralLifetimeCreated(ephemeral_domain,
storage_partition_config);
@@ -365,9 +363,8 @@ TEST_F(EphemeralStorageServiceForgetFirstPartyTest, CleanupFirstPartyStorage) {
test_case.forget_first_party ? CONTENT_SETTING_BLOCK
: CONTENT_SETTING_ALLOW);
-#if BUILDFLAG(IS_ANDROID)
- EXPECT_CALL(*mock_delegate_, TriggerCurrentAppStateNotification());
-#endif
+ EXPECT_CALL(*mock_delegate_, GetAutoShredMode(url))
+ .WillOnce(testing::Return(std::nullopt));
service_->TLDEphemeralLifetimeCreated(ephemeral_domain,
storage_partition_config);
EXPECT_EQ(
@@ -411,9 +408,8 @@ TEST_F(EphemeralStorageServiceForgetFirstPartyTest, CleanupOnRestart) {
url, url, ContentSettingsType::BRAVE_REMEMBER_1P_STORAGE,
CONTENT_SETTING_BLOCK);
-#if BUILDFLAG(IS_ANDROID)
- EXPECT_CALL(*mock_delegate_, TriggerCurrentAppStateNotification());
-#endif
+ EXPECT_CALL(*mock_delegate_, GetAutoShredMode(url))
+ .WillOnce(testing::Return(std::nullopt));
// Create tld ephemeral lifetime.
service_->TLDEphemeralLifetimeCreated(ephemeral_domain,
storage_partition_config);
@@ -472,9 +468,8 @@ TEST_F(EphemeralStorageServiceForgetFirstPartyTest,
url, url, ContentSettingsType::BRAVE_REMEMBER_1P_STORAGE,
CONTENT_SETTING_BLOCK);
-#if BUILDFLAG(IS_ANDROID)
- EXPECT_CALL(*mock_delegate_, TriggerCurrentAppStateNotification());
-#endif
+ EXPECT_CALL(*mock_delegate_, GetAutoShredMode(url))
+ .WillOnce(testing::Return(std::nullopt));
// Create tld ephemeral lifetime.
service_->TLDEphemeralLifetimeCreated(ephemeral_domain,
storage_partition_config);
@@ -497,12 +492,11 @@ TEST_F(EphemeralStorageServiceForgetFirstPartyTest,
service_ = CreateEphemeralStorageService(&profile_, mock_delegate_,
&mock_observer_);
ScopedVerifyAndClearExpectations verify(mock_delegate_);
-#if BUILDFLAG(IS_ANDROID)
- EXPECT_CALL(*mock_delegate_, TriggerCurrentAppStateNotification());
-#endif
EXPECT_EQ(
profile_.GetPrefs()->GetList(kFirstPartyStorageOriginsToCleanup).size(),
1u);
+ EXPECT_CALL(*mock_delegate_, GetAutoShredMode(url))
+ .WillOnce(testing::Return(std::nullopt));
service_->TLDEphemeralLifetimeCreated(ephemeral_domain,
storage_partition_config);
EXPECT_EQ(
@@ -531,9 +525,9 @@ TEST_F(EphemeralStorageServiceForgetFirstPartyTest,
url, url, ContentSettingsType::BRAVE_REMEMBER_1P_STORAGE,
CONTENT_SETTING_BLOCK);
-#if BUILDFLAG(IS_ANDROID)
- EXPECT_CALL(*mock_delegate_, TriggerCurrentAppStateNotification()).Times(2);
-#endif
+ EXPECT_CALL(*mock_delegate_, GetAutoShredMode(url))
+ .Times(2)
+ .WillRepeatedly(testing::Return(std::nullopt));
// Create tld ephemeral lifetime.
service_->TLDEphemeralLifetimeCreated(ephemeral_domain,
storage_partition_config);
@@ -564,9 +558,8 @@ TEST_F(EphemeralStorageServiceForgetFirstPartyTest,
EXPECT_EQ(
profile_.GetPrefs()->GetList(kFirstPartyStorageOriginsToCleanup).size(),
2u);
-#if BUILDFLAG(IS_ANDROID)
- EXPECT_CALL(*mock_delegate_, TriggerCurrentAppStateNotification());
-#endif
+ EXPECT_CALL(*mock_delegate_, GetAutoShredMode(url))
+ .WillOnce(testing::Return(std::nullopt));
service_->TLDEphemeralLifetimeCreated(ephemeral_domain,
storage_partition_config);
EXPECT_EQ(
@@ -599,9 +592,8 @@ TEST_F(EphemeralStorageServiceForgetFirstPartyTest,
url, url, ContentSettingsType::BRAVE_REMEMBER_1P_STORAGE,
CONTENT_SETTING_BLOCK);
-#if BUILDFLAG(IS_ANDROID)
- EXPECT_CALL(*mock_delegate_, TriggerCurrentAppStateNotification());
-#endif
+ EXPECT_CALL(*mock_delegate_, GetAutoShredMode(url))
+ .WillOnce(testing::Return(std::nullopt));
// Create tld ephemeral lifetime.
service_->TLDEphemeralLifetimeCreated(ephemeral_domain,
storage_partition_config);
@@ -676,9 +668,7 @@ TEST_F(EphemeralStorageServiceForgetFirstPartyTest, OffTheRecordSkipsPrefs) {
url, url, ContentSettingsType::BRAVE_REMEMBER_1P_STORAGE,
CONTENT_SETTING_BLOCK);
-#if BUILDFLAG(IS_ANDROID)
- EXPECT_CALL(*mock_delegate_, TriggerCurrentAppStateNotification());
-#endif
+ EXPECT_CALL(*mock_delegate_, GetAutoShredMode(url)).Times(0);
// Create tld ephemeral lifetime.
otr_service->TLDEphemeralLifetimeCreated(ephemeral_domain,
storage_partition_config);
@@ -840,9 +830,8 @@ TEST_F(EphemeralStorageServiceAutoShredForgetFirstPartyTest,
test_case.auto_shred_mode.value(), url);
}
-#if BUILDFLAG(IS_ANDROID)
- EXPECT_CALL(*mock_delegate_, TriggerCurrentAppStateNotification());
-#endif
+ EXPECT_CALL(*mock_delegate_, GetAutoShredMode(url))
+ .WillOnce(testing::Return(std::nullopt));
service_->TLDEphemeralLifetimeCreated(ephemeral_domain,
storage_partition_config);
EXPECT_EQ(
@@ -945,9 +934,8 @@ TEST_F(EphemeralStorageServiceAutoShredForgetFirstPartyTest, CleanupOnRestart) {
test_case.auto_shred_mode.value(), url);
}
-#if BUILDFLAG(IS_ANDROID)
- EXPECT_CALL(*mock_delegate_, TriggerCurrentAppStateNotification());
-#endif
+ EXPECT_CALL(*mock_delegate_, GetAutoShredMode(url))
+ .WillOnce(testing::Return(test_case.auto_shred_mode));
// Create tld ephemeral lifetime.
service_->TLDEphemeralLifetimeCreated(ephemeral_domain,
storage_partition_config);
diff --git a/browser/ui/android/strings/android_brave_strings.grd b/browser/ui/android/strings/android_brave_strings.grd
index bbd44476253..2e4adaa8d7d 100644
--- a/browser/ui/android/strings/android_brave_strings.grd
+++ b/browser/ui/android/strings/android_brave_strings.grd
@@ -1445,6 +1445,27 @@ Are you sure you want to do this?
Block element
+
+ Shred site's data
+
+
+ Auto shred: %1$s
+
+
+ Shred site data now
+
+
+ Auto shred
+
+
+ Never
+
+
+ Site tab closed
+
+
+ App close
+
Report a broken site
@@ -3592,7 +3613,7 @@ If you don't accept this request, VPN will not reconnect and your internet conne
Shredding will delete site data and close all '%1$s' tabs. This cannot be undone.
- Shred
+ Shred site data
Shred data
diff --git a/components/ephemeral_storage/ephemeral_storage_service.cc b/components/ephemeral_storage/ephemeral_storage_service.cc
index 81914b2045f..7bbe18ae19f 100644
--- a/components/ephemeral_storage/ephemeral_storage_service.cc
+++ b/components/ephemeral_storage/ephemeral_storage_service.cc
@@ -221,11 +221,6 @@ void EphemeralStorageService::TLDEphemeralLifetimeCreated(
const TLDEphemeralAreaKey key(ephemeral_domain, storage_partition_config);
tld_ephemeral_areas_to_cleanup_.erase(key);
FirstPartyStorageAreaInUse(ephemeral_domain, storage_partition_config);
-#if BUILDFLAG(IS_ANDROID)
- // Triggers notification of current app state on Android. We need to call it
- // at the beginning of the TLD ephemeral lifetime.
- delegate_->TriggerCurrentAppStateNotification();
-#endif
}
void EphemeralStorageService::TLDEphemeralLifetimeDestroyed(
@@ -293,6 +288,12 @@ void EphemeralStorageService::RemoveObserver(
observer_list_.RemoveObserver(observer);
}
+#if BUILDFLAG(IS_ANDROID)
+void EphemeralStorageService::TriggerCurrentAppStateNotification() {
+ delegate_->TriggerCurrentAppStateNotification();
+}
+#endif // BUILDFLAG(IS_ANDROID)
+
void EphemeralStorageService::CleanupTLDFirstPartyStorage(
const GURL& url,
const content::StoragePartitionConfig& storage_partition_config,
@@ -328,6 +329,12 @@ void EphemeralStorageService::FirstPartyStorageAreaInUse(
const GURL url(GetFirstPartyStorageURL(ephemeral_domain));
const base::Value value_to_cleanup =
GetFirstPartyStorageValueToCleanup(url, storage_partition_config);
+ auto auto_shred_mode = delegate_->GetAutoShredMode(url);
+ if (auto_shred_mode.has_value() &&
+ auto_shred_mode.value() ==
+ brave_shields::mojom::AutoShredMode::APP_EXIT) {
+ return;
+ }
ScopedListPrefUpdate pref_update(prefs_,
kFirstPartyStorageOriginsToCleanup);
pref_update->EraseValue(value_to_cleanup);
diff --git a/components/ephemeral_storage/ephemeral_storage_service.h b/components/ephemeral_storage/ephemeral_storage_service.h
index b7839d2af9e..50ffff2d7d3 100644
--- a/components/ephemeral_storage/ephemeral_storage_service.h
+++ b/components/ephemeral_storage/ephemeral_storage_service.h
@@ -90,6 +90,9 @@ class EphemeralStorageService : public KeyedService {
const GURL& url,
const content::StoragePartitionConfig& storage_partition_config,
const bool enforced_by_user);
+#if BUILDFLAG(IS_ANDROID)
+ void TriggerCurrentAppStateNotification();
+#endif // BUILDFLAG(IS_ANDROID)
private:
FRIEND_TEST_ALL_PREFIXES(EphemeralStorageServiceAutoShredForgetFirstPartyTest,