77import android .net .Uri ;
88import android .os .Parcel ;
99import android .os .Parcelable ;
10+ import android .util .Log ;
1011
1112import androidx .annotation .ColorRes ;
1213import androidx .annotation .NonNull ;
1314import androidx .annotation .Nullable ;
1415import androidx .browser .customtabs .CustomTabColorSchemeParams ;
16+ import androidx .browser .customtabs .CustomTabsClient ;
1517import androidx .browser .customtabs .CustomTabsIntent ;
1618import androidx .browser .customtabs .CustomTabsSession ;
1719import androidx .browser .trusted .TrustedWebActivityIntentBuilder ;
1820import androidx .core .content .ContextCompat ;
1921
22+ import com .auth0 .android .annotation .ExperimentalAuth0Api ;
2023import com .auth0 .android .authentication .AuthenticationException ;
2124
2225import java .util .List ;
2629 */
2730public class CustomTabsOptions implements Parcelable {
2831
32+ private static final String TAG = "CustomTabsOptions" ;
33+
2934 private final boolean showTitle ;
3035 @ ColorRes
3136 private final int toolbarColor ;
@@ -34,11 +39,14 @@ public class CustomTabsOptions implements Parcelable {
3439 @ Nullable
3540 private final List <String > disabledCustomTabsPackages ;
3641
37- private CustomTabsOptions (boolean showTitle , @ ColorRes int toolbarColor , @ NonNull BrowserPicker browserPicker , @ Nullable List <String > disabledCustomTabsPackages ) {
42+ private final boolean ephemeralBrowsing ;
43+
44+ private CustomTabsOptions (boolean showTitle , @ ColorRes int toolbarColor , @ NonNull BrowserPicker browserPicker , @ Nullable List <String > disabledCustomTabsPackages , boolean ephemeralBrowsing ) {
3845 this .showTitle = showTitle ;
3946 this .toolbarColor = toolbarColor ;
4047 this .browserPicker = browserPicker ;
4148 this .disabledCustomTabsPackages = disabledCustomTabsPackages ;
49+ this .ephemeralBrowsing = ephemeralBrowsing ;
4250 }
4351
4452 @ Nullable
@@ -60,6 +68,12 @@ boolean isDisabledCustomTabBrowser(@NonNull String preferredPackage) {
6068 return disabledCustomTabsPackages != null && disabledCustomTabsPackages .contains (preferredPackage );
6169 }
6270
71+ @ NonNull
72+ CustomTabsOptions copyWithEphemeralBrowsing () {
73+ return new CustomTabsOptions (showTitle , toolbarColor , browserPicker ,
74+ disabledCustomTabsPackages , true );
75+ }
76+
6377 /**
6478 * Create a new CustomTabsOptions.Builder instance.
6579 *
@@ -82,6 +96,18 @@ Intent toIntent(@NonNull Context context, @Nullable CustomTabsSession session) {
8296 final CustomTabsIntent .Builder builder = new CustomTabsIntent .Builder (session )
8397 .setShowTitle (showTitle )
8498 .setShareState (CustomTabsIntent .SHARE_STATE_OFF );
99+
100+ if (ephemeralBrowsing ) {
101+ if (preferredPackage != null
102+ && CustomTabsClient .isEphemeralBrowsingSupported (context , preferredPackage )) {
103+ builder .setEphemeralBrowsingEnabled (true );
104+ } else {
105+ Log .w (TAG , "Ephemeral browsing was requested but is not supported by the "
106+ + "current browser (" + preferredPackage + "). "
107+ + "Falling back to a regular Custom Tab." );
108+ }
109+ }
110+
85111 if (toolbarColor > 0 ) {
86112 //Resource exists
87113 final CustomTabColorSchemeParams .Builder colorBuilder = new CustomTabColorSchemeParams .Builder ()
@@ -108,6 +134,7 @@ protected CustomTabsOptions(@NonNull Parcel in) {
108134 toolbarColor = in .readInt ();
109135 browserPicker = in .readParcelable (BrowserPicker .class .getClassLoader ());
110136 disabledCustomTabsPackages = in .createStringArrayList ();
137+ ephemeralBrowsing = in .readByte () != 0 ;
111138 }
112139
113140 @ Override
@@ -116,6 +143,7 @@ public void writeToParcel(@NonNull Parcel dest, int flags) {
116143 dest .writeInt (toolbarColor );
117144 dest .writeParcelable (browserPicker , flags );
118145 dest .writeStringList (disabledCustomTabsPackages );
146+ dest .writeByte ((byte ) (ephemeralBrowsing ? 1 : 0 ));
119147 }
120148
121149 @ Override
@@ -147,11 +175,14 @@ public static class Builder {
147175 @ Nullable
148176 private List <String > disabledCustomTabsPackages ;
149177
178+ private boolean ephemeralBrowsing ;
179+
150180 Builder () {
151181 this .showTitle = false ;
152182 this .toolbarColor = 0 ;
153183 this .browserPicker = BrowserPicker .newBuilder ().build ();
154184 this .disabledCustomTabsPackages = null ;
185+ this .ephemeralBrowsing = false ;
155186 }
156187
157188 /**
@@ -212,14 +243,35 @@ public Builder withDisabledCustomTabsPackages(List<String> disabledCustomTabsPac
212243 return this ;
213244 }
214245
246+ /**
247+ * Enable ephemeral browsing for the Custom Tab.
248+ * When enabled, the Custom Tab runs in an isolated session — cookies, cache,
249+ * history, and credentials are deleted when the tab closes.
250+ * Requires Chrome 136+ or a compatible browser. On unsupported browsers,
251+ * a warning is logged and a regular Custom Tab is used instead.
252+ * By default, ephemeral browsing is disabled.
253+ *
254+ * <p><b>Warning:</b> Ephemeral browsing support in Auth0.Android is still experimental
255+ * and can change in the future. Please test it thoroughly in all the targeted browsers
256+ * and OS variants and let us know your feedback.</p>
257+ *
258+ * @return this same builder instance.
259+ */
260+ @ ExperimentalAuth0Api
261+ @ NonNull
262+ public Builder withEphemeralBrowsing () {
263+ this .ephemeralBrowsing = true ;
264+ return this ;
265+ }
266+
215267 /**
216268 * Create a new CustomTabsOptions instance with the customization settings.
217269 *
218270 * @return an instance of CustomTabsOptions with the customization settings.
219271 */
220272 @ NonNull
221273 public CustomTabsOptions build () {
222- return new CustomTabsOptions (showTitle , toolbarColor , browserPicker , disabledCustomTabsPackages );
274+ return new CustomTabsOptions (showTitle , toolbarColor , browserPicker , disabledCustomTabsPackages , ephemeralBrowsing );
223275 }
224276 }
225277
0 commit comments