Files
app_Settings/src/com/android/settings/PrivacySettings.java
Christopher Tate 4a6c259179 Don't crash if the backup transport supplies bogus intents
Preflight the (activity) intents supplied by the transport so that when
clicked, they don't crash the Preference that called startActivity().

Bug 27689847

Change-Id: I7cbdd6077ac74500ecdf9607310727af56d55a3c
2016-03-16 13:45:03 -07:00

340 lines
13 KiB
Java

/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings;
import android.app.Activity;
import android.app.backup.IBackupManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.SearchIndexableResource;
import android.provider.Settings;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.Preference.OnPreferenceChangeListener;
import android.support.v7.preference.PreferenceScreen;
import android.util.Log;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedPreference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Gesture lock pattern settings.
*/
public class PrivacySettings extends SettingsPreferenceFragment implements Indexable {
// Vendor specific
private static final String GSETTINGS_PROVIDER = "com.google.settings";
private static final String BACKUP_DATA = "backup_data";
private static final String AUTO_RESTORE = "auto_restore";
private static final String CONFIGURE_ACCOUNT = "configure_account";
private static final String DATA_MANAGEMENT = "data_management";
private static final String BACKUP_INACTIVE = "backup_inactive";
private static final String NETWORK_RESET = "network_reset";
private static final String FACTORY_RESET = "factory_reset";
private static final String TAG = "PrivacySettings";
private IBackupManager mBackupManager;
private PreferenceScreen mBackup;
private SwitchPreference mAutoRestore;
private PreferenceScreen mConfigure;
private PreferenceScreen mManageData;
private boolean mEnabled;
@Override
protected int getMetricsCategory() {
return MetricsEvent.PRIVACY;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Don't allow any access if this is not an admin user.
// TODO: backup/restore currently only works with owner user b/22760572
mEnabled = UserManager.get(getActivity()).isAdminUser();
if (!mEnabled) {
return;
}
addPreferencesFromResource(R.xml.privacy_settings);
final PreferenceScreen screen = getPreferenceScreen();
mBackupManager = IBackupManager.Stub.asInterface(
ServiceManager.getService(Context.BACKUP_SERVICE));
mBackup = (PreferenceScreen) screen.findPreference(BACKUP_DATA);
mAutoRestore = (SwitchPreference) screen.findPreference(AUTO_RESTORE);
mAutoRestore.setOnPreferenceChangeListener(preferenceChangeListener);
mConfigure = (PreferenceScreen) screen.findPreference(CONFIGURE_ACCOUNT);
mManageData = (PreferenceScreen) screen.findPreference(DATA_MANAGEMENT);
Set<String> keysToRemove = new HashSet<>();
getNonVisibleKeys(getActivity(), keysToRemove);
final int screenPreferenceCount = screen.getPreferenceCount();
for (int i = screenPreferenceCount - 1; i >= 0; --i) {
Preference preference = screen.getPreference(i);
if (keysToRemove.contains(preference.getKey())) {
screen.removePreference(preference);
}
}
updateToggles();
}
@Override
public void onResume() {
super.onResume();
// Refresh UI
if (mEnabled) {
updateToggles();
}
}
private OnPreferenceChangeListener preferenceChangeListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (!(preference instanceof SwitchPreference)) {
return true;
}
boolean nextValue = (Boolean) newValue;
boolean result = false;
if (preference == mAutoRestore) {
try {
mBackupManager.setAutoRestore(nextValue);
result = true;
} catch (RemoteException e) {
mAutoRestore.setChecked(!nextValue);
}
}
return result;
}
};
/*
* Creates toggles for each backup/reset preference.
*/
private void updateToggles() {
ContentResolver res = getContentResolver();
boolean backupEnabled = false;
Intent configIntent = null;
String configSummary = null;
Intent manageIntent = null;
String manageLabel = null;
try {
backupEnabled = mBackupManager.isBackupEnabled();
String transport = mBackupManager.getCurrentTransport();
configIntent = validatedActivityIntent(
mBackupManager.getConfigurationIntent(transport), "config");
configSummary = mBackupManager.getDestinationString(transport);
manageIntent = validatedActivityIntent(
mBackupManager.getDataManagementIntent(transport), "management");
manageLabel = mBackupManager.getDataManagementLabel(transport);
mBackup.setSummary(backupEnabled
? R.string.accessibility_feature_state_on
: R.string.accessibility_feature_state_off);
} catch (RemoteException e) {
// leave it 'false' and disable the UI; there's no backup manager
mBackup.setEnabled(false);
}
mAutoRestore.setChecked(Settings.Secure.getInt(res,
Settings.Secure.BACKUP_AUTO_RESTORE, 1) == 1);
mAutoRestore.setEnabled(backupEnabled);
final boolean configureEnabled = (configIntent != null) && backupEnabled;
mConfigure.setEnabled(configureEnabled);
mConfigure.setIntent(configIntent);
setConfigureSummary(configSummary);
final boolean manageEnabled = (manageIntent != null) && backupEnabled;
if (manageEnabled) {
mManageData.setIntent(manageIntent);
if (manageLabel != null) {
mManageData.setTitle(manageLabel);
}
} else {
// Hide the item if data management intent is not supported by transport.
getPreferenceScreen().removePreference(mManageData);
}
}
private Intent validatedActivityIntent(Intent intent, String logLabel) {
if (intent != null) {
PackageManager pm = getPackageManager();
List<ResolveInfo> resolved = pm.queryIntentActivities(intent, 0);
if (resolved == null || resolved.isEmpty()) {
intent = null;
Log.e(TAG, "Backup " + logLabel + " intent " + intent
+ " fails to resolve; ignoring");
}
}
return intent;
}
private void setConfigureSummary(String summary) {
if (summary != null) {
mConfigure.setSummary(summary);
} else {
mConfigure.setSummary(R.string.backup_configure_account_default_summary);
}
}
@Override
protected int getHelpResource() {
return R.string.help_url_backup_reset;
}
private static class SummaryProvider implements SummaryLoader.SummaryProvider {
private final Context mContext;
private final SummaryLoader mSummaryLoader;
public SummaryProvider(Context context, SummaryLoader summaryLoader) {
mContext = context;
mSummaryLoader = summaryLoader;
}
@Override
public void setListening(boolean listening) {
if (listening) {
IBackupManager backupManager = IBackupManager.Stub.asInterface(
ServiceManager.getService(Context.BACKUP_SERVICE));
try {
boolean backupEnabled = backupManager.isBackupEnabled();
if (backupEnabled) {
String transport = backupManager.getCurrentTransport();
String configSummary = backupManager.getDestinationString(transport);
if (configSummary != null) {
mSummaryLoader.setSummary(this, configSummary);
} else {
mSummaryLoader.setSummary(this, mContext.getString(
R.string.backup_configure_account_default_summary));
}
} else {
mSummaryLoader.setSummary(this, mContext.getString(
R.string.backup_disabled));
}
} catch (RemoteException e) {
}
}
}
}
public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
= new SummaryLoader.SummaryProviderFactory() {
@Override
public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
SummaryLoader summaryLoader) {
return new SummaryProvider(activity, summaryLoader);
}
};
/**
* For Search.
*/
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new PrivacySearchIndexProvider();
private static class PrivacySearchIndexProvider extends BaseSearchIndexProvider {
boolean mIsPrimary;
public PrivacySearchIndexProvider() {
super();
mIsPrimary = UserHandle.myUserId() == UserHandle.USER_SYSTEM;
}
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(
Context context, boolean enabled) {
List<SearchIndexableResource> result = new ArrayList<SearchIndexableResource>();
// For non-primary user, no backup or reset is available
// TODO: http://b/22388012
if (!mIsPrimary) {
return result;
}
SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.privacy_settings;
result.add(sir);
return result;
}
@Override
public List<String> getNonIndexableKeys(Context context) {
final List<String> nonVisibleKeys = new ArrayList<>();
getNonVisibleKeys(context, nonVisibleKeys);
return nonVisibleKeys;
}
}
private static void getNonVisibleKeys(Context context, Collection<String> nonVisibleKeys) {
final IBackupManager backupManager = IBackupManager.Stub.asInterface(
ServiceManager.getService(Context.BACKUP_SERVICE));
boolean isServiceActive = false;
try {
isServiceActive = backupManager.isBackupServiceActive(UserHandle.myUserId());
} catch (RemoteException e) {
Log.w(TAG, "Failed querying backup manager service activity status. " +
"Assuming it is inactive.");
}
boolean vendorSpecific = context.getPackageManager().
resolveContentProvider(GSETTINGS_PROVIDER, 0) == null;
if (vendorSpecific || isServiceActive) {
nonVisibleKeys.add(BACKUP_INACTIVE);
}
if (vendorSpecific || !isServiceActive) {
nonVisibleKeys.add(BACKUP_DATA);
nonVisibleKeys.add(AUTO_RESTORE);
nonVisibleKeys.add(CONFIGURE_ACCOUNT);
}
if (RestrictedLockUtils.hasBaseUserRestriction(context,
UserManager.DISALLOW_FACTORY_RESET, UserHandle.myUserId())) {
nonVisibleKeys.add(FACTORY_RESET);
}
if (RestrictedLockUtils.hasBaseUserRestriction(context,
UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId())) {
nonVisibleKeys.add(NETWORK_RESET);
}
}
}