// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.preferences;
import android.preference.Preference;
import android.view.View;
import android.view.ViewGroup;
/**
* A delegate that determines whether a Preference is managed by enterprise policy. This is used
* in various Preference subclasses (e.g. ChromeSwitchPreference) to determine whether to show
* an enterprise icon next to the Preference and whether to disable clicks on the Preference.
*
* An implementation of this delegate should override isPreferenceControlledByPolicy() and,
* optionally, isPreferenceClickDisabledByPolicy(). Example:
*
* class RocketManagedPreferenceDelegate extends ManagedPreferenceDelegate {
* @Override
* public boolean isPreferenceControlledByPolicy(Preference preference) {
* if ("enable_rockets".equals(preference.getKey())) {
* return RocketUtils.isEnableRocketsManaged();
* }
* return false;
* }
* }
*
* ChromeSwitchPreference enableRocketsPref = ...;
* enableRocketsPref.setManagedPreferenceDelegate(new RocketManagedPreferenceDelegate());
*/
public abstract class ManagedPreferenceDelegate {
/**
* Returns whether the given Preference is controlled by a policy.
*/
public abstract boolean isPreferenceControlledByPolicy(Preference preference);
/**
* Returns whether clicking on the given Preference is disabled due to a policy. The default
* implementation just returns isPreferenceControlledByPolicy(preference). However, some
* preferences that are controlled by policy may still be clicked to show an informational
* subscreen, in which case this method needs a custom implementation.
*/
public boolean isPreferenceClickDisabledByPolicy(Preference preference) {
return isPreferenceControlledByPolicy(preference);
}
/**
* Initializes the Preference based on the state of any policies that may affect it,
* e.g. by showing a managed icon or disabling clicks on the preference.
*
* This should be called once, before the preference is displayed.
*/
public void initPreference(Preference preference) {
if (isPreferenceControlledByPolicy(preference)) {
preference.setIcon(ManagedPreferencesUtils.getManagedByEnterpriseIconId());
if (isPreferenceClickDisabledByPolicy(preference)) {
// Disable the views and prevent the Preference from mucking with the enabled state.
preference.setShouldDisableView(false);
// Prevent default click behavior.
preference.setFragment(null);
preference.setIntent(null);
preference.setOnPreferenceClickListener(null);
}
}
}
/**
* Disables the Preference's views if the preference is not clickable.
*
* Note: this disables the View instead of disabling the Preference, so that the Preference
* still receives click events, which will trigger a "Managed by your administrator" toast.
*
* This should be called from the Preference's onBindView() method.
*
* @param preference The Preference that owns the view
* @param view The View that was bound to the Preference
*/
public void onBindViewToPreference(Preference preference, View view) {
if (isPreferenceClickDisabledByPolicy(preference)) {
disableView(view);
}
}
/**
* Shows the "Managed by your administrator" toast if the given Preference is managed.
*
* This should be called from the Preference's onClick() method.
*
* @param preference The Preference that was clicked.
* @return true if the click event was handled by this helper and shouldn't be further
* propagated; false otherwise.
*/
public boolean onClickPreference(Preference preference) {
if (isPreferenceClickDisabledByPolicy(preference)) {
ManagedPreferencesUtils.showManagedByAdministratorToast(preference.getContext());
return true;
}
return false;
}
/**
* Disables the given View and any subviews, recursively.
*/
private static void disableView(View view) {
view.setEnabled(false);
if (view instanceof ViewGroup) {
ViewGroup group = (ViewGroup) view;
for (int i = 0; i < group.getChildCount(); i++) {
disableView(group.getChildAt(i));
}
}
}
}