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.notifications; 17 18 import static com.android.adservices.ui.UxUtil.isUxStatesReady; 19 20 import android.content.Context; 21 import android.os.Build; 22 import android.os.Bundle; 23 24 import androidx.annotation.NonNull; 25 import androidx.annotation.RequiresApi; 26 import androidx.core.view.WindowCompat; 27 import androidx.fragment.app.FragmentActivity; 28 29 import com.android.adservices.LogUtil; 30 import com.android.adservices.api.R; 31 import com.android.adservices.service.FlagsFactory; 32 import com.android.adservices.service.stats.UiStatsLogger; 33 import com.android.adservices.ui.OTAResourcesManager; 34 import com.android.adservices.ui.UxSelector; 35 36 /** 37 * Android application activity for controlling settings related to PP (Privacy Preserving) APIs. 38 */ 39 // TODO(b/269798827): Enable for R. 40 @RequiresApi(Build.VERSION_CODES.S) 41 public class ConsentNotificationActivity extends FragmentActivity implements UxSelector { 42 public enum NotificationFragmentEnum { 43 LANDING_PAGE_DISPLAYED, 44 LANDING_PAGE_DISMISSED, 45 LANDING_PAGE_SCROLLED, 46 LANDING_PAGE_SCROLLED_TO_BOTTOM, 47 LANDING_PAGE_ADDITIONAL_INFO_CLICKED, 48 LANDING_PAGE_ADDITIONAL_INFO_2_CLICKED, 49 LANDING_PAGE_MORE_BUTTON_CLICKED, 50 LANDING_PAGE_SETTINGS_BUTTON_CLICKED, 51 LANDING_PAGE_OPT_IN_CLICKED, 52 LANDING_PAGE_OPT_OUT_CLICKED, 53 LANDING_PAGE_GOT_IT_CLICKED, 54 CONFIRMATION_PAGE_DISPLAYED, 55 CONFIRMATION_PAGE_DISMISSED, 56 CONFIRMATION_PAGE_OPT_IN_MORE_INFO_CLICKED, 57 CONFIRMATION_PAGE_OPT_OUT_MORE_INFO_CLICKED, 58 CONFIRMATION_PAGE_OPT_IN_SETTINGS_CLICKED, 59 CONFIRMATION_PAGE_OPT_OUT_SETTINGS_CLICKED, 60 CONFIRMATION_PAGE_OPT_IN_GOT_IT_BUTTON_CLICKED, 61 CONFIRMATION_PAGE_OPT_OUT_GOT_IT_BUTTON_CLICKED, 62 } 63 64 private static NotificationFragmentEnum sCurrentFragment; 65 private static boolean sLandingPageDismissed; 66 private static boolean sConfirmationPageDismissed; 67 private static boolean sLandingPageDisplayed; 68 private static boolean sLandingPageMoreButtonClicked; 69 private static boolean sLandingPageSettingsButtonClicked; 70 private static boolean sConfirmationPageDisplayed; 71 private static boolean sLandingPageScrolled; 72 private static boolean sLandingPageScrolledToBottom; 73 private static boolean sLandingPageAdditionalInfoClicked; 74 private static boolean sLandingPageSecondAdditionalInfoClicked; 75 private static boolean sLandingPageOptInClicked; 76 private static boolean sLandingPageOptOutClicked; 77 private static boolean sLandingPageGotItClicked; 78 private static boolean sConfirmationPageOptInMoreInfoClicked; 79 private static boolean sConfirmationPageOptOutMoreInfoClicked; 80 private static boolean sConfirmationPageOptInSettingsClicked; 81 private static boolean sConfirmationPageOptOutSettingsClicked; 82 private static boolean sConfirmationPageOptInGotItClicked; 83 private static boolean sConfirmationPageOptOutGotItClicked; 84 85 @Override onCreate(Bundle savedInstanceState)86 protected void onCreate(Bundle savedInstanceState) { 87 super.onCreate(savedInstanceState); 88 89 Context context = getApplicationContext(); 90 91 WindowCompat.setDecorFitsSystemWindows(getWindow(), false); 92 if (FlagsFactory.getFlags().getUiOtaStringsFeatureEnabled() 93 || FlagsFactory.getFlags().getUiOtaResourcesFeatureEnabled()) { 94 OTAResourcesManager.applyOTAResources(context, true); 95 } 96 97 if (FlagsFactory.getFlags().getConsentNotificationActivityDebugMode() 98 || isUxStatesReady(this)) { 99 initWithUx(context, /* beforePasUxActive */ true); 100 } else { 101 initFragment(); 102 } 103 } 104 105 @Override initGA()106 public void initGA() { 107 setContentView(R.layout.consent_notification_ga_v2_activity); 108 } 109 110 @Override initU18()111 public void initU18() { 112 setContentView(R.layout.consent_notification_u18_activity); 113 } 114 115 @Override initRvc()116 public void initRvc() { 117 initU18(); 118 } 119 120 @Override initGaUxWithPas()121 public void initGaUxWithPas() { 122 setContentView(R.layout.consent_notification_pas_activity); 123 } 124 125 @Override onSaveInstanceState(@onNull Bundle outBundle)126 protected void onSaveInstanceState(@NonNull Bundle outBundle) { 127 super.onSaveInstanceState(outBundle); 128 } 129 initFragment()130 private void initFragment() { 131 setContentView(R.layout.consent_notification_ga_v2_activity); 132 } 133 134 /** 135 * Notification fragments should call this when view is created. Used to keep track of user's 136 * current page and log correct page exit if user exits. 137 */ handleAction(NotificationFragmentEnum fragmentAction, Context context)138 public static void handleAction(NotificationFragmentEnum fragmentAction, Context context) { 139 switch (fragmentAction) { 140 case LANDING_PAGE_DISPLAYED: 141 sCurrentFragment = fragmentAction; 142 if (sLandingPageDisplayed) { 143 return; 144 } 145 LogUtil.v("LANDING_PAGE_DISPLAYED logged!"); 146 sLandingPageDisplayed = true; 147 UiStatsLogger.logLandingPageDisplayed(); 148 break; 149 case LANDING_PAGE_DISMISSED: 150 if (sLandingPageDismissed 151 || sCurrentFragment != NotificationFragmentEnum.LANDING_PAGE_DISPLAYED) { 152 return; 153 } 154 sLandingPageDismissed = true; 155 LogUtil.v("LANDING_PAGE_DISMISSED logged!"); 156 UiStatsLogger.logLandingPageDismissed(); 157 break; 158 case LANDING_PAGE_SCROLLED: 159 if (sLandingPageScrolled) { 160 return; 161 } 162 sLandingPageScrolled = true; 163 LogUtil.v("LANDING_PAGE_SCROLLED logged!"); 164 UiStatsLogger.logLandingPageScrolled(); 165 break; 166 case LANDING_PAGE_SCROLLED_TO_BOTTOM: 167 if (sLandingPageScrolledToBottom) { 168 return; 169 } 170 sLandingPageScrolledToBottom = true; 171 LogUtil.v("LANDING_PAGE_SCROLLED_TO_BOTTOM logged!"); 172 UiStatsLogger.logLandingPageScrolledToBottom(); 173 break; 174 case LANDING_PAGE_ADDITIONAL_INFO_CLICKED: 175 if (sLandingPageAdditionalInfoClicked) { 176 return; 177 } 178 sLandingPageAdditionalInfoClicked = true; 179 LogUtil.v("LANDING_PAGE_ADDITIONAL_INFO_CLICKED logged!"); 180 UiStatsLogger.logLandingPageAdditionalInfoClicked(); 181 break; 182 case LANDING_PAGE_ADDITIONAL_INFO_2_CLICKED: 183 if (sLandingPageSecondAdditionalInfoClicked) { 184 return; 185 } 186 sLandingPageSecondAdditionalInfoClicked = true; 187 LogUtil.v("LANDING_PAGE_ADDITIONAL_INFO_2_CLICKED logged!"); 188 UiStatsLogger.logLandingPageSecondAdditionalInfoClicked(); 189 break; 190 case LANDING_PAGE_MORE_BUTTON_CLICKED: 191 if (sLandingPageMoreButtonClicked) { 192 return; 193 } 194 sLandingPageMoreButtonClicked = true; 195 LogUtil.v("LANDING_PAGE_MORE_BUTTON_CLICKED logged!"); 196 UiStatsLogger.logLandingPageMoreButtonClicked(); 197 break; 198 case LANDING_PAGE_SETTINGS_BUTTON_CLICKED: 199 if (sLandingPageSettingsButtonClicked) { 200 return; 201 } 202 sLandingPageSettingsButtonClicked = true; 203 LogUtil.v("LANDING_PAGE_SETTINGS_BUTTON_CLICKED logged!"); 204 UiStatsLogger.logLandingPageSettingsButtonClicked(); 205 break; 206 case LANDING_PAGE_OPT_IN_CLICKED: 207 if (sLandingPageOptInClicked) { 208 return; 209 } 210 sLandingPageOptInClicked = true; 211 LogUtil.v("LANDING_PAGE_OPT_IN_CLICKED logged!"); 212 UiStatsLogger.logLandingPageOptIn(); 213 break; 214 case LANDING_PAGE_OPT_OUT_CLICKED: 215 if (sLandingPageOptOutClicked) { 216 return; 217 } 218 sLandingPageOptOutClicked = true; 219 LogUtil.v("LANDING_PAGE_OPT_OUT_CLICKED logged!"); 220 UiStatsLogger.logLandingPageOptOut(); 221 break; 222 case LANDING_PAGE_GOT_IT_CLICKED: 223 if (sLandingPageGotItClicked) { 224 return; 225 } 226 sLandingPageGotItClicked = true; 227 LogUtil.v("LANDING_PAGE_GOT_IT_CLICKED logged!"); 228 UiStatsLogger.logLandingPageGotItButtonClicked(); 229 break; 230 case CONFIRMATION_PAGE_DISPLAYED: 231 sCurrentFragment = fragmentAction; 232 if (sConfirmationPageDisplayed) { 233 return; 234 } 235 LogUtil.v("CONFIRMATION_PAGE_DISPLAYED logged!"); 236 sConfirmationPageDisplayed = true; 237 UiStatsLogger.logConfirmationPageDisplayed(); 238 break; 239 case CONFIRMATION_PAGE_DISMISSED: 240 if (sConfirmationPageDismissed 241 || sCurrentFragment 242 != NotificationFragmentEnum.CONFIRMATION_PAGE_DISPLAYED) { 243 return; 244 } 245 sConfirmationPageDismissed = true; 246 LogUtil.v("CONFIRMATION_PAGE_DISMISSED logged!"); 247 UiStatsLogger.logConfirmationPageDismissed(); 248 break; 249 case CONFIRMATION_PAGE_OPT_IN_MORE_INFO_CLICKED: 250 if (sConfirmationPageOptInMoreInfoClicked) { 251 return; 252 } 253 sConfirmationPageOptInMoreInfoClicked = true; 254 LogUtil.v("CONFIRMATION_PAGE_OPT_IN_MORE_INFO_CLICKED logged!"); 255 UiStatsLogger.logOptInConfirmationPageMoreInfoClicked(); 256 break; 257 case CONFIRMATION_PAGE_OPT_OUT_MORE_INFO_CLICKED: 258 if (sConfirmationPageOptOutMoreInfoClicked) { 259 return; 260 } 261 sConfirmationPageOptOutMoreInfoClicked = true; 262 LogUtil.v("CONFIRMATION_PAGE_OPT_OUT_MORE_INFO_CLICKED logged!"); 263 UiStatsLogger.logOptOutConfirmationPageMoreInfoClicked(); 264 break; 265 case CONFIRMATION_PAGE_OPT_IN_SETTINGS_CLICKED: 266 if (sConfirmationPageOptInSettingsClicked) { 267 return; 268 } 269 sConfirmationPageOptInSettingsClicked = true; 270 LogUtil.v("CONFIRMATION_PAGE_OPT_IN_SETTINGS_CLICKED logged!"); 271 UiStatsLogger.logOptInConfirmationPageSettingsClicked(); 272 break; 273 case CONFIRMATION_PAGE_OPT_OUT_SETTINGS_CLICKED: 274 if (sConfirmationPageOptOutSettingsClicked) { 275 return; 276 } 277 sConfirmationPageOptOutSettingsClicked = true; 278 LogUtil.v("CONFIRMATION_PAGE_OPT_OUT_SETTINGS_CLICKED logged!"); 279 UiStatsLogger.logOptOutConfirmationPageSettingsClicked(); 280 break; 281 case CONFIRMATION_PAGE_OPT_IN_GOT_IT_BUTTON_CLICKED: 282 if (sConfirmationPageOptInGotItClicked) { 283 return; 284 } 285 sConfirmationPageOptInGotItClicked = true; 286 LogUtil.v("CONFIRMATION_PAGE_OPT_IN_GOT_IT_BUTTON_CLICKED logged!"); 287 UiStatsLogger.logOptInConfirmationPageGotItClicked(); 288 break; 289 case CONFIRMATION_PAGE_OPT_OUT_GOT_IT_BUTTON_CLICKED: 290 if (sConfirmationPageOptOutGotItClicked) { 291 return; 292 } 293 sConfirmationPageOptOutGotItClicked = true; 294 LogUtil.v("CONFIRMATION_PAGE_OPT_OUT_GOT_IT_BUTTON_CLICKED logged!"); 295 UiStatsLogger.logOptOutConfirmationPageGotItClicked(); 296 break; 297 } 298 } 299 } 300