• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.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
onCreate(Bundle savedInstanceState)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
onViewCreated(View view, Bundle savedInstanceState)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
onDestroyView()104     public void onDestroyView() {
105         super.onDestroyView();
106 
107         mToggleSwitch.setOnBeforeCheckedChangeListener(null);
108         mSwitchBar.hide();
109     }
110 
111     @Override
onActivityCreated(Bundle savedInstanceState)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
onStop()139     public void onStop() {
140         if (mConfirmDialog != null && mConfirmDialog.isShowing()) {
141             mConfirmDialog.dismiss();
142         }
143         mConfirmDialog = null;
144         super.onStop();
145     }
146 
147     @Override
onClick(DialogInterface dialog, int which)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
onDismiss(DialogInterface dialog)163     public void onDismiss(DialogInterface dialog) {
164         if (mWaitingForConfirmationDialog) {
165             // dismiss turning off backup
166             setBackupEnabled(true);
167             mSwitchBar.setCheckedInternal(true);
168         }
169     }
170 
showEraseBackupDialog()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
getMetricsCategory()195     protected 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      */
setBackupEnabled(boolean enable)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