1/*
2 * Copyright (C) 2016 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.settingslib;
18
19import android.content.Context;
20import android.content.res.TypedArray;
21import android.graphics.drawable.Drawable;
22import android.os.UserHandle;
23import android.support.v7.preference.Preference;
24import android.support.v7.preference.PreferenceViewHolder;
25import android.text.TextUtils;
26import android.util.AttributeSet;
27import android.util.TypedValue;
28import android.view.View;
29import android.widget.TextView;
30
31import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
32
33/**
34 * Helper class for managing settings preferences that can be disabled
35 * by device admins via user restrictions.
36 */
37public class RestrictedPreferenceHelper {
38    private final Context mContext;
39    private final Preference mPreference;
40
41    private boolean mDisabledByAdmin;
42    private EnforcedAdmin mEnforcedAdmin;
43    private String mAttrUserRestriction = null;
44    private boolean mUseAdminDisabledSummary = false;
45
46    public RestrictedPreferenceHelper(Context context, Preference preference,
47            AttributeSet attrs) {
48        mContext = context;
49        mPreference = preference;
50
51        if (attrs != null) {
52            final TypedArray attributes = context.obtainStyledAttributes(attrs,
53                    R.styleable.RestrictedPreference);
54            final TypedValue userRestriction =
55                    attributes.peekValue(R.styleable.RestrictedPreference_userRestriction);
56            CharSequence data = null;
57            if (userRestriction != null && userRestriction.type == TypedValue.TYPE_STRING) {
58                if (userRestriction.resourceId != 0) {
59                    data = context.getText(userRestriction.resourceId);
60                } else {
61                    data = userRestriction.string;
62                }
63            }
64            mAttrUserRestriction = data == null ? null : data.toString();
65            // If the system has set the user restriction, then we shouldn't add the padlock.
66            if (RestrictedLockUtils.hasBaseUserRestriction(mContext, mAttrUserRestriction,
67                    UserHandle.myUserId())) {
68                mAttrUserRestriction = null;
69                return;
70            }
71
72            final TypedValue useAdminDisabledSummary =
73                    attributes.peekValue(R.styleable.RestrictedPreference_useAdminDisabledSummary);
74            if (useAdminDisabledSummary != null) {
75                mUseAdminDisabledSummary =
76                        (useAdminDisabledSummary.type == TypedValue.TYPE_INT_BOOLEAN
77                                && useAdminDisabledSummary.data != 0);
78            }
79        }
80    }
81
82    /**
83     * Modify PreferenceViewHolder to add padlock if restriction is disabled.
84     */
85    public void onBindViewHolder(PreferenceViewHolder holder) {
86        if (mDisabledByAdmin) {
87            holder.itemView.setEnabled(true);
88        }
89        if (mUseAdminDisabledSummary) {
90            final TextView summaryView = (TextView) holder.findViewById(android.R.id.summary);
91            if (summaryView != null) {
92                final CharSequence disabledText = summaryView.getContext().getText(
93                        R.string.disabled_by_admin_summary_text);
94                if (mDisabledByAdmin) {
95                    summaryView.setText(disabledText);
96                } else if (TextUtils.equals(disabledText, summaryView.getText())) {
97                    // It's previously set to disabled text, clear it.
98                    summaryView.setText(null);
99                }
100            }
101        }
102    }
103
104    public void useAdminDisabledSummary(boolean useSummary) {
105        mUseAdminDisabledSummary = useSummary;
106    }
107
108    /**
109     * Check if the preference is disabled if so handle the click by informing the user.
110     *
111     * @return true if the method handled the click.
112     */
113    public boolean performClick() {
114        if (mDisabledByAdmin) {
115            RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext, mEnforcedAdmin);
116            return true;
117        }
118        return false;
119    }
120
121    /**
122     * Disable / enable if we have been passed the restriction in the xml.
123     */
124    public void onAttachedToHierarchy() {
125        if (mAttrUserRestriction != null) {
126            checkRestrictionAndSetDisabled(mAttrUserRestriction, UserHandle.myUserId());
127        }
128    }
129
130    /**
131     * Set the user restriction that is used to disable this preference.
132     *
133     * @param userRestriction constant from {@link android.os.UserManager}
134     * @param userId user to check the restriction for.
135     */
136    public void checkRestrictionAndSetDisabled(String userRestriction, int userId) {
137        EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
138                userRestriction, userId);
139        setDisabledByAdmin(admin);
140    }
141
142    /**
143     * Disable this preference based on the enforce admin.
144     *
145     * @param EnforcedAdmin Details of the admin who enforced the restriction. If it
146     * is {@code null}, then this preference will be enabled. Otherwise, it will be disabled.
147     * @return true if the disabled state was changed.
148     */
149    public boolean setDisabledByAdmin(EnforcedAdmin admin) {
150        final boolean disabled = (admin != null ? true : false);
151        mEnforcedAdmin = admin;
152        boolean changed = false;
153        if (mDisabledByAdmin != disabled) {
154            mDisabledByAdmin = disabled;
155            changed = true;
156        }
157        mPreference.setEnabled(!disabled);
158        return changed;
159    }
160
161    public boolean isDisabledByAdmin() {
162        return mDisabledByAdmin;
163    }
164}
165