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.viewmodels; 17 18 import android.app.Application; 19 import android.os.Build; 20 import android.widget.Switch; 21 22 import androidx.annotation.NonNull; 23 import androidx.annotation.RequiresApi; 24 import androidx.lifecycle.AndroidViewModel; 25 import androidx.lifecycle.LiveData; 26 import androidx.lifecycle.MutableLiveData; 27 28 import com.android.adservices.service.FlagsFactory; 29 import com.android.adservices.service.consent.AdServicesApiConsent; 30 import com.android.adservices.service.consent.AdServicesApiType; 31 import com.android.adservices.service.consent.ConsentManager; 32 import com.android.adservices.ui.settings.fragments.AdServicesSettingsMeasurementFragment; 33 import com.android.internal.annotations.VisibleForTesting; 34 import com.android.settingslib.widget.MainSwitchBar; 35 36 /** 37 * View model for the Measurement view of the AdServices Settings App. This view model is 38 * responsible for serving Measurement to the Measurement view, and interacting with the {@link 39 * ConsentManager} that persists and changes the Measurement data in a storage. 40 */ 41 // TODO(b/269798827): Enable for R. 42 @RequiresApi(Build.VERSION_CODES.S) 43 public class MeasurementViewModel extends AndroidViewModel { 44 45 private final MutableLiveData<MeasurementViewModelUiEvent> mEventTrigger = 46 new MutableLiveData<>(); 47 private final MutableLiveData<Boolean> mMeasurementConsent; 48 private final ConsentManager mConsentManager; 49 50 /** UI event in measurement triggered by view model */ 51 public enum MeasurementViewModelUiEvent { 52 SWITCH_ON_MEASUREMENT, 53 SWITCH_OFF_MEASUREMENT, 54 RESET_MEASUREMENT 55 } 56 MeasurementViewModel(@onNull Application application)57 public MeasurementViewModel(@NonNull Application application) { 58 super(application); 59 mConsentManager = ConsentManager.getInstance(); 60 mMeasurementConsent = new MutableLiveData<>(getMeasurementConsentFromConsentManager()); 61 } 62 63 @VisibleForTesting MeasurementViewModel(@onNull Application application, ConsentManager consentManager)64 public MeasurementViewModel(@NonNull Application application, ConsentManager consentManager) { 65 super(application); 66 mConsentManager = consentManager; 67 mMeasurementConsent = new MutableLiveData<>(true); 68 } 69 70 /** 71 * Provides {@link AdServicesApiConsent} displayed in {@link 72 * AdServicesSettingsMeasurementFragment} as a Switch value. 73 * 74 * @return mMeasurementConsent indicates if user has consented to Mesaurement Api usage. 75 */ getMeasurementConsent()76 public MutableLiveData<Boolean> getMeasurementConsent() { 77 return mMeasurementConsent; 78 } 79 80 /** 81 * Sets the user consent for PP APIs. 82 * 83 * @param newMeasurementConsentValue the new value that user consent should be set to for 84 * Measurement PP APIs. 85 */ setMeasurementConsent(Boolean newMeasurementConsentValue)86 public void setMeasurementConsent(Boolean newMeasurementConsentValue) { 87 if (newMeasurementConsentValue) { 88 mConsentManager.enable(getApplication(), AdServicesApiType.MEASUREMENTS); 89 } else { 90 mConsentManager.disable(getApplication(), AdServicesApiType.MEASUREMENTS); 91 } 92 mMeasurementConsent.postValue(getMeasurementConsentFromConsentManager()); 93 if (FlagsFactory.getFlags().getRecordManualInteractionEnabled()) { 94 ConsentManager.getInstance() 95 .recordUserManualInteractionWithConsent( 96 ConsentManager.MANUAL_INTERACTIONS_RECORDED); 97 } 98 } 99 100 /** Reset all information related to Measurement */ resetMeasurement()101 public void resetMeasurement() { 102 mConsentManager.resetMeasurement(); 103 // add the msmt data reset bit 104 mConsentManager.setMeasurementDataReset(true); 105 } 106 107 /** Returns an observable but immutable event enum representing an action on UI. */ getUiEvents()108 public LiveData<MeasurementViewModelUiEvent> getUiEvents() { 109 return mEventTrigger; 110 } 111 112 /** 113 * Sets the UI Event as handled so the action will not be handled again if activity is 114 * recreated. 115 */ uiEventHandled()116 public void uiEventHandled() { 117 mEventTrigger.postValue(null); 118 } 119 120 /** Triggers a reset of all Measurement related data. */ resetMeasurementButtonClickHandler()121 public void resetMeasurementButtonClickHandler() { 122 mEventTrigger.postValue(MeasurementViewModelUiEvent.RESET_MEASUREMENT); 123 } 124 125 /** 126 * Triggers opt out process for Privacy Sandbox. Also reverts the switch state, since 127 * confirmation dialog will handle switch change. 128 */ consentSwitchClickHandler(MainSwitchBar measurementSwitchBar)129 public void consentSwitchClickHandler(MainSwitchBar measurementSwitchBar) { 130 if (measurementSwitchBar.isChecked()) { 131 measurementSwitchBar.setChecked(false); 132 mEventTrigger.postValue(MeasurementViewModelUiEvent.SWITCH_ON_MEASUREMENT); 133 } else { 134 measurementSwitchBar.setChecked(true); 135 mEventTrigger.postValue(MeasurementViewModelUiEvent.SWITCH_OFF_MEASUREMENT); 136 } 137 } 138 139 /** 140 * Triggers opt out process for Privacy Sandbox. Also reverts the switch state, since 141 * confirmation dialog will handle switch change. 142 */ consentSwitchClickHandlerOnR(Switch measurementSwitchBar)143 public void consentSwitchClickHandlerOnR(Switch measurementSwitchBar) { 144 if (measurementSwitchBar.isChecked()) { 145 measurementSwitchBar.setChecked(false); 146 mEventTrigger.postValue(MeasurementViewModelUiEvent.SWITCH_ON_MEASUREMENT); 147 } else { 148 measurementSwitchBar.setChecked(true); 149 mEventTrigger.postValue(MeasurementViewModelUiEvent.SWITCH_OFF_MEASUREMENT); 150 } 151 } 152 getMeasurementConsentFromConsentManager()153 private boolean getMeasurementConsentFromConsentManager() { 154 return mConsentManager.getConsent(AdServicesApiType.MEASUREMENTS).isGiven(); 155 } 156 } 157