PrivacySettings.java revision ac81f26e30352dd441c099012c4489701d9aee2f
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 17package com.android.settings; 18 19import android.app.backup.IBackupManager; 20import android.content.ContentResolver; 21import android.content.Context; 22import android.content.Intent; 23import android.content.pm.PackageManager; 24import android.content.pm.ResolveInfo; 25import android.os.Bundle; 26import android.os.RemoteException; 27import android.os.ServiceManager; 28import android.os.UserHandle; 29import android.os.UserManager; 30import android.provider.SearchIndexableResource; 31import android.provider.Settings; 32import android.support.annotation.VisibleForTesting; 33import android.support.v14.preference.SwitchPreference; 34import android.support.v7.preference.Preference; 35import android.support.v7.preference.Preference.OnPreferenceChangeListener; 36import android.support.v7.preference.PreferenceScreen; 37import android.util.Log; 38 39import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 40import com.android.settings.search.BaseSearchIndexProvider; 41import com.android.settings.search.Indexable; 42import com.android.settingslib.RestrictedLockUtils; 43 44import java.util.ArrayList; 45import java.util.Collection; 46import java.util.HashSet; 47import java.util.List; 48import java.util.Set; 49 50/** 51 * Gesture lock pattern settings. 52 */ 53public class PrivacySettings extends SettingsPreferenceFragment implements Indexable { 54 55 // Vendor specific 56 private static final String GSETTINGS_PROVIDER = "com.google.settings"; 57 @VisibleForTesting 58 static final String BACKUP_DATA = "backup_data"; 59 @VisibleForTesting 60 static final String AUTO_RESTORE = "auto_restore"; 61 @VisibleForTesting 62 static final String CONFIGURE_ACCOUNT = "configure_account"; 63 @VisibleForTesting 64 static final String DATA_MANAGEMENT = "data_management"; 65 private static final String BACKUP_INACTIVE = "backup_inactive"; 66 private static final String FACTORY_RESET = "factory_reset"; 67 private static final String TAG = "PrivacySettings"; 68 private IBackupManager mBackupManager; 69 private Preference mBackup; 70 private SwitchPreference mAutoRestore; 71 private Preference mConfigure; 72 private Preference mManageData; 73 private boolean mEnabled; 74 75 @Override 76 public int getMetricsCategory() { 77 return MetricsEvent.PRIVACY; 78 } 79 80 @Override 81 public void onCreate(Bundle savedInstanceState) { 82 super.onCreate(savedInstanceState); 83 // Don't allow any access if this is not an admin user. 84 // TODO: backup/restore currently only works with owner user b/22760572 85 mEnabled = UserManager.get(getActivity()).isAdminUser(); 86 if (!mEnabled) { 87 return; 88 } 89 90 addPreferencesFromResource(R.xml.privacy_settings); 91 final PreferenceScreen screen = getPreferenceScreen(); 92 mBackupManager = IBackupManager.Stub.asInterface( 93 ServiceManager.getService(Context.BACKUP_SERVICE)); 94 95 setPreferenceReferences(screen); 96 97 Set<String> keysToRemove = new HashSet<>(); 98 getNonVisibleKeys(getActivity(), keysToRemove); 99 final int screenPreferenceCount = screen.getPreferenceCount(); 100 for (int i = screenPreferenceCount - 1; i >= 0; --i) { 101 Preference preference = screen.getPreference(i); 102 if (keysToRemove.contains(preference.getKey())) { 103 screen.removePreference(preference); 104 } 105 } 106 107 updateToggles(); 108 } 109 110 @Override 111 public void onResume() { 112 super.onResume(); 113 114 // Refresh UI 115 if (mEnabled) { 116 updateToggles(); 117 } 118 } 119 120 @VisibleForTesting 121 void setPreferenceReferences(PreferenceScreen screen) { 122 mBackup = screen.findPreference(BACKUP_DATA); 123 124 mAutoRestore = (SwitchPreference) screen.findPreference(AUTO_RESTORE); 125 mAutoRestore.setOnPreferenceChangeListener(preferenceChangeListener); 126 127 mConfigure = screen.findPreference(CONFIGURE_ACCOUNT); 128 mManageData = screen.findPreference(DATA_MANAGEMENT); 129 } 130 131 private OnPreferenceChangeListener preferenceChangeListener = new OnPreferenceChangeListener() { 132 @Override 133 public boolean onPreferenceChange(Preference preference, Object newValue) { 134 if (!(preference instanceof SwitchPreference)) { 135 return true; 136 } 137 boolean nextValue = (Boolean) newValue; 138 boolean result = false; 139 if (preference == mAutoRestore) { 140 try { 141 mBackupManager.setAutoRestore(nextValue); 142 result = true; 143 } catch (RemoteException e) { 144 mAutoRestore.setChecked(!nextValue); 145 } 146 } 147 return result; 148 } 149 }; 150 151 152 /* 153 * Creates toggles for each backup/reset preference. 154 */ 155 private void updateToggles() { 156 ContentResolver res = getContentResolver(); 157 158 boolean backupEnabled = false; 159 Intent configIntent = null; 160 String configSummary = null; 161 Intent manageIntent = null; 162 String manageLabel = null; 163 try { 164 backupEnabled = mBackupManager.isBackupEnabled(); 165 String transport = mBackupManager.getCurrentTransport(); 166 configIntent = validatedActivityIntent( 167 mBackupManager.getConfigurationIntent(transport), "config"); 168 configSummary = mBackupManager.getDestinationString(transport); 169 manageIntent = validatedActivityIntent( 170 mBackupManager.getDataManagementIntent(transport), "management"); 171 manageLabel = mBackupManager.getDataManagementLabel(transport); 172 173 mBackup.setSummary(backupEnabled 174 ? R.string.accessibility_feature_state_on 175 : R.string.accessibility_feature_state_off); 176 } catch (RemoteException e) { 177 // leave it 'false' and disable the UI; there's no backup manager 178 mBackup.setEnabled(false); 179 } 180 181 mAutoRestore.setChecked(Settings.Secure.getInt(res, 182 Settings.Secure.BACKUP_AUTO_RESTORE, 1) == 1); 183 mAutoRestore.setEnabled(backupEnabled); 184 185 final boolean configureEnabled = (configIntent != null) && backupEnabled; 186 mConfigure.setEnabled(configureEnabled); 187 mConfigure.setIntent(configIntent); 188 setConfigureSummary(configSummary); 189 190 final boolean manageEnabled = (manageIntent != null) && backupEnabled; 191 if (manageEnabled) { 192 mManageData.setIntent(manageIntent); 193 if (manageLabel != null) { 194 mManageData.setTitle(manageLabel); 195 } 196 } else { 197 // Hide the item if data management intent is not supported by transport. 198 getPreferenceScreen().removePreference(mManageData); 199 } 200 } 201 202 private Intent validatedActivityIntent(Intent intent, String logLabel) { 203 if (intent != null) { 204 PackageManager pm = getPackageManager(); 205 List<ResolveInfo> resolved = pm.queryIntentActivities(intent, 0); 206 if (resolved == null || resolved.isEmpty()) { 207 intent = null; 208 Log.e(TAG, "Backup " + logLabel + " intent " + intent 209 + " fails to resolve; ignoring"); 210 } 211 } 212 return intent; 213 } 214 215 private void setConfigureSummary(String summary) { 216 if (summary != null) { 217 mConfigure.setSummary(summary); 218 } else { 219 mConfigure.setSummary(R.string.backup_configure_account_default_summary); 220 } 221 } 222 223 @Override 224 protected int getHelpResource() { 225 return R.string.help_url_backup_reset; 226 } 227 228 /** 229 * For Search. 230 */ 231 public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = 232 new PrivacySearchIndexProvider(); 233 234 private static class PrivacySearchIndexProvider extends BaseSearchIndexProvider { 235 236 boolean mIsPrimary; 237 238 public PrivacySearchIndexProvider() { 239 super(); 240 241 mIsPrimary = UserHandle.myUserId() == UserHandle.USER_SYSTEM; 242 } 243 244 @Override 245 public List<SearchIndexableResource> getXmlResourcesToIndex( 246 Context context, boolean enabled) { 247 248 List<SearchIndexableResource> result = new ArrayList<SearchIndexableResource>(); 249 250 // For non-primary user, no backup or reset is available 251 // TODO: http://b/22388012 252 if (!mIsPrimary) { 253 return result; 254 } 255 256 SearchIndexableResource sir = new SearchIndexableResource(context); 257 sir.xmlResId = R.xml.privacy_settings; 258 result.add(sir); 259 260 return result; 261 } 262 263 @Override 264 public List<String> getNonIndexableKeys(Context context) { 265 final List<String> nonVisibleKeys = new ArrayList<>(); 266 getNonVisibleKeys(context, nonVisibleKeys); 267 return nonVisibleKeys; 268 } 269 } 270 271 private static void getNonVisibleKeys(Context context, Collection<String> nonVisibleKeys) { 272 final IBackupManager backupManager = IBackupManager.Stub.asInterface( 273 ServiceManager.getService(Context.BACKUP_SERVICE)); 274 boolean isServiceActive = false; 275 try { 276 isServiceActive = backupManager.isBackupServiceActive(UserHandle.myUserId()); 277 } catch (RemoteException e) { 278 Log.w(TAG, "Failed querying backup manager service activity status. " + 279 "Assuming it is inactive."); 280 } 281 boolean vendorSpecific = context.getPackageManager(). 282 resolveContentProvider(GSETTINGS_PROVIDER, 0) == null; 283 if (vendorSpecific || isServiceActive) { 284 nonVisibleKeys.add(BACKUP_INACTIVE); 285 } 286 if (vendorSpecific || !isServiceActive) { 287 nonVisibleKeys.add(BACKUP_DATA); 288 nonVisibleKeys.add(AUTO_RESTORE); 289 nonVisibleKeys.add(CONFIGURE_ACCOUNT); 290 } 291 if (RestrictedLockUtils.hasBaseUserRestriction(context, 292 UserManager.DISALLOW_FACTORY_RESET, UserHandle.myUserId())) { 293 nonVisibleKeys.add(FACTORY_RESET); 294 } 295 } 296} 297