1 /* 2 * Copyright (C) 2009 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; 18 19 import android.app.AlertDialog; 20 import android.app.Dialog; 21 import android.app.backup.IBackupManager; 22 import android.content.ContentResolver; 23 import android.content.Context; 24 import android.content.DialogInterface; 25 import android.content.Intent; 26 import android.os.Bundle; 27 import android.os.Process; 28 import android.os.RemoteException; 29 import android.os.ServiceManager; 30 import android.os.UserHandle; 31 import android.os.UserManager; 32 import android.preference.Preference; 33 import android.preference.Preference.OnPreferenceChangeListener; 34 import android.preference.PreferenceScreen; 35 import android.preference.SwitchPreference; 36 import android.provider.SearchIndexableResource; 37 import android.provider.Settings; 38 39 import com.android.settings.search.BaseSearchIndexProvider; 40 import com.android.settings.search.Indexable.SearchIndexProvider; 41 42 import java.util.ArrayList; 43 import java.util.List; 44 45 /** 46 * Gesture lock pattern settings. 47 */ 48 public class PrivacySettings extends SettingsPreferenceFragment implements 49 DialogInterface.OnClickListener { 50 51 // Vendor specific 52 private static final String GSETTINGS_PROVIDER = "com.google.settings"; 53 private static final String BACKUP_CATEGORY = "backup_category"; 54 private static final String BACKUP_DATA = "backup_data"; 55 private static final String AUTO_RESTORE = "auto_restore"; 56 private static final String CONFIGURE_ACCOUNT = "configure_account"; 57 private static final String PERSONAL_DATA_CATEGORY = "personal_data_category"; 58 private IBackupManager mBackupManager; 59 private SwitchPreference mBackup; 60 private SwitchPreference mAutoRestore; 61 private Dialog mConfirmDialog; 62 private PreferenceScreen mConfigure; 63 private boolean mEnabled; 64 65 private static final int DIALOG_ERASE_BACKUP = 2; 66 private int mDialogType; 67 68 @Override onCreate(Bundle savedInstanceState)69 public void onCreate(Bundle savedInstanceState) { 70 super.onCreate(savedInstanceState); 71 // Don't allow any access if this is a secondary user 72 mEnabled = Process.myUserHandle().isOwner(); 73 if (!mEnabled) { 74 return; 75 } 76 77 addPreferencesFromResource(R.xml.privacy_settings); 78 final PreferenceScreen screen = getPreferenceScreen(); 79 mBackupManager = IBackupManager.Stub.asInterface( 80 ServiceManager.getService(Context.BACKUP_SERVICE)); 81 82 mBackup = (SwitchPreference) screen.findPreference(BACKUP_DATA); 83 mBackup.setOnPreferenceChangeListener(preferenceChangeListener); 84 85 mAutoRestore = (SwitchPreference) screen.findPreference(AUTO_RESTORE); 86 mAutoRestore.setOnPreferenceChangeListener(preferenceChangeListener); 87 88 mConfigure = (PreferenceScreen) screen.findPreference(CONFIGURE_ACCOUNT); 89 90 if (UserManager.get(getActivity()).hasUserRestriction( 91 UserManager.DISALLOW_FACTORY_RESET)) { 92 screen.removePreference(findPreference(PERSONAL_DATA_CATEGORY)); 93 } 94 95 // Vendor specific 96 if (getActivity().getPackageManager(). 97 resolveContentProvider(GSETTINGS_PROVIDER, 0) == null) { 98 screen.removePreference(findPreference(BACKUP_CATEGORY)); 99 } 100 updateToggles(); 101 } 102 103 @Override onResume()104 public void onResume() { 105 super.onResume(); 106 107 // Refresh UI 108 if (mEnabled) { 109 updateToggles(); 110 } 111 } 112 113 @Override onStop()114 public void onStop() { 115 if (mConfirmDialog != null && mConfirmDialog.isShowing()) { 116 mConfirmDialog.dismiss(); 117 } 118 mConfirmDialog = null; 119 mDialogType = 0; 120 super.onStop(); 121 } 122 123 private OnPreferenceChangeListener preferenceChangeListener = new OnPreferenceChangeListener() { 124 @Override 125 public boolean onPreferenceChange(Preference preference, Object newValue) { 126 if (!(preference instanceof SwitchPreference)) { 127 return true; 128 } 129 boolean nextValue = (Boolean) newValue; 130 boolean result = false; 131 if (preference == mBackup) { 132 if (nextValue == false) { 133 // Don't change Switch status until user makes choice in dialog 134 // so return false here. 135 showEraseBackupDialog(); 136 } else { 137 setBackupEnabled(true); 138 result = true; 139 } 140 } else if (preference == mAutoRestore) { 141 try { 142 mBackupManager.setAutoRestore(nextValue); 143 result = true; 144 } catch (RemoteException e) { 145 mAutoRestore.setChecked(!nextValue); 146 } 147 } 148 return result; 149 } 150 }; 151 showEraseBackupDialog()152 private void showEraseBackupDialog() { 153 mDialogType = DIALOG_ERASE_BACKUP; 154 CharSequence msg = getResources().getText(R.string.backup_erase_dialog_message); 155 // TODO: DialogFragment? 156 mConfirmDialog = new AlertDialog.Builder(getActivity()).setMessage(msg) 157 .setTitle(R.string.backup_erase_dialog_title) 158 .setPositiveButton(android.R.string.ok, this) 159 .setNegativeButton(android.R.string.cancel, this) 160 .show(); 161 } 162 163 /* 164 * Creates toggles for each available location provider 165 */ updateToggles()166 private void updateToggles() { 167 ContentResolver res = getContentResolver(); 168 169 boolean backupEnabled = false; 170 Intent configIntent = null; 171 String configSummary = null; 172 try { 173 backupEnabled = mBackupManager.isBackupEnabled(); 174 String transport = mBackupManager.getCurrentTransport(); 175 configIntent = mBackupManager.getConfigurationIntent(transport); 176 configSummary = mBackupManager.getDestinationString(transport); 177 } catch (RemoteException e) { 178 // leave it 'false' and disable the UI; there's no backup manager 179 mBackup.setEnabled(false); 180 } 181 mBackup.setChecked(backupEnabled); 182 183 mAutoRestore.setChecked(Settings.Secure.getInt(res, 184 Settings.Secure.BACKUP_AUTO_RESTORE, 1) == 1); 185 mAutoRestore.setEnabled(backupEnabled); 186 187 final boolean configureEnabled = (configIntent != null) && backupEnabled; 188 mConfigure.setEnabled(configureEnabled); 189 mConfigure.setIntent(configIntent); 190 setConfigureSummary(configSummary); 191 } 192 setConfigureSummary(String summary)193 private void setConfigureSummary(String summary) { 194 if (summary != null) { 195 mConfigure.setSummary(summary); 196 } else { 197 mConfigure.setSummary(R.string.backup_configure_account_default_summary); 198 } 199 } 200 updateConfigureSummary()201 private void updateConfigureSummary() { 202 try { 203 String transport = mBackupManager.getCurrentTransport(); 204 String summary = mBackupManager.getDestinationString(transport); 205 setConfigureSummary(summary); 206 } catch (RemoteException e) { 207 // Not much we can do here 208 } 209 } 210 211 @Override onClick(DialogInterface dialog, int which)212 public void onClick(DialogInterface dialog, int which) { 213 // Dialog is triggered before Switch status change, that means marking the Switch to 214 // true in showEraseBackupDialog() method will be override by following status change. 215 // So we do manual switching here due to users' response. 216 if (mDialogType == DIALOG_ERASE_BACKUP) { 217 // Accept turning off backup 218 if (which == DialogInterface.BUTTON_POSITIVE) { 219 setBackupEnabled(false); 220 } else if (which == DialogInterface.BUTTON_NEGATIVE) { 221 // Reject turning off backup 222 setBackupEnabled(true); 223 } 224 updateConfigureSummary(); 225 } 226 mDialogType = 0; 227 } 228 229 /** 230 * Informs the BackupManager of a change in backup state - if backup is disabled, 231 * the data on the server will be erased. 232 * @param enable whether to enable backup 233 */ setBackupEnabled(boolean enable)234 private void setBackupEnabled(boolean enable) { 235 if (mBackupManager != null) { 236 try { 237 mBackupManager.setBackupEnabled(enable); 238 } catch (RemoteException e) { 239 mBackup.setChecked(!enable); 240 mAutoRestore.setEnabled(!enable); 241 return; 242 } 243 } 244 mBackup.setChecked(enable); 245 mAutoRestore.setEnabled(enable); 246 mConfigure.setEnabled(enable); 247 } 248 249 @Override getHelpResource()250 protected int getHelpResource() { 251 return R.string.help_url_backup_reset; 252 } 253 254 /** 255 * For Search. 256 */ 257 public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = 258 new PrivacySearchIndexProvider(); 259 260 private static class PrivacySearchIndexProvider extends BaseSearchIndexProvider { 261 262 boolean mIsPrimary; 263 PrivacySearchIndexProvider()264 public PrivacySearchIndexProvider() { 265 super(); 266 267 mIsPrimary = UserHandle.myUserId() == UserHandle.USER_OWNER; 268 } 269 270 @Override getXmlResourcesToIndex( Context context, boolean enabled)271 public List<SearchIndexableResource> getXmlResourcesToIndex( 272 Context context, boolean enabled) { 273 274 List<SearchIndexableResource> result = new ArrayList<SearchIndexableResource>(); 275 276 // For non-primary user, no backup or reset is available 277 if (!mIsPrimary) { 278 return result; 279 } 280 281 SearchIndexableResource sir = new SearchIndexableResource(context); 282 sir.xmlResId = R.xml.privacy_settings; 283 result.add(sir); 284 285 return result; 286 } 287 } 288 289 }