RestrictedSettingsFragment.java revision e407e67a3b42d42beb44de50cb9ccdf2f559854f
1/*
2 * Copyright (C) 2013 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.content.BroadcastReceiver;
21import android.content.Context;
22import android.content.Intent;
23import android.content.IntentFilter;
24import android.content.RestrictionsManager;
25import android.os.Bundle;
26import android.os.PersistableBundle;
27import android.os.UserHandle;
28import android.os.UserManager;
29import android.view.View;
30import android.widget.TextView;
31
32import com.android.settings.dashboard.RestrictedDashboardFragment;
33import com.android.settingslib.RestrictedLockUtils;
34
35import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
36
37/**
38 * Base class for settings screens that should be pin protected when in restricted mode or
39 * that will display an admin support message in case an admin has disabled the options.
40 * The constructor for this class will take the restriction key that this screen should be
41 * locked by.  If {@link RestrictionsManager.hasRestrictionsProvider()} and
42 * {@link UserManager.hasUserRestriction()}, then the user will have to enter the restrictions
43 * pin before seeing the Settings screen.
44 *
45 * If this settings screen should be pin protected whenever
46 * {@link RestrictionsManager.hasRestrictionsProvider()} returns true, pass in
47 * {@link RESTRICT_IF_OVERRIDABLE} to the constructor instead of a restrictions key.
48 *
49 * @deprecated Use {@link RestrictedDashboardFragment} instead
50 */
51@Deprecated
52public abstract class RestrictedSettingsFragment extends SettingsPreferenceFragment {
53
54    protected static final String RESTRICT_IF_OVERRIDABLE = "restrict_if_overridable";
55
56    // No RestrictedSettingsFragment screens should use this number in startActivityForResult.
57    private static final int REQUEST_PIN_CHALLENGE = 12309;
58
59    private static final String KEY_CHALLENGE_SUCCEEDED = "chsc";
60    private static final String KEY_CHALLENGE_REQUESTED = "chrq";
61
62    // If the restriction PIN is entered correctly.
63    private boolean mChallengeSucceeded;
64    private boolean mChallengeRequested;
65
66    private UserManager mUserManager;
67    private RestrictionsManager mRestrictionsManager;
68
69    private final String mRestrictionKey;
70    private View mAdminSupportDetails;
71    private EnforcedAdmin mEnforcedAdmin;
72    private TextView mEmptyTextView;
73
74    private boolean mOnlyAvailableForAdmins = false;
75    private boolean mIsAdminUser;
76
77    // Receiver to clear pin status when the screen is turned off.
78    private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
79        @Override
80        public void onReceive(Context context, Intent intent) {
81            if (!mChallengeRequested) {
82                mChallengeSucceeded = false;
83                mChallengeRequested = false;
84            }
85        }
86    };
87
88    /**
89     * @param restrictionKey The restriction key to check before pin protecting
90     *            this settings page. Pass in {@link RESTRICT_IF_OVERRIDABLE} if it should
91     *            be protected whenever a restrictions provider is set. Pass in
92     *            null if it should never be protected.
93     */
94    public RestrictedSettingsFragment(String restrictionKey) {
95        mRestrictionKey = restrictionKey;
96    }
97
98    @Override
99    public void onCreate(Bundle icicle) {
100        super.onCreate(icicle);
101
102        mRestrictionsManager = (RestrictionsManager) getSystemService(Context.RESTRICTIONS_SERVICE);
103        mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
104        mIsAdminUser = mUserManager.isAdminUser();
105
106        if (icicle != null) {
107            mChallengeSucceeded = icicle.getBoolean(KEY_CHALLENGE_SUCCEEDED, false);
108            mChallengeRequested = icicle.getBoolean(KEY_CHALLENGE_REQUESTED, false);
109        }
110
111        IntentFilter offFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
112        offFilter.addAction(Intent.ACTION_USER_PRESENT);
113        getActivity().registerReceiver(mScreenOffReceiver, offFilter);
114    }
115
116    @Override
117    public void onActivityCreated(Bundle savedInstanceState) {
118        super.onActivityCreated(savedInstanceState);
119        mAdminSupportDetails = initAdminSupportDetailsView();
120        mEmptyTextView = initEmptyTextView();
121    }
122
123    @Override
124    public void onSaveInstanceState(Bundle outState) {
125        super.onSaveInstanceState(outState);
126
127        if (getActivity().isChangingConfigurations()) {
128            outState.putBoolean(KEY_CHALLENGE_REQUESTED, mChallengeRequested);
129            outState.putBoolean(KEY_CHALLENGE_SUCCEEDED, mChallengeSucceeded);
130        }
131    }
132
133    @Override
134    public void onResume() {
135        super.onResume();
136
137        if (shouldBeProviderProtected(mRestrictionKey)) {
138            ensurePin();
139        }
140    }
141
142    @Override
143    public void onDestroy() {
144        getActivity().unregisterReceiver(mScreenOffReceiver);
145        super.onDestroy();
146    }
147
148    @Override
149    public void onActivityResult(int requestCode, int resultCode, Intent data) {
150        if (requestCode == REQUEST_PIN_CHALLENGE) {
151            if (resultCode == Activity.RESULT_OK) {
152                mChallengeSucceeded = true;
153                mChallengeRequested = false;
154            } else {
155                mChallengeSucceeded = false;
156            }
157            return;
158        }
159
160        super.onActivityResult(requestCode, resultCode, data);
161    }
162
163    private void ensurePin() {
164        if (!mChallengeSucceeded && !mChallengeRequested
165                && mRestrictionsManager.hasRestrictionsProvider()) {
166            Intent intent = mRestrictionsManager.createLocalApprovalIntent();
167            if (intent != null) {
168                mChallengeRequested = true;
169                mChallengeSucceeded = false;
170                PersistableBundle request = new PersistableBundle();
171                request.putString(RestrictionsManager.REQUEST_KEY_MESSAGE,
172                        getResources().getString(R.string.restr_pin_enter_admin_pin));
173                intent.putExtra(RestrictionsManager.EXTRA_REQUEST_BUNDLE, request);
174                startActivityForResult(intent, REQUEST_PIN_CHALLENGE);
175            }
176        }
177    }
178
179    /**
180     * Returns true if this activity is restricted, but no restrictions provider has been set.
181     * Used to determine if the settings UI should disable UI.
182     */
183    protected boolean isRestrictedAndNotProviderProtected() {
184        if (mRestrictionKey == null || RESTRICT_IF_OVERRIDABLE.equals(mRestrictionKey)) {
185            return false;
186        }
187        return mUserManager.hasUserRestriction(mRestrictionKey)
188                && !mRestrictionsManager.hasRestrictionsProvider();
189    }
190
191    protected boolean hasChallengeSucceeded() {
192        return (mChallengeRequested && mChallengeSucceeded) || !mChallengeRequested;
193    }
194
195    /**
196     * Returns true if this restrictions key is locked down.
197     */
198    protected boolean shouldBeProviderProtected(String restrictionKey) {
199        if (restrictionKey == null) {
200            return false;
201        }
202        boolean restricted = RESTRICT_IF_OVERRIDABLE.equals(restrictionKey)
203                || mUserManager.hasUserRestriction(mRestrictionKey);
204        return restricted && mRestrictionsManager.hasRestrictionsProvider();
205    }
206
207    private View initAdminSupportDetailsView() {
208        return getActivity().findViewById(R.id.admin_support_details);
209    }
210
211    protected TextView initEmptyTextView() {
212        TextView emptyView = (TextView) getActivity().findViewById(android.R.id.empty);
213        return emptyView;
214    }
215
216    public EnforcedAdmin getRestrictionEnforcedAdmin() {
217        mEnforcedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(getActivity(),
218                mRestrictionKey, UserHandle.myUserId());
219        if (mEnforcedAdmin != null && mEnforcedAdmin.userId == UserHandle.USER_NULL) {
220            mEnforcedAdmin.userId = UserHandle.myUserId();
221        }
222        return mEnforcedAdmin;
223    }
224
225    public TextView getEmptyTextView() {
226        return mEmptyTextView;
227    }
228
229    @Override
230    protected void onDataSetChanged() {
231        highlightPreferenceIfNeeded();
232        if (mAdminSupportDetails != null && isUiRestrictedByOnlyAdmin()) {
233            final EnforcedAdmin admin = getRestrictionEnforcedAdmin();
234            ShowAdminSupportDetailsDialog.setAdminSupportDetails(getActivity(),
235                    mAdminSupportDetails, admin, false);
236            setEmptyView(mAdminSupportDetails);
237        } else if (mEmptyTextView != null) {
238            setEmptyView(mEmptyTextView);
239        }
240        super.onDataSetChanged();
241    }
242
243    public void setIfOnlyAvailableForAdmins(boolean onlyForAdmins) {
244        mOnlyAvailableForAdmins = onlyForAdmins;
245    }
246
247    /**
248     * Returns whether restricted or actionable UI elements should be removed or disabled.
249     */
250    protected boolean isUiRestricted() {
251        return isRestrictedAndNotProviderProtected() || !hasChallengeSucceeded()
252                || (!mIsAdminUser && mOnlyAvailableForAdmins);
253    }
254
255    protected boolean isUiRestrictedByOnlyAdmin() {
256        return isUiRestricted() && !mUserManager.hasBaseUserRestriction(mRestrictionKey,
257                UserHandle.of(UserHandle.myUserId())) && (mIsAdminUser || !mOnlyAvailableForAdmins);
258    }
259}
260