/**
   * Updates the preference that controls whether TalkBack will attempt to request Explore by Touch.
   *
   * @param requestedState The state requested by the user.
   * @return Whether to update the reflected state.
   */
  private boolean setTouchExplorationRequested(boolean requestedState) {
    final SharedPreferences prefs =
        PreferenceManager.getDefaultSharedPreferences(TalkBackPreferencesActivity.this);

    // Update the "requested" state. This will trigger a listener in
    // TalkBack that changes the "actual" state.
    SharedPreferencesUtils.putBooleanPref(
        prefs, getResources(), R.string.pref_explore_by_touch_key, requestedState);

    // If TalkBack is inactive, we should immediately reflect the change in
    // "requested" state.
    if (!MyAccessibilityService.isServiceActive()) {
      return true;
    }
    if (requestedState && MyAccessibilityService.getInstance() != null) {
      // TODO
      //            MyAccessibilityService.getInstance().showTutorial();
    }

    // If accessibility is on, we should wait for the "actual" state to
    // change, then reflect that change. If the user declines the system's
    // touch exploration dialog, the "actual" state will not change and
    // nothing needs to happen.
    LogUtils.log(this, Log.DEBUG, "TalkBack active, waiting for EBT request to take effect");
    return false;
  }
  @Override
  public void onPause() {
    super.onPause();
    MyAccessibilityService talkBackService = MyAccessibilityService.getInstance();
    if (talkBackService != null && talkBackService.supportsTouchScreen()) {
      getContentResolver().unregisterContentObserver(mTouchExploreObserver);
    }

    if (mExploreByTouchDialog != null) {
      mExploreByTouchDialog.dismiss();
    }

    if (mTreeDebugDialog != null) {
      mTreeDebugDialog.dismiss();
    }
  }
  @Override
  public void onResume() {
    super.onResume();
    MyAccessibilityService talkBackService = MyAccessibilityService.getInstance();
    if (talkBackService != null && talkBackService.supportsTouchScreen()) {
      registerTouchSettingObserver();
    }

    if (mExploreByTouchDialog != null) {
      mExploreByTouchDialog.show();
    }

    if (mTreeDebugDialog != null) {
      mTreeDebugDialog.show();
    }

    updateTalkBackShortcutStatus();
    updateDimingPreferenceStatus();
  }
  private void updateDimingPreferenceStatus() {
    final CheckBoxPreference dimPreference =
        (CheckBoxPreference) findPreferenceByResId(R.string.pref_dim_when_talkback_enabled_key);
    if (dimPreference == null) {
      return;
    }

    if (Build.VERSION.SDK_INT < ProcessorVolumeStream.MIN_API_LEVEL) {
      final PreferenceGroup category =
          (PreferenceGroup) findPreferenceByResId(R.string.pref_category_miscellaneous_key);
      if (category == null) {
        return;
      }
      category.removePreference(dimPreference);
      return;
    }

    dimPreference.setEnabled(MyAccessibilityService.isServiceActive() || dimPreference.isChecked());
    dimPreference.setOnPreferenceChangeListener(
        new OnPreferenceChangeListener() {
          @Override
          public boolean onPreferenceChange(Preference preference, Object newValue) {
            if (newValue == null || !(newValue instanceof Boolean)) {
              return true;
            }

            boolean boolValue = (Boolean) newValue;

            if (!boolValue && !MyAccessibilityService.isServiceActive()) {
              dimPreference.setEnabled(false);
            } else if (boolValue
                && mPrefs.getBoolean(
                    getString(R.string.pref_show_dim_screen_confirmation_dialog), true)) {
              showDimScreenDialog(
                  new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                      dimPreference.setChecked(true);
                    }
                  });
              return false;
            }
            return true;
          }
        });
  }
 private void updateTalkBackShortcutStatus() {
   final CheckBoxPreference preference =
       (CheckBoxPreference) findPreferenceByResId(R.string.pref_two_volume_long_press_key);
   if (preference == null) {
     return;
   }
   if (Build.VERSION.SDK_INT >= ProcessorVolumeStream.MIN_API_LEVEL) {
     preference.setEnabled(MyAccessibilityService.getInstance() != null || preference.isChecked());
   } else {
     final PreferenceGroup category =
         (PreferenceGroup) findPreferenceByResId(R.string.pref_category_miscellaneous_key);
     if (category == null) {
       return;
     }
     category.removePreference(preference);
   }
 }
  /**
   * Updates the preferences state to match the actual state of touch exploration. This is called
   * once when the preferences activity launches and again whenever the actual state of touch
   * exploration changes.
   */
  @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
  private void updateTouchExplorationState() {
    final CheckBoxPreference prefTouchExploration =
        (CheckBoxPreference) findPreferenceByResId(R.string.pref_explore_by_touch_reflect_key);

    if (prefTouchExploration == null) {
      return;
    }

    final ContentResolver resolver = getContentResolver();
    final Resources res = getResources();
    final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
    final boolean requestedState =
        SharedPreferencesUtils.getBooleanPref(
            prefs, res, R.string.pref_explore_by_touch_key, R.bool.pref_explore_by_touch_default);
    final boolean reflectedState = prefTouchExploration.isChecked();
    final boolean actualState;

    // If accessibility is disabled then touch exploration is always
    // disabled, so the "actual" state should just be the requested state.
    if (MyAccessibilityService.isServiceActive()) {
      actualState = isTouchExplorationEnabled(resolver);
    } else {
      actualState = requestedState;
    }

    // If touch exploration is actually off and we requested it on, the user
    // must have declined the "Enable touch exploration" dialog. Update the
    // requested value to reflect this.
    if (requestedState != actualState) {
      LogUtils.log(
          this,
          Log.DEBUG,
          "Set touch exploration preference to reflect actual state %b",
          actualState);
      SharedPreferencesUtils.putBooleanPref(
          prefs, res, R.string.pref_explore_by_touch_key, actualState);
    }

    // Ensure that the check box preference reflects the requested state,
    // which was just synchronized to match the actual state.
    if (reflectedState != actualState) {
      prefTouchExploration.setChecked(actualState);
    }
  }