Commit 5cb4830a authored by Peter Kotwicz's avatar Peter Kotwicz Committed by Chromium LUCI CQ

Migrate first run dialog to viewpager2

The motivation for the migration is that FragmentStatePagerAdapter is
deprecated.

BUG=1162839

Change-Id: I600ef392633b9c75cf1b11a6e56a862a685f7c6f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2611949
Commit-Queue: Peter Kotwicz <pkotwicz@chromium.org>
Reviewed-by: default avatarSky Malice <skym@chromium.org>
Reviewed-by: default avatarWenyu Fu <wenyufu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#843402}
parent 50ba4848
......@@ -611,7 +611,6 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/firstrun/FirstRunStatus.java",
"java/src/org/chromium/chrome/browser/firstrun/FirstRunUtils.java",
"java/src/org/chromium/chrome/browser/firstrun/FirstRunView.java",
"java/src/org/chromium/chrome/browser/firstrun/FirstRunViewPager.java",
"java/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessor.java",
"java/src/org/chromium/chrome/browser/firstrun/FreIntentCreator.java",
"java/src/org/chromium/chrome/browser/firstrun/LightweightFirstRunActivity.java",
......
......@@ -1640,17 +1640,6 @@
column="9"/>
</issue>
<issue
id="ClickableViewAccessibility"
message="Custom view `FirstRunViewPager` overrides `onTouchEvent` but not `performClick`"
errorLine1=" public boolean onTouchEvent(MotionEvent event) {"
errorLine2=" ~~~~~~~~~~~~">
<location
file="../../chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunViewPager.java"
line="21"
column="20"/>
</issue>
<issue
id="ClickableViewAccessibility"
message="Custom view ``EditText`` has `setOnTouchListener` called on it but does not override `performClick`"
......
......@@ -14,6 +14,7 @@ import androidx.annotation.CallSuper;
import androidx.annotation.StringRes;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.widget.ViewPager2;
import org.chromium.base.ActivityState;
import org.chromium.base.ApplicationStatus;
......@@ -96,8 +97,6 @@ public class FirstRunActivity extends FirstRunActivityBase implements FirstRunPa
private Set<FirstRunFragment> mPagesToNotifyOfNativeInit;
private boolean mDeferredCompleteFRE;
private FirstRunViewPager mPager;
private FirstRunFlowSequencer mFirstRunFlowSequencer;
private Bundle mFreProperties;
......@@ -118,6 +117,8 @@ public class FirstRunActivity extends FirstRunActivityBase implements FirstRunPa
private final List<FirstRunPage> mPages = new ArrayList<>();
private final List<Integer> mFreProgressStates = new ArrayList<>();
private ViewPager2 mPager;
/**
* The pager adapter, which provides the pages to the view pager widget.
*/
......@@ -204,7 +205,11 @@ public class FirstRunActivity extends FirstRunActivityBase implements FirstRunPa
*/
@CallSuper
protected View createContentView() {
mPager = new FirstRunViewPager(this);
mPager = new ViewPager2(this);
// Disable swipe gesture.
mPager.setUserInputEnabled(false);
mPager.setId(R.id.fre_pager);
mPager.setOffscreenPageLimit(3);
return mPager;
......@@ -245,8 +250,7 @@ public class FirstRunActivity extends FirstRunActivityBase implements FirstRunPa
return;
}
mPagerAdapter = new FirstRunPagerAdapter(getSupportFragmentManager(), mPages);
stopProgressionIfNotAcceptedTermsOfService();
mPagerAdapter = new FirstRunPagerAdapter(FirstRunActivity.this, mPages);
mPager.setAdapter(mPagerAdapter);
if (areNativeAndPoliciesInitialized()) {
......@@ -369,7 +373,6 @@ public class FirstRunActivity extends FirstRunActivityBase implements FirstRunPa
@Override
public void onStart() {
super.onStart();
stopProgressionIfNotAcceptedTermsOfService();
}
@Override
......@@ -380,12 +383,6 @@ public class FirstRunActivity extends FirstRunActivityBase implements FirstRunPa
return;
}
Object currentItem = mPagerAdapter.instantiateItem(mPager, mPager.getCurrentItem());
if (currentItem instanceof FirstRunFragment) {
FirstRunFragment page = (FirstRunFragment) currentItem;
if (page.interceptBackPressed()) return;
}
if (mPager.getCurrentItem() == 0) {
abortFirstRunExperience();
} else {
......@@ -522,7 +519,6 @@ public class FirstRunActivity extends FirstRunActivityBase implements FirstRunPa
FirstRunUtils.acceptTermsOfService(allowCrashUpload);
FirstRunStatus.setSkipWelcomePage(true);
flushPersistentData();
stopProgressionIfNotAcceptedTermsOfService();
jumpToPage(mPager.getCurrentItem() + 1);
}
......@@ -557,7 +553,7 @@ public class FirstRunActivity extends FirstRunActivityBase implements FirstRunPa
}
private boolean setCurrentItemForPager(int position) {
if (position >= mPagerAdapter.getCount()) {
if (position >= mPagerAdapter.getItemCount()) {
completeFirstRunExperience();
return false;
}
......@@ -565,26 +561,14 @@ public class FirstRunActivity extends FirstRunActivityBase implements FirstRunPa
mPager.setCurrentItem(position, false);
// Set A11y focus if possible. See https://crbug.com/1094064 for more context.
// * Screen reader can lose focus when switching between pages with ViewPager;
// * FragmentPagerStateAdapter is trying to limit access for the real fragment that we are
// creating / created;
// * Note that despite the function name and javadoc,
// FragmentPagerStateAdapter#instantiateItem returns cached fragments when possible. This
// should always be the case here as ViewPager#setCurrentItem will trigger instantiation if
// needed. This function call to #instantiateItem is not creating new fragment here but
// rather reading the ones already created.
Object currentFragment = mPagerAdapter.instantiateItem(mPager, position);
if (currentFragment instanceof FirstRunFragment) {
((FirstRunFragment) currentFragment).setInitialA11yFocus();
// The screen reader can lose focus when switching between pages with ViewPager2.
FirstRunFragment currentFragment = mPagerAdapter.getFirstRunFragment(position);
if (currentFragment != null) {
currentFragment.setInitialA11yFocus();
}
return true;
}
private void stopProgressionIfNotAcceptedTermsOfService() {
if (mPagerAdapter == null) return;
mPagerAdapter.setStopAtTheFirstPage(!didAcceptTermsOfService());
}
private void skipPagesIfNecessary() {
if (mPagerAdapter == null) return;
......
......@@ -15,13 +15,6 @@ public interface FirstRunFragment {
*/
default void onNativeInitialized() {}
/**
* @return Whether the back button press was handled by this page.
*/
default boolean interceptBackPressed() {
return false;
}
/**
* @see Fragment#getActivity().
*/
......
......@@ -5,46 +5,53 @@
package org.chromium.chrome.browser.firstrun;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import java.util.ArrayList;
import java.util.List;
/**
* Adapter used to provide First Run pages to the FirstRunActivity ViewPager.
*/
class FirstRunPagerAdapter extends FragmentStatePagerAdapter {
class FirstRunPagerAdapter extends FragmentStateAdapter {
private final List<FirstRunPage> mPages;
private boolean mStopAtTheFirstPage;
private final List<FirstRunFragment> mFragments = new ArrayList<>();
public FirstRunPagerAdapter(FragmentManager fragmentManager, List<FirstRunPage> pages) {
super(fragmentManager);
public FirstRunPagerAdapter(FragmentActivity activity, List<FirstRunPage> pages) {
super(activity);
assert pages != null;
assert pages.size() > 0;
mPages = pages;
}
/**
* Controls progression beyond the first page.
* @param stop True if no progression beyond the first page is allowed.
* Returns the FirstRunFragment at the passed-in position. Returns null if the fragment has not
* yet been instantiated by RecyclerView.
*/
void setStopAtTheFirstPage(boolean stop) {
if (stop != mStopAtTheFirstPage) {
mStopAtTheFirstPage = stop;
notifyDataSetChanged();
}
public FirstRunFragment getFirstRunFragment(int position) {
return (position < mFragments.size()) ? mFragments.get(position) : null;
}
@Override
public Fragment getItem(int position) {
public Fragment createFragment(int position) {
assert position >= 0 && position < mPages.size();
return mPages.get(position).instantiateFragment();
Fragment fragment = mPages.get(position).instantiateFragment();
for (int i = mFragments.size(); i <= position; i++) {
mFragments.add(null);
}
// Caching fragment is OK because FirstRunActivity retains all of the fragments via
// ViewPager2#setOffscreenPageLimit(). See crbug.com/740897 for details.
mFragments.set(position, (FirstRunFragment) fragment);
return fragment;
}
@Override
public int getCount() {
if (mStopAtTheFirstPage) return 1;
public int getItemCount() {
return mPages.size();
}
}
// Copyright 2016 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.chrome.browser.firstrun;
import android.content.Context;
import android.view.MotionEvent;
import androidx.viewpager.widget.ViewPager;
/**
* ViewPager without swipe gesture.
*/
public class FirstRunViewPager extends ViewPager {
FirstRunViewPager(Context context) {
super(context);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return false;
}
}
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