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