1 /* 2 * Copyright (C) 2013 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 17 package com.android.settings.accessibility; 18 19 import static com.android.settings.accessibility.AccessibilityDialogUtils.DialogEnums; 20 import static com.android.settings.accessibility.AccessibilityStatsLogUtils.logAccessibilityServiceEnabled; 21 22 import android.accessibilityservice.AccessibilityServiceInfo; 23 import android.app.AlertDialog; 24 import android.app.Dialog; 25 import android.app.settings.SettingsEnums; 26 import android.content.BroadcastReceiver; 27 import android.content.ComponentName; 28 import android.content.ContentResolver; 29 import android.content.Context; 30 import android.content.DialogInterface; 31 import android.content.Intent; 32 import android.content.IntentFilter; 33 import android.content.pm.ApplicationInfo; 34 import android.content.pm.ResolveInfo; 35 import android.net.Uri; 36 import android.os.Bundle; 37 import android.os.SystemClock; 38 import android.text.BidiFormatter; 39 import android.text.TextUtils; 40 import android.util.Log; 41 import android.view.Menu; 42 import android.view.MenuInflater; 43 import android.view.View; 44 import android.view.accessibility.AccessibilityManager; 45 import android.widget.CompoundButton; 46 47 import androidx.annotation.Nullable; 48 49 import com.android.internal.accessibility.common.ShortcutConstants; 50 import com.android.settings.R; 51 import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType; 52 import com.android.settings.accessibility.shortcuts.EditShortcutsPreferenceFragment; 53 import com.android.settingslib.accessibility.AccessibilityUtils; 54 55 import java.util.List; 56 import java.util.Locale; 57 import java.util.concurrent.atomic.AtomicBoolean; 58 59 /** Fragment for providing toggle bar and basic accessibility service setup. */ 60 public class ToggleAccessibilityServicePreferenceFragment extends 61 ToggleFeaturePreferenceFragment { 62 63 private static final String TAG = "ToggleAccessibilityServicePreferenceFragment"; 64 private static final String KEY_HAS_LOGGED = "has_logged"; 65 private final AtomicBoolean mIsDialogShown = new AtomicBoolean(/* initialValue= */ false); 66 67 private Dialog mWarningDialog; 68 private ComponentName mTileComponentName; 69 private BroadcastReceiver mPackageRemovedReceiver; 70 private boolean mDisabledStateLogged = false; 71 private long mStartTimeMillsForLogging = 0; 72 73 @Override getMetricsCategory()74 public int getMetricsCategory() { 75 return getArguments().getInt(AccessibilitySettings.EXTRA_METRICS_CATEGORY); 76 } 77 78 @Override onCreateOptionsMenu(Menu menu, MenuInflater inflater)79 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 80 // Do not call super. We don't want to see the "Help & feedback" option on this page so as 81 // not to confuse users who think they might be able to send feedback about a specific 82 // accessibility service from this page. 83 } 84 85 @Override onCreate(Bundle savedInstanceState)86 public void onCreate(Bundle savedInstanceState) { 87 super.onCreate(savedInstanceState); 88 if (savedInstanceState != null) { 89 if (savedInstanceState.containsKey(KEY_HAS_LOGGED)) { 90 mDisabledStateLogged = savedInstanceState.getBoolean(KEY_HAS_LOGGED); 91 } 92 } 93 } 94 95 @Override registerKeysToObserverCallback( AccessibilitySettingsContentObserver contentObserver)96 protected void registerKeysToObserverCallback( 97 AccessibilitySettingsContentObserver contentObserver) { 98 super.registerKeysToObserverCallback(contentObserver); 99 contentObserver.registerObserverCallback(key -> updateSwitchBarToggleSwitch()); 100 } 101 102 @Override onStart()103 public void onStart() { 104 super.onStart(); 105 final AccessibilityServiceInfo serviceInfo = getAccessibilityServiceInfo(); 106 if (serviceInfo == null) { 107 getActivity().finishAndRemoveTask(); 108 } else if (!AccessibilityUtil.isSystemApp(serviceInfo)) { 109 registerPackageRemoveReceiver(); 110 } 111 } 112 113 @Override onResume()114 public void onResume() { 115 super.onResume(); 116 updateSwitchBarToggleSwitch(); 117 } 118 119 @Override onSaveInstanceState(Bundle outState)120 public void onSaveInstanceState(Bundle outState) { 121 if (mStartTimeMillsForLogging > 0) { 122 outState.putBoolean(KEY_HAS_LOGGED, mDisabledStateLogged); 123 } 124 super.onSaveInstanceState(outState); 125 } 126 127 @Override onPreferenceToggled(String preferenceKey, boolean enabled)128 public void onPreferenceToggled(String preferenceKey, boolean enabled) { 129 ComponentName toggledService = ComponentName.unflattenFromString(preferenceKey); 130 logAccessibilityServiceEnabled(toggledService, enabled); 131 if (!enabled) { 132 logDisabledState(toggledService.getPackageName()); 133 } 134 AccessibilityUtils.setAccessibilityServiceState(getPrefContext(), toggledService, enabled); 135 } 136 137 // IMPORTANT: Refresh the info since there are dynamically changing capabilities. For 138 // example, before JellyBean MR2 the user was granting the explore by touch one. 139 @Nullable getAccessibilityServiceInfo()140 AccessibilityServiceInfo getAccessibilityServiceInfo() { 141 final List<AccessibilityServiceInfo> infos = AccessibilityManager.getInstance( 142 getPrefContext()).getInstalledAccessibilityServiceList(); 143 144 for (int i = 0, count = infos.size(); i < count; i++) { 145 AccessibilityServiceInfo serviceInfo = infos.get(i); 146 ResolveInfo resolveInfo = serviceInfo.getResolveInfo(); 147 if (mComponentName.getPackageName().equals(resolveInfo.serviceInfo.packageName) 148 && mComponentName.getClassName().equals(resolveInfo.serviceInfo.name)) { 149 return serviceInfo; 150 } 151 } 152 return null; 153 } 154 155 @Override onCreateDialog(int dialogId)156 public Dialog onCreateDialog(int dialogId) { 157 final AccessibilityServiceInfo info = getAccessibilityServiceInfo(); 158 switch (dialogId) { 159 case DialogEnums.ENABLE_WARNING_FROM_TOGGLE: 160 if (info == null) { 161 return null; 162 } 163 mWarningDialog = 164 com.android.internal.accessibility.dialog.AccessibilityServiceWarning 165 .createAccessibilityServiceWarningDialog(getPrefContext(), info, 166 v -> onAllowButtonFromEnableToggleClicked(), 167 v -> onDenyButtonFromEnableToggleClicked(), 168 v -> onDialogButtonFromUninstallClicked()); 169 return mWarningDialog; 170 case DialogEnums.ENABLE_WARNING_FROM_SHORTCUT_TOGGLE: 171 if (info == null) { 172 return null; 173 } 174 mWarningDialog = 175 com.android.internal.accessibility.dialog.AccessibilityServiceWarning 176 .createAccessibilityServiceWarningDialog(getPrefContext(), info, 177 v -> onAllowButtonFromShortcutToggleClicked(), 178 v -> onDenyButtonFromShortcutToggleClicked(), 179 v -> onDialogButtonFromUninstallClicked()); 180 return mWarningDialog; 181 case DialogEnums.ENABLE_WARNING_FROM_SHORTCUT: 182 if (info == null) { 183 return null; 184 } 185 mWarningDialog = 186 com.android.internal.accessibility.dialog.AccessibilityServiceWarning 187 .createAccessibilityServiceWarningDialog(getPrefContext(), info, 188 v -> onAllowButtonFromShortcutClicked(), 189 v -> onDenyButtonFromShortcutClicked(), 190 v -> onDialogButtonFromUninstallClicked()); 191 return mWarningDialog; 192 case DialogEnums.DISABLE_WARNING_FROM_TOGGLE: 193 if (info == null) { 194 return null; 195 } 196 mWarningDialog = createDisableDialog( 197 getPrefContext(), info, this::onDialogButtonFromDisableToggleClicked); 198 return mWarningDialog; 199 default: 200 return super.onCreateDialog(dialogId); 201 } 202 } 203 204 /** Returns a {@link Dialog} to be shown to confirm that they want to disable a service. */ createDisableDialog(Context context, AccessibilityServiceInfo info, DialogInterface.OnClickListener listener)205 private static Dialog createDisableDialog(Context context, 206 AccessibilityServiceInfo info, DialogInterface.OnClickListener listener) { 207 final Locale locale = context.getResources().getConfiguration().getLocales().get(0); 208 final CharSequence label = 209 info.getResolveInfo().loadLabel(context.getPackageManager()); 210 CharSequence serviceName = BidiFormatter.getInstance(locale).unicodeWrap(label); 211 212 return new AlertDialog.Builder(context) 213 .setTitle(context.getString(R.string.disable_service_title, serviceName)) 214 .setCancelable(true) 215 .setPositiveButton(R.string.accessibility_dialog_button_stop, listener) 216 .setNegativeButton(R.string.accessibility_dialog_button_cancel, listener) 217 .create(); 218 } 219 220 @Override getDialogMetricsCategory(int dialogId)221 public int getDialogMetricsCategory(int dialogId) { 222 switch (dialogId) { 223 case DialogEnums.ENABLE_WARNING_FROM_TOGGLE: 224 case DialogEnums.ENABLE_WARNING_FROM_SHORTCUT: 225 case DialogEnums.ENABLE_WARNING_FROM_SHORTCUT_TOGGLE: 226 return SettingsEnums.DIALOG_ACCESSIBILITY_SERVICE_ENABLE; 227 case DialogEnums.DISABLE_WARNING_FROM_TOGGLE: 228 return SettingsEnums.DIALOG_ACCESSIBILITY_SERVICE_DISABLE; 229 case DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL: 230 return SettingsEnums.DIALOG_ACCESSIBILITY_TUTORIAL; 231 default: 232 return super.getDialogMetricsCategory(dialogId); 233 } 234 } 235 236 @Override getUserShortcutTypes()237 int getUserShortcutTypes() { 238 return AccessibilityUtil.getUserShortcutTypesFromSettings(getPrefContext(), 239 mComponentName); 240 } 241 242 @Override getTileComponentName()243 ComponentName getTileComponentName() { 244 return mTileComponentName; 245 } 246 247 @Override getTileTooltipContent(@uickSettingsTooltipType int type)248 CharSequence getTileTooltipContent(@QuickSettingsTooltipType int type) { 249 final ComponentName componentName = getTileComponentName(); 250 if (componentName == null) { 251 return null; 252 } 253 254 final CharSequence tileName = loadTileLabel(getPrefContext(), componentName); 255 if (tileName == null) { 256 return null; 257 } 258 259 final int titleResId = type == QuickSettingsTooltipType.GUIDE_TO_EDIT 260 ? R.string.accessibility_service_qs_tooltip_content 261 : R.string.accessibility_service_auto_added_qs_tooltip_content; 262 return getString(titleResId, tileName); 263 } 264 265 @Override updateSwitchBarToggleSwitch()266 protected void updateSwitchBarToggleSwitch() { 267 final boolean checked = isAccessibilityServiceEnabled(); 268 if (mToggleServiceSwitchPreference.isChecked() == checked) { 269 return; 270 } 271 mToggleServiceSwitchPreference.setChecked(checked); 272 } 273 isAccessibilityServiceEnabled()274 private boolean isAccessibilityServiceEnabled() { 275 return AccessibilityUtils.getEnabledServicesFromSettings(getPrefContext()) 276 .contains(mComponentName); 277 } 278 279 @Override onActivityResult(int requestCode, int resultCode, Intent data)280 public void onActivityResult(int requestCode, int resultCode, Intent data) { 281 } 282 registerPackageRemoveReceiver()283 private void registerPackageRemoveReceiver() { 284 if (mPackageRemovedReceiver != null || getContext() == null) { 285 return; 286 } 287 mPackageRemovedReceiver = new BroadcastReceiver() { 288 @Override 289 public void onReceive(Context context, Intent intent) { 290 final String packageName = intent.getData().getSchemeSpecificPart(); 291 if (TextUtils.equals(mComponentName.getPackageName(), packageName)) { 292 getActivity().finishAndRemoveTask(); 293 } 294 } 295 }; 296 final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED); 297 filter.addDataScheme("package"); 298 getContext().registerReceiver(mPackageRemovedReceiver, filter); 299 } 300 unregisterPackageRemoveReceiver()301 private void unregisterPackageRemoveReceiver() { 302 if (mPackageRemovedReceiver == null || getContext() == null) { 303 return; 304 } 305 getContext().unregisterReceiver(mPackageRemovedReceiver); 306 mPackageRemovedReceiver = null; 307 } 308 serviceSupportsAccessibilityButton()309 boolean serviceSupportsAccessibilityButton() { 310 final AccessibilityServiceInfo info = getAccessibilityServiceInfo(); 311 return info != null 312 && (info.flags & AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0; 313 } 314 handleConfirmServiceEnabled(boolean confirmed)315 private void handleConfirmServiceEnabled(boolean confirmed) { 316 getArguments().putBoolean(AccessibilitySettings.EXTRA_CHECKED, confirmed); 317 onPreferenceToggled(mPreferenceKey, confirmed); 318 } 319 320 @Override onCheckedChanged(CompoundButton buttonView, boolean isChecked)321 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 322 if (isChecked != isAccessibilityServiceEnabled()) { 323 onPreferenceClick(isChecked); 324 } 325 } 326 327 @Override onToggleClicked(ShortcutPreference preference)328 public void onToggleClicked(ShortcutPreference preference) { 329 final int shortcutTypes = getUserPreferredShortcutTypes(); 330 if (preference.isChecked()) { 331 final boolean isWarningRequired = 332 getPrefContext().getSystemService(AccessibilityManager.class) 333 .isAccessibilityServiceWarningRequired(getAccessibilityServiceInfo()); 334 if (isWarningRequired) { 335 preference.setChecked(false); 336 showPopupDialog(DialogEnums.ENABLE_WARNING_FROM_SHORTCUT_TOGGLE); 337 } else { 338 onAllowButtonFromShortcutToggleClicked(); 339 } 340 } else { 341 AccessibilityUtil.optOutAllValuesFromSettings(getPrefContext(), shortcutTypes, 342 mComponentName); 343 } 344 mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext())); 345 } 346 347 @Override onSettingsClicked(ShortcutPreference preference)348 public void onSettingsClicked(ShortcutPreference preference) { 349 final boolean isWarningRequired = 350 getPrefContext().getSystemService(AccessibilityManager.class) 351 .isAccessibilityServiceWarningRequired(getAccessibilityServiceInfo()); 352 if (isWarningRequired) { 353 showPopupDialog(DialogEnums.ENABLE_WARNING_FROM_SHORTCUT); 354 } else { 355 onAllowButtonFromShortcutClicked(); 356 } 357 } 358 359 @Override onProcessArguments(Bundle arguments)360 protected void onProcessArguments(Bundle arguments) { 361 super.onProcessArguments(arguments); 362 // Settings title and intent. 363 String settingsTitle = arguments.getString(AccessibilitySettings.EXTRA_SETTINGS_TITLE); 364 String settingsComponentName = arguments.getString( 365 AccessibilitySettings.EXTRA_SETTINGS_COMPONENT_NAME); 366 if (!TextUtils.isEmpty(settingsTitle) && !TextUtils.isEmpty(settingsComponentName)) { 367 Intent settingsIntent = new Intent(Intent.ACTION_MAIN).setComponent( 368 ComponentName.unflattenFromString(settingsComponentName.toString())); 369 if (!getPackageManager().queryIntentActivities(settingsIntent, 0).isEmpty()) { 370 mSettingsTitle = settingsTitle; 371 mSettingsIntent = settingsIntent; 372 setHasOptionsMenu(true); 373 } 374 } 375 376 mComponentName = arguments.getParcelable(AccessibilitySettings.EXTRA_COMPONENT_NAME); 377 378 // Settings animated image. 379 final int animatedImageRes = arguments.getInt( 380 AccessibilitySettings.EXTRA_ANIMATED_IMAGE_RES); 381 if (animatedImageRes > 0) { 382 mImageUri = new Uri.Builder().scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) 383 .authority(mComponentName.getPackageName()) 384 .appendPath(String.valueOf(animatedImageRes)) 385 .build(); 386 } 387 388 // Get Accessibility service name. 389 mPackageName = getAccessibilityServiceInfo().getResolveInfo().loadLabel( 390 getPackageManager()); 391 392 if (arguments.containsKey(AccessibilitySettings.EXTRA_TILE_SERVICE_COMPONENT_NAME)) { 393 final String tileServiceComponentName = arguments.getString( 394 AccessibilitySettings.EXTRA_TILE_SERVICE_COMPONENT_NAME); 395 mTileComponentName = ComponentName.unflattenFromString(tileServiceComponentName); 396 } 397 398 mStartTimeMillsForLogging = arguments.getLong(AccessibilitySettings.EXTRA_TIME_FOR_LOGGING); 399 } 400 onDialogButtonFromDisableToggleClicked(DialogInterface dialog, int which)401 private void onDialogButtonFromDisableToggleClicked(DialogInterface dialog, int which) { 402 switch (which) { 403 case DialogInterface.BUTTON_POSITIVE: 404 handleConfirmServiceEnabled(/* confirmed= */ false); 405 break; 406 case DialogInterface.BUTTON_NEGATIVE: 407 handleConfirmServiceEnabled(/* confirmed= */ true); 408 break; 409 default: 410 throw new IllegalArgumentException("Unexpected button identifier"); 411 } 412 } 413 onDialogButtonFromEnableToggleClicked(View view)414 private void onDialogButtonFromEnableToggleClicked(View view) { 415 final int viewId = view.getId(); 416 if (viewId == R.id.permission_enable_allow_button) { 417 onAllowButtonFromEnableToggleClicked(); 418 } else if (viewId == R.id.permission_enable_deny_button) { 419 onDenyButtonFromEnableToggleClicked(); 420 } else { 421 throw new IllegalArgumentException("Unexpected view id"); 422 } 423 } 424 onDialogButtonFromUninstallClicked()425 private void onDialogButtonFromUninstallClicked() { 426 mWarningDialog.dismiss(); 427 final Intent uninstallIntent = createUninstallPackageActivityIntent(); 428 if (uninstallIntent == null) { 429 return; 430 } 431 startActivity(uninstallIntent); 432 } 433 434 @Nullable createUninstallPackageActivityIntent()435 private Intent createUninstallPackageActivityIntent() { 436 final AccessibilityServiceInfo a11yServiceInfo = getAccessibilityServiceInfo(); 437 if (a11yServiceInfo == null) { 438 Log.w(TAG, "createUnInstallIntent -- invalid a11yServiceInfo"); 439 return null; 440 } 441 final ApplicationInfo appInfo = 442 a11yServiceInfo.getResolveInfo().serviceInfo.applicationInfo; 443 final Uri packageUri = Uri.parse("package:" + appInfo.packageName); 444 final Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri); 445 return uninstallIntent; 446 } 447 448 @Override onStop()449 public void onStop() { 450 super.onStop(); 451 unregisterPackageRemoveReceiver(); 452 } 453 454 @Override getPreferenceScreenResId()455 protected int getPreferenceScreenResId() { 456 // TODO(b/171272809): Add back when controllers move to static type 457 return 0; 458 } 459 460 @Override getLogTag()461 protected String getLogTag() { 462 return TAG; 463 } 464 465 @Override getDefaultShortcutTypes()466 protected int getDefaultShortcutTypes() { 467 if (android.view.accessibility.Flags.a11yQsShortcut()) { 468 AccessibilityServiceInfo info = getAccessibilityServiceInfo(); 469 boolean isAccessibilityTool = info != null && info.isAccessibilityTool(); 470 return !isAccessibilityTool || getTileComponentName() == null 471 ? super.getDefaultShortcutTypes() 472 : ShortcutConstants.UserShortcutType.QUICK_SETTINGS; 473 } 474 475 return super.getDefaultShortcutTypes(); 476 } 477 onAllowButtonFromEnableToggleClicked()478 private void onAllowButtonFromEnableToggleClicked() { 479 handleConfirmServiceEnabled(/* confirmed= */ true); 480 if (serviceSupportsAccessibilityButton()) { 481 mIsDialogShown.set(false); 482 showPopupDialog(DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL); 483 } 484 if (mWarningDialog != null) { 485 mWarningDialog.dismiss(); 486 } 487 } 488 onDenyButtonFromEnableToggleClicked()489 private void onDenyButtonFromEnableToggleClicked() { 490 handleConfirmServiceEnabled(/* confirmed= */ false); 491 mWarningDialog.dismiss(); 492 } 493 onDialogButtonFromShortcutToggleClicked(View view)494 void onDialogButtonFromShortcutToggleClicked(View view) { 495 final int viewId = view.getId(); 496 if (viewId == R.id.permission_enable_allow_button) { 497 onAllowButtonFromShortcutToggleClicked(); 498 } else if (viewId == R.id.permission_enable_deny_button) { 499 onDenyButtonFromShortcutToggleClicked(); 500 } else { 501 throw new IllegalArgumentException("Unexpected view id"); 502 } 503 } 504 onAllowButtonFromShortcutToggleClicked()505 void onAllowButtonFromShortcutToggleClicked() { 506 mShortcutPreference.setChecked(true); 507 508 final int shortcutTypes = getUserPreferredShortcutTypes(); 509 AccessibilityUtil.optInAllValuesToSettings(getPrefContext(), shortcutTypes, mComponentName); 510 511 mIsDialogShown.set(false); 512 showPopupDialog(DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL); 513 514 if (mWarningDialog != null) { 515 mWarningDialog.dismiss(); 516 } 517 518 mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext())); 519 } 520 onDenyButtonFromShortcutToggleClicked()521 private void onDenyButtonFromShortcutToggleClicked() { 522 mShortcutPreference.setChecked(false); 523 524 mWarningDialog.dismiss(); 525 } 526 onAllowButtonFromShortcutClicked()527 private void onAllowButtonFromShortcutClicked() { 528 mIsDialogShown.set(false); 529 if (Flags.editShortcutsInFullScreen()) { 530 EditShortcutsPreferenceFragment.showEditShortcutScreen( 531 getContext(), 532 getMetricsCategory(), 533 getShortcutTitle(), 534 mComponentName, 535 getIntent() 536 ); 537 } else { 538 showPopupDialog(DialogEnums.EDIT_SHORTCUT); 539 } 540 541 if (mWarningDialog != null) { 542 mWarningDialog.dismiss(); 543 } 544 } 545 onDenyButtonFromShortcutClicked()546 private void onDenyButtonFromShortcutClicked() { 547 mWarningDialog.dismiss(); 548 } 549 onPreferenceClick(boolean isChecked)550 private boolean onPreferenceClick(boolean isChecked) { 551 if (isChecked) { 552 mToggleServiceSwitchPreference.setChecked(false); 553 getArguments().putBoolean(AccessibilitySettings.EXTRA_CHECKED, 554 /* disableService */ false); 555 final boolean isWarningRequired = 556 getPrefContext().getSystemService(AccessibilityManager.class) 557 .isAccessibilityServiceWarningRequired(getAccessibilityServiceInfo()); 558 if (isWarningRequired) { 559 showPopupDialog(DialogEnums.ENABLE_WARNING_FROM_TOGGLE); 560 } else { 561 onAllowButtonFromEnableToggleClicked(); 562 } 563 } else { 564 mToggleServiceSwitchPreference.setChecked(true); 565 getArguments().putBoolean(AccessibilitySettings.EXTRA_CHECKED, 566 /* enableService */ true); 567 showDialog(DialogEnums.DISABLE_WARNING_FROM_TOGGLE); 568 } 569 return true; 570 } 571 showPopupDialog(int dialogId)572 private void showPopupDialog(int dialogId) { 573 if (mIsDialogShown.compareAndSet(/* expect= */ false, /* update= */ true)) { 574 showDialog(dialogId); 575 setOnDismissListener( 576 dialog -> mIsDialogShown.compareAndSet(/* expect= */ true, /* update= */ 577 false)); 578 } 579 } 580 logDisabledState(String packageName)581 private void logDisabledState(String packageName) { 582 if (mStartTimeMillsForLogging > 0 && !mDisabledStateLogged) { 583 AccessibilityStatsLogUtils.logDisableNonA11yCategoryService( 584 packageName, 585 SystemClock.elapsedRealtime() - mStartTimeMillsForLogging); 586 mDisabledStateLogged = true; 587 } 588 } 589 } 590