1e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard/* 2e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard * Copyright (C) 2013 The Android Open Source Project 3e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard * 4e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard * Licensed under the Apache License, Version 2.0 (the "License"); 5e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard * you may not use this file except in compliance with the License. 6e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard * You may obtain a copy of the License at 7e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard * 8e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard * http://www.apache.org/licenses/LICENSE-2.0 9e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard * 10e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard * Unless required by applicable law or agreed to in writing, software 11e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard * distributed under the License is distributed on an "AS IS" BASIS, 12e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard * See the License for the specific language governing permissions and 14e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard * limitations under the License. 15e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard */ 16e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard 17e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaardpackage com.android.settings; 18e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard 19e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaardimport android.app.Activity; 204453496448feaf9152aca7ebffd952ad05a97fddMaggie Benthallimport android.content.BroadcastReceiver; 21e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaardimport android.content.Context; 22e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaardimport android.content.Intent; 234453496448feaf9152aca7ebffd952ad05a97fddMaggie Benthallimport android.content.IntentFilter; 241a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynoldsimport android.content.RestrictionsManager; 25e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaardimport android.os.Bundle; 261a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynoldsimport android.os.PersistableBundle; 27e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaardimport android.os.UserManager; 28e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard 29e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard/** 301a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds * Base class for settings screens that should be pin protected when in restricted mode. 31e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard * The constructor for this class will take the restriction key that this screen should be 321a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds * locked by. If {@link RestrictionsManager.hasRestrictionsProvider()} and 331a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds * {@link UserManager.hasUserRestriction()}, then the user will have to enter the restrictions 341a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds * pin before seeing the Settings screen. 35e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard * 36fe21d9aaa8a8c7f8a759805ba021b59dd821e4feGeoffrey Borggaard * If this settings screen should be pin protected whenever 371a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds * {@link RestrictionsManager.hasRestrictionsProvider()} returns true, pass in 381a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds * {@link RESTRICT_IF_OVERRIDABLE} to the constructor instead of a restrictions key. 39e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard */ 408a963babe2e36b7a41f77b8d2598c97658196e58Chris Wrenpublic abstract class RestrictedSettingsFragment extends SettingsPreferenceFragment { 414453496448feaf9152aca7ebffd952ad05a97fddMaggie Benthall 421a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds protected static final String RESTRICT_IF_OVERRIDABLE = "restrict_if_overridable"; 43e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard 441a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds // No RestrictedSettingsFragment screens should use this number in startActivityForResult. 45e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard private static final int REQUEST_PIN_CHALLENGE = 12309; 46e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard 47e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard private static final String KEY_CHALLENGE_SUCCEEDED = "chsc"; 48e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard private static final String KEY_CHALLENGE_REQUESTED = "chrq"; 49e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard 50e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard // If the restriction PIN is entered correctly. 51e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard private boolean mChallengeSucceeded; 52e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard private boolean mChallengeRequested; 53e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard 54e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard private UserManager mUserManager; 551a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds private RestrictionsManager mRestrictionsManager; 56e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard 57e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard private final String mRestrictionKey; 58e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard 594453496448feaf9152aca7ebffd952ad05a97fddMaggie Benthall // Receiver to clear pin status when the screen is turned off. 604453496448feaf9152aca7ebffd952ad05a97fddMaggie Benthall private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() { 614453496448feaf9152aca7ebffd952ad05a97fddMaggie Benthall @Override 624453496448feaf9152aca7ebffd952ad05a97fddMaggie Benthall public void onReceive(Context context, Intent intent) { 631a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds if (!mChallengeRequested) { 641a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds mChallengeSucceeded = false; 651a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds mChallengeRequested = false; 664453496448feaf9152aca7ebffd952ad05a97fddMaggie Benthall } 674453496448feaf9152aca7ebffd952ad05a97fddMaggie Benthall } 684453496448feaf9152aca7ebffd952ad05a97fddMaggie Benthall }; 694453496448feaf9152aca7ebffd952ad05a97fddMaggie Benthall 70fe21d9aaa8a8c7f8a759805ba021b59dd821e4feGeoffrey Borggaard /** 71fe21d9aaa8a8c7f8a759805ba021b59dd821e4feGeoffrey Borggaard * @param restrictionKey The restriction key to check before pin protecting 721a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds * this settings page. Pass in {@link RESTRICT_IF_OVERRIDABLE} if it should 731a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds * be protected whenever a restrictions provider is set. Pass in 741a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds * null if it should never be protected. 75fe21d9aaa8a8c7f8a759805ba021b59dd821e4feGeoffrey Borggaard */ 76fe21d9aaa8a8c7f8a759805ba021b59dd821e4feGeoffrey Borggaard public RestrictedSettingsFragment(String restrictionKey) { 77fe21d9aaa8a8c7f8a759805ba021b59dd821e4feGeoffrey Borggaard mRestrictionKey = restrictionKey; 78e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard } 79e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard 80e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard @Override 81e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard public void onCreate(Bundle icicle) { 82e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard super.onCreate(icicle); 83e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard 841a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds mRestrictionsManager = (RestrictionsManager) getSystemService(Context.RESTRICTIONS_SERVICE); 85fe21d9aaa8a8c7f8a759805ba021b59dd821e4feGeoffrey Borggaard mUserManager = (UserManager) getSystemService(Context.USER_SERVICE); 86fe21d9aaa8a8c7f8a759805ba021b59dd821e4feGeoffrey Borggaard 87e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard if (icicle != null) { 88e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard mChallengeSucceeded = icicle.getBoolean(KEY_CHALLENGE_SUCCEEDED, false); 89e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard mChallengeRequested = icicle.getBoolean(KEY_CHALLENGE_REQUESTED, false); 901a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds } 911a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds 921a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds IntentFilter offFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF); 931a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds offFilter.addAction(Intent.ACTION_USER_PRESENT); 941a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds getActivity().registerReceiver(mScreenOffReceiver, offFilter); 95e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard } 96e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard 97e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard @Override 98e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard public void onSaveInstanceState(Bundle outState) { 99e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard super.onSaveInstanceState(outState); 100e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard 101e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard if (getActivity().isChangingConfigurations()) { 1021a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds outState.putBoolean(KEY_CHALLENGE_REQUESTED, mChallengeRequested); 103e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard outState.putBoolean(KEY_CHALLENGE_SUCCEEDED, mChallengeSucceeded); 104e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard } 105e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard } 106e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard 107e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard @Override 108e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard public void onResume() { 109e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard super.onResume(); 110d6e493f6499c3be4a0a5af14eb433dec2ab725d3Julia Reynolds 111d6e493f6499c3be4a0a5af14eb433dec2ab725d3Julia Reynolds if (shouldBeProviderProtected(mRestrictionKey)) { 112d6e493f6499c3be4a0a5af14eb433dec2ab725d3Julia Reynolds ensurePin(); 113e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard } 1144453496448feaf9152aca7ebffd952ad05a97fddMaggie Benthall } 1154453496448feaf9152aca7ebffd952ad05a97fddMaggie Benthall 1164453496448feaf9152aca7ebffd952ad05a97fddMaggie Benthall @Override 1171a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds public void onDestroy() { 1184453496448feaf9152aca7ebffd952ad05a97fddMaggie Benthall getActivity().unregisterReceiver(mScreenOffReceiver); 1191a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds super.onDestroy(); 120e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard } 121e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard 122e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard @Override 123e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard public void onActivityResult(int requestCode, int resultCode, Intent data) { 124e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard if (requestCode == REQUEST_PIN_CHALLENGE) { 125e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard if (resultCode == Activity.RESULT_OK) { 126e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard mChallengeSucceeded = true; 1271a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds mChallengeRequested = false; 1281a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds } else { 1291a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds mChallengeSucceeded = false; 130e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard } 131e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard return; 132e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard } 133e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard 134e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard super.onActivityResult(requestCode, resultCode, data); 135e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard } 136e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard 1371a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds private void ensurePin() { 1381a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds if (!mChallengeSucceeded && !mChallengeRequested 1391a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds && mRestrictionsManager.hasRestrictionsProvider()) { 140375baea4563f475e3ae1d1a43518362b0a53f302Amith Yamasani Intent intent = mRestrictionsManager.createLocalApprovalIntent(); 1411a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds if (intent != null) { 1421a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds mChallengeRequested = true; 1431a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds mChallengeSucceeded = false; 1441a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds PersistableBundle request = new PersistableBundle(); 1451a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds request.putString(RestrictionsManager.REQUEST_KEY_MESSAGE, 1461a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds getResources().getString(R.string.restr_pin_enter_admin_pin)); 1471a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds intent.putExtra(RestrictionsManager.EXTRA_REQUEST_BUNDLE, request); 1481a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds startActivityForResult(intent, REQUEST_PIN_CHALLENGE); 149e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard } 150e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard } 151e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard } 152e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard 153e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard /** 1541a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds * Returns true if this activity is restricted, but no restrictions provider has been set. 155e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard * Used to determine if the settings UI should disable UI. 156e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard */ 1571a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds protected boolean isRestrictedAndNotProviderProtected() { 1581a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds if (mRestrictionKey == null || RESTRICT_IF_OVERRIDABLE.equals(mRestrictionKey)) { 159fe21d9aaa8a8c7f8a759805ba021b59dd821e4feGeoffrey Borggaard return false; 160fe21d9aaa8a8c7f8a759805ba021b59dd821e4feGeoffrey Borggaard } 161e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard return mUserManager.hasUserRestriction(mRestrictionKey) 1621a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds && !mRestrictionsManager.hasRestrictionsProvider(); 1631a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds } 1641a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds 1651a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds protected boolean hasChallengeSucceeded() { 1661a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds return (mChallengeRequested && mChallengeSucceeded) || !mChallengeRequested; 167e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard } 168fe21d9aaa8a8c7f8a759805ba021b59dd821e4feGeoffrey Borggaard 169fe21d9aaa8a8c7f8a759805ba021b59dd821e4feGeoffrey Borggaard /** 1701a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds * Returns true if this restrictions key is locked down. 171fe21d9aaa8a8c7f8a759805ba021b59dd821e4feGeoffrey Borggaard */ 1721a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds protected boolean shouldBeProviderProtected(String restrictionKey) { 1731a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds if (restrictionKey == null) { 1741a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds return false; 1751a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds } 1761a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds boolean restricted = RESTRICT_IF_OVERRIDABLE.equals(restrictionKey) 1771a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds || mUserManager.hasUserRestriction(mRestrictionKey); 1781a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds return restricted && mRestrictionsManager.hasRestrictionsProvider(); 1791a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds } 1806e1102d9faf1b8f038857709412c291ef6140aa9Geoffrey Borggaard 1816e1102d9faf1b8f038857709412c291ef6140aa9Geoffrey Borggaard /** 1821a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds * Returns whether restricted or actionable UI elements should be removed or disabled. 1836e1102d9faf1b8f038857709412c291ef6140aa9Geoffrey Borggaard */ 1841a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds protected boolean isUiRestricted() { 1851a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds return isRestrictedAndNotProviderProtected() || !hasChallengeSucceeded(); 1861a0297c544cb15ed4b56e70575b169b3889543b7Julia Reynolds } 187e38ea38002290da8ed16f07ea45f0ebfb41b38cdGeoffrey Borggaard} 188