| package com.android.settings.backup; |
| |
| import android.app.Dialog; |
| import android.app.backup.IBackupManager; |
| import android.content.Context; |
| import android.content.DialogInterface; |
| import android.os.Bundle; |
| import android.os.RemoteException; |
| import android.os.ServiceManager; |
| import android.provider.Settings; |
| import android.util.Log; |
| import android.view.View; |
| import android.widget.TextView; |
| |
| import androidx.appcompat.app.AlertDialog; |
| import androidx.preference.Preference; |
| import androidx.preference.PreferenceScreen; |
| import androidx.preference.PreferenceViewHolder; |
| |
| import com.android.internal.logging.nano.MetricsProto.MetricsEvent; |
| import com.android.settings.R; |
| import com.android.settings.SettingsActivity; |
| import com.android.settings.SettingsPreferenceFragment; |
| import com.android.settings.widget.SwitchBar; |
| import com.android.settings.widget.ToggleSwitch; |
| |
| /** |
| * Fragment to display a bunch of text about backup and restore, and allow the user to enable/ |
| * disable it. |
| */ |
| public class ToggleBackupSettingFragment extends SettingsPreferenceFragment |
| implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener { |
| private static final String TAG = "ToggleBackupSettingFragment"; |
| |
| private static final String BACKUP_TOGGLE = "toggle_backup"; |
| |
| // System setting that governs whether the user is eligible for full app-data backup, |
| // based on whether they have been presented with the details of what that backup entails |
| // (usually surfaced somewhere like device setup) |
| private static final String USER_FULL_DATA_BACKUP_AWARE = "user_full_data_backup_aware"; |
| |
| private IBackupManager mBackupManager; |
| |
| protected SwitchBar mSwitchBar; |
| protected ToggleSwitch mToggleSwitch; |
| |
| private Preference mSummaryPreference; |
| |
| private Dialog mConfirmDialog; |
| |
| private boolean mWaitingForConfirmationDialog = false; |
| |
| @Override |
| public void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| |
| mBackupManager = IBackupManager.Stub.asInterface( |
| ServiceManager.getService(Context.BACKUP_SERVICE)); |
| |
| PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen( |
| getActivity()); |
| setPreferenceScreen(preferenceScreen); |
| mSummaryPreference = new Preference(getPrefContext()) { |
| @Override |
| public void onBindViewHolder(PreferenceViewHolder view) { |
| super.onBindViewHolder(view); |
| final TextView summaryView = (TextView) view.findViewById(android.R.id.summary); |
| summaryView.setText(getSummary()); |
| } |
| }; |
| mSummaryPreference.setPersistent(false); |
| mSummaryPreference.setLayoutResource(R.layout.text_description_preference); |
| preferenceScreen.addPreference(mSummaryPreference); |
| } |
| |
| @Override |
| public void onViewCreated(View view, Bundle savedInstanceState) { |
| super.onViewCreated(view, savedInstanceState); |
| |
| SettingsActivity activity = (SettingsActivity) getActivity(); |
| mSwitchBar = activity.getSwitchBar(); |
| mToggleSwitch = mSwitchBar.getSwitch(); |
| |
| // Set up UI. |
| // If the user has not seen legal text for full data backup (if they OTA from L to M) then |
| // full data backup will be off and here we want to show the old summary here that does |
| // not mention full data backup |
| if (Settings.Secure.getInt(getContentResolver(), USER_FULL_DATA_BACKUP_AWARE, 0) != 0) { |
| mSummaryPreference.setSummary(R.string.fullbackup_data_summary); |
| } else { |
| mSummaryPreference.setSummary(R.string.backup_data_summary); |
| } |
| try { |
| boolean backupEnabled = mBackupManager == null ? |
| false : mBackupManager.isBackupEnabled(); |
| mSwitchBar.setCheckedInternal(backupEnabled); |
| } catch (RemoteException e) { |
| // The world is aflame, turn it off. |
| mSwitchBar.setEnabled(false); |
| } |
| getActivity().setTitle(R.string.backup_data_title); |
| } |
| |
| @Override |
| public void onDestroyView() { |
| super.onDestroyView(); |
| |
| mToggleSwitch.setOnBeforeCheckedChangeListener(null); |
| mSwitchBar.hide(); |
| } |
| |
| @Override |
| public void onActivityCreated(Bundle savedInstanceState) { |
| super.onActivityCreated(savedInstanceState); |
| |
| // Set up toggle listener. We need this b/c we have to intercept the toggle event in order |
| // to pop up the dialogue. |
| mToggleSwitch.setOnBeforeCheckedChangeListener( |
| new ToggleSwitch.OnBeforeCheckedChangeListener() { |
| @Override |
| public boolean onBeforeCheckedChanged( |
| ToggleSwitch toggleSwitch, boolean checked) { |
| if (!checked) { |
| // Don't change Switch status until user makes choice in dialog |
| // so return true here. |
| showEraseBackupDialog(); |
| return true; |
| } else { |
| setBackupEnabled(true); |
| mSwitchBar.setCheckedInternal(true); |
| return true; |
| } |
| } |
| }); |
| mSwitchBar.show(); |
| } |
| |
| /** Get rid of the dialog if it's still showing. */ |
| @Override |
| public void onStop() { |
| if (mConfirmDialog != null && mConfirmDialog.isShowing()) { |
| mConfirmDialog.dismiss(); |
| } |
| mConfirmDialog = null; |
| super.onStop(); |
| } |
| |
| @Override |
| public void onClick(DialogInterface dialog, int which) { |
| // Accept turning off backup |
| if (which == DialogInterface.BUTTON_POSITIVE) { |
| mWaitingForConfirmationDialog = false; |
| setBackupEnabled(false); |
| mSwitchBar.setCheckedInternal(false); |
| } else if (which == DialogInterface.BUTTON_NEGATIVE) { |
| // Reject turning off backup |
| mWaitingForConfirmationDialog = false; |
| setBackupEnabled(true); |
| mSwitchBar.setCheckedInternal(true); |
| } |
| } |
| |
| @Override |
| public void onDismiss(DialogInterface dialog) { |
| if (mWaitingForConfirmationDialog) { |
| // dismiss turning off backup |
| setBackupEnabled(true); |
| mSwitchBar.setCheckedInternal(true); |
| } |
| } |
| |
| private void showEraseBackupDialog() { |
| CharSequence msg; |
| |
| // If the user has not seen legal text for full data backup (if they OTA from L to M) then |
| // full data backup will be off and here we want to show the old erase_dialog_message here |
| // that does not mention full data backup |
| if (Settings.Secure.getInt(getContentResolver(), USER_FULL_DATA_BACKUP_AWARE, 0) != 0) { |
| msg = getResources().getText(R.string.fullbackup_erase_dialog_message); |
| } else { |
| msg = getResources().getText(R.string.backup_erase_dialog_message); |
| } |
| |
| mWaitingForConfirmationDialog = true; |
| |
| // TODO: DialogFragment? |
| mConfirmDialog = new AlertDialog.Builder(getActivity()).setMessage(msg) |
| .setTitle(R.string.backup_erase_dialog_title) |
| .setPositiveButton(android.R.string.ok, this) |
| .setNegativeButton(android.R.string.cancel, this) |
| .setOnDismissListener(this) |
| .show(); |
| } |
| |
| @Override |
| public int getMetricsCategory() { |
| return MetricsEvent.PRIVACY; |
| } |
| |
| /** |
| * Informs the BackupManager of a change in backup state - if backup is disabled, |
| * the data on the server will be erased. |
| * @param enable whether to enable backup |
| */ |
| private void setBackupEnabled(boolean enable) { |
| if (mBackupManager != null) { |
| try { |
| mBackupManager.setBackupEnabled(enable); |
| } catch (RemoteException e) { |
| Log.e(TAG, "Error communicating with BackupManager", e); |
| return; |
| } |
| } |
| } |
| } |