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.os.Build;
19 import android.text.method.LinkMovementMethod;
20 import android.view.View;
21 import android.widget.Switch;
22 import android.widget.TextView;
23 import android.widget.Toast;
24 
25 import androidx.annotation.RequiresApi;
26 import androidx.lifecycle.Observer;
27 
28 import com.android.adservices.api.R;
29 import com.android.adservices.service.FlagsFactory;
30 import com.android.adservices.service.stats.UiStatsLogger;
31 import com.android.adservices.ui.settings.DialogFragmentManager;
32 import com.android.adservices.ui.settings.activities.MeasurementActivity;
33 import com.android.adservices.ui.settings.fragments.AdServicesSettingsMeasurementFragment;
34 import com.android.adservices.ui.settings.viewmodels.MeasurementViewModel;
35 import com.android.adservices.ui.settings.viewmodels.MeasurementViewModel.MeasurementViewModelUiEvent;
36 import com.android.modules.utils.build.SdkLevel;
37 import com.android.settingslib.widget.MainSwitchBar;
38 
39 /**
40  * Delegate class that helps AdServices Settings fragments to respond to all view model/user events.
41  */
42 // TODO(b/269798827): Enable for R.
43 @RequiresApi(Build.VERSION_CODES.S)
44 public class MeasurementActionDelegate {
45     private final MeasurementActivity mMeasurementActivity;
46     private final MeasurementViewModel mMeasurementViewModel;
47 
MeasurementActionDelegate( MeasurementActivity measurementActivity, MeasurementViewModel measurementViewModel)48     public MeasurementActionDelegate(
49             MeasurementActivity measurementActivity, MeasurementViewModel measurementViewModel) {
50         this.mMeasurementActivity = measurementActivity;
51         this.mMeasurementViewModel = measurementViewModel;
52         listenToMeasurementViewModelUiEvents();
53     }
54 
listenToMeasurementViewModelUiEvents()55     private void listenToMeasurementViewModelUiEvents() {
56         Observer<MeasurementViewModelUiEvent> observer =
57                 event -> {
58                     if (event == null) {
59                         return;
60                     }
61                     try {
62                         switch (event) {
63                             case SWITCH_ON_MEASUREMENT:
64                                 if (FlagsFactory.getFlags().getToggleSpeedBumpEnabled()) {
65                                     DialogFragmentManager.showOptInMeasurementDialog(
66                                             mMeasurementActivity);
67                                 }
68                                 mMeasurementViewModel.setMeasurementConsent(true);
69                                 break;
70                             case SWITCH_OFF_MEASUREMENT:
71                                 if (FlagsFactory.getFlags().getToggleSpeedBumpEnabled()) {
72                                     DialogFragmentManager.showOptOutMeasurementDialog(
73                                             mMeasurementActivity, mMeasurementViewModel);
74                                 } else {
75                                     mMeasurementViewModel.setMeasurementConsent(false);
76                                 }
77                                 break;
78                             case RESET_MEASUREMENT:
79                                 UiStatsLogger.logResetMeasurementSelected();
80                                 mMeasurementViewModel.resetMeasurement();
81                                 Toast.makeText(
82                                                 mMeasurementActivity,
83                                                 R.string.settingsUI_measurement_are_reset,
84                                                 Toast.LENGTH_SHORT)
85                                         .show();
86                                 break;
87                         }
88                     } finally {
89                         mMeasurementViewModel.uiEventHandled();
90                     }
91                 };
92         mMeasurementViewModel.getUiEvents().observe(mMeasurementActivity, observer);
93     }
94 
95     /**
96      * Configure all UI elements in {@link AdServicesSettingsMeasurementFragment} to handle user
97      * actions.
98      */
initMeasurementFragment(AdServicesSettingsMeasurementFragment fragment)99     public void initMeasurementFragment(AdServicesSettingsMeasurementFragment fragment) {
100         mMeasurementActivity.setTitle(R.string.settingsUI_measurement_view_title);
101         if (SdkLevel.isAtLeastR() && !SdkLevel.isAtLeastS()) {
102             configureMeasurementConsentSwitchOnR(fragment);
103         } else {
104             configureMeasurementConsentSwitch(fragment);
105         }
106         configureResetMeasurementButton(fragment);
107         configurePrivacyPolicyLink();
108     }
109 
configureResetMeasurementButton(AdServicesSettingsMeasurementFragment fragment)110     private void configureResetMeasurementButton(AdServicesSettingsMeasurementFragment fragment) {
111         View resetMeasurementButton =
112                 fragment.requireView().findViewById(R.id.reset_measurement_button);
113 
114         resetMeasurementButton.setOnClickListener(
115                 view -> mMeasurementViewModel.resetMeasurementButtonClickHandler());
116     }
117 
configureMeasurementConsentSwitch(AdServicesSettingsMeasurementFragment fragment)118     private void configureMeasurementConsentSwitch(AdServicesSettingsMeasurementFragment fragment) {
119         MainSwitchBar measurementSwitchBar =
120                 mMeasurementActivity.findViewById(R.id.measurement_switch_bar);
121         mMeasurementViewModel
122                 .getMeasurementConsent()
123                 .observe(fragment, measurementSwitchBar::setChecked);
124         measurementSwitchBar.setOnClickListener(
125                 switchBar ->
126                         mMeasurementViewModel.consentSwitchClickHandler((MainSwitchBar) switchBar));
127     }
128 
configureMeasurementConsentSwitchOnR( AdServicesSettingsMeasurementFragment fragment)129     private void configureMeasurementConsentSwitchOnR(
130             AdServicesSettingsMeasurementFragment fragment) {
131         Switch measurementSwitchBar =
132                 mMeasurementActivity.findViewById(R.id.measurement_switch_bar);
133         mMeasurementViewModel
134                 .getMeasurementConsent()
135                 .observe(fragment, measurementSwitchBar::setChecked);
136         measurementSwitchBar.setOnClickListener(
137                 switchBar ->
138                         mMeasurementViewModel.consentSwitchClickHandlerOnR((Switch) switchBar));
139     }
140 
configurePrivacyPolicyLink()141     private void configurePrivacyPolicyLink() {
142         TextView measurementFooter = mMeasurementActivity.findViewById(R.id.measurement_footer);
143         measurementFooter.setMovementMethod(LinkMovementMethod.getInstance());
144     }
145 }
146