PrivacySettings.java revision 4a6c2591791ae4b81f58248f2c9d9f4379e91610
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.Activity;
20import android.app.backup.IBackupManager;
21import android.content.ContentResolver;
22import android.content.Context;
23import android.content.Intent;
24import android.content.pm.PackageManager;
25import android.content.pm.ResolveInfo;
26import android.os.Bundle;
27import android.os.RemoteException;
28import android.os.ServiceManager;
29import android.os.UserHandle;
30import android.os.UserManager;
31import android.provider.SearchIndexableResource;
32import android.provider.Settings;
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.MetricsProto.MetricsEvent;
40import com.android.settings.dashboard.SummaryLoader;
41import com.android.settings.search.BaseSearchIndexProvider;
42import com.android.settings.search.Indexable;
43import com.android.settingslib.RestrictedLockUtils;
44import com.android.settingslib.RestrictedPreference;
45
46import java.util.ArrayList;
47import java.util.Collection;
48import java.util.HashSet;
49import java.util.List;
50import java.util.Set;
51
52/**
53 * Gesture lock pattern settings.
54 */
55public 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 NETWORK_RESET = "network_reset";
65    private static final String FACTORY_RESET = "factory_reset";
66    private static final String TAG = "PrivacySettings";
67    private IBackupManager mBackupManager;
68    private PreferenceScreen mBackup;
69    private SwitchPreference mAutoRestore;
70    private PreferenceScreen mConfigure;
71    private PreferenceScreen mManageData;
72    private boolean mEnabled;
73
74    @Override
75    protected 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        mBackup = (PreferenceScreen) screen.findPreference(BACKUP_DATA);
95
96        mAutoRestore = (SwitchPreference) screen.findPreference(AUTO_RESTORE);
97        mAutoRestore.setOnPreferenceChangeListener(preferenceChangeListener);
98
99        mConfigure = (PreferenceScreen) screen.findPreference(CONFIGURE_ACCOUNT);
100        mManageData = (PreferenceScreen) screen.findPreference(DATA_MANAGEMENT);
101
102        Set<String> keysToRemove = new HashSet<>();
103        getNonVisibleKeys(getActivity(), keysToRemove);
104        final int screenPreferenceCount = screen.getPreferenceCount();
105        for (int i = screenPreferenceCount - 1; i >= 0; --i) {
106            Preference preference = screen.getPreference(i);
107            if (keysToRemove.contains(preference.getKey())) {
108                screen.removePreference(preference);
109            }
110        }
111
112        updateToggles();
113    }
114
115    @Override
116    public void onResume() {
117        super.onResume();
118
119        // Refresh UI
120        if (mEnabled) {
121            updateToggles();
122        }
123    }
124
125    private OnPreferenceChangeListener preferenceChangeListener = new OnPreferenceChangeListener() {
126        @Override
127        public boolean onPreferenceChange(Preference preference, Object newValue) {
128            if (!(preference instanceof SwitchPreference)) {
129                return true;
130            }
131            boolean nextValue = (Boolean) newValue;
132            boolean result = false;
133            if (preference == mAutoRestore) {
134                try {
135                    mBackupManager.setAutoRestore(nextValue);
136                    result = true;
137                } catch (RemoteException e) {
138                    mAutoRestore.setChecked(!nextValue);
139                }
140            }
141            return result;
142        }
143    };
144
145
146    /*
147     * Creates toggles for each backup/reset preference.
148     */
149    private void updateToggles() {
150        ContentResolver res = getContentResolver();
151
152        boolean backupEnabled = false;
153        Intent configIntent = null;
154        String configSummary = null;
155        Intent manageIntent = null;
156        String manageLabel = null;
157        try {
158            backupEnabled = mBackupManager.isBackupEnabled();
159            String transport = mBackupManager.getCurrentTransport();
160            configIntent = validatedActivityIntent(
161                    mBackupManager.getConfigurationIntent(transport), "config");
162            configSummary = mBackupManager.getDestinationString(transport);
163            manageIntent = validatedActivityIntent(
164                    mBackupManager.getDataManagementIntent(transport), "management");
165            manageLabel = mBackupManager.getDataManagementLabel(transport);
166
167            mBackup.setSummary(backupEnabled
168                    ? R.string.accessibility_feature_state_on
169                    : R.string.accessibility_feature_state_off);
170        } catch (RemoteException e) {
171            // leave it 'false' and disable the UI; there's no backup manager
172            mBackup.setEnabled(false);
173        }
174
175        mAutoRestore.setChecked(Settings.Secure.getInt(res,
176                Settings.Secure.BACKUP_AUTO_RESTORE, 1) == 1);
177        mAutoRestore.setEnabled(backupEnabled);
178
179        final boolean configureEnabled = (configIntent != null) && backupEnabled;
180        mConfigure.setEnabled(configureEnabled);
181        mConfigure.setIntent(configIntent);
182        setConfigureSummary(configSummary);
183
184        final boolean manageEnabled = (manageIntent != null) && backupEnabled;
185        if (manageEnabled) {
186            mManageData.setIntent(manageIntent);
187            if (manageLabel != null) {
188                mManageData.setTitle(manageLabel);
189            }
190        } else {
191            // Hide the item if data management intent is not supported by transport.
192            getPreferenceScreen().removePreference(mManageData);
193        }
194    }
195
196    private Intent validatedActivityIntent(Intent intent, String logLabel) {
197        if (intent != null) {
198            PackageManager pm = getPackageManager();
199            List<ResolveInfo> resolved = pm.queryIntentActivities(intent, 0);
200            if (resolved == null || resolved.isEmpty()) {
201                intent = null;
202                Log.e(TAG, "Backup " + logLabel + " intent " + intent
203                        + " fails to resolve; ignoring");
204            }
205        }
206        return intent;
207    }
208
209    private void setConfigureSummary(String summary) {
210        if (summary != null) {
211            mConfigure.setSummary(summary);
212        } else {
213            mConfigure.setSummary(R.string.backup_configure_account_default_summary);
214        }
215    }
216
217    @Override
218    protected int getHelpResource() {
219        return R.string.help_url_backup_reset;
220    }
221
222    private static class SummaryProvider implements SummaryLoader.SummaryProvider {
223
224        private final Context mContext;
225        private final SummaryLoader mSummaryLoader;
226
227        public SummaryProvider(Context context, SummaryLoader summaryLoader) {
228            mContext = context;
229            mSummaryLoader = summaryLoader;
230        }
231
232        @Override
233        public void setListening(boolean listening) {
234            if (listening) {
235                IBackupManager backupManager = IBackupManager.Stub.asInterface(
236                        ServiceManager.getService(Context.BACKUP_SERVICE));
237                try {
238                    boolean backupEnabled = backupManager.isBackupEnabled();
239                    if (backupEnabled) {
240                        String transport = backupManager.getCurrentTransport();
241                        String configSummary = backupManager.getDestinationString(transport);
242                        if (configSummary != null) {
243                            mSummaryLoader.setSummary(this, configSummary);
244                        } else {
245                            mSummaryLoader.setSummary(this, mContext.getString(
246                                    R.string.backup_configure_account_default_summary));
247                        }
248                    } else {
249                        mSummaryLoader.setSummary(this, mContext.getString(
250                                R.string.backup_disabled));
251                    }
252                } catch (RemoteException e) {
253                }
254            }
255        }
256    }
257
258    public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
259            = new SummaryLoader.SummaryProviderFactory() {
260        @Override
261        public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
262                                                                   SummaryLoader summaryLoader) {
263            return new SummaryProvider(activity, summaryLoader);
264        }
265    };
266
267    /**
268     * For Search.
269     */
270    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
271            new PrivacySearchIndexProvider();
272
273    private static class PrivacySearchIndexProvider extends BaseSearchIndexProvider {
274
275        boolean mIsPrimary;
276
277        public PrivacySearchIndexProvider() {
278            super();
279
280            mIsPrimary = UserHandle.myUserId() == UserHandle.USER_SYSTEM;
281        }
282
283        @Override
284        public List<SearchIndexableResource> getXmlResourcesToIndex(
285                Context context, boolean enabled) {
286
287            List<SearchIndexableResource> result = new ArrayList<SearchIndexableResource>();
288
289            // For non-primary user, no backup or reset is available
290            // TODO: http://b/22388012
291            if (!mIsPrimary) {
292                return result;
293            }
294
295            SearchIndexableResource sir = new SearchIndexableResource(context);
296            sir.xmlResId = R.xml.privacy_settings;
297            result.add(sir);
298
299            return result;
300        }
301
302        @Override
303        public List<String> getNonIndexableKeys(Context context) {
304            final List<String> nonVisibleKeys = new ArrayList<>();
305            getNonVisibleKeys(context, nonVisibleKeys);
306            return nonVisibleKeys;
307        }
308    }
309
310    private static void getNonVisibleKeys(Context context, Collection<String> nonVisibleKeys) {
311        final IBackupManager backupManager = IBackupManager.Stub.asInterface(
312                ServiceManager.getService(Context.BACKUP_SERVICE));
313        boolean isServiceActive = false;
314        try {
315            isServiceActive = backupManager.isBackupServiceActive(UserHandle.myUserId());
316        } catch (RemoteException e) {
317            Log.w(TAG, "Failed querying backup manager service activity status. " +
318                    "Assuming it is inactive.");
319        }
320        boolean vendorSpecific = context.getPackageManager().
321                resolveContentProvider(GSETTINGS_PROVIDER, 0) == null;
322        if (vendorSpecific || isServiceActive) {
323            nonVisibleKeys.add(BACKUP_INACTIVE);
324        }
325        if (vendorSpecific || !isServiceActive) {
326            nonVisibleKeys.add(BACKUP_DATA);
327            nonVisibleKeys.add(AUTO_RESTORE);
328            nonVisibleKeys.add(CONFIGURE_ACCOUNT);
329        }
330        if (RestrictedLockUtils.hasBaseUserRestriction(context,
331                UserManager.DISALLOW_FACTORY_RESET, UserHandle.myUserId())) {
332            nonVisibleKeys.add(FACTORY_RESET);
333        }
334        if (RestrictedLockUtils.hasBaseUserRestriction(context,
335                UserManager.DISALLOW_NETWORK_RESET, UserHandle.myUserId())) {
336            nonVisibleKeys.add(NETWORK_RESET);
337        }
338    }
339}
340