diff options
Diffstat (limited to 'adservices/apk/java/com/android/adservices/ui/notifications/ConsentNotificationFragment.java')
-rw-r--r-- | adservices/apk/java/com/android/adservices/ui/notifications/ConsentNotificationFragment.java | 162 |
1 files changed, 128 insertions, 34 deletions
diff --git a/adservices/apk/java/com/android/adservices/ui/notifications/ConsentNotificationFragment.java b/adservices/apk/java/com/android/adservices/ui/notifications/ConsentNotificationFragment.java index e943afdb54..be43dc5daa 100644 --- a/adservices/apk/java/com/android/adservices/ui/notifications/ConsentNotificationFragment.java +++ b/adservices/apk/java/com/android/adservices/ui/notifications/ConsentNotificationFragment.java @@ -20,27 +20,34 @@ import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICE import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_SETTINGS_USAGE_REPORTED__REGION__EU; import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_SETTINGS_USAGE_REPORTED__REGION__ROW; import static com.android.adservices.ui.notifications.ConsentNotificationConfirmationFragment.IS_CONSENT_GIVEN_ARGUMENT_KEY; +import static com.android.adservices.ui.settings.activities.AdServicesSettingsMainActivity.FROM_NOTIFICATION_KEY; +import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; +import android.view.View.OnScrollChangeListener; import android.view.ViewGroup; import android.widget.Button; +import android.widget.ScrollView; import android.widget.TextView; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import com.android.adservices.api.R; import com.android.adservices.service.consent.ConsentManager; import com.android.adservices.service.stats.AdServicesLoggerImpl; import com.android.adservices.service.stats.UIStats; -import com.android.adservices.ui.settings.AdServicesSettingsActivity; +import com.android.adservices.ui.settings.activities.AdServicesSettingsMainActivity; /** Fragment for the topics view of the AdServices Settings App. */ public class ConsentNotificationFragment extends Fragment { public static final String IS_EU_DEVICE_ARGUMENT_KEY = "isEUDevice"; + private boolean mIsEUDevice; + private @Nullable ScrollToBottomController mScrollToBottomController; @Override public View onCreateView( @@ -50,22 +57,23 @@ public class ConsentNotificationFragment extends Fragment { @Override public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { - boolean isEUDevice = + mIsEUDevice = requireActivity().getIntent().getBooleanExtra(IS_EU_DEVICE_ARGUMENT_KEY, true); - logLandingPageDisplayed(isEUDevice); - setupListeners(isEUDevice); + logLandingPageDisplayed(); + setupListeners(savedInstanceState); } - private void logLandingPageDisplayed(boolean isEUDevice) { - UIStats uiStats = new UIStats.Builder() - .setCode(AD_SERVICES_SETTINGS_USAGE_REPORTED) - .setRegion( - isEUDevice - ? AD_SERVICES_SETTINGS_USAGE_REPORTED__REGION__EU - : AD_SERVICES_SETTINGS_USAGE_REPORTED__REGION__ROW) - .setAction( - AD_SERVICES_SETTINGS_USAGE_REPORTED__ACTION__LANDING_PAGE_DISPLAYED) - .build(); + private void logLandingPageDisplayed() { + UIStats uiStats = + new UIStats.Builder() + .setCode(AD_SERVICES_SETTINGS_USAGE_REPORTED) + .setRegion( + mIsEUDevice + ? AD_SERVICES_SETTINGS_USAGE_REPORTED__REGION__EU + : AD_SERVICES_SETTINGS_USAGE_REPORTED__REGION__ROW) + .setAction( + AD_SERVICES_SETTINGS_USAGE_REPORTED__ACTION__LANDING_PAGE_DISPLAYED) + .build(); AdServicesLoggerImpl.getInstance().logUIStats(uiStats); } @@ -82,7 +90,7 @@ public class ConsentNotificationFragment extends Fragment { return rootView; } - private void setupListeners(boolean isEUDevice) { + private void setupListeners(Bundle savedInstanceState) { TextView howItWorksExpander = requireActivity().findViewById(R.id.how_it_works_expander); howItWorksExpander.setOnClickListener( view -> { @@ -101,37 +109,29 @@ public class ConsentNotificationFragment extends Fragment { Button leftControlButton = requireActivity().findViewById(R.id.leftControlButton); leftControlButton.setOnClickListener( view -> { - if (isEUDevice) { + if (mIsEUDevice) { // opt-out confirmation activity - ConsentManager.getInstance(requireContext()) - .disable(requireContext()); + ConsentManager.getInstance(requireContext()).disable(requireContext()); Bundle args = new Bundle(); args.putBoolean(IS_CONSENT_GIVEN_ARGUMENT_KEY, false); startConfirmationFragment(args); } else { // go to settings activity Intent intent = - new Intent(requireActivity(), AdServicesSettingsActivity.class); - intent.addFlags( - Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + new Intent(requireActivity(), AdServicesSettingsMainActivity.class); + intent.putExtra(FROM_NOTIFICATION_KEY, true); startActivity(intent); + requireActivity().finish(); } }); Button rightControlButton = requireActivity().findViewById(R.id.rightControlButton); - rightControlButton.setOnClickListener( - view -> { - if (isEUDevice) { - // opt-in confirmation activity - ConsentManager.getInstance(requireContext()).enable(requireContext()); - Bundle args = new Bundle(); - args.putBoolean(IS_CONSENT_GIVEN_ARGUMENT_KEY, true); - startConfirmationFragment(args); - } else { - // acknowledge and dismiss - requireActivity().finish(); - } - }); + ScrollView scrollView = requireView().findViewById(R.id.notification_fragment_scrollview); + + mScrollToBottomController = + new ScrollToBottomController( + scrollView, leftControlButton, rightControlButton, savedInstanceState); + mScrollToBottomController.bind(); } private void startConfirmationFragment(Bundle args) { @@ -142,7 +142,101 @@ public class ConsentNotificationFragment extends Fragment { R.id.fragment_container_view, ConsentNotificationConfirmationFragment.class, args) + .setReorderingAllowed(true) .addToBackStack(null) .commit(); } + + /** + * Allows the positive, acceptance button to scroll the view. + * + * <p>When the positive button first appears it will show the text "More". When the user taps + * the button, the view will scroll to the bottom. Once the view has scrolled to the bottom, the + * button text will be replaced with the acceptance text. Once the text has changed, the button + * will trigger the positive action no matter where the view is scrolled. + */ + private class ScrollToBottomController implements OnScrollChangeListener { + private static final String STATE_HAS_SCROLLED_TO_BOTTOM = "has_scrolled_to_bottom"; + private static final int SCROLL_DIRECTION_DOWN = 1; + private static final double SCROLL_MULTIPLIER = 0.8; + + private final ScrollView mScrollContainer; + private final Button mLeftControlButton; + private final Button mRightControlButton; + + private boolean mHasScrolledToBottom; + + ScrollToBottomController( + ScrollView scrollContainer, + Button leftControlButton, + Button rightControlButton, + @Nullable Bundle savedInstanceState) { + this.mScrollContainer = scrollContainer; + this.mLeftControlButton = leftControlButton; + this.mRightControlButton = rightControlButton; + mHasScrolledToBottom = + savedInstanceState != null + && savedInstanceState.containsKey(STATE_HAS_SCROLLED_TO_BOTTOM) + && savedInstanceState.getBoolean(STATE_HAS_SCROLLED_TO_BOTTOM); + } + + public void bind() { + mScrollContainer.setOnScrollChangeListener(this); + mRightControlButton.setOnClickListener(this::onMoreOrAcceptClicked); + updateControlButtons(); + } + + public void saveInstanceState(Bundle bundle) { + if (mHasScrolledToBottom) { + bundle.putBoolean(STATE_HAS_SCROLLED_TO_BOTTOM, true); + } + } + + private void updateControlButtons() { + if (mHasScrolledToBottom) { + mLeftControlButton.setVisibility(View.VISIBLE); + mRightControlButton.setText( + mIsEUDevice + ? R.string.notificationUI_right_control_button_text_eu + : R.string.notificationUI_right_control_button_text); + } else { + mLeftControlButton.setVisibility(View.INVISIBLE); + mRightControlButton.setText(R.string.notificationUI_more_button_text); + } + } + + private void onMoreOrAcceptClicked(View view) { + Context context = getContext(); + if (context == null) { + return; + } + + if (mHasScrolledToBottom) { + if (mIsEUDevice) { + // opt-in confirmation activity + ConsentManager.getInstance(requireContext()).enable(requireContext()); + Bundle args = new Bundle(); + args.putBoolean(IS_CONSENT_GIVEN_ARGUMENT_KEY, true); + startConfirmationFragment(args); + } else { + // acknowledge and dismiss + requireActivity().finish(); + } + } else { + mScrollContainer.smoothScrollTo( + 0, + mScrollContainer.getScrollY() + + (int) (mScrollContainer.getHeight() * SCROLL_MULTIPLIER)); + } + } + + @Override + public void onScrollChange( + View view, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { + if (!mScrollContainer.canScrollVertically(SCROLL_DIRECTION_DOWN)) { + mHasScrolledToBottom = true; + updateControlButtons(); + } + } + } } |