1 package com.android.settings.backup; 2 3 import android.app.AlertDialog; 4 import android.app.Dialog; 5 import android.app.backup.IBackupManager; 6 import android.content.Context; 7 import android.content.DialogInterface; 8 import android.os.Bundle; 9 import android.os.RemoteException; 10 import android.os.ServiceManager; 11 import android.provider.Settings; 12 import android.support.v7.preference.Preference; 13 import android.support.v7.preference.PreferenceScreen; 14 import android.support.v7.preference.PreferenceViewHolder; 15 import android.util.Log; 16 import android.view.View; 17 import android.widget.TextView; 18 19 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 20 import com.android.settings.R; 21 import com.android.settings.SettingsActivity; 22 import com.android.settings.SettingsPreferenceFragment; 23 import com.android.settings.widget.SwitchBar; 24 import com.android.settings.widget.ToggleSwitch; 25 26 /** 27 * Fragment to display a bunch of text about backup and restore, and allow the user to enable/ 28 * disable it. 29 */ 30 public class ToggleBackupSettingFragment extends SettingsPreferenceFragment 31 implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener { 32 private static final String TAG = "ToggleBackupSettingFragment"; 33 34 private static final String BACKUP_TOGGLE = "toggle_backup"; 35 36 // System setting that governs whether the user is eligible for full app-data backup, 37 // based on whether they have been presented with the details of what that backup entails 38 // (usually surfaced somewhere like device setup) 39 private static final String USER_FULL_DATA_BACKUP_AWARE = "user_full_data_backup_aware"; 40 41 private IBackupManager mBackupManager; 42 43 protected SwitchBar mSwitchBar; 44 protected ToggleSwitch mToggleSwitch; 45 46 private Preference mSummaryPreference; 47 48 private Dialog mConfirmDialog; 49 50 private boolean mWaitingForConfirmationDialog = false; 51 52 @Override 53 public void onCreate(Bundle savedInstanceState) { 54 super.onCreate(savedInstanceState); 55 56 mBackupManager = IBackupManager.Stub.asInterface( 57 ServiceManager.getService(Context.BACKUP_SERVICE)); 58 59 PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen( 60 getActivity()); 61 setPreferenceScreen(preferenceScreen); 62 mSummaryPreference = new Preference(getPrefContext()) { 63 @Override 64 public void onBindViewHolder(PreferenceViewHolder view) { 65 super.onBindViewHolder(view); 66 final TextView summaryView = (TextView) view.findViewById(android.R.id.summary); 67 summaryView.setText(getSummary()); 68 } 69 }; 70 mSummaryPreference.setPersistent(false); 71 mSummaryPreference.setLayoutResource(R.layout.text_description_preference); 72 preferenceScreen.addPreference(mSummaryPreference); 73 } 74 75 @Override 76 public void onViewCreated(View view, Bundle savedInstanceState) { 77 super.onViewCreated(view, savedInstanceState); 78 79 SettingsActivity activity = (SettingsActivity) getActivity(); 80 mSwitchBar = activity.getSwitchBar(); 81 mToggleSwitch = mSwitchBar.getSwitch(); 82 83 // Set up UI. 84 // If the user has not seen legal text for full data backup (if they OTA from L to M) then 85 // full data backup will be off and here we want to show the old summary here that does 86 // not mention full data backup 87 if (Settings.Secure.getInt(getContentResolver(), USER_FULL_DATA_BACKUP_AWARE, 0) != 0) { 88 mSummaryPreference.setSummary(R.string.fullbackup_data_summary); 89 } else { 90 mSummaryPreference.setSummary(R.string.backup_data_summary); 91 } 92 try { 93 boolean backupEnabled = mBackupManager == null ? 94 false : mBackupManager.isBackupEnabled(); 95 mSwitchBar.setCheckedInternal(backupEnabled); 96 } catch (RemoteException e) { 97 // The world is aflame, turn it off. 98 mSwitchBar.setEnabled(false); 99 } 100 getActivity().setTitle(R.string.backup_data_title); 101 } 102 103 @Override 104 public void onDestroyView() { 105 super.onDestroyView(); 106 107 mToggleSwitch.setOnBeforeCheckedChangeListener(null); 108 mSwitchBar.hide(); 109 } 110 111 @Override 112 public void onActivityCreated(Bundle savedInstanceState) { 113 super.onActivityCreated(savedInstanceState); 114 115 // Set up toggle listener. We need this b/c we have to intercept the toggle event in order 116 // to pop up the dialogue. 117 mToggleSwitch.setOnBeforeCheckedChangeListener( 118 new ToggleSwitch.OnBeforeCheckedChangeListener() { 119 @Override 120 public boolean onBeforeCheckedChanged( 121 ToggleSwitch toggleSwitch, boolean checked) { 122 if (!checked) { 123 // Don't change Switch status until user makes choice in dialog 124 // so return true here. 125 showEraseBackupDialog(); 126 return true; 127 } else { 128 setBackupEnabled(true); 129 mSwitchBar.setCheckedInternal(true); 130 return true; 131 } 132 } 133 }); 134 mSwitchBar.show(); 135 } 136 137 /** Get rid of the dialog if it's still showing. */ 138 @Override 139 public void onStop() { 140 if (mConfirmDialog != null && mConfirmDialog.isShowing()) { 141 mConfirmDialog.dismiss(); 142 } 143 mConfirmDialog = null; 144 super.onStop(); 145 } 146 147 @Override 148 public void onClick(DialogInterface dialog, int which) { 149 // Accept turning off backup 150 if (which == DialogInterface.BUTTON_POSITIVE) { 151 mWaitingForConfirmationDialog = false; 152 setBackupEnabled(false); 153 mSwitchBar.setCheckedInternal(false); 154 } else if (which == DialogInterface.BUTTON_NEGATIVE) { 155 // Reject turning off backup 156 mWaitingForConfirmationDialog = false; 157 setBackupEnabled(true); 158 mSwitchBar.setCheckedInternal(true); 159 } 160 } 161 162 @Override 163 public void onDismiss(DialogInterface dialog) { 164 if (mWaitingForConfirmationDialog) { 165 // dismiss turning off backup 166 setBackupEnabled(true); 167 mSwitchBar.setCheckedInternal(true); 168 } 169 } 170 171 private void showEraseBackupDialog() { 172 CharSequence msg; 173 174 // If the user has not seen legal text for full data backup (if they OTA from L to M) then 175 // full data backup will be off and here we want to show the old erase_dialog_message here 176 // that does not mention full data backup 177 if (Settings.Secure.getInt(getContentResolver(), USER_FULL_DATA_BACKUP_AWARE, 0) != 0) { 178 msg = getResources().getText(R.string.fullbackup_erase_dialog_message); 179 } else { 180 msg = getResources().getText(R.string.backup_erase_dialog_message); 181 } 182 183 mWaitingForConfirmationDialog = true; 184 185 // TODO: DialogFragment? 186 mConfirmDialog = new AlertDialog.Builder(getActivity()).setMessage(msg) 187 .setTitle(R.string.backup_erase_dialog_title) 188 .setPositiveButton(android.R.string.ok, this) 189 .setNegativeButton(android.R.string.cancel, this) 190 .setOnDismissListener(this) 191 .show(); 192 } 193 194 @Override 195 public int getMetricsCategory() { 196 return MetricsEvent.PRIVACY; 197 } 198 199 /** 200 * Informs the BackupManager of a change in backup state - if backup is disabled, 201 * the data on the server will be erased. 202 * @param enable whether to enable backup 203 */ 204 private void setBackupEnabled(boolean enable) { 205 if (mBackupManager != null) { 206 try { 207 mBackupManager.setBackupEnabled(enable); 208 } catch (RemoteException e) { 209 Log.e(TAG, "Error communicating with BackupManager", e); 210 return; 211 } 212 } 213 } 214 } 215