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