• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.adservices.ui.settings.delegates;
17 
18 import android.content.Intent;
19 import android.os.Build;
20 import android.text.method.LinkMovementMethod;
21 import android.util.Pair;
22 import android.view.View;
23 import android.widget.TextView;
24 
25 import androidx.annotation.RequiresApi;
26 import androidx.lifecycle.Observer;
27 
28 import com.android.adservices.api.R;
29 import com.android.adservices.data.topics.Topic;
30 import com.android.adservices.service.FlagsFactory;
31 import com.android.adservices.service.stats.UiStatsLogger;
32 import com.android.adservices.ui.settings.DialogFragmentManager;
33 import com.android.adservices.ui.settings.DialogManager;
34 import com.android.adservices.ui.settings.activities.BlockedTopicsActivity;
35 import com.android.adservices.ui.settings.activities.TopicsActivity;
36 import com.android.adservices.ui.settings.fragments.AdServicesSettingsTopicsFragment;
37 import com.android.adservices.ui.settings.viewmodels.TopicsViewModel;
38 import com.android.adservices.ui.settings.viewmodels.TopicsViewModel.TopicsViewModelUiEvent;
39 import com.android.settingslib.widget.MainSwitchBar;
40 
41 /**
42  * Delegate class that helps AdServices Settings fragments to respond to all view model/user events.
43  */
44 // TODO(b/269798827): Enable for R.
45 @RequiresApi(Build.VERSION_CODES.S)
46 public class TopicsActionDelegate {
47     private final TopicsActivity mTopicsActivity;
48     private final TopicsViewModel mTopicsViewModel;
49 
TopicsActionDelegate(TopicsActivity topicsActivity, TopicsViewModel topicsViewModel)50     public TopicsActionDelegate(TopicsActivity topicsActivity, TopicsViewModel topicsViewModel) {
51         mTopicsActivity = topicsActivity;
52         mTopicsViewModel = topicsViewModel;
53         listenToTopicsViewModelUiEvents();
54     }
55 
listenToTopicsViewModelUiEvents()56     private void listenToTopicsViewModelUiEvents() {
57         Observer<Pair<TopicsViewModelUiEvent, Topic>> observer =
58                 eventTopicPair -> {
59                     if (eventTopicPair == null) {
60                         return;
61                     }
62                     TopicsViewModelUiEvent event = eventTopicPair.first;
63                     Topic topic = eventTopicPair.second;
64                     if (event == null) {
65                         return;
66                     }
67                     try {
68                         switch (event) {
69                             case SWITCH_ON_TOPICS:
70                                 mTopicsViewModel.setTopicsConsent(true);
71                                 mTopicsViewModel.refresh();
72                                 break;
73                             case SWITCH_OFF_TOPICS:
74                                 mTopicsViewModel.setTopicsConsent(false);
75                                 mTopicsViewModel.refresh();
76                                 break;
77                             case BLOCK_TOPIC:
78                                 UiStatsLogger.logBlockTopicSelected(mTopicsActivity);
79                                 if (FlagsFactory.getFlags().getUIDialogsFeatureEnabled()) {
80                                     if (FlagsFactory.getFlags().getUiDialogFragmentEnabled()) {
81                                         DialogFragmentManager.showBlockTopicDialog(
82                                                 mTopicsActivity, mTopicsViewModel, topic);
83                                     } else {
84                                         DialogManager.showBlockTopicDialog(
85                                                 mTopicsActivity, mTopicsViewModel, topic);
86                                     }
87                                 } else {
88                                     mTopicsViewModel.revokeTopicConsent(topic);
89                                 }
90                                 break;
91                             case RESET_TOPICS:
92                                 UiStatsLogger.logResetTopicSelected(mTopicsActivity);
93                                 if (FlagsFactory.getFlags().getUIDialogsFeatureEnabled()) {
94                                     if (FlagsFactory.getFlags().getUiDialogFragmentEnabled()) {
95                                         DialogFragmentManager.showResetTopicDialog(
96                                                 mTopicsActivity, mTopicsViewModel);
97                                     } else {
98                                         DialogManager.showResetTopicDialog(
99                                                 mTopicsActivity, mTopicsViewModel);
100                                     }
101                                 } else {
102                                     mTopicsViewModel.resetTopics();
103                                 }
104                                 break;
105                             case DISPLAY_BLOCKED_TOPICS_FRAGMENT:
106                                 Intent intent =
107                                         new Intent(mTopicsActivity, BlockedTopicsActivity.class);
108                                 mTopicsActivity.startActivity(intent);
109                                 break;
110                         }
111                     } finally {
112                         mTopicsViewModel.uiEventHandled();
113                     }
114                 };
115         mTopicsViewModel.getUiEvents().observe(mTopicsActivity, observer);
116     }
117 
118     /**
119      * Configure all UI elements (except topics list) in {@link AdServicesSettingsTopicsFragment} to
120      * handle user actions.
121      */
initTopicsFragment(AdServicesSettingsTopicsFragment fragment)122     public void initTopicsFragment(AdServicesSettingsTopicsFragment fragment) {
123         if (FlagsFactory.getFlags().getGaUxFeatureEnabled()) {
124             mTopicsActivity.setTitle(R.string.settingsUI_topics_ga_title);
125 
126             configureTopicsConsentSwitch(fragment);
127 
128             setGaUxLayoutVisibilities(View.VISIBLE);
129             setBetaLayoutVisibilities(View.GONE);
130             setGaUxTopicsViewText();
131         } else {
132             mTopicsActivity.setTitle(R.string.settingsUI_topics_view_title);
133 
134             setGaUxLayoutVisibilities(View.GONE);
135             setBetaLayoutVisibilities(View.VISIBLE);
136             setBetaTopicsViewText();
137         }
138         configureBlockedTopicsFragmentButton(fragment);
139         configureResetTopicsButton(fragment);
140     }
141 
setGaUxTopicsViewText()142     private void setGaUxTopicsViewText() {
143         ((TextView) mTopicsActivity.findViewById(R.id.blocked_topics_button_child))
144                 .setText(R.string.settingsUI_blocked_topics_ga_title);
145         ((TextView) mTopicsActivity.findViewById(R.id.reset_topics_button_child))
146                 .setText(R.string.settingsUI_reset_topics_ga_title);
147         ((TextView) mTopicsActivity.findViewById(R.id.no_topics_state))
148                 .setText(R.string.settingsUI_topics_view_no_topics_ga_text);
149         ((TextView) mTopicsActivity.findViewById(R.id.no_topics_state))
150                 .setMovementMethod(LinkMovementMethod.getInstance());
151     }
152 
setBetaTopicsViewText()153     private void setBetaTopicsViewText() {
154         ((TextView) mTopicsActivity.findViewById(R.id.blocked_topics_button_child))
155                 .setText(R.string.settingsUI_blocked_topics_title);
156         ((TextView) mTopicsActivity.findViewById(R.id.reset_topics_button_child))
157                 .setText(R.string.settingsUI_reset_topics_title);
158         ((TextView) mTopicsActivity.findViewById(R.id.no_topics_state))
159                 .setText(R.string.settingsUI_topics_view_no_topics_text);
160     }
161 
setBetaLayoutVisibilities(int visibility)162     private void setBetaLayoutVisibilities(int visibility) {
163         mTopicsActivity.findViewById(R.id.topics_introduction).setVisibility(visibility);
164         mTopicsActivity.findViewById(R.id.topics_view_footer).setVisibility(visibility);
165     }
166 
setGaUxLayoutVisibilities(int visibility)167     private void setGaUxLayoutVisibilities(int visibility) {
168         mTopicsActivity.findViewById(R.id.topics_ga_introduction).setVisibility(visibility);
169         mTopicsActivity.findViewById(R.id.topics_view_ga_footer).setVisibility(visibility);
170     }
171 
configureTopicsConsentSwitch(AdServicesSettingsTopicsFragment fragment)172     private void configureTopicsConsentSwitch(AdServicesSettingsTopicsFragment fragment) {
173         MainSwitchBar topicsSwitchBar = mTopicsActivity.findViewById(R.id.topics_switch_bar);
174         topicsSwitchBar.setVisibility(View.VISIBLE);
175 
176         mTopicsViewModel.getTopicsConsent().observe(fragment, topicsSwitchBar::setChecked);
177         topicsSwitchBar.setOnClickListener(
178                 switchBar -> mTopicsViewModel.consentSwitchClickHandler((MainSwitchBar) switchBar));
179     }
180 
configureBlockedTopicsFragmentButton(AdServicesSettingsTopicsFragment fragment)181     private void configureBlockedTopicsFragmentButton(AdServicesSettingsTopicsFragment fragment) {
182         View blockedTopicsButton = fragment.requireView().findViewById(R.id.blocked_topics_button);
183         View blockedTopicsWhenEmptyListButton =
184                 fragment.requireView().findViewById(R.id.blocked_topics_when_empty_state_button);
185         blockedTopicsButton.setOnClickListener(
186                 view -> mTopicsViewModel.blockedTopicsFragmentButtonClickHandler());
187         blockedTopicsWhenEmptyListButton.setOnClickListener(
188                 view -> mTopicsViewModel.blockedTopicsFragmentButtonClickHandler());
189     }
190 
configureResetTopicsButton(AdServicesSettingsTopicsFragment fragment)191     private void configureResetTopicsButton(AdServicesSettingsTopicsFragment fragment) {
192         View resetTopicsButton = fragment.requireView().findViewById(R.id.reset_topics_button);
193         resetTopicsButton.setOnClickListener(
194                 view -> mTopicsViewModel.resetTopicsButtonClickHandler());
195     }
196 }
197