9
9
10
10
import static org .chromium .ui .base .ViewUtils .dpToPx ;
11
11
12
- import android .Manifest ;
13
12
import android .animation .LayoutTransition ;
14
13
import android .content .Intent ;
15
- import android .os .Build ;
16
14
import android .os .Bundle ;
17
- import android .os .Handler ;
18
15
import android .os .RemoteException ;
19
16
import android .view .View ;
20
17
import android .view .ViewGroup ;
35
32
import com .android .installreferrer .api .InstallReferrerStateListener ;
36
33
import com .android .installreferrer .api .ReferrerDetails ;
37
34
38
- import org .chromium .base .BraveFeatureList ;
39
35
import org .chromium .base .BravePreferenceKeys ;
40
36
import org .chromium .base .Log ;
41
37
import org .chromium .base .ThreadUtils ;
42
38
import org .chromium .chrome .R ;
43
39
import org .chromium .chrome .browser .BraveLocalState ;
44
40
import org .chromium .chrome .browser .back_press .SecondaryActivityBackPressUma .SecondaryActivity ;
45
41
import org .chromium .chrome .browser .customtabs .CustomTabActivity ;
46
- import org .chromium .chrome .browser .flags .ChromeFeatureList ;
47
42
import org .chromium .chrome .browser .metrics .ChangeMetricsReportingStateCalledFrom ;
48
43
import org .chromium .chrome .browser .metrics .UmaSessionStats ;
49
44
import org .chromium .chrome .browser .onboarding .OnboardingPrefManager ;
60
55
import java .util .Locale ;
61
56
62
57
/**
63
- * This is on boarding activity
64
- * */
58
+ * Activity that handles the first run onboarding experience for new Brave browser installations.
59
+ * Extends FirstRunActivityBase to provide onboarding flows for: - Setting Brave as default browser
60
+ * - Configuring privacy and analytics preferences (P3A and crash reporting) - Accepting terms of
61
+ * service The activity guides users through a series of steps using animations and clear UI
62
+ * elements to explain Brave's key features and privacy-focused approach.
63
+ */
65
64
public class WelcomeOnboardingActivity extends FirstRunActivityBase {
66
- // mInitializeViewsDone and mInvokePostWorkAtInitializeViews are accessed
67
- // from the same thread, so no need to use extra locks
68
65
private static final String P3A_URL =
69
66
"https://support.brave.com/hc/en-us/articles/9140465918093-What-is-P3A-in-Brave" ;
70
67
71
68
private static final String TAG = "WelcomeOnboarding" ;
72
69
70
+ // mInitializeViewsDone and mInvokePostWorkAtInitializeViews are accessed
71
+ // from the same thread, so no need to use extra locks
73
72
private boolean mInitializeViewsDone ;
74
73
private boolean mInvokePostWorkAtInitializeViews ;
74
+
75
75
private boolean mIsTablet ;
76
76
private BraveFirstRunFlowSequencer mFirstRunFlowSequencer ;
77
77
private int mCurrentStep = -1 ;
@@ -83,29 +83,37 @@ public class WelcomeOnboardingActivity extends FirstRunActivityBase {
83
83
private ImageView mIvBrave ;
84
84
private ImageView mIvArrowDown ;
85
85
private LinearLayout mLayoutCard ;
86
- private TextView mTvWelcome ;
87
86
private TextView mTvCard ;
88
87
private TextView mTvDefault ;
89
88
private Button mBtnPositive ;
90
89
private Button mBtnNegative ;
91
90
private CheckBox mCheckboxCrash ;
92
91
private CheckBox mCheckboxP3a ;
93
92
93
+ /**
94
+ * Initializes the views and sets up the onboarding activity UI. This method handles the initial
95
+ * setup of the welcome onboarding screen, including loading the layout, initializing views and
96
+ * click listeners, and performing first-run setup tasks.
97
+ */
94
98
private void initializeViews () {
95
99
assert !mInitializeViewsDone ;
100
+
96
101
setContentView (R .layout .activity_welcome_onboarding );
97
102
98
103
mIsTablet = DeviceFormFactor .isNonMultiDisplayContextOnTablet (this );
99
104
100
105
initViews ();
106
+
101
107
onClickViews ();
102
108
103
109
mInitializeViewsDone = true ;
110
+
104
111
if (mInvokePostWorkAtInitializeViews ) {
105
112
finishNativeInitializationPostWork ();
106
113
}
107
114
108
115
checkReferral ();
116
+
109
117
maybeUpdateFirstRunDefaultValues ();
110
118
}
111
119
@@ -166,7 +174,6 @@ private void initViews() {
166
174
mIvBrave = findViewById (R .id .iv_brave );
167
175
mIvArrowDown = findViewById (R .id .iv_arrow_down );
168
176
mLayoutCard = findViewById (R .id .layout_card );
169
- mTvWelcome = findViewById (R .id .tv_welcome );
170
177
mTvCard = findViewById (R .id .tv_card );
171
178
mTvDefault = findViewById (R .id .tv_default );
172
179
mCheckboxCrash = findViewById (R .id .checkbox_crash );
@@ -211,7 +218,7 @@ private void onClickViews() {
211
218
if (mBtnPositive != null ) {
212
219
mBtnPositive .setOnClickListener (
213
220
view -> {
214
- if (mCurrentStep == 1 && !isDefaultBrowser ()) {
221
+ if (mCurrentStep == 0 && !isDefaultBrowser ()) {
215
222
setDefaultBrowserAndProceedToNextStep ();
216
223
} else {
217
224
nextOnboardingStep ();
@@ -232,11 +239,7 @@ private void onClickViews() {
232
239
}
233
240
234
241
private boolean shouldForceDefaultBrowserPrompt () {
235
- return isNewOnboardingEnabled () && !isDefaultBrowser ();
236
- }
237
-
238
- private boolean isNewOnboardingEnabled () {
239
- return ChromeFeatureList .isEnabled (BraveFeatureList .BRAVE_NEW_ANDROID_ONBOARDING );
242
+ return !isDefaultBrowser ();
240
243
}
241
244
242
245
private void setDefaultBrowserAndProceedToNextStep () {
@@ -251,82 +254,46 @@ private boolean isDefaultBrowser() {
251
254
return BraveSetDefaultBrowserUtils .isBraveSetAsDefaultBrowser (this );
252
255
}
253
256
254
- private void startTimer ( int delayMillis ) {
255
- new Handler (). postDelayed ( this :: nextOnboardingStep , delayMillis );
256
- }
257
-
258
- ActivityResultLauncher < String > mRequestPermissionLauncher = registerForActivityResult (
259
- new ActivityResultContracts . RequestPermission (), isGranted -> { startTimer ( 3000 ); });
257
+ ActivityResultLauncher < String > mRequestPermissionLauncher =
258
+ registerForActivityResult (
259
+ new ActivityResultContracts . RequestPermission (),
260
+ isGranted -> {
261
+ nextOnboardingStep ();
262
+ });
260
263
261
264
private void nextOnboardingStep () {
262
265
if (isActivityFinishingOrDestroyed ()) return ;
263
266
264
267
mCurrentStep ++;
265
268
if (mCurrentStep == 0 ) {
266
- showIntroPage ();
267
- } else if (mCurrentStep == 1 ) {
268
- if (!isNewOnboardingEnabled ()
269
- || !BraveSetDefaultBrowserUtils .supportsDefaultRoleManager ()) {
269
+ if (!BraveSetDefaultBrowserUtils .supportsDefaultRoleManager ()) {
270
+ mIvBrave .setVisibility (View .VISIBLE );
270
271
showBrowserSelectionPage ();
271
272
} else if (!isDefaultBrowser ()) {
272
273
setDefaultBrowserAndProceedToNextStep ();
273
274
} else {
274
275
nextOnboardingStep ();
275
276
}
276
277
} else if (mCurrentStep == getAnalyticsConsentPageStep ()) {
278
+ mIvBrave .setVisibility (View .VISIBLE );
277
279
showAnalyticsConsentPage ();
278
280
} else {
279
281
OnboardingPrefManager .getInstance ().setP3aOnboardingShown (true );
280
282
OnboardingPrefManager .getInstance ().setOnboardingSearchBoxTooltip (true );
283
+
281
284
FirstRunStatus .setFirstRunFlowComplete (true );
285
+
282
286
ChromeSharedPreferences .getInstance ()
283
287
.writeBoolean (ChromePreferenceKeys .FIRST_RUN_CACHED_TOS_ACCEPTED , true );
284
288
FirstRunUtils .setEulaAccepted ();
289
+
285
290
finish ();
286
291
sendFirstRunCompletePendingIntent ();
287
292
}
288
293
}
289
294
290
295
private int getAnalyticsConsentPageStep () {
291
- return 2 ;
292
- }
293
-
294
- private void showIntroPage () {
295
- int margin = mIsTablet ? 100 : 0 ;
296
- setLeafAnimation (mVLeafAlignTop , mIvLeafTop , 1f , margin , true );
297
- setLeafAnimation (mVLeafAlignBottom , mIvLeafBottom , 1f , margin , false );
298
- if (mTvWelcome != null ) {
299
- mTvWelcome
300
- .animate ()
301
- .alpha (1f )
302
- .setDuration (200 )
303
- .withEndAction (() -> mTvWelcome .setVisibility (View .VISIBLE ));
304
- }
305
- if (mIvBrave != null ) {
306
- mIvBrave .animate ().scaleX (0.8f ).scaleY (0.8f ).setDuration (1000 );
307
- }
308
- new Handler ()
309
- .postDelayed (
310
- new Runnable () {
311
- @ Override
312
- public void run () {
313
- if (mTvWelcome != null ) {
314
- mTvWelcome
315
- .animate ()
316
- .translationYBy (
317
- -dpToPx (WelcomeOnboardingActivity .this , 20 ))
318
- .setDuration (3000 )
319
- .start ();
320
- }
321
- }
322
- },
323
- 200 );
324
-
325
- if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .TIRAMISU && !isNewOnboardingEnabled ()) {
326
- mRequestPermissionLauncher .launch (Manifest .permission .POST_NOTIFICATIONS );
327
- } else {
328
- startTimer (3000 );
329
- }
296
+ return 1 ;
330
297
}
331
298
332
299
private void showBrowserSelectionPage () {
@@ -342,9 +309,6 @@ private void showBrowserSelectionPage() {
342
309
mBtnNegative .setVisibility (View .GONE );
343
310
}
344
311
}
345
- if (mTvWelcome != null ) {
346
- mTvWelcome .setVisibility (View .GONE );
347
- }
348
312
if (mLayoutCard != null ) {
349
313
mLayoutCard .setVisibility (View .VISIBLE );
350
314
}
@@ -388,24 +352,30 @@ private void showAnalyticsConsentPage() {
388
352
mBtnNegative .setVisibility (View .VISIBLE );
389
353
}
390
354
355
+ // Handle crash reporting consent based on installation status
391
356
if (PackageUtils .isFirstInstall (this )
392
357
&& !OnboardingPrefManager .getInstance ().isP3aCrashReportingMessageShown ()) {
358
+ // For first time installs, enable crash reporting by default
393
359
if (mCheckboxCrash != null ) {
394
360
mCheckboxCrash .setChecked (true );
395
361
}
362
+ // Update metrics reporting consent
396
363
UmaSessionStats .changeMetricsReportingConsent (
397
364
true , ChangeMetricsReportingStateCalledFrom .UI_FIRST_RUN );
365
+ // Mark crash reporting message as shown
398
366
OnboardingPrefManager .getInstance ().setP3aCrashReportingMessageShown (true );
399
367
} else {
368
+ // For existing installations, restore previous crash reporting preference
400
369
boolean isCrashReporting = false ;
401
370
try {
371
+ // Get current crash reporting permission status
402
372
isCrashReporting =
403
373
PrivacyPreferencesManagerImpl .getInstance ()
404
374
.isUsageAndCrashReportingPermittedByUser ();
405
-
406
375
} catch (Exception e ) {
407
376
Log .e (TAG , "isCrashReportingOnboarding: " + e .getMessage ());
408
377
}
378
+ // Update checkbox to match current preference
409
379
if (mCheckboxCrash != null ) {
410
380
mCheckboxCrash .setChecked (isCrashReporting );
411
381
}
@@ -525,7 +495,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
525
495
526
496
private void finishNativeInitializationPostWork () {
527
497
assert mInitializeViewsDone ;
528
- startTimer ( 1000 );
498
+ nextOnboardingStep ( );
529
499
}
530
500
531
501
@ Override
0 commit comments