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; 17 18 import android.content.DialogInterface.OnClickListener; 19 import android.os.Build; 20 import android.widget.Toast; 21 22 import androidx.annotation.NonNull; 23 import androidx.annotation.RequiresApi; 24 import androidx.fragment.app.FragmentActivity; 25 26 import com.android.adservices.api.R; 27 import com.android.adservices.data.topics.Topic; 28 import com.android.adservices.service.consent.App; 29 import com.android.adservices.service.topics.TopicsMapper; 30 import com.android.adservices.ui.settings.viewmodels.AppsViewModel; 31 import com.android.adservices.ui.settings.viewmodels.MainViewModel; 32 import com.android.adservices.ui.settings.viewmodels.TopicsViewModel; 33 34 import java.io.IOException; 35 36 /** 37 * Creates and displays dialogs for the Privacy Sandbox application. This should be a substitute of 38 * DialogManager It should solve double click and dismiss when rotating 39 */ 40 // TODO(b/269798827): Enable for R. 41 @RequiresApi(Build.VERSION_CODES.S) 42 public class DialogFragmentManager { 43 static boolean sIsShowing = false; 44 /** 45 * Shows the dialog for opting out of Privacy Sandbox. 46 * 47 * @param fragmentActivity {@link FragmentActivity}. 48 * @param mainViewModel {@link MainViewModel}. 49 */ showOptOutDialogFragment( @onNull FragmentActivity fragmentActivity, MainViewModel mainViewModel)50 public static void showOptOutDialogFragment( 51 @NonNull FragmentActivity fragmentActivity, MainViewModel mainViewModel) { 52 if (sIsShowing) return; 53 54 OnClickListener positiveOnClickListener = 55 (dialogInterface, buttonId) -> { 56 mainViewModel.setConsent(false); 57 sIsShowing = false; 58 }; 59 60 SpeedBumpDialogFragment dialog = 61 SpeedBumpDialogFragment.newInstance( 62 fragmentActivity.getString(R.string.settingsUI_dialog_opt_out_title), 63 fragmentActivity.getString(R.string.settingsUI_dialog_opt_out_message), 64 fragmentActivity.getString( 65 R.string.settingsUI_dialog_opt_out_positive_text), 66 fragmentActivity.getString(R.string.settingsUI_dialog_negative_text), 67 positiveOnClickListener); 68 69 sIsShowing = true; 70 dialog.show(fragmentActivity.getSupportFragmentManager(), "OptOutDialogFragment"); 71 } 72 73 /** 74 * Shows the dialog for blocking a topic. 75 * 76 * @param fragmentActivity {@link FragmentActivity}. 77 * @param topicsViewModel {@link TopicsViewModel}. 78 * @param topic topic to block. 79 */ showBlockTopicDialog( @onNull FragmentActivity fragmentActivity, TopicsViewModel topicsViewModel, Topic topic)80 public static void showBlockTopicDialog( 81 @NonNull FragmentActivity fragmentActivity, 82 TopicsViewModel topicsViewModel, 83 Topic topic) { 84 if (sIsShowing) return; 85 OnClickListener positiveOnClickListener = 86 (dialogInterface, buttonId) -> { 87 topicsViewModel.revokeTopicConsent(topic); 88 sIsShowing = false; 89 }; 90 91 String topicName = 92 fragmentActivity.getString( 93 TopicsMapper.getResourceIdByTopic(topic, fragmentActivity)); 94 SpeedBumpDialogFragment dialog = 95 SpeedBumpDialogFragment.newInstance( 96 fragmentActivity.getString( 97 R.string.settingsUI_dialog_block_topic_title, topicName), 98 fragmentActivity.getString(R.string.settingsUI_dialog_block_topic_message), 99 fragmentActivity.getString( 100 R.string.settingsUI_dialog_block_topic_positive_text), 101 fragmentActivity.getString(R.string.settingsUI_dialog_negative_text), 102 positiveOnClickListener); 103 104 sIsShowing = true; 105 dialog.show(fragmentActivity.getSupportFragmentManager(), "showBlockTopicDialog"); 106 } 107 108 /** 109 * Shows the dialog for unblocking a topic. 110 * 111 * @param fragmentActivity {@link FragmentActivity}. 112 * @param topic topic to unblock. 113 */ showUnblockTopicDialog( @onNull FragmentActivity fragmentActivity, Topic topic)114 public static void showUnblockTopicDialog( 115 @NonNull FragmentActivity fragmentActivity, Topic topic) { 116 if (sIsShowing) return; 117 OnClickListener positiveOnClickListener = (dialogInterface, buttonId) -> sIsShowing = false; 118 String topicName = 119 fragmentActivity.getString( 120 TopicsMapper.getResourceIdByTopic(topic, fragmentActivity)); 121 SpeedBumpDialogFragment dialog = 122 SpeedBumpDialogFragment.newInstance( 123 fragmentActivity.getString( 124 R.string.settingsUI_dialog_unblock_topic_title, topicName), 125 fragmentActivity.getString( 126 R.string.settingsUI_dialog_unblock_topic_message), 127 fragmentActivity.getString( 128 R.string.settingsUI_dialog_unblock_topic_positive_text), 129 "", 130 positiveOnClickListener); 131 132 sIsShowing = true; 133 dialog.show(fragmentActivity.getSupportFragmentManager(), "showUnBlockTopicDialog"); 134 } 135 136 /** 137 * Shows the dialog for resetting topics. (reset does not reset blocked topics 138 * 139 * @param fragmentActivity {@link FragmentActivity}. 140 * @param topicsViewModel {@link TopicsViewModel}. 141 */ showResetTopicDialog( @onNull FragmentActivity fragmentActivity, TopicsViewModel topicsViewModel)142 public static void showResetTopicDialog( 143 @NonNull FragmentActivity fragmentActivity, TopicsViewModel topicsViewModel) { 144 if (sIsShowing) return; 145 146 OnClickListener resetOnCLickListener = 147 (dialog, which) -> { 148 topicsViewModel.resetTopics(); 149 sIsShowing = false; 150 Toast.makeText( 151 fragmentActivity, 152 R.string.settingsUI_topics_are_reset, 153 Toast.LENGTH_SHORT) 154 .show(); 155 }; 156 157 SpeedBumpDialogFragment dialog = 158 SpeedBumpDialogFragment.newInstance( 159 fragmentActivity.getString(R.string.settingsUI_dialog_reset_topic_title), 160 fragmentActivity.getString(R.string.settingsUI_dialog_reset_topic_message), 161 fragmentActivity.getString( 162 R.string.settingsUI_dialog_reset_topic_positive_text), 163 fragmentActivity.getString(R.string.settingsUI_dialog_negative_text), 164 resetOnCLickListener); 165 166 sIsShowing = true; 167 dialog.show(fragmentActivity.getSupportFragmentManager(), "showResetTopicDialog"); 168 } 169 170 /** 171 * Shows the dialog for blocking a topic. 172 * 173 * @param fragmentActivity {@link FragmentActivity}. 174 * @param appsViewModel {@link AppsViewModel}. 175 * @param app the app {@link App} to block. 176 */ showBlockAppDialog( @onNull FragmentActivity fragmentActivity, AppsViewModel appsViewModel, App app)177 public static void showBlockAppDialog( 178 @NonNull FragmentActivity fragmentActivity, AppsViewModel appsViewModel, App app) { 179 if (sIsShowing) return; 180 OnClickListener positiveOnClickListener = 181 (dialogInterface, buttonId) -> { 182 try { 183 appsViewModel.revokeAppConsent(app); 184 } catch (IOException e) { 185 e.printStackTrace(); 186 } 187 sIsShowing = false; 188 }; 189 190 String appName = app.getAppDisplayName(fragmentActivity.getPackageManager()); 191 SpeedBumpDialogFragment dialog = 192 SpeedBumpDialogFragment.newInstance( 193 fragmentActivity.getString( 194 R.string.settingsUI_dialog_block_app_title, appName), 195 fragmentActivity.getString(R.string.settingsUI_dialog_block_app_message), 196 fragmentActivity.getString( 197 R.string.settingsUI_dialog_block_app_positive_text), 198 fragmentActivity.getString(R.string.settingsUI_dialog_negative_text), 199 positiveOnClickListener); 200 201 sIsShowing = true; 202 dialog.show(fragmentActivity.getSupportFragmentManager(), "showBlockAppDialog"); 203 } 204 205 /** 206 * Shows the dialog for unblocking a app. 207 * 208 * @param fragmentActivity {@link FragmentActivity}. 209 * @param app app {@link App} to unblock. 210 */ showUnblockAppDialog(@onNull FragmentActivity fragmentActivity, App app)211 public static void showUnblockAppDialog(@NonNull FragmentActivity fragmentActivity, App app) { 212 if (sIsShowing) return; 213 OnClickListener positiveOnClickListener = (dialogInterface, buttonId) -> sIsShowing = false; 214 String appName = app.getAppDisplayName(fragmentActivity.getPackageManager()); 215 SpeedBumpDialogFragment dialog = 216 SpeedBumpDialogFragment.newInstance( 217 fragmentActivity.getString( 218 R.string.settingsUI_dialog_unblock_app_title, appName), 219 fragmentActivity.getString(R.string.settingsUI_dialog_unblock_app_message), 220 fragmentActivity.getString( 221 R.string.settingsUI_dialog_unblock_app_positive_text), 222 "", 223 positiveOnClickListener); 224 225 sIsShowing = true; 226 dialog.show(fragmentActivity.getSupportFragmentManager(), "showUnBlockAppDialog"); 227 } 228 229 /** 230 * Shows the dialog for resetting apps. (reset does not reset blocked apps 231 * 232 * @param fragmentActivity {@link FragmentActivity}. 233 * @param appsViewModel {@link AppsViewModel}. 234 */ showResetAppDialog( @onNull FragmentActivity fragmentActivity, AppsViewModel appsViewModel)235 public static void showResetAppDialog( 236 @NonNull FragmentActivity fragmentActivity, AppsViewModel appsViewModel) { 237 if (sIsShowing) return; 238 239 OnClickListener resetOnCLickListener = 240 (dialog, which) -> { 241 try { 242 appsViewModel.resetApps(); 243 sIsShowing = false; 244 Toast.makeText( 245 fragmentActivity, 246 R.string.settingsUI_apps_are_reset, 247 Toast.LENGTH_SHORT) 248 .show(); 249 } catch (IOException ioException) { 250 ioException.printStackTrace(); 251 } 252 253 sIsShowing = false; 254 }; 255 256 SpeedBumpDialogFragment dialog = 257 SpeedBumpDialogFragment.newInstance( 258 fragmentActivity.getString(R.string.settingsUI_dialog_reset_app_title), 259 fragmentActivity.getString(R.string.settingsUI_dialog_reset_app_message), 260 fragmentActivity.getString( 261 R.string.settingsUI_dialog_reset_app_positive_text), 262 fragmentActivity.getString(R.string.settingsUI_dialog_negative_text), 263 resetOnCLickListener); 264 265 sIsShowing = true; 266 dialog.show(fragmentActivity.getSupportFragmentManager(), "showResetAppDialog"); 267 } 268 } 269