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