blob: 6b538b81f21a2d7959cb9840ec9a3d80ebd206b8 [file] [log] [blame]
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -04001/*
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
Fan Zhangc7162cd2018-06-18 15:21:41 -070019import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
20
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -040021import android.app.Activity;
Maggie Benthall44534962013-08-29 10:49:13 -040022import android.content.BroadcastReceiver;
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -040023import android.content.Context;
24import android.content.Intent;
Maggie Benthall44534962013-08-29 10:49:13 -040025import android.content.IntentFilter;
Julia Reynolds1a0297c2014-06-18 09:23:15 -040026import android.content.RestrictionsManager;
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -040027import android.os.Bundle;
Julia Reynolds1a0297c2014-06-18 09:23:15 -040028import android.os.PersistableBundle;
Sudheer Shanka95a71e02016-01-12 10:36:18 +000029import android.os.UserHandle;
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -040030import android.os.UserManager;
Sudheer Shanka95a71e02016-01-12 10:36:18 +000031import android.view.View;
32import android.widget.TextView;
33
Fan Zhang23f8d592018-08-28 15:11:40 -070034import androidx.annotation.VisibleForTesting;
35import androidx.appcompat.app.AlertDialog;
36
jackqdyuleie407e672017-05-05 16:07:48 -070037import com.android.settings.dashboard.RestrictedDashboardFragment;
arangelove35badd2017-10-27 13:51:28 +010038import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper;
Philip P. Moltmanne3f72112018-08-28 15:01:43 -070039import com.android.settingslib.RestrictedLockUtilsInternal;
Sudheer Shanka95a71e02016-01-12 10:36:18 +000040
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -040041/**
Sudheer Shanka95a71e02016-01-12 10:36:18 +000042 * Base class for settings screens that should be pin protected when in restricted mode or
43 * that will display an admin support message in case an admin has disabled the options.
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -040044 * The constructor for this class will take the restriction key that this screen should be
Julia Reynolds1a0297c2014-06-18 09:23:15 -040045 * locked by. If {@link RestrictionsManager.hasRestrictionsProvider()} and
46 * {@link UserManager.hasUserRestriction()}, then the user will have to enter the restrictions
47 * pin before seeing the Settings screen.
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -040048 *
Geoffrey Borggaardfe21d9a2013-08-02 18:16:27 -040049 * If this settings screen should be pin protected whenever
Julia Reynolds1a0297c2014-06-18 09:23:15 -040050 * {@link RestrictionsManager.hasRestrictionsProvider()} returns true, pass in
51 * {@link RESTRICT_IF_OVERRIDABLE} to the constructor instead of a restrictions key.
jackqdyuleie407e672017-05-05 16:07:48 -070052 *
53 * @deprecated Use {@link RestrictedDashboardFragment} instead
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -040054 */
jackqdyuleie407e672017-05-05 16:07:48 -070055@Deprecated
Sudheer Shanka8b72e562016-06-02 12:40:22 -070056public abstract class RestrictedSettingsFragment extends SettingsPreferenceFragment {
Maggie Benthall44534962013-08-29 10:49:13 -040057
Julia Reynolds1a0297c2014-06-18 09:23:15 -040058 protected static final String RESTRICT_IF_OVERRIDABLE = "restrict_if_overridable";
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -040059
Julia Reynolds1a0297c2014-06-18 09:23:15 -040060 // No RestrictedSettingsFragment screens should use this number in startActivityForResult.
Salvador Martinez8c975b72018-04-18 17:38:46 -070061 @VisibleForTesting static final int REQUEST_PIN_CHALLENGE = 12309;
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -040062
63 private static final String KEY_CHALLENGE_SUCCEEDED = "chsc";
64 private static final String KEY_CHALLENGE_REQUESTED = "chrq";
65
66 // If the restriction PIN is entered correctly.
67 private boolean mChallengeSucceeded;
68 private boolean mChallengeRequested;
69
70 private UserManager mUserManager;
Julia Reynolds1a0297c2014-06-18 09:23:15 -040071 private RestrictionsManager mRestrictionsManager;
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -040072
73 private final String mRestrictionKey;
Sudheer Shanka95a71e02016-01-12 10:36:18 +000074 private EnforcedAdmin mEnforcedAdmin;
75 private TextView mEmptyTextView;
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -040076
Sudheer Shanka7dbbe132016-02-16 14:19:32 +000077 private boolean mOnlyAvailableForAdmins = false;
78 private boolean mIsAdminUser;
79
Maggie Benthall44534962013-08-29 10:49:13 -040080 // Receiver to clear pin status when the screen is turned off.
81 private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
82 @Override
83 public void onReceive(Context context, Intent intent) {
Julia Reynolds1a0297c2014-06-18 09:23:15 -040084 if (!mChallengeRequested) {
85 mChallengeSucceeded = false;
86 mChallengeRequested = false;
Maggie Benthall44534962013-08-29 10:49:13 -040087 }
88 }
89 };
90
Salvador Martinez8c975b72018-04-18 17:38:46 -070091 @VisibleForTesting
92 AlertDialog mActionDisabledDialog;
arangelove35badd2017-10-27 13:51:28 +010093
Geoffrey Borggaardfe21d9a2013-08-02 18:16:27 -040094 /**
95 * @param restrictionKey The restriction key to check before pin protecting
Julia Reynolds1a0297c2014-06-18 09:23:15 -040096 * this settings page. Pass in {@link RESTRICT_IF_OVERRIDABLE} if it should
97 * be protected whenever a restrictions provider is set. Pass in
98 * null if it should never be protected.
Geoffrey Borggaardfe21d9a2013-08-02 18:16:27 -040099 */
100 public RestrictedSettingsFragment(String restrictionKey) {
101 mRestrictionKey = restrictionKey;
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -0400102 }
103
104 @Override
105 public void onCreate(Bundle icicle) {
106 super.onCreate(icicle);
107
Julia Reynolds1a0297c2014-06-18 09:23:15 -0400108 mRestrictionsManager = (RestrictionsManager) getSystemService(Context.RESTRICTIONS_SERVICE);
Geoffrey Borggaardfe21d9a2013-08-02 18:16:27 -0400109 mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
Sudheer Shanka7dbbe132016-02-16 14:19:32 +0000110 mIsAdminUser = mUserManager.isAdminUser();
Geoffrey Borggaardfe21d9a2013-08-02 18:16:27 -0400111
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -0400112 if (icicle != null) {
113 mChallengeSucceeded = icicle.getBoolean(KEY_CHALLENGE_SUCCEEDED, false);
114 mChallengeRequested = icicle.getBoolean(KEY_CHALLENGE_REQUESTED, false);
Julia Reynolds1a0297c2014-06-18 09:23:15 -0400115 }
Julia Reynolds1a0297c2014-06-18 09:23:15 -0400116
117 IntentFilter offFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
118 offFilter.addAction(Intent.ACTION_USER_PRESENT);
119 getActivity().registerReceiver(mScreenOffReceiver, offFilter);
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -0400120 }
121
122 @Override
Sudheer Shanka95a71e02016-01-12 10:36:18 +0000123 public void onActivityCreated(Bundle savedInstanceState) {
124 super.onActivityCreated(savedInstanceState);
Sudheer Shanka95a71e02016-01-12 10:36:18 +0000125 mEmptyTextView = initEmptyTextView();
126 }
127
128 @Override
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -0400129 public void onSaveInstanceState(Bundle outState) {
130 super.onSaveInstanceState(outState);
131
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -0400132 if (getActivity().isChangingConfigurations()) {
Julia Reynolds1a0297c2014-06-18 09:23:15 -0400133 outState.putBoolean(KEY_CHALLENGE_REQUESTED, mChallengeRequested);
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -0400134 outState.putBoolean(KEY_CHALLENGE_SUCCEEDED, mChallengeSucceeded);
135 }
136 }
137
138 @Override
139 public void onResume() {
140 super.onResume();
Julia Reynoldsd6e493f2014-07-29 09:50:04 -0400141
142 if (shouldBeProviderProtected(mRestrictionKey)) {
143 ensurePin();
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -0400144 }
Maggie Benthall44534962013-08-29 10:49:13 -0400145 }
146
147 @Override
Julia Reynolds1a0297c2014-06-18 09:23:15 -0400148 public void onDestroy() {
Maggie Benthall44534962013-08-29 10:49:13 -0400149 getActivity().unregisterReceiver(mScreenOffReceiver);
Julia Reynolds1a0297c2014-06-18 09:23:15 -0400150 super.onDestroy();
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -0400151 }
152
153 @Override
154 public void onActivityResult(int requestCode, int resultCode, Intent data) {
155 if (requestCode == REQUEST_PIN_CHALLENGE) {
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -0400156 if (resultCode == Activity.RESULT_OK) {
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -0400157 mChallengeSucceeded = true;
Julia Reynolds1a0297c2014-06-18 09:23:15 -0400158 mChallengeRequested = false;
Salvador Martinez8c975b72018-04-18 17:38:46 -0700159 if (mActionDisabledDialog != null && mActionDisabledDialog.isShowing()) {
160 mActionDisabledDialog.setOnDismissListener(null);
161 mActionDisabledDialog.dismiss();
162 }
Julia Reynolds1a0297c2014-06-18 09:23:15 -0400163 } else {
164 mChallengeSucceeded = false;
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -0400165 }
166 return;
167 }
168
169 super.onActivityResult(requestCode, resultCode, data);
170 }
171
Julia Reynolds1a0297c2014-06-18 09:23:15 -0400172 private void ensurePin() {
173 if (!mChallengeSucceeded && !mChallengeRequested
174 && mRestrictionsManager.hasRestrictionsProvider()) {
Amith Yamasani375baea2014-09-05 10:23:04 -0700175 Intent intent = mRestrictionsManager.createLocalApprovalIntent();
Julia Reynolds1a0297c2014-06-18 09:23:15 -0400176 if (intent != null) {
177 mChallengeRequested = true;
178 mChallengeSucceeded = false;
179 PersistableBundle request = new PersistableBundle();
180 request.putString(RestrictionsManager.REQUEST_KEY_MESSAGE,
181 getResources().getString(R.string.restr_pin_enter_admin_pin));
182 intent.putExtra(RestrictionsManager.EXTRA_REQUEST_BUNDLE, request);
183 startActivityForResult(intent, REQUEST_PIN_CHALLENGE);
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -0400184 }
185 }
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -0400186 }
187
188 /**
Julia Reynolds1a0297c2014-06-18 09:23:15 -0400189 * Returns true if this activity is restricted, but no restrictions provider has been set.
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -0400190 * Used to determine if the settings UI should disable UI.
191 */
Julia Reynolds1a0297c2014-06-18 09:23:15 -0400192 protected boolean isRestrictedAndNotProviderProtected() {
193 if (mRestrictionKey == null || RESTRICT_IF_OVERRIDABLE.equals(mRestrictionKey)) {
Geoffrey Borggaardfe21d9a2013-08-02 18:16:27 -0400194 return false;
195 }
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -0400196 return mUserManager.hasUserRestriction(mRestrictionKey)
Julia Reynolds1a0297c2014-06-18 09:23:15 -0400197 && !mRestrictionsManager.hasRestrictionsProvider();
198 }
199
200 protected boolean hasChallengeSucceeded() {
201 return (mChallengeRequested && mChallengeSucceeded) || !mChallengeRequested;
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -0400202 }
Geoffrey Borggaardfe21d9a2013-08-02 18:16:27 -0400203
204 /**
Julia Reynolds1a0297c2014-06-18 09:23:15 -0400205 * Returns true if this restrictions key is locked down.
Geoffrey Borggaardfe21d9a2013-08-02 18:16:27 -0400206 */
Julia Reynolds1a0297c2014-06-18 09:23:15 -0400207 protected boolean shouldBeProviderProtected(String restrictionKey) {
208 if (restrictionKey == null) {
209 return false;
210 }
211 boolean restricted = RESTRICT_IF_OVERRIDABLE.equals(restrictionKey)
212 || mUserManager.hasUserRestriction(mRestrictionKey);
213 return restricted && mRestrictionsManager.hasRestrictionsProvider();
214 }
Geoffrey Borggaard6e1102d2013-08-07 14:57:43 -0400215
Sudheer Shanka95a71e02016-01-12 10:36:18 +0000216 protected TextView initEmptyTextView() {
Sudheer Shanka7dbbe132016-02-16 14:19:32 +0000217 TextView emptyView = (TextView) getActivity().findViewById(android.R.id.empty);
Sudheer Shanka7dbbe132016-02-16 14:19:32 +0000218 return emptyView;
Sudheer Shanka95a71e02016-01-12 10:36:18 +0000219 }
220
Sudheer Shanka7dbbe132016-02-16 14:19:32 +0000221 public EnforcedAdmin getRestrictionEnforcedAdmin() {
Philip P. Moltmanne3f72112018-08-28 15:01:43 -0700222 mEnforcedAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(getActivity(),
Sudheer Shanka7dbbe132016-02-16 14:19:32 +0000223 mRestrictionKey, UserHandle.myUserId());
Philip P. Moltmann035ea3b2018-10-08 10:46:04 -0700224 if (mEnforcedAdmin != null && mEnforcedAdmin.user == null) {
225 mEnforcedAdmin.user = UserHandle.of(UserHandle.myUserId());
Sudheer Shanka7dbbe132016-02-16 14:19:32 +0000226 }
227 return mEnforcedAdmin;
228 }
229
Sudheer Shanka95a71e02016-01-12 10:36:18 +0000230 public TextView getEmptyTextView() {
231 return mEmptyTextView;
232 }
233
234 @Override
235 protected void onDataSetChanged() {
236 highlightPreferenceIfNeeded();
arangelove35badd2017-10-27 13:51:28 +0100237 if (isUiRestrictedByOnlyAdmin()
238 && (mActionDisabledDialog == null || !mActionDisabledDialog.isShowing())) {
Sudheer Shanka7dbbe132016-02-16 14:19:32 +0000239 final EnforcedAdmin admin = getRestrictionEnforcedAdmin();
arangelove35badd2017-10-27 13:51:28 +0100240 mActionDisabledDialog = new ActionDisabledByAdminDialogHelper(getActivity())
241 .prepareDialogBuilder(mRestrictionKey, admin)
242 .setOnDismissListener(__ -> getActivity().finish())
243 .show();
244 setEmptyView(new View(getContext()));
Sudheer Shanka95a71e02016-01-12 10:36:18 +0000245 } else if (mEmptyTextView != null) {
246 setEmptyView(mEmptyTextView);
247 }
248 super.onDataSetChanged();
249 }
250
Sudheer Shanka7dbbe132016-02-16 14:19:32 +0000251 public void setIfOnlyAvailableForAdmins(boolean onlyForAdmins) {
252 mOnlyAvailableForAdmins = onlyForAdmins;
253 }
254
Geoffrey Borggaard6e1102d2013-08-07 14:57:43 -0400255 /**
Julia Reynolds1a0297c2014-06-18 09:23:15 -0400256 * Returns whether restricted or actionable UI elements should be removed or disabled.
Geoffrey Borggaard6e1102d2013-08-07 14:57:43 -0400257 */
Julia Reynolds1a0297c2014-06-18 09:23:15 -0400258 protected boolean isUiRestricted() {
Sudheer Shanka7dbbe132016-02-16 14:19:32 +0000259 return isRestrictedAndNotProviderProtected() || !hasChallengeSucceeded()
260 || (!mIsAdminUser && mOnlyAvailableForAdmins);
Julia Reynolds1a0297c2014-06-18 09:23:15 -0400261 }
Sudheer Shanka9e9e63b2016-02-11 18:48:14 +0000262
263 protected boolean isUiRestrictedByOnlyAdmin() {
264 return isUiRestricted() && !mUserManager.hasBaseUserRestriction(mRestrictionKey,
Sudheer Shanka7dbbe132016-02-16 14:19:32 +0000265 UserHandle.of(UserHandle.myUserId())) && (mIsAdminUser || !mOnlyAvailableForAdmins);
Sudheer Shanka9e9e63b2016-02-11 18:48:14 +0000266 }
Geoffrey Borggaarde38ea382013-08-02 15:03:22 -0400267}